From 439abb0af83355f556ce2e57dec9a7ca024c5c58 Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 8 Oct 2012 09:12:01 +0000 Subject: [PATCH] ide: Fixed release build of packages with only .icpp files, Skylark: Removed DDUMPs git-svn-id: svn://ultimatepp.org/upp/trunk@5416 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Skylark/Exe.cpp | 1 - uppsrc/Skylark/Iml/Lib.icpp | 2 +- uppsrc/Skylark/Iml/init | 3 +- uppsrc/ide/Builders/GccBuilder.icpp | 879 ++++++++--------- uppsrc/ide/Builders/MscBuilder.icpp | 1227 ++++++++++++------------ uppsrc/ide/Builders/OwcBuilder.icpp | 3 +- uppsrc/ide/Builders/ScriptBuilder.icpp | 689 ++++++------- 7 files changed, 1403 insertions(+), 1401 deletions(-) diff --git a/uppsrc/Skylark/Exe.cpp b/uppsrc/Skylark/Exe.cpp index 18ec9956b..fc2258d58 100644 --- a/uppsrc/Skylark/Exe.cpp +++ b/uppsrc/Skylark/Exe.cpp @@ -420,7 +420,6 @@ Value Compiler::ExeBlock::Eval(ExeContext& x) const String Render(const One& exe, Renderer *r, Vector& var) { LTIMING("Render0"); - DDUMPC(var); ExeContext x(var, r); Value v = exe->Eval(x); x.out.Cat(AsString(v)); diff --git a/uppsrc/Skylark/Iml/Lib.icpp b/uppsrc/Skylark/Iml/Lib.icpp index 60ed9d823..894261865 100644 --- a/uppsrc/Skylark/Iml/Lib.icpp +++ b/uppsrc/Skylark/Iml/Lib.icpp @@ -30,4 +30,4 @@ INITBLOCK { Compiler::Register("ImlImg", ImlImg); }; -}; \ No newline at end of file +}; diff --git a/uppsrc/Skylark/Iml/init b/uppsrc/Skylark/Iml/init index 85b2f7095..60122448e 100644 --- a/uppsrc/Skylark/Iml/init +++ b/uppsrc/Skylark/Iml/init @@ -2,8 +2,7 @@ #define _Skylark_Iml_icpp_init_stub #include "Draw/init" #include "plugin\png/init" -#include "plugin\jpg/init" -#define BLITZ_INDEX__ F2cfe659668367946f7f2baa1fbeb2b5e +#define BLITZ_INDEX__ Fe08bb47a4f2334977b7d8bba44463f3f #include "Lib.icpp" #undef BLITZ_INDEX__ #endif diff --git a/uppsrc/ide/Builders/GccBuilder.icpp b/uppsrc/ide/Builders/GccBuilder.icpp index 08dca3b76..d4415c8ec 100644 --- a/uppsrc/ide/Builders/GccBuilder.icpp +++ b/uppsrc/ide/Builders/GccBuilder.icpp @@ -1,439 +1,440 @@ -#include "Builders.h" - -void GccBuilder::AddFlags(Index& cfg) -{ -} - -String GccBuilder::CompilerName() const -{ - if(!IsNull(compiler)) return compiler; - return HasFlag("GCC_ARM") ? "arm-wince-pe-c++" : "c++"; -} - -String GccBuilder::CmdLine(const String& package, const Package& pkg) -{ - String cc = CompilerName(); - cc << " -c "; - cc << IncludesDefinesTargetTime(package, pkg); - if(HasFlag("GCC32")) - cc << " -m32"; - return cc; -} - -void GccBuilder::BinaryToObject(String objfile, CParser& binscript, String basedir, - const String& package, const Package& pkg) -{ - String fo = BrcToC(binscript, basedir); - String tmpfile = ForceExt(objfile, ".c"); - SaveFile(tmpfile, fo); - String cc = CmdLine(package, pkg); - cc << " -c -o " << GetHostPathQ(objfile) << " -x c " << GetHostPathQ(tmpfile); - int slot = AllocSlot(); - if(slot < 0 || !Run(cc, slot, objfile, 1)) - throw Exc(NFormat("Error compiling binary object '%s'.", objfile)); -} - -bool GccBuilder::BuildPackage(const String& package, Vector& linkfile, - String& linkoptions, const Vector& all_uses, const Vector& all_libraries, - int opt) -{ - int i; - String packagepath = PackagePath(package); - Package pkg; - pkg.Load(packagepath); - String packagedir = GetFileFolder(packagepath); - ChDir(packagedir); - PutVerbose("cd " + packagedir); - IdeConsoleBeginGroup(package); - Vector obj; - - bool is_shared = HasFlag("SO"); - String shared_ext = (HasFlag("WIN32") ? ".dll" : ".so"); - - String cc = CmdLine(package, pkg); - if(HasFlag("WIN32") && HasFlag("MT")) - cc << " -mthreads"; - if(HasFlag("DEBUG_MINIMAL")) - cc << (HasFlag("WIN32") ? " -g1" : " -ggdb -g1"); - if(HasFlag("DEBUG_FULL")) - cc << (HasFlag("WIN32") ? " -g2" : " -ggdb -g2"); - String fuse_cxa_atexit; - if(is_shared /*&& !HasFlag("MAIN")*/) { - cc << " -shared -fPIC"; - fuse_cxa_atexit = " -fuse-cxa-atexit"; - } - if(!HasFlag("SHARED") && !is_shared) - cc << " -static "; -// else if(!HasFlag("WIN32")) // TRC 05/03/08: dynamic fPIC doesn't seem to work in MinGW -// cc << " -dynamic -fPIC "; // TRC 05/03/30: dynamic fPIC doesn't seem to work in GCC either :-) - cc << ' ' << Gather(pkg.option, config.GetKeys()); - cc << " -fexceptions "; - - if (HasFlag("OSX11")) { - if (HasFlag("POWERPC")) - cc << " -arch ppc"; - if (HasFlag("X86")) - cc << " -arch i386"; - } - - if(HasFlag("SSE2")) - cc << " -msse2 -mfpmath=sse"; - - String cc_speed = cc; - bool release = false; - - if(HasFlag("DEBUG")) - cc << " -D_DEBUG " << debug_options; - else { - release = true; - cc << ' ' << release_size_options; - cc_speed << ' ' << release_options; - if(opt == R_SPEED || pkg.optimize_speed) - cc = cc_speed; - } - - Vector sfile, isfile; - Vector soptions, isoptions; - Vector optimize, ioptimize; - bool error = false; - - for(i = 0; i < pkg.GetCount(); i++) { - if(!IdeIsBuilding()) - return false; - if(!pkg[i].separator) { - String gop = Gather(pkg[i].option, config.GetKeys()); - Vector srcfile = CustomStep(pkg[i], package, error); - if(srcfile.GetCount() == 0) - error = true; - for(int j = 0; j < srcfile.GetCount(); j++) { - String fn = srcfile[j]; - String ext = ToLower(GetFileExt(fn)); - if(ext == ".c" || ext == ".cpp" || ext == ".cc" || ext == ".cxx" || ext == ".m" || ext == ".mm" - || ext == ".s" || ext == ".S" - || ext == ".brc" || (ext == ".rc" && HasFlag("WIN32"))) { - sfile.Add(fn); - soptions.Add(gop); - optimize.Add(release && pkg[i].optimize_speed && opt == R_OPTIMAL); - } - else - if(ext == ".icpp") { - isfile.Add(fn); - isoptions.Add(gop); - ioptimize.Add(release && pkg[i].optimize_speed && opt == R_OPTIMAL); - } - else - if(ext == ".o") - obj.Add(fn); - else - if(ext == ".a" || ext == ".so") - linkfile.Add(fn); - } - } - } - - if(HasFlag("BLITZ")) { - Blitz b = BlitzStep(sfile, soptions, obj, ".o", optimize); - if(b.build) { - PutConsole("BLITZ:" + b.info); - int slot = AllocSlot(); - if(slot < 0 || !Run(String().Cat() << cc << ' ' - << GetHostPathQ(b.path) << " -o " << GetHostPathQ(b.object), slot, GetHostPath(b.object), b.count)) - error = true; - } - } - - int first_ifile = sfile.GetCount(); - sfile.AppendPick(isfile); - soptions.AppendPick(isoptions); - optimize.AppendPick(ioptimize); - - int ccount = 0; - for(i = 0; i < sfile.GetCount(); i++) { - if(!IdeIsBuilding()) - return false; - String fn = sfile[i]; - String ext = ToLower(GetFileExt(fn)); - bool rc = (ext == ".rc"); - bool brc = (ext == ".brc"); - bool init = (i >= first_ifile); - String objfile = CatAnyPath(outdir, GetFileTitle(fn) + (rc ? "$rc.o" : brc ? "$brc.o" : ".o")); - if(HdependFileTime(fn) > GetFileTime(GetHostPath(objfile))) { - PutConsole(GetFileName(fn)); - int time = GetTickCount(); - bool execerr = false; - if(rc) { - String exec; - exec << "windres -i " << GetHostPathQ(fn) - << " -o " << GetHostPathQ(objfile) << IncludesShort(" --include-dir=", package, pkg); - PutVerbose(exec); - int slot = AllocSlot(); - execerr = (slot < 0 || !Run(exec, slot, GetHostPath(objfile), 1)); - } - else if(brc) { - try { -// String hfn = GetHostPath(fn); - String brcdata = LoadFile(fn); - if(brcdata.IsVoid()) - throw Exc(NFormat("error reading file '%s'", fn)); - CParser parser(brcdata, fn); - BinaryToObject(GetHostPath(objfile), parser, GetFileDirectory(fn), package, pkg); - } - catch(Exc e) { - PutConsole(e); - execerr = true; - } - } - else { - String exec = optimize[i] ? cc_speed : cc; - if(ext == ".c") - exec << " -x c "; - else if(ext == ".s" || ext == ".S") - exec << " -x assembler-with-cpp "; - else if (ext == ".m" || ext == ".mm") - exec << fuse_cxa_atexit << " -x objective-c++ "; - else - exec << fuse_cxa_atexit << " -x c++ "; - exec << GetHostPathQ(fn) << " " << soptions[i] << " -o " << GetHostPathQ(objfile); - PutVerbose(exec); - int slot = AllocSlot(); - execerr = (slot < 0 || !Run(exec, slot, GetHostPath(objfile), 1)); - } - if(execerr) - DeleteFile(objfile); - error |= execerr; - PutVerbose("compiled in " + GetPrintTime(time)); - ccount++; - } - if(init) - linkfile.Add(objfile); - else - obj.Add(objfile); - } - - if(error) { -// if(ccount) -// PutCompileTime(time, ccount); - IdeConsoleEndGroup(); - return false; - } - - linkoptions << Gather(pkg.link, config.GetKeys()); - if(linkoptions.GetCount()) - linkoptions << ' '; - - Vector libs = Split(Gather(pkg.library, config.GetKeys()), ' '); - linkfile.Append(libs); - - int libtime = GetTickCount(); - if(!HasFlag("MAIN")) { - if(HasFlag("BLITZ") || HasFlag("NOLIB")) { - linkfile.Append(obj); - IdeConsoleEndGroup(); -// if(ccount) -// PutCompileTime(time, ccount); - return true; - } - IdeConsoleEndGroup(); - if(!Wait()) - return false; - String product; - if(is_shared) - product = GetSharedLibPath(package); - else - product = CatAnyPath(outdir, GetAnyFileName(package) + ".a"); - String hproduct = GetHostPath(product); - Time producttime = GetFileTime(hproduct); -// LOG("hproduct = " << hproduct << ", time = " << producttime); - linkfile.Add(GetHostPath(product)); - for(int i = 0; i < obj.GetCount(); i++) - if(GetFileTime(obj[i]) > producttime) { - String lib; - if(is_shared) { - lib = CompilerName(); - lib << " -shared -fPIC -fuse-cxa-atexit"; - if(!HasFlag("SHARED") && !is_shared) - lib << " -static"; -// else if(!HasFlag("WIN32")) // TRC 05/03/08: dynamic fPIC causes trouble in MinGW -// lib << " -dynamic -fPIC"; // TRC 05/03/30: dynamic fPIC doesn't seem to work in GCC either :-) - if(HasFlag("GCC32")) - lib << " -m32"; - Point p = ExtractVersion(); - if(!IsNull(p.x)) { - lib << " -Xlinker --major-image-version -Xlinker " << p.x; - if(!IsNull(p.y)) - lib << " -Xlinker --minor-image-version -Xlinker " << p.y; - } - lib << ' ' << Gather(pkg.link, config.GetKeys()); - lib << " -o "; - } - else - lib = "ar -sr "; - lib << GetHostPathQ(product); - for(int i = 0; i < obj.GetCount(); i++) - lib << ' ' << GetHostPathQ(obj[i]); - PutConsole("Creating library..."); - DeleteFile(hproduct); - if(is_shared) { - for(int i = 0; i < libpath.GetCount(); i++) - lib << " -L" << GetHostPathQ(libpath[i]); - for(int i = 0; i < all_uses.GetCount(); i++) - lib << ' ' << GetHostPathQ(GetSharedLibPath(all_uses[i])); - for(int i = 0; i < all_libraries.GetCount(); i++) - lib << " -l" << GetHostPathQ(all_libraries[i]); - } - if(!Execute(lib) == 0) { - DeleteFile(hproduct); - return false; - } - PutConsole(String().Cat() << hproduct << " (" << GetFileInfo(hproduct).length - << " B) created in " << GetPrintTime(libtime)); - break; - } - return true; - } - - IdeConsoleEndGroup(); - obj.Append(linkfile); - linkfile = obj; - return true; -} - - -bool GccBuilder::Link(const Vector& linkfile, const String& linkoptions, bool createmap) -{ - if(!Wait()) - return false; - int time = GetTickCount(); - for(int i = 0; i < linkfile.GetCount(); i++) - if(GetFileTime(linkfile[i]) >= targettime) { - Vector lib; - String lnk = CompilerName(); - if(HasFlag("GCC32")) - lnk << " -m32"; - if(HasFlag("DLL")) - lnk << " -shared"; - if(!HasFlag("SHARED") && !HasFlag("SO")) - lnk << " -static"; -// else if(!HasFlag("WIN32")) // TRC 05/03/08: see above -// lnk << " -dynamic -fPIC"; // TRC 05/03/30: dynamic fPIC doesn't seem to work in GCC either :-) - if(HasFlag("WINCE")) - lnk << " -mwindowsce"; - else if(HasFlag("WIN32")) { - lnk << " -mwindows"; - if(HasFlag("MT")) - lnk << " -mthreads"; - if(!HasFlag("GUI")) - lnk << " -mconsole"; - } - lnk << " -o " << GetHostPathQ(target); - if(createmap) - lnk << " -Wl,-Map," << GetHostPathQ(GetFileDirectory(target) + GetFileTitle(target) + ".map"); - if(HasFlag("DEBUG") || HasFlag("DEBUG_MINIMAL") || HasFlag("DEBUG_FULL")) - lnk << " -ggdb"; - else - lnk << (!HasFlag("OSX11") ? " -Wl,-s" : ""); - for(i = 0; i < libpath.GetCount(); i++) - lnk << " -L" << GetHostPathQ(libpath[i]); -// lnk << " -Wl,--gc-sections,-O,2 "; - if(!HasFlag("OSX11")) - lnk << " -Wl,-O,2 "; - lnk << linkoptions; - - if (HasFlag("OSX11")) { - if (HasFlag("POWERPC")) - lnk << " -arch ppc"; - if (HasFlag("X86")) - lnk << " -arch i386"; - } - - String lfilename; - if(HasFlag("OBJC")) { - String lfilename; - String linklist; - for(i = 0; i < linkfile.GetCount(); i++) - if(ToLower(GetFileExt(linkfile[i])) == ".o" || ToLower(GetFileExt(linkfile[i])) == ".a") - linklist << GetHostPath(linkfile[i]) << '\n'; - - String linklistM = "Producing link file list ...\n"; - String odir = GetFileDirectory(linkfile[0]); - lfilename << GetHostPath(GetFileFolder(linkfile[0])) << ".LinkFileList"; - - linklistM << lfilename; - UPP::SaveFile(lfilename, linklist); - lnk << " -L" << GetHostPathQ(odir) - << " -F" << GetHostPathQ(odir) - << " -filelist " << lfilename << " "; - PutConsole( linklistM ); - } - else - for(i = 0; i < linkfile.GetCount(); i++) - if(ToLower(GetFileExt(linkfile[i])) == ".o") - lnk << ' ' << GetHostPathQ(linkfile[i]); - else - lib.Add(linkfile[i]); - - if(!HasFlag("SOLARIS") && !HasFlag("OSX11") && !HasFlag("OBJC")) - lnk << " -Wl,--start-group "; - for(int pass = 0; pass < 2; pass++) - for(i = 0; i < lib.GetCount(); i++) { - String ln = lib[i]; - String ext = ToLower(GetFileExt(ln)); - if(pass == 0) { - if(ext == ".a") - lnk << ' ' << GetHostPathQ(FindInDirs(libpath, lib[i])); - } - else - if(ext != ".a") - if(ext == ".so" || ext == ".dll" || ext == ".lib") - lnk << ' ' << GetHostPathQ(FindInDirs(libpath, lib[i])); - else - lnk << " -l" << ln; - } - if(!HasFlag("SOLARIS") && !HasFlag("OSX11")) - lnk << " -Wl,--end-group"; - PutConsole("Linking..."); - bool error = false; - CustomStep(".pre-link", Null, error); - if(!error && Execute(lnk) == 0) { - CustomStep(".post-link", Null, error); - PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length - << " B) linked in " << GetPrintTime(time)); - return !error; - } - else { - DeleteFile(target); - return false; - } - } - PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length - << " B) is up to date."); - return true; -} - -bool GccBuilder::Preprocess(const String& package, const String& file, const String& target, bool asmout) -{ - Package pkg; - String packagepath = PackagePath(package); - pkg.Load(packagepath); - String packagedir = GetFileFolder(packagepath); - ChDir(packagedir); - PutVerbose("cd " + packagedir); - - String cmd = CmdLine(package, pkg); - cmd << " " << Gather(pkg.option, config.GetKeys()); - cmd << " -o " << target; - cmd << (asmout ? " -S " : " -E ") << GetHostPathQ(file); - return Execute(cmd); -} - -Builder *CreateGccBuilder() -{ - return new GccBuilder; -} - -INITBLOCK -{ - RegisterBuilder("GCC", CreateGccBuilder); - RegisterBuilder("GCC32", CreateGccBuilder); - RegisterBuilder("GCC_ARM", CreateGccBuilder); -} +#include "Builders.h" + +void GccBuilder::AddFlags(Index& cfg) +{ +} + +String GccBuilder::CompilerName() const +{ + if(!IsNull(compiler)) return compiler; + return HasFlag("GCC_ARM") ? "arm-wince-pe-c++" : "c++"; +} + +String GccBuilder::CmdLine(const String& package, const Package& pkg) +{ + String cc = CompilerName(); + cc << " -c "; + cc << IncludesDefinesTargetTime(package, pkg); + if(HasFlag("GCC32")) + cc << " -m32"; + return cc; +} + +void GccBuilder::BinaryToObject(String objfile, CParser& binscript, String basedir, + const String& package, const Package& pkg) +{ + String fo = BrcToC(binscript, basedir); + String tmpfile = ForceExt(objfile, ".c"); + SaveFile(tmpfile, fo); + String cc = CmdLine(package, pkg); + cc << " -c -o " << GetHostPathQ(objfile) << " -x c " << GetHostPathQ(tmpfile); + int slot = AllocSlot(); + if(slot < 0 || !Run(cc, slot, objfile, 1)) + throw Exc(NFormat("Error compiling binary object '%s'.", objfile)); +} + +bool GccBuilder::BuildPackage(const String& package, Vector& linkfile, + String& linkoptions, const Vector& all_uses, const Vector& all_libraries, + int opt) +{ + int i; + String packagepath = PackagePath(package); + Package pkg; + pkg.Load(packagepath); + String packagedir = GetFileFolder(packagepath); + ChDir(packagedir); + PutVerbose("cd " + packagedir); + IdeConsoleBeginGroup(package); + Vector obj; + + bool is_shared = HasFlag("SO"); + String shared_ext = (HasFlag("WIN32") ? ".dll" : ".so"); + + String cc = CmdLine(package, pkg); + if(HasFlag("WIN32") && HasFlag("MT")) + cc << " -mthreads"; + if(HasFlag("DEBUG_MINIMAL")) + cc << (HasFlag("WIN32") ? " -g1" : " -ggdb -g1"); + if(HasFlag("DEBUG_FULL")) + cc << (HasFlag("WIN32") ? " -g2" : " -ggdb -g2"); + String fuse_cxa_atexit; + if(is_shared /*&& !HasFlag("MAIN")*/) { + cc << " -shared -fPIC"; + fuse_cxa_atexit = " -fuse-cxa-atexit"; + } + if(!HasFlag("SHARED") && !is_shared) + cc << " -static "; +// else if(!HasFlag("WIN32")) // TRC 05/03/08: dynamic fPIC doesn't seem to work in MinGW +// cc << " -dynamic -fPIC "; // TRC 05/03/30: dynamic fPIC doesn't seem to work in GCC either :-) + cc << ' ' << Gather(pkg.option, config.GetKeys()); + cc << " -fexceptions "; + + if (HasFlag("OSX11")) { + if (HasFlag("POWERPC")) + cc << " -arch ppc"; + if (HasFlag("X86")) + cc << " -arch i386"; + } + + if(HasFlag("SSE2")) + cc << " -msse2 -mfpmath=sse"; + + String cc_speed = cc; + bool release = false; + + if(HasFlag("DEBUG")) + cc << " -D_DEBUG " << debug_options; + else { + release = true; + cc << ' ' << release_size_options; + cc_speed << ' ' << release_options; + if(opt == R_SPEED || pkg.optimize_speed) + cc = cc_speed; + } + + Vector sfile, isfile; + Vector soptions, isoptions; + Vector optimize, ioptimize; + bool error = false; + + for(i = 0; i < pkg.GetCount(); i++) { + if(!IdeIsBuilding()) + return false; + if(!pkg[i].separator) { + String gop = Gather(pkg[i].option, config.GetKeys()); + Vector srcfile = CustomStep(pkg[i], package, error); + if(srcfile.GetCount() == 0) + error = true; + for(int j = 0; j < srcfile.GetCount(); j++) { + String fn = srcfile[j]; + String ext = ToLower(GetFileExt(fn)); + if(ext == ".c" || ext == ".cpp" || ext == ".cc" || ext == ".cxx" || ext == ".m" || ext == ".mm" + || ext == ".s" || ext == ".S" + || ext == ".brc" || (ext == ".rc" && HasFlag("WIN32"))) { + sfile.Add(fn); + soptions.Add(gop); + optimize.Add(release && pkg[i].optimize_speed && opt == R_OPTIMAL); + } + else + if(ext == ".icpp") { + isfile.Add(fn); + isoptions.Add(gop); + ioptimize.Add(release && pkg[i].optimize_speed && opt == R_OPTIMAL); + } + else + if(ext == ".o") + obj.Add(fn); + else + if(ext == ".a" || ext == ".so") + linkfile.Add(fn); + } + } + } + + if(HasFlag("BLITZ")) { + Blitz b = BlitzStep(sfile, soptions, obj, ".o", optimize); + if(b.build) { + PutConsole("BLITZ:" + b.info); + int slot = AllocSlot(); + if(slot < 0 || !Run(String().Cat() << cc << ' ' + << GetHostPathQ(b.path) << " -o " << GetHostPathQ(b.object), slot, GetHostPath(b.object), b.count)) + error = true; + } + } + + int first_ifile = sfile.GetCount(); + sfile.AppendPick(isfile); + soptions.AppendPick(isoptions); + optimize.AppendPick(ioptimize); + + int ccount = 0; + for(i = 0; i < sfile.GetCount(); i++) { + if(!IdeIsBuilding()) + return false; + String fn = sfile[i]; + String ext = ToLower(GetFileExt(fn)); + bool rc = (ext == ".rc"); + bool brc = (ext == ".brc"); + bool init = (i >= first_ifile); + String objfile = CatAnyPath(outdir, GetFileTitle(fn) + (rc ? "$rc.o" : brc ? "$brc.o" : ".o")); + if(HdependFileTime(fn) > GetFileTime(GetHostPath(objfile))) { + PutConsole(GetFileName(fn)); + int time = GetTickCount(); + bool execerr = false; + if(rc) { + String exec; + exec << "windres -i " << GetHostPathQ(fn) + << " -o " << GetHostPathQ(objfile) << IncludesShort(" --include-dir=", package, pkg); + PutVerbose(exec); + int slot = AllocSlot(); + execerr = (slot < 0 || !Run(exec, slot, GetHostPath(objfile), 1)); + } + else if(brc) { + try { +// String hfn = GetHostPath(fn); + String brcdata = LoadFile(fn); + if(brcdata.IsVoid()) + throw Exc(NFormat("error reading file '%s'", fn)); + CParser parser(brcdata, fn); + BinaryToObject(GetHostPath(objfile), parser, GetFileDirectory(fn), package, pkg); + } + catch(Exc e) { + PutConsole(e); + execerr = true; + } + } + else { + String exec = optimize[i] ? cc_speed : cc; + if(ext == ".c") + exec << " -x c "; + else if(ext == ".s" || ext == ".S") + exec << " -x assembler-with-cpp "; + else if (ext == ".m" || ext == ".mm") + exec << fuse_cxa_atexit << " -x objective-c++ "; + else + exec << fuse_cxa_atexit << " -x c++ "; + exec << GetHostPathQ(fn) << " " << soptions[i] << " -o " << GetHostPathQ(objfile); + PutVerbose(exec); + int slot = AllocSlot(); + execerr = (slot < 0 || !Run(exec, slot, GetHostPath(objfile), 1)); + } + if(execerr) + DeleteFile(objfile); + error |= execerr; + PutVerbose("compiled in " + GetPrintTime(time)); + ccount++; + } + if(init) + linkfile.Add(objfile); + else + obj.Add(objfile); + } + + if(error) { +// if(ccount) +// PutCompileTime(time, ccount); + IdeConsoleEndGroup(); + return false; + } + + linkoptions << Gather(pkg.link, config.GetKeys()); + if(linkoptions.GetCount()) + linkoptions << ' '; + + Vector libs = Split(Gather(pkg.library, config.GetKeys()), ' '); + linkfile.Append(libs); + + int libtime = GetTickCount(); + if(!HasFlag("MAIN")) { + if(HasFlag("BLITZ") || HasFlag("NOLIB")) { + linkfile.Append(obj); + IdeConsoleEndGroup(); +// if(ccount) +// PutCompileTime(time, ccount); + return true; + } + IdeConsoleEndGroup(); + if(!Wait()) + return false; + String product; + if(is_shared) + product = GetSharedLibPath(package); + else + product = CatAnyPath(outdir, GetAnyFileName(package) + ".a"); + String hproduct = GetHostPath(product); + Time producttime = GetFileTime(hproduct); +// LOG("hproduct = " << hproduct << ", time = " << producttime); + if(obj.GetCount()) + linkfile.Add(GetHostPath(product)); + for(int i = 0; i < obj.GetCount(); i++) + if(GetFileTime(obj[i]) > producttime) { + String lib; + if(is_shared) { + lib = CompilerName(); + lib << " -shared -fPIC -fuse-cxa-atexit"; + if(!HasFlag("SHARED") && !is_shared) + lib << " -static"; +// else if(!HasFlag("WIN32")) // TRC 05/03/08: dynamic fPIC causes trouble in MinGW +// lib << " -dynamic -fPIC"; // TRC 05/03/30: dynamic fPIC doesn't seem to work in GCC either :-) + if(HasFlag("GCC32")) + lib << " -m32"; + Point p = ExtractVersion(); + if(!IsNull(p.x)) { + lib << " -Xlinker --major-image-version -Xlinker " << p.x; + if(!IsNull(p.y)) + lib << " -Xlinker --minor-image-version -Xlinker " << p.y; + } + lib << ' ' << Gather(pkg.link, config.GetKeys()); + lib << " -o "; + } + else + lib = "ar -sr "; + lib << GetHostPathQ(product); + for(int i = 0; i < obj.GetCount(); i++) + lib << ' ' << GetHostPathQ(obj[i]); + PutConsole("Creating library..."); + DeleteFile(hproduct); + if(is_shared) { + for(int i = 0; i < libpath.GetCount(); i++) + lib << " -L" << GetHostPathQ(libpath[i]); + for(int i = 0; i < all_uses.GetCount(); i++) + lib << ' ' << GetHostPathQ(GetSharedLibPath(all_uses[i])); + for(int i = 0; i < all_libraries.GetCount(); i++) + lib << " -l" << GetHostPathQ(all_libraries[i]); + } + if(!Execute(lib) == 0) { + DeleteFile(hproduct); + return false; + } + PutConsole(String().Cat() << hproduct << " (" << GetFileInfo(hproduct).length + << " B) created in " << GetPrintTime(libtime)); + break; + } + return true; + } + + IdeConsoleEndGroup(); + obj.Append(linkfile); + linkfile = obj; + return true; +} + + +bool GccBuilder::Link(const Vector& linkfile, const String& linkoptions, bool createmap) +{ + if(!Wait()) + return false; + int time = GetTickCount(); + for(int i = 0; i < linkfile.GetCount(); i++) + if(GetFileTime(linkfile[i]) >= targettime) { + Vector lib; + String lnk = CompilerName(); + if(HasFlag("GCC32")) + lnk << " -m32"; + if(HasFlag("DLL")) + lnk << " -shared"; + if(!HasFlag("SHARED") && !HasFlag("SO")) + lnk << " -static"; +// else if(!HasFlag("WIN32")) // TRC 05/03/08: see above +// lnk << " -dynamic -fPIC"; // TRC 05/03/30: dynamic fPIC doesn't seem to work in GCC either :-) + if(HasFlag("WINCE")) + lnk << " -mwindowsce"; + else if(HasFlag("WIN32")) { + lnk << " -mwindows"; + if(HasFlag("MT")) + lnk << " -mthreads"; + if(!HasFlag("GUI")) + lnk << " -mconsole"; + } + lnk << " -o " << GetHostPathQ(target); + if(createmap) + lnk << " -Wl,-Map," << GetHostPathQ(GetFileDirectory(target) + GetFileTitle(target) + ".map"); + if(HasFlag("DEBUG") || HasFlag("DEBUG_MINIMAL") || HasFlag("DEBUG_FULL")) + lnk << " -ggdb"; + else + lnk << (!HasFlag("OSX11") ? " -Wl,-s" : ""); + for(i = 0; i < libpath.GetCount(); i++) + lnk << " -L" << GetHostPathQ(libpath[i]); +// lnk << " -Wl,--gc-sections,-O,2 "; + if(!HasFlag("OSX11")) + lnk << " -Wl,-O,2 "; + lnk << linkoptions; + + if (HasFlag("OSX11")) { + if (HasFlag("POWERPC")) + lnk << " -arch ppc"; + if (HasFlag("X86")) + lnk << " -arch i386"; + } + + String lfilename; + if(HasFlag("OBJC")) { + String lfilename; + String linklist; + for(i = 0; i < linkfile.GetCount(); i++) + if(ToLower(GetFileExt(linkfile[i])) == ".o" || ToLower(GetFileExt(linkfile[i])) == ".a") + linklist << GetHostPath(linkfile[i]) << '\n'; + + String linklistM = "Producing link file list ...\n"; + String odir = GetFileDirectory(linkfile[0]); + lfilename << GetHostPath(GetFileFolder(linkfile[0])) << ".LinkFileList"; + + linklistM << lfilename; + UPP::SaveFile(lfilename, linklist); + lnk << " -L" << GetHostPathQ(odir) + << " -F" << GetHostPathQ(odir) + << " -filelist " << lfilename << " "; + PutConsole( linklistM ); + } + else + for(i = 0; i < linkfile.GetCount(); i++) + if(ToLower(GetFileExt(linkfile[i])) == ".o") + lnk << ' ' << GetHostPathQ(linkfile[i]); + else + lib.Add(linkfile[i]); + + if(!HasFlag("SOLARIS") && !HasFlag("OSX11") && !HasFlag("OBJC")) + lnk << " -Wl,--start-group "; + for(int pass = 0; pass < 2; pass++) + for(i = 0; i < lib.GetCount(); i++) { + String ln = lib[i]; + String ext = ToLower(GetFileExt(ln)); + if(pass == 0) { + if(ext == ".a") + lnk << ' ' << GetHostPathQ(FindInDirs(libpath, lib[i])); + } + else + if(ext != ".a") + if(ext == ".so" || ext == ".dll" || ext == ".lib") + lnk << ' ' << GetHostPathQ(FindInDirs(libpath, lib[i])); + else + lnk << " -l" << ln; + } + if(!HasFlag("SOLARIS") && !HasFlag("OSX11")) + lnk << " -Wl,--end-group"; + PutConsole("Linking..."); + bool error = false; + CustomStep(".pre-link", Null, error); + if(!error && Execute(lnk) == 0) { + CustomStep(".post-link", Null, error); + PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length + << " B) linked in " << GetPrintTime(time)); + return !error; + } + else { + DeleteFile(target); + return false; + } + } + PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length + << " B) is up to date."); + return true; +} + +bool GccBuilder::Preprocess(const String& package, const String& file, const String& target, bool asmout) +{ + Package pkg; + String packagepath = PackagePath(package); + pkg.Load(packagepath); + String packagedir = GetFileFolder(packagepath); + ChDir(packagedir); + PutVerbose("cd " + packagedir); + + String cmd = CmdLine(package, pkg); + cmd << " " << Gather(pkg.option, config.GetKeys()); + cmd << " -o " << target; + cmd << (asmout ? " -S " : " -E ") << GetHostPathQ(file); + return Execute(cmd); +} + +Builder *CreateGccBuilder() +{ + return new GccBuilder; +} + +INITBLOCK +{ + RegisterBuilder("GCC", CreateGccBuilder); + RegisterBuilder("GCC32", CreateGccBuilder); + RegisterBuilder("GCC_ARM", CreateGccBuilder); +} diff --git a/uppsrc/ide/Builders/MscBuilder.icpp b/uppsrc/ide/Builders/MscBuilder.icpp index f912df1c8..541b3e1d0 100644 --- a/uppsrc/ide/Builders/MscBuilder.icpp +++ b/uppsrc/ide/Builders/MscBuilder.icpp @@ -1,613 +1,614 @@ -#include "Builders.h" - -#include - -#ifdef PLATFORM_WIN32 -static bool HasTail(String s, const char *tail) -{ - int tl = (int)strlen(tail); - int sl = s.GetLength(); - if(sl < tl) - return false; - for(const char *p = s.GetIter(sl - tl); *p; p++, tail++) - if(*tail != '*' && *tail != *p) - return false; - return *tail == 0; -} -#endif - -static void AddObjectExports(const char *path, Index& out) -{ -#ifdef PLATFORM_WIN32 - FileMapping mapping; - if(!mapping.Open(path)) - return; - const byte *begin = mapping.Begin(); - const COFF_IMAGE_FILE_HEADER *hdr = (const COFF_IMAGE_FILE_HEADER *)begin; - if(hdr->Machine != COFF_IMAGE_FILE_MACHINE_I386) - return; - const COFF_IMAGE_SECTION_HEADER *sechdr = (const COFF_IMAGE_SECTION_HEADER *)(begin - + sizeof(COFF_IMAGE_FILE_HEADER) + hdr->SizeOfOptionalHeader); - Index code_sections; - for(int i = 0; i < hdr->NumberOfSections; i++) - if(sechdr[i].Characteristics & COFF_IMAGE_SCN_CNT_CODE) - code_sections.Add(i + 1); - const COFF_IMAGE_SYMBOL *symtbl = (const COFF_IMAGE_SYMBOL *)(begin + hdr->PointerToSymbolTable); - const char *strtbl = (const char *)(symtbl + hdr->NumberOfSymbols); - for(int i = 0; i < (int)hdr->NumberOfSymbols; i++) - { - const COFF_IMAGE_SYMBOL& sym = symtbl[i]; - if(sym.StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL && code_sections.Find(sym.SectionNumber) >= 0) - { - String name = COFFSymbolName(sym, strtbl); - if(!HasTail(name, "AEPAXI@Z")) - { - if(*name == '_' && name.Find('@') < 0) - name.Remove(0, 1); - out.FindAdd(name); - } - } - i += sym.NumberOfAuxSymbols; - } -#endif -} - -void MscBuilder::AddFlags(Index& cfg) -{ - cfg.FindAdd("MSC"); -} - -String MscBuilder::CmdLine(const String& package, const Package& pkg) -{ - String cc; - if(HasFlag("ARM")) - cc = "clarm"; - else - if(HasFlag("MIPS")) - cc = "clmips"; - else - if(HasFlag("SH3")) - cc = "shcl /Qsh3"; - else - if(HasFlag("SH4")) - cc = "shcl /Qsh4"; - else - if(HasFlag("MSC8ARM")) - cc = "cl -GS- "; - else - cc = HasFlag("INTEL") ? "icl" : "cl"; -// TRC 080605-documentation says Wp64 works in 32-bit compilation only -// cc << (IsMsc64() ? " -nologo -Wp64 -W3 -GR -c" : " -nologo -W3 -GR -c"); - cc << " -nologo -W3 -GR -c"; - cc << IncludesDefinesTargetTime(package, pkg); - - return cc; -} - -String MscBuilder::MachineName() const -{ - if(HasFlag("ARM")) return "ARM"; - if(HasFlag("MIPS")) return "MIPS"; - if(HasFlag("SH3")) return "SH3"; - if(HasFlag("SH4")) return "SH4"; - if(IsMscArm()) return "ARM"; - if(IsMsc64()) return "x64"; - if(HasFlag("WIN32")) return "I386"; - return "IX86"; -} - -bool MscBuilder::IsMsc89() const -{ - return IsMsc86() || IsMsc64() || IsMscArm(); -} - -bool MscBuilder::IsMsc86() const -{ - return HasFlag("MSC8") || HasFlag("MSC9") || HasFlag("MSC10"); -} - -bool MscBuilder::IsMscArm() const -{ - return HasFlag("MSC8ARM") || HasFlag("MSC9ARM"); -} - -bool MscBuilder::IsMsc64() const -{ - return HasFlag("MSC8X64") || HasFlag("MSC9X64") || HasFlag("MSC10X64"); -} - -String MscBuilder::LinkerName() const -{ - if(HasFlag("ULD")) return "uld"; - if(HasFlag("INTEL")) return "xilink"; - return "link"; -} - -static bool sContainsPchOptions(const String& x) -{ - Index a = Split(x, ' '); - return a.Find("-GL") >= 0 || a.Find("/GL") >= 0 || a.Find("-Y-") >= 0 || a.Find("/Y-") >= 0 - || a.Find("-Yc") >= 0 || a.Find("/Yc") >= 0 || a.Find("-Yd") >= 0 || a.Find("/Yd") >= 0 - || a.Find("-Yl") >= 0 || a.Find("/Yl") >= 0 || a.Find("-Yu") >= 0 || a.Find("/Yu") >= 0 - || a.Find("-YX") >= 0 || a.Find("/YX") >= 0; -} - -bool MscBuilder::HasAnyDebug() const -{ - return HasFlag("DEBUG") || HasFlag("DEBUG_MINIMAL") || HasFlag("DEBUG_FULL"); -} - -String MscBuilder::PdbPch(String package, int slot, bool do_pch) const -{ - String pkg_slot = NFormat("%s-%d", GetAnyFileName(package), slot + 1); - String pdb = GetHostPathQ(CatAnyPath(outdir, pkg_slot + ".pdb")); - String cc; - cc << " -Gy -Fd" << pdb; - if(do_pch && !IsMsc89()) // MSC8/9 does not support automatic precompiled headers... - cc << " -YX -Fp" << GetHostPathQ(CatAnyPath(outdir, pkg_slot + ".pch")) << ' '; - return cc; -} - -bool MscBuilder::BuildPackage(const String& package, Vector& linkfile, String& linkoptions, - const Vector& all_uses, const Vector& all_libraries, int opt) -{ - int i; - String packagepath = PackagePath(package); - Package pkg; - pkg.Load(packagepath); - String packagedir = GetFileFolder(packagepath); - ChDir(packagedir); - PutVerbose("cd " + packagedir); - IdeConsoleBeginGroup(package); - Vector obj; - - bool is_shared = HasFlag("SO"), - is_clr = HasFlag("CLR"); - - String cc = CmdLine(package, pkg); - if(HasFlag("EVC")) { - if(!HasFlag("SH3") && !HasFlag("SH4")) - cc << " -Gs8192"; // disable stack checking - cc << " -GF" // read-only string pooling - " -GX-"; // turn off exception handling - } - else - if(is_clr) - cc << " -EHac"; - else - if(IsMsc89()) - cc << " -EHsc"; - else - cc << " -GX"; -// String pdb = GetHostPathQ(CatAnyPath(outdir, GetAnyFileName(package) + ".pdb")); -// String pch; -// if(!HasFlag("MSC8")) // MSC8 does not support automatic precompiled headers... -// pch << " -YX -Fp" << GetHostPathQ(CatAnyPath(outdir, GetAnyFileName(package) + ".pch")) << ' '; -// cc << " -Gy -Fd" << pdb; - if(HasFlag("SSE2") && !IsMsc64()) - cc << " /arch:SSE2"; - if(HasFlag("DEBUG_MINIMAL")) - cc << " -Zd"; - if(HasFlag("DEBUG_FULL")) - cc << " -Zi"; - cc << ' ' << Gather(pkg.option, config.GetKeys()); - cc << (HasFlag("SHARED") || is_shared || is_clr ? " -MD" - : (HasFlag("MT") || IsMsc89()) ? " -MT" : " -ML"); - - String cc_size = cc; - String cc_speed = cc; - bool release = false; - - if(HasFlag("DEBUG")) - cc << "d " << debug_options; - else { - release = true; - cc << ' ' << release_size_options; - cc_speed << ' ' << release_options; - if(opt == R_SPEED || pkg.optimize_speed) - cc = cc_speed; - } - - - Vector sfile, isfile; - Vector soptions, isoptions; - Vector optimize, ioptimize; - Vector sobjfile; - bool error = false; - - for(i = 0; i < pkg.GetCount(); i++) { - if(!IdeIsBuilding()) - return false; - if(!pkg[i].separator) { - String gop = Gather(pkg[i].option, config.GetKeys()); - Vector srcfile = CustomStep(pkg[i], package, error); - if(srcfile.GetCount() == 0) - error = true; - for(int j = 0; j < srcfile.GetCount(); j++) { - String fn = srcfile[j]; - String ext = ToLower(GetFileExt(fn)); - if(ext == ".c" || ext == ".cpp" || ext == ".cc" || ext == ".cxx" || ext == ".rc" || ext == ".brc") { - sfile.Add(fn); - soptions.Add(gop); - optimize.Add(release && pkg[i].optimize_speed && opt == R_OPTIMAL); - } - else - if(ext == ".icpp") { - isfile.Add(fn); - isoptions.Add(gop); - ioptimize.Add(release && pkg[i].optimize_speed && opt == R_OPTIMAL); - } - else - if(ext == ".obj") - obj.Add(fn); - else - if(ext == ".lib") - linkfile.Add(fn); - } - } - } - - if(HasFlag("BLITZ")) { - Blitz b = BlitzStep(sfile, soptions, obj, ".obj", optimize); - if(b.build) { - PutConsole("BLITZ:" + b.info); - int slot = AllocSlot(); - if(slot < 0 || ! Run(cc + PdbPch(package, slot, false) - + " -Tp " + GetHostPathQ(b.path) + " -Fo" + GetHostPathQ(b.object), slot, GetHostPath(b.object), b.count)) - error = true; - } - } - - int first_ifile = sfile.GetCount(); - sfile.AppendPick(isfile); - soptions.AppendPick(isoptions); - optimize.AppendPick(ioptimize); - - int ccount = 0; - -// if(sContainsPchOptions(cc)) -// pch = Null; - - for(i = 0; i < sfile.GetCount(); i++) { - if(!IdeIsBuilding()) - return false; - String fn = sfile[i]; - String ext = ToLower(GetFileExt(fn)); - bool rc = (ext == ".rc"); - bool brc = (ext == ".brc"); - bool init = (i >= first_ifile); - String objfile = CatAnyPath(outdir, GetFileTitle(fn) + (rc ? "$rc.obj" : brc ? "$brc.obj" : ".obj")); - if(HdependFileTime(fn) > GetFileTime(objfile)) { - int time = GetTickCount(); - bool execerr = false; - if(rc) { - PutConsole(GetFileNamePos(fn)); - int slot = AllocSlot(); - if(slot < 0 || !Run("rc /fo" + GetHostPathQ(objfile) + Includes(" /i", package, pkg) - + ' ' + GetHostPathQ(fn), slot, GetHostPath(objfile), 1)) - execerr = true; - } - else - if(brc) { - try { -// String hfn = GetHostPath(fn); - String brcdata = LoadFile(fn); - if(brcdata.IsVoid()) - throw Exc(NFormat("error reading file '%s'", fn)); - CParser parser(brcdata, fn); - String fo = BrcToC(parser, GetFileDirectory(fn)); - String tmpfile = ForceExt(objfile, ".c"); - SaveFile(tmpfile, fo); - int slot = AllocSlot(); - StringBuffer cmdline; - cmdline << cc << PdbPch(package, slot, false) - << " -Tc " << GetHostPathQ(tmpfile) << " -Fo" << GetHostPathQ(objfile); - if(slot < 0 || !Run(String(cmdline), slot, GetHostPath(objfile), 1)) - throw Exc(NFormat("Error compiling binary object '%s'.", objfile)); - } - catch(Exc e) { - PutConsole(e); - execerr = true; - } - } - else { - String c = cc; - if(optimize[i]) - c = cc_speed; - int slot = AllocSlot(); - if(slot < 0 || !Run(c + PdbPch(package, slot, !sContainsPchOptions(cc) && !sContainsPchOptions(soptions[i])) - + " " + soptions[i] + (ext == ".c" ? " -Tc " : " -Tp ") - + GetHostPathQ(fn) + " -Fo" + GetHostPathQ(objfile), slot, GetHostPath(objfile), 1)) - execerr = true; - } - if(execerr) - DeleteFile(objfile); - error |= execerr; - PutVerbose("compiled in " + GetPrintTime(time)); - ccount++; - } - if(init) - linkfile.Add(objfile); - else - obj.Add(objfile); - } - if(error) { - IdeConsoleEndGroup(); - return false; - } - - Vector pkglibs = Split(Gather(pkg.library, config.GetKeys()), ' '); - for(int i = 0; i < pkglibs.GetCount(); i++) { - String libfile = AppendExt(pkglibs[i], ".lib"); - if(!IsFullPath(libfile)) { - for(int p = 0; p < libpath.GetCount(); p++) { - String nf = NormalizePath(libfile, libpath[p]); - if(FileExists(nf)) { - libfile = nf; - break; - } - } - } - linkfile.Add(libfile); - } - linkoptions << ' ' << Gather(pkg.link, config.GetKeys()); - - int linktime = GetTickCount(); - if(!HasFlag("MAIN")) { - if(HasFlag("BLITZ") || HasFlag("NOLIB")) { - linkfile.Append(obj); -// ShowTime(ccount, time); - IdeConsoleEndGroup(); - return true; - } - String product; - if(is_shared) - product = GetSharedLibPath(package); - else - product = CatAnyPath(outdir, GetAnyFileName(package) + ".lib"); - Time producttime = GetFileTime(product); - linkfile.Add(ForceExt(product, ".lib")); - if(!Wait()) { - IdeConsoleEndGroup(); - return false; - } - Vector objinfo = host->GetFileInfo(obj); - for(int i = 0; i < obj.GetCount(); i++) - if(objinfo[i] > producttime) { - String linker, lib; - if(is_shared) { - linker << LinkerName() << "-dll -nologo "; - lib << "-machine:" << MachineName() - << " -pdb:" << GetHostPathQ(ForceExt(product, ".pdb")) - << " -out:" << GetHostPathQ(product); - if(!HasFlag("MSC10") && !HasFlag("MSC10X64")) - lib << " -incremental:no"; - if(HasFlag("FORCE_SIZE")){ - if(sContainsPchOptions(release_size_options)) - lib << " -ltcg"; - } - else - if(HasFlag("FORCE_SPEED")) - if(sContainsPchOptions(release_options)) - lib << " -ltcg"; - if(HasAnyDebug()) - lib << " -debug -OPT:NOREF"; - else - lib << " -release -OPT:REF,ICF"; - if(IsMscArm()) - lib << " -subsystem:windowsce,4.20 /ARMPADCODE"; - else - if(HasFlag("GUI")) - lib << (HasFlag("WIN32") ? " -subsystem:windows" - : " -subsystem:windowsce"); - else - lib << " -subsystem:console"; - Index exports; - for(int o = 0; o < obj.GetCount(); o++) - AddObjectExports(obj[o], exports); - String def; - def << "LIBRARY " << AsCString(GetFileName(product)) << "\n\n" - "EXPORTS\n"; - for(int o = 0; o < exports.GetCount(); o++) - def << '\t' << exports[o] << "\n"; //" @" << (o + 1) << "\n"; - String deffile = ForceExt(product, ".def"); - if(!SaveChangedFile(deffile, def)) - { - PutConsole(NFormat("%s: error saving file", deffile)); - return false; - } - lib << " -def:" << GetHostPathQ(deffile); - for(int i = 0; i < libpath.GetCount(); i++) - lib << " -LIBPATH:" << GetHostPathQ(libpath[i]); - lib << ' ' << Gather(pkg.link, config.GetKeys()); - for(int i = 0; i < all_uses.GetCount(); i++) - lib << ' ' << GetHostPathQ(ForceExt(GetSharedLibPath(all_uses[i]), ".lib")); - for(int i = 0; i < all_libraries.GetCount(); i++) { - String libfile = AppendExt(all_libraries[i], ".lib"); - if(!IsFullPath(libfile)) { - for(int p = 0; p < libpath.GetCount(); p++) { - String nf = NormalizePath(libfile, libpath[p]); - if(FileExists(nf)) { - libfile = nf; - break; - } - } - } - lib << ' ' << GetHostPathQ(libfile); - } - } - else{ - linker << (HasFlag("INTEL") ? "xilib" : "link /lib") << " -nologo "; - if(HasFlag("FORCE_SIZE")){ - if(sContainsPchOptions(release_size_options)) - lib << " -ltcg"; - } - else - if(HasFlag("FORCE_SPEED")) - if(sContainsPchOptions(release_options)) - lib << " -ltcg"; - lib << " -out:" << GetHostPathQ(product) << ' ' << Gather(pkg.link, config.GetKeys()); - } - for(int i = 0; i < obj.GetCount(); i++) - lib << ' ' << GetHostPathQ(obj[i]); - PutConsole("Creating library..."); - IdeConsoleEndGroup(); - DeleteFile(product); - String tmpFileName; - if(linker.GetCount() + lib.GetCount() >= 8192) - { - tmpFileName = GetTempFileName(); - // we can't simply put all data on a single line - // as it has a limit of around 130000 chars too, so we split - // in multiple lines - FileOut f(tmpFileName); - while(lib != "") - { - int found = 0; - bool quotes = false; - int lim = min(8192, lib.GetCount()); - for(int i = 0; i < lim; i++) - { - char c = lib[i]; - if(isspace(c) && !quotes) - found = i; - else if(c == '"') - quotes = !quotes; - } - if(!found) - found = lib.GetCount(); - f.PutLine(lib.Left(found)); - lib.Remove(0, found); - } - f.Close(); - linker << "@" << tmpFileName; - } - else - linker << lib; - bool res = Execute(linker); - if(tmpFileName != "") - FileDelete(tmpFileName); - if(res) { - DeleteFile(product); - return false; - } - else - if((IsMsc86() || IsMsc64()) && is_shared) { - String mt("mt -nologo -manifest "); - mt << GetHostPathQ(product) << ".manifest -outputresource:" << GetHostPathQ(product) << ";2"; - Execute(mt); - } - PutConsole(String().Cat() << product << " (" << GetFileInfo(product).length - << " B) created in " << GetPrintTime(linktime)); - break; - } - return true; - } - - IdeConsoleEndGroup(); - obj.Append(linkfile); - linkfile = obj; - return true; -} - -bool MscBuilder::Link(const Vector& linkfile, const String& linkoptions, bool createmap) -{ - int time = GetTickCount(); - if(!Wait()) - return false; - for(int i = 0; i < linkfile.GetCount(); i++) - if(GetFileTime(linkfile[i]) >= targettime) { - String link; - link << LinkerName() << " -nologo -machine:" << MachineName() - << " -pdb:" << GetHostPathQ(ForceExt(target, ".pdb")) - << " -out:" << GetHostPathQ(target); - if(HasFlag("FORCE_SIZE")){ - if(sContainsPchOptions(release_size_options)) - link << " -ltcg"; - } - else - if(HasFlag("FORCE_SPEED")) - if(sContainsPchOptions(release_options)) - link << " -ltcg"; - if(!HasFlag("MSC10") && !HasFlag("MSC10X64")) - if(HasAnyDebug()) - link << " -incremental:yes -debug -OPT:NOREF"; - else - link << " -incremental:no -release -OPT:REF,ICF"; - else - if(HasAnyDebug()) - link << " -debug -OPT:NOREF"; - else - link << " -release -OPT:REF,ICF"; - if(IsMscArm()) - link << " -subsystem:windowsce,4.20 /ARMPADCODE -NODEFAULTLIB:\"oldnames.lib\" "; - else - if(HasFlag("GUI") || IsMscArm()) - link << (HasFlag("WIN32") ? " -subsystem:windows" : " -subsystem:windowsce"); - else - link << " -subsystem:console"; - if(createmap) - link << " -MAP"; - if(HasFlag("DLL")) - link << " -DLL"; - for(i = 0; i < libpath.GetCount(); i++) - link << " -LIBPATH:\"" << libpath[i] << '\"'; - link << ' ' << linkoptions << ' '; - for(i = 0; i < linkfile.GetCount(); i++) - link << ' ' << GetHostPathQ(AppendExt(linkfile[i], ".lib")); - PutConsole("Linking..."); - bool error = false; - CustomStep(".pre-link", Null, error); - if(!error && Execute(link) == 0) { - CustomStep(".post-link", Null, error); - if((IsMsc86() || IsMsc64()) && HasFlag("SHARED")) { - String mt("mt -nologo -manifest "); - mt << GetHostPathQ(target) << ".manifest -outputresource:" << GetHostPathQ(target) - << (HasFlag("DLL") ? ";2" : ";1"); - Execute(mt); - } - PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length - << " B) linked in " << GetPrintTime(time)); - return !error; - } - else { - DeleteFile(target); - return false; - } - } - PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length - << " B) is up to date."); - return true; -} - -bool MscBuilder::Preprocess(const String& package, const String& file, const String& target, bool) -{ - FileOut out(target); - String packagepath = PackagePath(package); - Package pkg; - pkg.Load(packagepath); - return Execute(CmdLine(package, pkg) + " -E " + file, out); -} - -Builder *CreateMscBuilder() -{ - return new MscBuilder; -} - -INITBLOCK -{ - RegisterBuilder("MSC71", CreateMscBuilder); - RegisterBuilder("MSC8", CreateMscBuilder); - RegisterBuilder("MSC8X64", CreateMscBuilder); - RegisterBuilder("MSC8ARM", CreateMscBuilder); - RegisterBuilder("MSC9", CreateMscBuilder); - RegisterBuilder("MSC9X64", CreateMscBuilder); - RegisterBuilder("MSC10", CreateMscBuilder); - RegisterBuilder("MSC10X64", CreateMscBuilder); - RegisterBuilder("MSC9ARM", CreateMscBuilder); - RegisterBuilder("EVC_ARM", CreateMscBuilder); - RegisterBuilder("EVC_MIPS", CreateMscBuilder); - RegisterBuilder("EVC_SH3", CreateMscBuilder); - RegisterBuilder("EVC_SH4", CreateMscBuilder); - RegisterBuilder("INTEL", CreateMscBuilder); -} +#include "Builders.h" + +#include + +#ifdef PLATFORM_WIN32 +static bool HasTail(String s, const char *tail) +{ + int tl = (int)strlen(tail); + int sl = s.GetLength(); + if(sl < tl) + return false; + for(const char *p = s.GetIter(sl - tl); *p; p++, tail++) + if(*tail != '*' && *tail != *p) + return false; + return *tail == 0; +} +#endif + +static void AddObjectExports(const char *path, Index& out) +{ +#ifdef PLATFORM_WIN32 + FileMapping mapping; + if(!mapping.Open(path)) + return; + const byte *begin = mapping.Begin(); + const COFF_IMAGE_FILE_HEADER *hdr = (const COFF_IMAGE_FILE_HEADER *)begin; + if(hdr->Machine != COFF_IMAGE_FILE_MACHINE_I386) + return; + const COFF_IMAGE_SECTION_HEADER *sechdr = (const COFF_IMAGE_SECTION_HEADER *)(begin + + sizeof(COFF_IMAGE_FILE_HEADER) + hdr->SizeOfOptionalHeader); + Index code_sections; + for(int i = 0; i < hdr->NumberOfSections; i++) + if(sechdr[i].Characteristics & COFF_IMAGE_SCN_CNT_CODE) + code_sections.Add(i + 1); + const COFF_IMAGE_SYMBOL *symtbl = (const COFF_IMAGE_SYMBOL *)(begin + hdr->PointerToSymbolTable); + const char *strtbl = (const char *)(symtbl + hdr->NumberOfSymbols); + for(int i = 0; i < (int)hdr->NumberOfSymbols; i++) + { + const COFF_IMAGE_SYMBOL& sym = symtbl[i]; + if(sym.StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL && code_sections.Find(sym.SectionNumber) >= 0) + { + String name = COFFSymbolName(sym, strtbl); + if(!HasTail(name, "AEPAXI@Z")) + { + if(*name == '_' && name.Find('@') < 0) + name.Remove(0, 1); + out.FindAdd(name); + } + } + i += sym.NumberOfAuxSymbols; + } +#endif +} + +void MscBuilder::AddFlags(Index& cfg) +{ + cfg.FindAdd("MSC"); +} + +String MscBuilder::CmdLine(const String& package, const Package& pkg) +{ + String cc; + if(HasFlag("ARM")) + cc = "clarm"; + else + if(HasFlag("MIPS")) + cc = "clmips"; + else + if(HasFlag("SH3")) + cc = "shcl /Qsh3"; + else + if(HasFlag("SH4")) + cc = "shcl /Qsh4"; + else + if(HasFlag("MSC8ARM")) + cc = "cl -GS- "; + else + cc = HasFlag("INTEL") ? "icl" : "cl"; +// TRC 080605-documentation says Wp64 works in 32-bit compilation only +// cc << (IsMsc64() ? " -nologo -Wp64 -W3 -GR -c" : " -nologo -W3 -GR -c"); + cc << " -nologo -W3 -GR -c"; + cc << IncludesDefinesTargetTime(package, pkg); + + return cc; +} + +String MscBuilder::MachineName() const +{ + if(HasFlag("ARM")) return "ARM"; + if(HasFlag("MIPS")) return "MIPS"; + if(HasFlag("SH3")) return "SH3"; + if(HasFlag("SH4")) return "SH4"; + if(IsMscArm()) return "ARM"; + if(IsMsc64()) return "x64"; + if(HasFlag("WIN32")) return "I386"; + return "IX86"; +} + +bool MscBuilder::IsMsc89() const +{ + return IsMsc86() || IsMsc64() || IsMscArm(); +} + +bool MscBuilder::IsMsc86() const +{ + return HasFlag("MSC8") || HasFlag("MSC9") || HasFlag("MSC10"); +} + +bool MscBuilder::IsMscArm() const +{ + return HasFlag("MSC8ARM") || HasFlag("MSC9ARM"); +} + +bool MscBuilder::IsMsc64() const +{ + return HasFlag("MSC8X64") || HasFlag("MSC9X64") || HasFlag("MSC10X64"); +} + +String MscBuilder::LinkerName() const +{ + if(HasFlag("ULD")) return "uld"; + if(HasFlag("INTEL")) return "xilink"; + return "link"; +} + +static bool sContainsPchOptions(const String& x) +{ + Index a = Split(x, ' '); + return a.Find("-GL") >= 0 || a.Find("/GL") >= 0 || a.Find("-Y-") >= 0 || a.Find("/Y-") >= 0 + || a.Find("-Yc") >= 0 || a.Find("/Yc") >= 0 || a.Find("-Yd") >= 0 || a.Find("/Yd") >= 0 + || a.Find("-Yl") >= 0 || a.Find("/Yl") >= 0 || a.Find("-Yu") >= 0 || a.Find("/Yu") >= 0 + || a.Find("-YX") >= 0 || a.Find("/YX") >= 0; +} + +bool MscBuilder::HasAnyDebug() const +{ + return HasFlag("DEBUG") || HasFlag("DEBUG_MINIMAL") || HasFlag("DEBUG_FULL"); +} + +String MscBuilder::PdbPch(String package, int slot, bool do_pch) const +{ + String pkg_slot = NFormat("%s-%d", GetAnyFileName(package), slot + 1); + String pdb = GetHostPathQ(CatAnyPath(outdir, pkg_slot + ".pdb")); + String cc; + cc << " -Gy -Fd" << pdb; + if(do_pch && !IsMsc89()) // MSC8/9 does not support automatic precompiled headers... + cc << " -YX -Fp" << GetHostPathQ(CatAnyPath(outdir, pkg_slot + ".pch")) << ' '; + return cc; +} + +bool MscBuilder::BuildPackage(const String& package, Vector& linkfile, String& linkoptions, + const Vector& all_uses, const Vector& all_libraries, int opt) +{ + int i; + String packagepath = PackagePath(package); + Package pkg; + pkg.Load(packagepath); + String packagedir = GetFileFolder(packagepath); + ChDir(packagedir); + PutVerbose("cd " + packagedir); + IdeConsoleBeginGroup(package); + Vector obj; + + bool is_shared = HasFlag("SO"), + is_clr = HasFlag("CLR"); + + String cc = CmdLine(package, pkg); + if(HasFlag("EVC")) { + if(!HasFlag("SH3") && !HasFlag("SH4")) + cc << " -Gs8192"; // disable stack checking + cc << " -GF" // read-only string pooling + " -GX-"; // turn off exception handling + } + else + if(is_clr) + cc << " -EHac"; + else + if(IsMsc89()) + cc << " -EHsc"; + else + cc << " -GX"; +// String pdb = GetHostPathQ(CatAnyPath(outdir, GetAnyFileName(package) + ".pdb")); +// String pch; +// if(!HasFlag("MSC8")) // MSC8 does not support automatic precompiled headers... +// pch << " -YX -Fp" << GetHostPathQ(CatAnyPath(outdir, GetAnyFileName(package) + ".pch")) << ' '; +// cc << " -Gy -Fd" << pdb; + if(HasFlag("SSE2") && !IsMsc64()) + cc << " /arch:SSE2"; + if(HasFlag("DEBUG_MINIMAL")) + cc << " -Zd"; + if(HasFlag("DEBUG_FULL")) + cc << " -Zi"; + cc << ' ' << Gather(pkg.option, config.GetKeys()); + cc << (HasFlag("SHARED") || is_shared || is_clr ? " -MD" + : (HasFlag("MT") || IsMsc89()) ? " -MT" : " -ML"); + + String cc_size = cc; + String cc_speed = cc; + bool release = false; + + if(HasFlag("DEBUG")) + cc << "d " << debug_options; + else { + release = true; + cc << ' ' << release_size_options; + cc_speed << ' ' << release_options; + if(opt == R_SPEED || pkg.optimize_speed) + cc = cc_speed; + } + + + Vector sfile, isfile; + Vector soptions, isoptions; + Vector optimize, ioptimize; + Vector sobjfile; + bool error = false; + + for(i = 0; i < pkg.GetCount(); i++) { + if(!IdeIsBuilding()) + return false; + if(!pkg[i].separator) { + String gop = Gather(pkg[i].option, config.GetKeys()); + Vector srcfile = CustomStep(pkg[i], package, error); + if(srcfile.GetCount() == 0) + error = true; + for(int j = 0; j < srcfile.GetCount(); j++) { + String fn = srcfile[j]; + String ext = ToLower(GetFileExt(fn)); + if(ext == ".c" || ext == ".cpp" || ext == ".cc" || ext == ".cxx" || ext == ".rc" || ext == ".brc") { + sfile.Add(fn); + soptions.Add(gop); + optimize.Add(release && pkg[i].optimize_speed && opt == R_OPTIMAL); + } + else + if(ext == ".icpp") { + isfile.Add(fn); + isoptions.Add(gop); + ioptimize.Add(release && pkg[i].optimize_speed && opt == R_OPTIMAL); + } + else + if(ext == ".obj") + obj.Add(fn); + else + if(ext == ".lib") + linkfile.Add(fn); + } + } + } + + if(HasFlag("BLITZ")) { + Blitz b = BlitzStep(sfile, soptions, obj, ".obj", optimize); + if(b.build) { + PutConsole("BLITZ:" + b.info); + int slot = AllocSlot(); + if(slot < 0 || ! Run(cc + PdbPch(package, slot, false) + + " -Tp " + GetHostPathQ(b.path) + " -Fo" + GetHostPathQ(b.object), slot, GetHostPath(b.object), b.count)) + error = true; + } + } + + int first_ifile = sfile.GetCount(); + sfile.AppendPick(isfile); + soptions.AppendPick(isoptions); + optimize.AppendPick(ioptimize); + + int ccount = 0; + +// if(sContainsPchOptions(cc)) +// pch = Null; + + for(i = 0; i < sfile.GetCount(); i++) { + if(!IdeIsBuilding()) + return false; + String fn = sfile[i]; + String ext = ToLower(GetFileExt(fn)); + bool rc = (ext == ".rc"); + bool brc = (ext == ".brc"); + bool init = (i >= first_ifile); + String objfile = CatAnyPath(outdir, GetFileTitle(fn) + (rc ? "$rc.obj" : brc ? "$brc.obj" : ".obj")); + if(HdependFileTime(fn) > GetFileTime(objfile)) { + int time = GetTickCount(); + bool execerr = false; + if(rc) { + PutConsole(GetFileNamePos(fn)); + int slot = AllocSlot(); + if(slot < 0 || !Run("rc /fo" + GetHostPathQ(objfile) + Includes(" /i", package, pkg) + + ' ' + GetHostPathQ(fn), slot, GetHostPath(objfile), 1)) + execerr = true; + } + else + if(brc) { + try { +// String hfn = GetHostPath(fn); + String brcdata = LoadFile(fn); + if(brcdata.IsVoid()) + throw Exc(NFormat("error reading file '%s'", fn)); + CParser parser(brcdata, fn); + String fo = BrcToC(parser, GetFileDirectory(fn)); + String tmpfile = ForceExt(objfile, ".c"); + SaveFile(tmpfile, fo); + int slot = AllocSlot(); + StringBuffer cmdline; + cmdline << cc << PdbPch(package, slot, false) + << " -Tc " << GetHostPathQ(tmpfile) << " -Fo" << GetHostPathQ(objfile); + if(slot < 0 || !Run(String(cmdline), slot, GetHostPath(objfile), 1)) + throw Exc(NFormat("Error compiling binary object '%s'.", objfile)); + } + catch(Exc e) { + PutConsole(e); + execerr = true; + } + } + else { + String c = cc; + if(optimize[i]) + c = cc_speed; + int slot = AllocSlot(); + if(slot < 0 || !Run(c + PdbPch(package, slot, !sContainsPchOptions(cc) && !sContainsPchOptions(soptions[i])) + + " " + soptions[i] + (ext == ".c" ? " -Tc " : " -Tp ") + + GetHostPathQ(fn) + " -Fo" + GetHostPathQ(objfile), slot, GetHostPath(objfile), 1)) + execerr = true; + } + if(execerr) + DeleteFile(objfile); + error |= execerr; + PutVerbose("compiled in " + GetPrintTime(time)); + ccount++; + } + if(init) + linkfile.Add(objfile); + else + obj.Add(objfile); + } + if(error) { + IdeConsoleEndGroup(); + return false; + } + + Vector pkglibs = Split(Gather(pkg.library, config.GetKeys()), ' '); + for(int i = 0; i < pkglibs.GetCount(); i++) { + String libfile = AppendExt(pkglibs[i], ".lib"); + if(!IsFullPath(libfile)) { + for(int p = 0; p < libpath.GetCount(); p++) { + String nf = NormalizePath(libfile, libpath[p]); + if(FileExists(nf)) { + libfile = nf; + break; + } + } + } + linkfile.Add(libfile); + } + linkoptions << ' ' << Gather(pkg.link, config.GetKeys()); + + int linktime = GetTickCount(); + if(!HasFlag("MAIN")) { + if(HasFlag("BLITZ") || HasFlag("NOLIB")) { + linkfile.Append(obj); +// ShowTime(ccount, time); + IdeConsoleEndGroup(); + return true; + } + String product; + if(is_shared) + product = GetSharedLibPath(package); + else + product = CatAnyPath(outdir, GetAnyFileName(package) + ".lib"); + Time producttime = GetFileTime(product); + if(obj.GetCount()) + linkfile.Add(ForceExt(product, ".lib")); + if(!Wait()) { + IdeConsoleEndGroup(); + return false; + } + Vector objinfo = host->GetFileInfo(obj); + for(int i = 0; i < obj.GetCount(); i++) + if(objinfo[i] > producttime) { + String linker, lib; + if(is_shared) { + linker << LinkerName() << "-dll -nologo "; + lib << "-machine:" << MachineName() + << " -pdb:" << GetHostPathQ(ForceExt(product, ".pdb")) + << " -out:" << GetHostPathQ(product); + if(!HasFlag("MSC10") && !HasFlag("MSC10X64")) + lib << " -incremental:no"; + if(HasFlag("FORCE_SIZE")){ + if(sContainsPchOptions(release_size_options)) + lib << " -ltcg"; + } + else + if(HasFlag("FORCE_SPEED")) + if(sContainsPchOptions(release_options)) + lib << " -ltcg"; + if(HasAnyDebug()) + lib << " -debug -OPT:NOREF"; + else + lib << " -release -OPT:REF,ICF"; + if(IsMscArm()) + lib << " -subsystem:windowsce,4.20 /ARMPADCODE"; + else + if(HasFlag("GUI")) + lib << (HasFlag("WIN32") ? " -subsystem:windows" + : " -subsystem:windowsce"); + else + lib << " -subsystem:console"; + Index exports; + for(int o = 0; o < obj.GetCount(); o++) + AddObjectExports(obj[o], exports); + String def; + def << "LIBRARY " << AsCString(GetFileName(product)) << "\n\n" + "EXPORTS\n"; + for(int o = 0; o < exports.GetCount(); o++) + def << '\t' << exports[o] << "\n"; //" @" << (o + 1) << "\n"; + String deffile = ForceExt(product, ".def"); + if(!SaveChangedFile(deffile, def)) + { + PutConsole(NFormat("%s: error saving file", deffile)); + return false; + } + lib << " -def:" << GetHostPathQ(deffile); + for(int i = 0; i < libpath.GetCount(); i++) + lib << " -LIBPATH:" << GetHostPathQ(libpath[i]); + lib << ' ' << Gather(pkg.link, config.GetKeys()); + for(int i = 0; i < all_uses.GetCount(); i++) + lib << ' ' << GetHostPathQ(ForceExt(GetSharedLibPath(all_uses[i]), ".lib")); + for(int i = 0; i < all_libraries.GetCount(); i++) { + String libfile = AppendExt(all_libraries[i], ".lib"); + if(!IsFullPath(libfile)) { + for(int p = 0; p < libpath.GetCount(); p++) { + String nf = NormalizePath(libfile, libpath[p]); + if(FileExists(nf)) { + libfile = nf; + break; + } + } + } + lib << ' ' << GetHostPathQ(libfile); + } + } + else{ + linker << (HasFlag("INTEL") ? "xilib" : "link /lib") << " -nologo "; + if(HasFlag("FORCE_SIZE")){ + if(sContainsPchOptions(release_size_options)) + lib << " -ltcg"; + } + else + if(HasFlag("FORCE_SPEED")) + if(sContainsPchOptions(release_options)) + lib << " -ltcg"; + lib << " -out:" << GetHostPathQ(product) << ' ' << Gather(pkg.link, config.GetKeys()); + } + for(int i = 0; i < obj.GetCount(); i++) + lib << ' ' << GetHostPathQ(obj[i]); + PutConsole("Creating library..."); + IdeConsoleEndGroup(); + DeleteFile(product); + String tmpFileName; + if(linker.GetCount() + lib.GetCount() >= 8192) + { + tmpFileName = GetTempFileName(); + // we can't simply put all data on a single line + // as it has a limit of around 130000 chars too, so we split + // in multiple lines + FileOut f(tmpFileName); + while(lib != "") + { + int found = 0; + bool quotes = false; + int lim = min(8192, lib.GetCount()); + for(int i = 0; i < lim; i++) + { + char c = lib[i]; + if(isspace(c) && !quotes) + found = i; + else if(c == '"') + quotes = !quotes; + } + if(!found) + found = lib.GetCount(); + f.PutLine(lib.Left(found)); + lib.Remove(0, found); + } + f.Close(); + linker << "@" << tmpFileName; + } + else + linker << lib; + bool res = Execute(linker); + if(tmpFileName != "") + FileDelete(tmpFileName); + if(res) { + DeleteFile(product); + return false; + } + else + if((IsMsc86() || IsMsc64()) && is_shared) { + String mt("mt -nologo -manifest "); + mt << GetHostPathQ(product) << ".manifest -outputresource:" << GetHostPathQ(product) << ";2"; + Execute(mt); + } + PutConsole(String().Cat() << product << " (" << GetFileInfo(product).length + << " B) created in " << GetPrintTime(linktime)); + break; + } + return true; + } + + IdeConsoleEndGroup(); + obj.Append(linkfile); + linkfile = obj; + return true; +} + +bool MscBuilder::Link(const Vector& linkfile, const String& linkoptions, bool createmap) +{ + int time = GetTickCount(); + if(!Wait()) + return false; + for(int i = 0; i < linkfile.GetCount(); i++) + if(GetFileTime(linkfile[i]) >= targettime) { + String link; + link << LinkerName() << " -nologo -machine:" << MachineName() + << " -pdb:" << GetHostPathQ(ForceExt(target, ".pdb")) + << " -out:" << GetHostPathQ(target); + if(HasFlag("FORCE_SIZE")){ + if(sContainsPchOptions(release_size_options)) + link << " -ltcg"; + } + else + if(HasFlag("FORCE_SPEED")) + if(sContainsPchOptions(release_options)) + link << " -ltcg"; + if(!HasFlag("MSC10") && !HasFlag("MSC10X64")) + if(HasAnyDebug()) + link << " -incremental:yes -debug -OPT:NOREF"; + else + link << " -incremental:no -release -OPT:REF,ICF"; + else + if(HasAnyDebug()) + link << " -debug -OPT:NOREF"; + else + link << " -release -OPT:REF,ICF"; + if(IsMscArm()) + link << " -subsystem:windowsce,4.20 /ARMPADCODE -NODEFAULTLIB:\"oldnames.lib\" "; + else + if(HasFlag("GUI") || IsMscArm()) + link << (HasFlag("WIN32") ? " -subsystem:windows" : " -subsystem:windowsce"); + else + link << " -subsystem:console"; + if(createmap) + link << " -MAP"; + if(HasFlag("DLL")) + link << " -DLL"; + for(i = 0; i < libpath.GetCount(); i++) + link << " -LIBPATH:\"" << libpath[i] << '\"'; + link << ' ' << linkoptions << ' '; + for(i = 0; i < linkfile.GetCount(); i++) + link << ' ' << GetHostPathQ(AppendExt(linkfile[i], ".lib")); + PutConsole("Linking..."); + bool error = false; + CustomStep(".pre-link", Null, error); + if(!error && Execute(link) == 0) { + CustomStep(".post-link", Null, error); + if((IsMsc86() || IsMsc64()) && HasFlag("SHARED")) { + String mt("mt -nologo -manifest "); + mt << GetHostPathQ(target) << ".manifest -outputresource:" << GetHostPathQ(target) + << (HasFlag("DLL") ? ";2" : ";1"); + Execute(mt); + } + PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length + << " B) linked in " << GetPrintTime(time)); + return !error; + } + else { + DeleteFile(target); + return false; + } + } + PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length + << " B) is up to date."); + return true; +} + +bool MscBuilder::Preprocess(const String& package, const String& file, const String& target, bool) +{ + FileOut out(target); + String packagepath = PackagePath(package); + Package pkg; + pkg.Load(packagepath); + return Execute(CmdLine(package, pkg) + " -E " + file, out); +} + +Builder *CreateMscBuilder() +{ + return new MscBuilder; +} + +INITBLOCK +{ + RegisterBuilder("MSC71", CreateMscBuilder); + RegisterBuilder("MSC8", CreateMscBuilder); + RegisterBuilder("MSC8X64", CreateMscBuilder); + RegisterBuilder("MSC8ARM", CreateMscBuilder); + RegisterBuilder("MSC9", CreateMscBuilder); + RegisterBuilder("MSC9X64", CreateMscBuilder); + RegisterBuilder("MSC10", CreateMscBuilder); + RegisterBuilder("MSC10X64", CreateMscBuilder); + RegisterBuilder("MSC9ARM", CreateMscBuilder); + RegisterBuilder("EVC_ARM", CreateMscBuilder); + RegisterBuilder("EVC_MIPS", CreateMscBuilder); + RegisterBuilder("EVC_SH3", CreateMscBuilder); + RegisterBuilder("EVC_SH4", CreateMscBuilder); + RegisterBuilder("INTEL", CreateMscBuilder); +} diff --git a/uppsrc/ide/Builders/OwcBuilder.icpp b/uppsrc/ide/Builders/OwcBuilder.icpp index ee24aae69..354841681 100644 --- a/uppsrc/ide/Builders/OwcBuilder.icpp +++ b/uppsrc/ide/Builders/OwcBuilder.icpp @@ -186,7 +186,8 @@ bool OwcBuilder::BuildPackage(const String& package, Vector& linkfile, S product = CatAnyPath(outdir, GetAnyFileName(package) + ".lib"); Time producttime = GetFileTime(product); - linkfile.Add(ForceExt(product, ".lib")); + if(obj.GetCount()) + linkfile.Add(ForceExt(product, ".lib")); Vector files, res; for (int i = 0, n = obj.GetCount(); i < n; ++i) diff --git a/uppsrc/ide/Builders/ScriptBuilder.icpp b/uppsrc/ide/Builders/ScriptBuilder.icpp index 09def6c30..bada80677 100644 --- a/uppsrc/ide/Builders/ScriptBuilder.icpp +++ b/uppsrc/ide/Builders/ScriptBuilder.icpp @@ -1,344 +1,345 @@ -#include "Builders.h" - -#include - -EscValue ScriptBuilder::ExecuteIf(const char *fn, Vector& args) -{ - CheckParse(); - EscValue out; - int f = globals.Find(fn); - if(f < 0) - return out; - try - { - out = ::Execute(globals, NULL, globals[f], args, 50000); - } - catch(Exc e) - { - script_error = true; - PutConsole(e); - } - return out; -} - -EscValue ScriptBuilder::ExecuteIf(const char *fn) -{ - Vector args; - return ExecuteIf(fn, args); -} - -EscValue ScriptBuilder::ExecuteIf(const char *fn, EscValue arg) -{ - Vector args; - args.Add(arg); - return ExecuteIf(fn, args); -} - -EscValue ScriptBuilder::ExecuteIf(const char *fn, EscValue arg1, EscValue arg2) -{ - Vector args; - args.Add(arg1); - args.Add(arg2); - return ExecuteIf(fn, args); -} - -EscValue ScriptBuilder::ExecuteIf(const char *fn, EscValue arg1, EscValue arg2, EscValue arg3) -{ - Vector args; - args.Add(arg1); - args.Add(arg2); - args.Add(arg3); - return ExecuteIf(fn, args); -} - -void ScriptBuilder::ESC_Execute(EscEscape& e) -{ - e = Execute(String(e[0])) ? 0 : 1; -} - -void ScriptBuilder::ESC_PutConsole(EscEscape& e) -{ - PutConsole(String(e[0])); -} - -void ScriptBuilder::ESC_PutVerbose(EscEscape& e) -{ - PutVerbose(String(e[0])); -} - -void ScriptBuilder::CheckParse() -{ - if(is_parsed) - return; - script_error = false; - is_parsed = true; - StdLib(globals); - Escape(globals, "Execute(cmdline)", THISBACK(ESC_Execute)); - Escape(globals, "PutConsole(text)", THISBACK(ESC_PutConsole)); - Escape(globals, "PutVerbose(text)", THISBACK(ESC_PutVerbose)); - EscValue inclist; - inclist.SetEmptyArray(); - for(int i = 0; i < include.GetCount(); i++) - inclist.ArrayAdd(GetHostPathQ(include[i])); - globals.GetAdd("INCLUDE") = inclist; - EscValue liblist; - liblist.SetEmptyArray(); - for(int i = 0; i < libpath.GetCount(); i++) - liblist.ArrayAdd(GetHostPathQ(libpath[i])); - globals.GetAdd("LIBPATH") = liblist; - - try - { - String sdata = LoadFile(script); - if(IsNull(sdata)) - throw Exc(NFormat("%s: not found or empty", script)); - CParser parser(sdata, script, 1); - while(!parser.IsEof()) { - String id = parser.ReadId(); - globals.GetAdd(id) = ReadLambda(parser); - } - } - catch(Exc e) - { - script_error = true; - PutConsole(e); - } -} - -bool ScriptBuilder::BuildPackage(const String& package, Vector& linkfile, String& linkoptions, - const Vector& all_uses, const Vector& all_libraries, int) -{ - int i; - String packagepath = PackagePath(package); - Package pkg; - pkg.Load(packagepath); - String packagedir = GetFileFolder(packagepath); - ChDir(packagedir); - PutVerbose("cd " + packagedir); - Vector obj; - script_error = false; - - String gfl = Gather(pkg.option, config.GetKeys()); - - Vector sfile; - Vector soptions; - bool error = false; - - for(i = 0; i < pkg.GetCount(); i++) { - if(!IdeIsBuilding()) - return false; - if(!pkg[i].separator) { - String gop = Gather(pkg[i].option, config.GetKeys()); - Vector srcfile = CustomStep(pkg[i], package, error); - if(srcfile.GetCount() == 0) - error = true; - for(int j = 0; j < srcfile.GetCount(); j++) { - String fn = srcfile[j]; - String ext = ToLower(GetFileExt(fn)); - if(ext == ".c" || ext == ".cpp" || ext == ".cc" || ext == ".cxx" || - (ext == ".rc" && HasFlag("WIN32"))) { - sfile.Add(fn); - soptions.Add(gfl + " " + gop); - } - else - if(ext == ".o") - obj.Add(fn); - else - if(ext == ".a" || ext == ".so") - linkfile.Add(fn); - } - } - } - -/* - if(HasFlag("BLITZ")) { - Blitz b = BlitzStep(sfile, soptions, obj, ".o"); - if(b.build) { - PutConsole("BLITZ:" + b.info); - int time = GetTickCount(); - if(Execute(cc + " " + GetHostPathQ(b.path) + " -o " + GetHostPathQ(b.object)) == 0) - PutCompileTime(time, b.count); - else - error = true; - } - } -*/ - int time = GetTickCount(); - int ccount = 0; - for(i = 0; i < sfile.GetCount() && !script_error; i++) { - if(!IdeIsBuilding()) - return false; - String fn = sfile[i]; - String ext = ToLower(GetFileExt(fn)); -// bool rc = ext == ".rc"; - String objfile = ExecuteIf("objectfile", fn); - if(script_error) - return false; - if(IsNull(objfile)) - objfile = CatAnyPath(outdir, GetFileTitle(fn) + ".o"); - if(HdependFileTime(fn) > GetFileTime(GetHostPath(objfile))) { - PutConsole(GetFileName(fn)); - int time = GetTickCount(); - if(!ExecuteIf("compile", GetHostPathQ(fn), GetHostPathQ(objfile), soptions[i]).GetNumber()) { - DeleteFile(objfile); - error = true; - } - PutVerbose("compiled in " + GetPrintTime(time)); - ccount++; - } - obj.Add(objfile); - } - if(ccount) - PutCompileTime(time, ccount); - - if(error || script_error) - return false; - - linkoptions << Gather(pkg.link, config.GetKeys()); - - Vector libs = Split(Gather(pkg.library, config.GetKeys()), ' '); - linkfile.Append(libs); - - time = GetTickCount(); - if(!HasFlag("MAIN")) { - if(HasFlag("NOLIB")) { - linkfile.Append(obj); - return true; - } - String product = ExecuteIf("libraryfile", package); - if(IsNull(product)) - product = CatAnyPath(outdir, GetAnyFileName(package) + ".a"); - Time producttime = GetFileTime(product); - linkfile.Add("*" + product); //!! ugly - for(int i = 0; i < obj.GetCount(); i++) - if(GetFileTime(obj[i]) > producttime) { - PutConsole("Creating library..."); - DeleteFile(product); - EscValue objlist; - objlist.SetEmptyArray(); - for(int i = 0; i < obj.GetCount(); i++) - objlist.ArrayAdd(GetHostPathQ(obj[i])); - if(!ExecuteIf("library", objlist, product).GetNumber()) { - DeleteFile(product); - error = true; - return false; - } - PutConsole(String().Cat() << product << " (" << GetFileInfo(product).length - << " B) created in " << GetPrintTime(time)); - break; - } - return true; - } - - obj.Append(linkfile); - linkfile = obj; - return true; -} - -bool ScriptBuilder::Link(const Vector& linkfile, const String& linkoptions, bool) -{ - int time = GetTickCount(); - for(int i = 0; i < linkfile.GetCount(); i++) - if(GetFileTime(linkfile[i]) >= targettime) { - EscValue objlist; - objlist.SetEmptyArray(); - EscValue liblist; - liblist.SetEmptyArray(); - for(i = 0; i < linkfile.GetCount(); i++) - if(*linkfile[i] == '*') - liblist.ArrayAdd(GetHostPathQ(linkfile[i].Mid(1))); - else - objlist.ArrayAdd(GetHostPathQ(linkfile[i])); - Vector linkargs; - linkargs.Add(objlist); - linkargs.Add(liblist); - linkargs.Add(GetHostPathQ(target)); - linkargs.Add(linkoptions); - PutConsole("Linking..."); - bool error = false; - CustomStep(".pre-link", Null, error); - if(!error && !ExecuteIf("link", linkargs).GetNumber()) { - DeleteFile(target); - return false; - } - CustomStep(".post-link", Null, error); - PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length - << " B) linked in " << GetPrintTime(time)); - return !error; - } - PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length - << " B) is up to date."); - return true; -} - -bool ScriptBuilder::Preprocess(const String& package, const String& file, const String& target, bool) -{ - return ExecuteIf("preprocess", file, target).GetNumber(); -} - -Builder *CreateScriptBuilder() -{ - return new ScriptBuilder; -} - -INITBLOCK -{ - RegisterBuilder("SCRIPT", CreateScriptBuilder); -} - -/* -EscValue LayoutItem::CreateEsc() const -{ - EscValue ctrl; - String tp = type; - String tm; - if(ParseTemplate(tp, tm)) { - CreateMethods(ctrl, tp, true); - ctrl("CtrlPaint") = ctrl("Paint"); - CreateMethods(ctrl, tm, false); - } - else - CreateMethods(ctrl, tp, false); - for(int q = 0; q < property.GetCount(); q++) { - EscValue& w = ctrl(property[q].name); - const Value& v = ~property[q]; - if(IsType(v)) - w = EscFont(v); - if(IsString(v)) - w = (WString)v; - if(IsNumber(v)) - w = (double)v; - if(IsType(v)) - w = EscColor(v); - } - ctrl("type") = (WString)type; - ctrl("GetSize") = ReadLambda(Format("() { return Size(%d, %d); }", - csize.cx, csize.cy)); - ctrl("GetRect") = ReadLambda(Format("() { return Rect(0, 0, %d, %d); }", - csize.cx, csize.cy)); - return ctrl; -} - -EscValue LayoutItem::ExecuteMethod(const char *method, Vector& arg) const -{ - try { - EscValue self = CreateEsc(); - return ::Execute(UscGlobal(), &self, method, arg, 50000); - } - catch(CParser::Error& e) { - PutConsole(e + "\n"); - } - return EscValue(); -} - -EscValue LayoutItem::ExecuteMethod(const char *method) const -{ - Vector arg; - return ExecuteMethod(method, arg); -} - -Size LayoutItem::GetMinSize() -{ - return SizeEsc(ExecuteMethod("GetMinSize")); -} -*/ +#include "Builders.h" + +#include + +EscValue ScriptBuilder::ExecuteIf(const char *fn, Vector& args) +{ + CheckParse(); + EscValue out; + int f = globals.Find(fn); + if(f < 0) + return out; + try + { + out = ::Execute(globals, NULL, globals[f], args, 50000); + } + catch(Exc e) + { + script_error = true; + PutConsole(e); + } + return out; +} + +EscValue ScriptBuilder::ExecuteIf(const char *fn) +{ + Vector args; + return ExecuteIf(fn, args); +} + +EscValue ScriptBuilder::ExecuteIf(const char *fn, EscValue arg) +{ + Vector args; + args.Add(arg); + return ExecuteIf(fn, args); +} + +EscValue ScriptBuilder::ExecuteIf(const char *fn, EscValue arg1, EscValue arg2) +{ + Vector args; + args.Add(arg1); + args.Add(arg2); + return ExecuteIf(fn, args); +} + +EscValue ScriptBuilder::ExecuteIf(const char *fn, EscValue arg1, EscValue arg2, EscValue arg3) +{ + Vector args; + args.Add(arg1); + args.Add(arg2); + args.Add(arg3); + return ExecuteIf(fn, args); +} + +void ScriptBuilder::ESC_Execute(EscEscape& e) +{ + e = Execute(String(e[0])) ? 0 : 1; +} + +void ScriptBuilder::ESC_PutConsole(EscEscape& e) +{ + PutConsole(String(e[0])); +} + +void ScriptBuilder::ESC_PutVerbose(EscEscape& e) +{ + PutVerbose(String(e[0])); +} + +void ScriptBuilder::CheckParse() +{ + if(is_parsed) + return; + script_error = false; + is_parsed = true; + StdLib(globals); + Escape(globals, "Execute(cmdline)", THISBACK(ESC_Execute)); + Escape(globals, "PutConsole(text)", THISBACK(ESC_PutConsole)); + Escape(globals, "PutVerbose(text)", THISBACK(ESC_PutVerbose)); + EscValue inclist; + inclist.SetEmptyArray(); + for(int i = 0; i < include.GetCount(); i++) + inclist.ArrayAdd(GetHostPathQ(include[i])); + globals.GetAdd("INCLUDE") = inclist; + EscValue liblist; + liblist.SetEmptyArray(); + for(int i = 0; i < libpath.GetCount(); i++) + liblist.ArrayAdd(GetHostPathQ(libpath[i])); + globals.GetAdd("LIBPATH") = liblist; + + try + { + String sdata = LoadFile(script); + if(IsNull(sdata)) + throw Exc(NFormat("%s: not found or empty", script)); + CParser parser(sdata, script, 1); + while(!parser.IsEof()) { + String id = parser.ReadId(); + globals.GetAdd(id) = ReadLambda(parser); + } + } + catch(Exc e) + { + script_error = true; + PutConsole(e); + } +} + +bool ScriptBuilder::BuildPackage(const String& package, Vector& linkfile, String& linkoptions, + const Vector& all_uses, const Vector& all_libraries, int) +{ + int i; + String packagepath = PackagePath(package); + Package pkg; + pkg.Load(packagepath); + String packagedir = GetFileFolder(packagepath); + ChDir(packagedir); + PutVerbose("cd " + packagedir); + Vector obj; + script_error = false; + + String gfl = Gather(pkg.option, config.GetKeys()); + + Vector sfile; + Vector soptions; + bool error = false; + + for(i = 0; i < pkg.GetCount(); i++) { + if(!IdeIsBuilding()) + return false; + if(!pkg[i].separator) { + String gop = Gather(pkg[i].option, config.GetKeys()); + Vector srcfile = CustomStep(pkg[i], package, error); + if(srcfile.GetCount() == 0) + error = true; + for(int j = 0; j < srcfile.GetCount(); j++) { + String fn = srcfile[j]; + String ext = ToLower(GetFileExt(fn)); + if(ext == ".c" || ext == ".cpp" || ext == ".cc" || ext == ".cxx" || + (ext == ".rc" && HasFlag("WIN32"))) { + sfile.Add(fn); + soptions.Add(gfl + " " + gop); + } + else + if(ext == ".o") + obj.Add(fn); + else + if(ext == ".a" || ext == ".so") + linkfile.Add(fn); + } + } + } + +/* + if(HasFlag("BLITZ")) { + Blitz b = BlitzStep(sfile, soptions, obj, ".o"); + if(b.build) { + PutConsole("BLITZ:" + b.info); + int time = GetTickCount(); + if(Execute(cc + " " + GetHostPathQ(b.path) + " -o " + GetHostPathQ(b.object)) == 0) + PutCompileTime(time, b.count); + else + error = true; + } + } +*/ + int time = GetTickCount(); + int ccount = 0; + for(i = 0; i < sfile.GetCount() && !script_error; i++) { + if(!IdeIsBuilding()) + return false; + String fn = sfile[i]; + String ext = ToLower(GetFileExt(fn)); +// bool rc = ext == ".rc"; + String objfile = ExecuteIf("objectfile", fn); + if(script_error) + return false; + if(IsNull(objfile)) + objfile = CatAnyPath(outdir, GetFileTitle(fn) + ".o"); + if(HdependFileTime(fn) > GetFileTime(GetHostPath(objfile))) { + PutConsole(GetFileName(fn)); + int time = GetTickCount(); + if(!ExecuteIf("compile", GetHostPathQ(fn), GetHostPathQ(objfile), soptions[i]).GetNumber()) { + DeleteFile(objfile); + error = true; + } + PutVerbose("compiled in " + GetPrintTime(time)); + ccount++; + } + obj.Add(objfile); + } + if(ccount) + PutCompileTime(time, ccount); + + if(error || script_error) + return false; + + linkoptions << Gather(pkg.link, config.GetKeys()); + + Vector libs = Split(Gather(pkg.library, config.GetKeys()), ' '); + linkfile.Append(libs); + + time = GetTickCount(); + if(!HasFlag("MAIN")) { + if(HasFlag("NOLIB")) { + linkfile.Append(obj); + return true; + } + String product = ExecuteIf("libraryfile", package); + if(IsNull(product)) + product = CatAnyPath(outdir, GetAnyFileName(package) + ".a"); + Time producttime = GetFileTime(product); + if(obj.GetCount()) + linkfile.Add("*" + product); //!! ugly + for(int i = 0; i < obj.GetCount(); i++) + if(GetFileTime(obj[i]) > producttime) { + PutConsole("Creating library..."); + DeleteFile(product); + EscValue objlist; + objlist.SetEmptyArray(); + for(int i = 0; i < obj.GetCount(); i++) + objlist.ArrayAdd(GetHostPathQ(obj[i])); + if(!ExecuteIf("library", objlist, product).GetNumber()) { + DeleteFile(product); + error = true; + return false; + } + PutConsole(String().Cat() << product << " (" << GetFileInfo(product).length + << " B) created in " << GetPrintTime(time)); + break; + } + return true; + } + + obj.Append(linkfile); + linkfile = obj; + return true; +} + +bool ScriptBuilder::Link(const Vector& linkfile, const String& linkoptions, bool) +{ + int time = GetTickCount(); + for(int i = 0; i < linkfile.GetCount(); i++) + if(GetFileTime(linkfile[i]) >= targettime) { + EscValue objlist; + objlist.SetEmptyArray(); + EscValue liblist; + liblist.SetEmptyArray(); + for(i = 0; i < linkfile.GetCount(); i++) + if(*linkfile[i] == '*') + liblist.ArrayAdd(GetHostPathQ(linkfile[i].Mid(1))); + else + objlist.ArrayAdd(GetHostPathQ(linkfile[i])); + Vector linkargs; + linkargs.Add(objlist); + linkargs.Add(liblist); + linkargs.Add(GetHostPathQ(target)); + linkargs.Add(linkoptions); + PutConsole("Linking..."); + bool error = false; + CustomStep(".pre-link", Null, error); + if(!error && !ExecuteIf("link", linkargs).GetNumber()) { + DeleteFile(target); + return false; + } + CustomStep(".post-link", Null, error); + PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length + << " B) linked in " << GetPrintTime(time)); + return !error; + } + PutConsole(String().Cat() << GetHostPath(target) << " (" << GetFileInfo(target).length + << " B) is up to date."); + return true; +} + +bool ScriptBuilder::Preprocess(const String& package, const String& file, const String& target, bool) +{ + return ExecuteIf("preprocess", file, target).GetNumber(); +} + +Builder *CreateScriptBuilder() +{ + return new ScriptBuilder; +} + +INITBLOCK +{ + RegisterBuilder("SCRIPT", CreateScriptBuilder); +} + +/* +EscValue LayoutItem::CreateEsc() const +{ + EscValue ctrl; + String tp = type; + String tm; + if(ParseTemplate(tp, tm)) { + CreateMethods(ctrl, tp, true); + ctrl("CtrlPaint") = ctrl("Paint"); + CreateMethods(ctrl, tm, false); + } + else + CreateMethods(ctrl, tp, false); + for(int q = 0; q < property.GetCount(); q++) { + EscValue& w = ctrl(property[q].name); + const Value& v = ~property[q]; + if(IsType(v)) + w = EscFont(v); + if(IsString(v)) + w = (WString)v; + if(IsNumber(v)) + w = (double)v; + if(IsType(v)) + w = EscColor(v); + } + ctrl("type") = (WString)type; + ctrl("GetSize") = ReadLambda(Format("() { return Size(%d, %d); }", + csize.cx, csize.cy)); + ctrl("GetRect") = ReadLambda(Format("() { return Rect(0, 0, %d, %d); }", + csize.cx, csize.cy)); + return ctrl; +} + +EscValue LayoutItem::ExecuteMethod(const char *method, Vector& arg) const +{ + try { + EscValue self = CreateEsc(); + return ::Execute(UscGlobal(), &self, method, arg, 50000); + } + catch(CParser::Error& e) { + PutConsole(e + "\n"); + } + return EscValue(); +} + +EscValue LayoutItem::ExecuteMethod(const char *method) const +{ + Vector arg; + return ExecuteMethod(method, arg); +} + +Size LayoutItem::GetMinSize() +{ + return SizeEsc(ExecuteMethod("GetMinSize")); +} +*/