From f0f5cd9c161aa37591ef1def88291b1ec06b5582 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Thu, 13 Mar 2025 17:27:38 +0100 Subject: [PATCH] GLCtrl: Fixed --- uppsrc/CtrlCore/DHCtrl.cpp | 2 +- uppsrc/GLCtrl/Win32GLCtrl.cpp | 2 +- uppsrc/ide/Builders/MscBuilder.cpp | 1548 ++++++++++++++-------------- 3 files changed, 776 insertions(+), 776 deletions(-) diff --git a/uppsrc/CtrlCore/DHCtrl.cpp b/uppsrc/CtrlCore/DHCtrl.cpp index 1ac261da2..718b39da4 100644 --- a/uppsrc/CtrlCore/DHCtrl.cpp +++ b/uppsrc/CtrlCore/DHCtrl.cpp @@ -67,7 +67,7 @@ void DHCtrl::OpenHWND() CloseHWND(); HWND phwnd = GetTopCtrl()->GetHWND(); if(phwnd) - CreateWindowEx(0, "UPP-CLASS-A", "", + CreateWindowEx(0, "UPP-CLASS-W", "", WS_CHILD|WS_DISABLED|WS_VISIBLE, 0, 0, 20, 20, phwnd, NULL, hInstance, this); diff --git a/uppsrc/GLCtrl/Win32GLCtrl.cpp b/uppsrc/GLCtrl/Win32GLCtrl.cpp index e4306cdef..074923b7c 100644 --- a/uppsrc/GLCtrl/Win32GLCtrl.cpp +++ b/uppsrc/GLCtrl/Win32GLCtrl.cpp @@ -15,7 +15,7 @@ void MakeWGLContext(int depthBits, int stencilBits, int samples) { ONCELOCK { for(int pass = 0; pass < 2; pass++) { - HWND hWND = CreateWindow("UPP-CLASS-A", "Fake Window", + HWND hWND = CreateWindow("UPP-CLASS-W", "Fake Window", WS_CAPTION|WS_SYSMENU|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, 0, 0, 1, 1, NULL, NULL, NULL, NULL); diff --git a/uppsrc/ide/Builders/MscBuilder.cpp b/uppsrc/ide/Builders/MscBuilder.cpp index 87e51e563..485975881 100644 --- a/uppsrc/ide/Builders/MscBuilder.cpp +++ b/uppsrc/ide/Builders/MscBuilder.cpp @@ -1,774 +1,774 @@ -#include "Builders.h" - -#include "coff.h" - -String MaxLenString(const byte *b, int maxlen) -{ - const byte *e = b + maxlen; - while(e > b && e[-1] == 0) - e--; - return String(b, int(e - b)); -} - -String COFFSymbolName(const COFF_IMAGE_SYMBOL& sym, const char *strtbl) -{ - String name; - if(sym.N.Name.Short) - name = MaxLenString(sym.N.ShortName, 8); - else - name = strtbl + sym.N.Name.Long; - return name; -} - -#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(); - if(!begin) - return; - 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 -W" << (pkg.nowarnings ? "0" : "3") << " -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") || HasFlag("MSC11") - || HasFlag("MSC12") || HasFlag("MSC15") || HasFlag("MSC14") || HasFlag("MSC17") - || HasFlag("MSC19") || HasFlag("MSC22"); -} - -bool MscBuilder::IsMscArm() const -{ - return HasFlag("MSC8ARM") || HasFlag("MSC9ARM"); -} - -bool MscBuilder::IsMsc64() const -{ - return HasFlag("MSC8X64") || HasFlag("MSC9X64") || HasFlag("MSC10X64") || HasFlag("MSC11X64") - || HasFlag("MSC12X64") || HasFlag("MSC14X64") || HasFlag("MSC15X64") || HasFlag("MSC17X64") - || HasFlag("MSC19X64") || HasFlag("MSC22X64"); -} - -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; -} - -String MscBuilder::Pdb(String package, int slot, bool separate_pdb) const -{ - String pdb_name = GetAnyFileName(package); - if(separate_pdb) - pdb_name << '-' << (slot + 1); - return " -Gy -Fd" + GetPathQ(CatAnyPath(outdir, pdb_name + ".pdb")); -} - -void DeletePCHFile(const String& pch_file) -{ - DeleteFile(pch_file); - PutVerbose("Deleting precompiled header: " + pch_file); -} - -bool MscBuilder::BuildPackage(const String& package, Vector& linkfile, Vector& immfile, - String& linkoptions, const Vector& all_uses, const Vector& all_libraries, int opt) -{ - if(HasFlag("MAKE_MLIB") && !HasFlag("MAIN")) - return true; - - SaveBuildInfo(package); - - 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"); - - Vector sfile, isfile; - Vector soptions, isoptions; - Vector sobjfile; - bool error = false; - - String pch_header; - - Index nopch, noblitz; - - bool blitz = HasFlag("BLITZ"); - bool release = !HasFlag("DEBUG"); - - 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 = NormalizePath(srcfile[j]); - String ext = ToLower(GetFileExt(fn)); - if(findarg(ext, ".c", ".cpp", ".cc", ".cxx", ".rc", ".brc") >= 0 || - ext == ".cu" && HasFlag("CUDA") || - (!release && blitz && ext == ".icpp")) { - if(FindIndex(sfile, fn) < 0) { - sfile.Add(fn); - soptions.Add(gop); - } - } - else - if(ext == ".icpp") { - isfile.Add(fn); - isoptions.Add(gop); - } - else - if(ext == ".obj") - obj.Add(fn); - else - if(ext == ".lib") - linkfile.Add(fn); - else - if(IsHeaderExt(ext) && pkg[i].pch && allow_pch && IsMsc89() && release && !HasAnyDebug() && !blitz) { - if(pch_header.GetCount()) - PutConsole(GetFileName(fn) + ": multiple PCHs are not allowed. Check your package configuration"); - else - pch_header = fn; - } - if(pkg[i].nopch) { - nopch.Add(fn); - if(allow_pch && release) - noblitz.Add(fn); - } - if(pkg[i].noblitz) - noblitz.Add(fn); - if(ext == ".c") - nopch.Add(fn); - } - } - } - - String nvcc = "nvcc -c " + IncludesDefinesTargetTime(package, pkg) + " "; - - 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 = GetPathQ(CatAnyPath(outdir, GetAnyFileName(package) + ".pdb")); -// String pch; -// if(!HasFlag("MSC8")) // MSC8 does not support automatic precompiled headers... -// pch << " -YX -Fp" << GetPathQ(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" : " -MT"); - - String cc_size = cc; - String cc_speed = cc; - - if(release) - cc << ' ' << release_options; - else - cc << "d " << debug_options; - - int recompile = 0; - Blitz b; - if(blitz) { - BlitzBuilderComponent bc(this); - b = bc.MakeBlitzStep(*this, sfile, soptions, obj, immfile, ".obj", noblitz, package); - recompile = b.build; - } - - for(i = 0; i < sfile.GetCount(); i++) { - String fn = sfile[i]; - String ext = ToLower(GetFileExt(fn)); - if(findarg(ext, ".rc", ".brc", ".c") < 0 && HdependFileTime(sfile[i]) > GetFileTime(CatAnyPath(outdir, GetFileTitle(fn) + ".obj"))) - recompile++; - } - - String pch_use; - String pch_file; - - if(pch_header.GetCount()) { - String pch_obj = CatAnyPath(outdir, GetFileTitle(pch_header) + "$pch.obj"); - pch_file = CatAnyPath(outdir, GetFileTitle(pch_header) + ".pch"); - RegisterPCHFile(pch_file); - String pch_common = GetPathQ(pch_header) + " -Fp" + GetPathQ(pch_file) + " -FI" + GetPathQ(pch_header); - - if(blitz) // enable MK__s macros - pch_common.Cat(" -DBLITZ_INDEX__=FPCH"); - - if(recompile > 0 || !FileExists(pch_file)) { - int pch_slot = AllocSlot(); - StringBuffer sb; - sb << Join(cc, cpp_options) << Pdb(package, pch_slot, false) << " -Yc" << pch_common - << " -Tp " << GetPathQ(pch_header) << " -Fo" + GetPathQ(pch_obj); - PutConsole("Precompiling header: " + GetFileName(pch_header)); - if(pch_slot < 0 || !Run(~sb, pch_slot, pch_obj, 1)) - error = true; - Wait(); - } - - pch_use = " -Yu" + pch_common; - obj.Add(pch_obj); - } - - if(blitz && b.build) { - PutConsole("BLITZ:" + b.info); - int slot = AllocSlot(); - String c = Join(cc, cpp_options); - if(HasAnyDebug()) - c << Pdb(package, slot, false); - if(slot < 0 || - !Run(c + " -Tp " + GetPathQ(b.path) + " -Fo" + GetPathQ(b.object), - slot, b.object, b.count)) - error = true; - } - - int first_ifile = sfile.GetCount(); - sfile.AppendPick(pick(isfile)); - soptions.AppendPick(pick(isoptions)); - - 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, SourceToObjName(package, fn) + (rc ? "$rc.obj" : brc ? "$brc.obj" : ".obj")); - if(HdependFileTime(fn) > GetFileTime(objfile)) { - int time = msecs(); - bool execerr = false; - if(rc) { - PutConsole(GetFileNamePos(fn)); - int slot = AllocSlot(); - if(slot < 0 || !Run("rc /fo" + GetPathQ(objfile) + Includes(" /i", package, pkg) - + DefinesTargetTime(" /d", package, pkg) + (HasFlag("DEBUG")?" /d_DEBUG":"") - + ' ' + GetPathQ(fn), slot, objfile, 1)) - execerr = true; - } - else - if(brc) { - try { -// String hfn = GetHostPath(fn); - String brcdata = LoadFile(fn); - if(brcdata.IsVoid()) - throw Exc(Format("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 << Pdb(package, slot, false) - << " -Tc " << GetPathQ(tmpfile) << " -Fo" << GetPathQ(objfile); - if(slot < 0 || !Run(String(cmdline), slot, objfile, 1)) - throw Exc(Format("Error compiling binary object '%s'.", objfile)); - } - catch(Exc e) { - PutConsole(e); - execerr = true; - } - } - else { - int slot = AllocSlot(); - String c; - if(ext == ".cu") - c << nvcc << (release ? release_cuda : debug_cuda) << " " << soptions[i] - << " -o " << GetPathQ(objfile) << " " << GetPathQ(fn); - else { - c = cc; - if(HasAnyDebug()) - c << Pdb(package, slot, !sContainsPchOptions(cc) && !sContainsPchOptions(soptions[i])); - c << " " + soptions[i] + (ext == ".c" ? Join(c_options, " -Tc") : Join(cpp_options, " -Tp")) + ' ' - + GetPathQ(fn) + " -Fo" + GetPathQ(objfile); - if(nopch.Find(fn) < 0) - c << pch_use; - } - if(slot < 0 || !Run(c, slot, objfile, 1)) - execerr = true; - } - if(execerr) - DeleteFile(objfile); - error |= execerr; - PutVerbose("compiled in " + GetPrintTime(time)); - } - if(init) - linkfile.Add(objfile); - else - obj.Add(objfile); - immfile.Add(objfile); - } - if(error) { - IdeConsoleEndGroup(); - return false; - } - - bool making_lib = HasFlag("MAKE_LIB") || HasFlag("MAKE_MLIB"); - - if(!making_lib) { - 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()); - -// if(pch_file.GetCount()) -// OnFinish(callback1(DeletePCHFile, pch_file)); - - if(!HasFlag("MAIN")) { - if(HasFlag("BLITZ") || HasFlag("NOLIB") || making_lib) { - 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()) { - String h = ForceExt(product, ".lib"); - linkfile.Add(h); - immfile.Add(h); - } - if(!Wait()) { - IdeConsoleEndGroup(); - return false; - } - Vector objinfo = host->GetFileInfo(obj); - for(int i = 0; i < obj.GetCount(); i++) - if(objinfo[i] > producttime) - return CreateLib(product, obj, all_uses, all_libraries, Gather(pkg.link, config.GetKeys())); - return true; - } - - IdeConsoleEndGroup(); - obj.Append(linkfile); - linkfile = pick(obj); - return true; -} - -bool MscBuilder::CreateLib(const String& product, const Vector& obj, - const Vector& all_uses, const Vector& all_libraries, - const String& link_options) -{ - int linktime = msecs(); - bool isgemsc10 = HasFlag("MSC10") || HasFlag("MSC10X64") - || HasFlag("MSC11") || HasFlag("MSC11X64") - || HasFlag("MSC12") || HasFlag("MSC12X64") - || HasFlag("MSC14") || HasFlag("MSC14X64") - || HasFlag("MSC15") || HasFlag("MSC15X64") - || HasFlag("MSC17") || HasFlag("MSC17X64") - || HasFlag("MSC19") || HasFlag("MSC19X64") - || HasFlag("MSC22") || HasFlag("MSC22X64") - ; - bool is_shared = HasFlag("SO"); - String linker, lib; - if(is_shared) { - linker << LinkerName() << " -dll -nologo "; - lib << "-machine:" << MachineName() - << " -pdb:" << GetPathQ(ForceExt(product, ".pdb")) - << " -out:" << GetPathQ(product); - if(!isgemsc10) - lib << " -incremental:no"; - 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(Format("%s: error saving file", deffile)); - return false; - } - lib << " -def:" << GetPathQ(deffile); - for(int i = 0; i < libpath.GetCount(); i++) - lib << " -LIBPATH:" << GetPathQ(libpath[i]); - lib << ' ' << link_options; - for(int i = 0; i < all_uses.GetCount(); i++) - lib << ' ' << GetPathQ(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 << ' ' << GetPathQ(libfile); - } - } - else{ - linker << (HasFlag("INTEL") ? "xilib" : "link /lib") << " -nologo "; - lib << " -out:" << GetPathQ(product) << ' ' << link_options; - } - for(int i = 0; i < obj.GetCount(); i++) - lib << ' ' << GetPathQ(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 << GetPathQ(product) << ".manifest -outputresource:" << GetPathQ(product) << ";2"; - Execute(mt); - } - PutConsole(String().Cat() << product << " (" << GetFileInfo(product).length - << " B) created in " << GetPrintTime(linktime)); - return true; -} - -bool MscBuilder::Link(const Vector& linkfile, const String& linkoptions, bool createmap) -{ - int time = msecs(); - if(!Wait()) - return false; - - PutLinking(); - - if(HasFlag("MAKE_MLIB") || HasFlag("MAKE_LIB")) - return CreateLib(ForceExt(target, ".lib"), linkfile, Vector(), Vector(), linkoptions); - - bool isgemsc10 = HasFlag("MSC10") || HasFlag("MSC10X64") - || HasFlag("MSC11") || HasFlag("MSC11X64") - || HasFlag("MSC12") || HasFlag("MSC12X64") - || HasFlag("MSC14") || HasFlag("MSC14X64") - || HasFlag("MSC15") || HasFlag("MSC15X64") - || HasFlag("MSC17") || HasFlag("MSC17X64") - || HasFlag("MSC19") || HasFlag("MSC19X64") - || HasFlag("MSC22") || HasFlag("MSC22X64") - ; - for(int i = 0; i < linkfile.GetCount(); i++) - if(GetFileTime(linkfile[i]) > targettime) { - String link, lib; - link << LinkerName() << " -nologo -machine:" << MachineName() - << " -pdb:" << GetPathQ(ForceExt(target, ".pdb")) - << " -out:" << GetPathQ(target); - if(!isgemsc10) - 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 << " -subsystem:windows"; - else - link << " -subsystem:console"; - if(!IsMsc64()) - link << ",5.01"; //,5.01 needed to support WindowsXP - 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++) - lib << ' ' << GetPathQ(AppendExt(linkfile[i], ".lib")); - PutConsole("Linking..."); - bool error = false; - - String tmpFileName; - if(link.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(); - link << "@" << tmpFileName; - } - else - link << lib; - - 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 << GetPathQ(target) << ".manifest -outputresource:" << GetPathQ(target) - << (HasFlag("DLL") ? ";2" : ";1"); - Execute(mt); - } - PutConsole(String().Cat() << target << " (" << GetFileInfo(target).length - << " B) linked in " << GetPrintTime(time)); - } - else { - DeleteFile(target); - error = true; - } - if(tmpFileName != "") - FileDelete(tmpFileName); - return !error; - } - PutConsole(String().Cat() << 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; -} - -INITIALIZER(MscBuilder) -{ - RegisterBuilder("MSC71", CreateMscBuilder); - RegisterBuilder("MSC8", CreateMscBuilder); - RegisterBuilder("MSC8X64", CreateMscBuilder); - RegisterBuilder("MSC8ARM", CreateMscBuilder); - RegisterBuilder("MSC9", CreateMscBuilder); - RegisterBuilder("MSC9X64", CreateMscBuilder); - RegisterBuilder("MSC9ARM", CreateMscBuilder); - RegisterBuilder("MSC10", CreateMscBuilder); - RegisterBuilder("MSC10X64", CreateMscBuilder); - RegisterBuilder("MSC11", CreateMscBuilder); - RegisterBuilder("MSC11X64", CreateMscBuilder); - RegisterBuilder("MSC12", CreateMscBuilder); - RegisterBuilder("MSC12X64", CreateMscBuilder); - RegisterBuilder("MSC14", CreateMscBuilder); - RegisterBuilder("MSC14X64", CreateMscBuilder); - RegisterBuilder("MSC15", CreateMscBuilder); - RegisterBuilder("MSC15X64", CreateMscBuilder); - RegisterBuilder("MSC17", CreateMscBuilder); - RegisterBuilder("MSC17X64", CreateMscBuilder); - RegisterBuilder("MSC19", CreateMscBuilder); - RegisterBuilder("MSC19X64", CreateMscBuilder); - RegisterBuilder("MSC22", CreateMscBuilder); - RegisterBuilder("MSC22X64", CreateMscBuilder); - RegisterBuilder("EVC_ARM", CreateMscBuilder); - RegisterBuilder("EVC_MIPS", CreateMscBuilder); - RegisterBuilder("EVC_SH3", CreateMscBuilder); - RegisterBuilder("EVC_SH4", CreateMscBuilder); - RegisterBuilder("INTEL", CreateMscBuilder); -} +#include "Builders.h" + +#include "coff.h" + +String MaxLenString(const byte *b, int maxlen) +{ + const byte *e = b + maxlen; + while(e > b && e[-1] == 0) + e--; + return String(b, int(e - b)); +} + +String COFFSymbolName(const COFF_IMAGE_SYMBOL& sym, const char *strtbl) +{ + String name; + if(sym.N.Name.Short) + name = MaxLenString(sym.N.ShortName, 8); + else + name = strtbl + sym.N.Name.Long; + return name; +} + +#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(); + if(!begin) + return; + 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 -W" << (pkg.nowarnings ? "0" : "3") << " -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") || HasFlag("MSC11") + || HasFlag("MSC12") || HasFlag("MSC15") || HasFlag("MSC14") || HasFlag("MSC17") + || HasFlag("MSC19") || HasFlag("MSC22"); +} + +bool MscBuilder::IsMscArm() const +{ + return HasFlag("MSC8ARM") || HasFlag("MSC9ARM"); +} + +bool MscBuilder::IsMsc64() const +{ + return HasFlag("MSC8X64") || HasFlag("MSC9X64") || HasFlag("MSC10X64") || HasFlag("MSC11X64") + || HasFlag("MSC12X64") || HasFlag("MSC14X64") || HasFlag("MSC15X64") || HasFlag("MSC17X64") + || HasFlag("MSC19X64") || HasFlag("MSC22X64"); +} + +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; +} + +String MscBuilder::Pdb(String package, int slot, bool separate_pdb) const +{ + String pdb_name = GetAnyFileName(package); + if(separate_pdb) + pdb_name << '-' << (slot + 1); + return " -Gy -Fd" + GetPathQ(CatAnyPath(outdir, pdb_name + ".pdb")); +} + +void DeletePCHFile(const String& pch_file) +{ + DeleteFile(pch_file); + PutVerbose("Deleting precompiled header: " + pch_file); +} + +bool MscBuilder::BuildPackage(const String& package, Vector& linkfile, Vector& immfile, + String& linkoptions, const Vector& all_uses, const Vector& all_libraries, int opt) +{ + if(HasFlag("MAKE_MLIB") && !HasFlag("MAIN")) + return true; + + SaveBuildInfo(package); + + 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"); + + Vector sfile, isfile; + Vector soptions, isoptions; + Vector sobjfile; + bool error = false; + + String pch_header; + + Index nopch, noblitz; + + bool blitz = HasFlag("BLITZ"); + bool release = !HasFlag("DEBUG"); + + 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 = NormalizePath(srcfile[j]); + String ext = ToLower(GetFileExt(fn)); + if(findarg(ext, ".c", ".cpp", ".cc", ".cxx", ".rc", ".brc") >= 0 || + ext == ".cu" && HasFlag("CUDA") || + (!release && blitz && ext == ".icpp")) { + if(FindIndex(sfile, fn) < 0) { + sfile.Add(fn); + soptions.Add(gop); + } + } + else + if(ext == ".icpp") { + isfile.Add(fn); + isoptions.Add(gop); + } + else + if(ext == ".obj") + obj.Add(fn); + else + if(ext == ".lib") + linkfile.Add(fn); + else + if(IsHeaderExt(ext) && pkg[i].pch && allow_pch && IsMsc89() && release && !HasAnyDebug() && !blitz) { + if(pch_header.GetCount()) + PutConsole(GetFileName(fn) + ": multiple PCHs are not allowed. Check your package configuration"); + else + pch_header = fn; + } + if(pkg[i].nopch) { + nopch.Add(fn); + if(allow_pch && release) + noblitz.Add(fn); + } + if(pkg[i].noblitz) + noblitz.Add(fn); + if(ext == ".c") + nopch.Add(fn); + } + } + } + + String nvcc = "nvcc -c " + IncludesDefinesTargetTime(package, pkg) + " "; + + 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 = GetPathQ(CatAnyPath(outdir, GetAnyFileName(package) + ".pdb")); +// String pch; +// if(!HasFlag("MSC8")) // MSC8 does not support automatic precompiled headers... +// pch << " -YX -Fp" << GetPathQ(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" : " -MT"); + + String cc_size = cc; + String cc_speed = cc; + + if(release) + cc << ' ' << release_options; + else + cc << "d " << debug_options; + + int recompile = 0; + Blitz b; + if(blitz) { + BlitzBuilderComponent bc(this); + b = bc.MakeBlitzStep(*this, sfile, soptions, obj, immfile, ".obj", noblitz, package); + recompile = b.build; + } + + for(i = 0; i < sfile.GetCount(); i++) { + String fn = sfile[i]; + String ext = ToLower(GetFileExt(fn)); + if(findarg(ext, ".rc", ".brc", ".c") < 0 && HdependFileTime(sfile[i]) > GetFileTime(CatAnyPath(outdir, GetFileTitle(fn) + ".obj"))) + recompile++; + } + + String pch_use; + String pch_file; + + if(pch_header.GetCount()) { + String pch_obj = CatAnyPath(outdir, GetFileTitle(pch_header) + "$pch.obj"); + pch_file = CatAnyPath(outdir, GetFileTitle(pch_header) + ".pch"); + RegisterPCHFile(pch_file); + String pch_common = GetPathQ(pch_header) + " -Fp" + GetPathQ(pch_file) + " -FI" + GetPathQ(pch_header); + + if(blitz) // enable MK__s macros + pch_common.Cat(" -DBLITZ_INDEX__=FPCH"); + + if(recompile > 0 || !FileExists(pch_file)) { + int pch_slot = AllocSlot(); + StringBuffer sb; + sb << Join(cc, cpp_options) << Pdb(package, pch_slot, false) << " -Yc" << pch_common + << " -Tp " << GetPathQ(pch_header) << " -Fo" + GetPathQ(pch_obj); + PutConsole("Precompiling header: " + GetFileName(pch_header)); + if(pch_slot < 0 || !Run(~sb, pch_slot, pch_obj, 1)) + error = true; + Wait(); + } + + pch_use = " -Yu" + pch_common; + obj.Add(pch_obj); + } + + if(blitz && b.build) { + PutConsole("BLITZ:" + b.info); + int slot = AllocSlot(); + String c = Join(cc, cpp_options); + if(HasAnyDebug()) + c << Pdb(package, slot, false); + if(slot < 0 || + !Run(c + " -Tp " + GetPathQ(b.path) + " -Fo" + GetPathQ(b.object), + slot, b.object, b.count)) + error = true; + } + + int first_ifile = sfile.GetCount(); + sfile.AppendPick(pick(isfile)); + soptions.AppendPick(pick(isoptions)); + + 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, SourceToObjName(package, fn) + (rc ? "$rc.obj" : brc ? "$brc.obj" : ".obj")); + if(HdependFileTime(fn) > GetFileTime(objfile)) { + int time = msecs(); + bool execerr = false; + if(rc) { + PutConsole(GetFileNamePos(fn)); + int slot = AllocSlot(); + if(slot < 0 || !Run("rc /fo" + GetPathQ(objfile) + Includes(" /i", package, pkg) + + DefinesTargetTime(" /d", package, pkg) + (HasFlag("DEBUG")?" /d_DEBUG":"") + + ' ' + GetPathQ(fn), slot, objfile, 1)) + execerr = true; + } + else + if(brc) { + try { +// String hfn = GetHostPath(fn); + String brcdata = LoadFile(fn); + if(brcdata.IsVoid()) + throw Exc(Format("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 << Pdb(package, slot, false) + << " -Tc " << GetPathQ(tmpfile) << " -Fo" << GetPathQ(objfile); + if(slot < 0 || !Run(String(cmdline), slot, objfile, 1)) + throw Exc(Format("Error compiling binary object '%s'.", objfile)); + } + catch(Exc e) { + PutConsole(e); + execerr = true; + } + } + else { + int slot = AllocSlot(); + String c; + if(ext == ".cu") + c << nvcc << (release ? release_cuda : debug_cuda) << " " << soptions[i] + << " -o " << GetPathQ(objfile) << " " << GetPathQ(fn); + else { + c = cc; + if(HasAnyDebug()) + c << Pdb(package, slot, !sContainsPchOptions(cc) && !sContainsPchOptions(soptions[i])); + c << " " + soptions[i] + (ext == ".c" ? Join(c_options, " -Tc") : Join(cpp_options, " -Tp")) + ' ' + + GetPathQ(fn) + " -Fo" + GetPathQ(objfile); + if(nopch.Find(fn) < 0) + c << pch_use; + } + if(slot < 0 || !Run(c, slot, objfile, 1)) + execerr = true; + } + if(execerr) + DeleteFile(objfile); + error |= execerr; + PutVerbose("compiled in " + GetPrintTime(time)); + } + if(init) + linkfile.Add(objfile); + else + obj.Add(objfile); + immfile.Add(objfile); + } + if(error) { + IdeConsoleEndGroup(); + return false; + } + + bool making_lib = HasFlag("MAKE_LIB") || HasFlag("MAKE_MLIB"); + + if(!making_lib) { + 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()); + +// if(pch_file.GetCount()) +// OnFinish(callback1(DeletePCHFile, pch_file)); + + if(!HasFlag("MAIN")) { + if(HasFlag("BLITZ") || HasFlag("NOLIB") || making_lib) { + 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()) { + String h = ForceExt(product, ".lib"); + linkfile.Add(h); + immfile.Add(h); + } + if(!Wait()) { + IdeConsoleEndGroup(); + return false; + } + Vector objinfo = host->GetFileInfo(obj); + for(int i = 0; i < obj.GetCount(); i++) + if(objinfo[i] > producttime) + return CreateLib(product, obj, all_uses, all_libraries, Gather(pkg.link, config.GetKeys())); + return true; + } + + IdeConsoleEndGroup(); + obj.Append(linkfile); + linkfile = pick(obj); + return true; +} + +bool MscBuilder::CreateLib(const String& product, const Vector& obj, + const Vector& all_uses, const Vector& all_libraries, + const String& link_options) +{ + int linktime = msecs(); + bool isgemsc10 = HasFlag("MSC10") || HasFlag("MSC10X64") + || HasFlag("MSC11") || HasFlag("MSC11X64") + || HasFlag("MSC12") || HasFlag("MSC12X64") + || HasFlag("MSC14") || HasFlag("MSC14X64") + || HasFlag("MSC15") || HasFlag("MSC15X64") + || HasFlag("MSC17") || HasFlag("MSC17X64") + || HasFlag("MSC19") || HasFlag("MSC19X64") + || HasFlag("MSC22") || HasFlag("MSC22X64") + ; + bool is_shared = HasFlag("SO"); + String linker, lib; + if(is_shared) { + linker << LinkerName() << " -dll -nologo "; + lib << "-machine:" << MachineName() + << " -pdb:" << GetPathQ(ForceExt(product, ".pdb")) + << " -out:" << GetPathQ(product); + if(!isgemsc10) + lib << " -incremental:no"; + 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(Format("%s: error saving file", deffile)); + return false; + } + lib << " -def:" << GetPathQ(deffile); + for(int i = 0; i < libpath.GetCount(); i++) + lib << " -LIBPATH:" << GetPathQ(libpath[i]); + lib << ' ' << link_options; + for(int i = 0; i < all_uses.GetCount(); i++) + lib << ' ' << GetPathQ(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 << ' ' << GetPathQ(libfile); + } + } + else{ + linker << (HasFlag("INTEL") ? "xilib" : "link /lib") << " -nologo "; + lib << " -out:" << GetPathQ(product) << ' ' << link_options; + } + for(int i = 0; i < obj.GetCount(); i++) + lib << ' ' << GetPathQ(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 << GetPathQ(product) << ".manifest -outputresource:" << GetPathQ(product) << ";2"; + Execute(mt); + } + PutConsole(String().Cat() << product << " (" << GetFileInfo(product).length + << " B) created in " << GetPrintTime(linktime)); + return true; +} + +bool MscBuilder::Link(const Vector& linkfile, const String& linkoptions, bool createmap) +{ + int time = msecs(); + if(!Wait()) + return false; + + PutLinking(); + + if(HasFlag("MAKE_MLIB") || HasFlag("MAKE_LIB")) + return CreateLib(ForceExt(target, ".lib"), linkfile, Vector(), Vector(), linkoptions); + + bool isgemsc10 = HasFlag("MSC10") || HasFlag("MSC10X64") + || HasFlag("MSC11") || HasFlag("MSC11X64") + || HasFlag("MSC12") || HasFlag("MSC12X64") + || HasFlag("MSC14") || HasFlag("MSC14X64") + || HasFlag("MSC15") || HasFlag("MSC15X64") + || HasFlag("MSC17") || HasFlag("MSC17X64") + || HasFlag("MSC19") || HasFlag("MSC19X64") + || HasFlag("MSC22") || HasFlag("MSC22X64") + ; + for(int i = 0; i < linkfile.GetCount(); i++) + if(GetFileTime(linkfile[i]) > targettime) { + String link, lib; + link << LinkerName() << " -nologo -machine:" << MachineName() + << " -pdb:" << GetPathQ(ForceExt(target, ".pdb")) + << " -out:" << GetPathQ(target); + if(!isgemsc10) + 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 << " -subsystem:windows"; + else + link << " -subsystem:console"; + if(!IsMsc64()) + link << ",5.01"; //,5.01 needed to support WindowsXP + 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++) + lib << ' ' << GetPathQ(AppendExt(linkfile[i], ".lib")); + PutConsole("Linking..."); + bool error = false; + + String tmpFileName; + if(link.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(); + link << "@" << tmpFileName; + } + else + link << lib; + + 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 << GetPathQ(target) << ".manifest -outputresource:" << GetPathQ(target) + << (HasFlag("DLL") ? ";2" : ";1"); + Execute(mt); + } + PutConsole(String().Cat() << target << " (" << GetFileInfo(target).length + << " B) linked in " << GetPrintTime(time)); + } + else { + DeleteFile(target); + error = true; + } + if(tmpFileName != "") + FileDelete(tmpFileName); + return !error; + } + PutConsole(String().Cat() << 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; +} + +INITIALIZER(MscBuilder) +{ + RegisterBuilder("MSC71", CreateMscBuilder); + RegisterBuilder("MSC8", CreateMscBuilder); + RegisterBuilder("MSC8X64", CreateMscBuilder); + RegisterBuilder("MSC8ARM", CreateMscBuilder); + RegisterBuilder("MSC9", CreateMscBuilder); + RegisterBuilder("MSC9X64", CreateMscBuilder); + RegisterBuilder("MSC9ARM", CreateMscBuilder); + RegisterBuilder("MSC10", CreateMscBuilder); + RegisterBuilder("MSC10X64", CreateMscBuilder); + RegisterBuilder("MSC11", CreateMscBuilder); + RegisterBuilder("MSC11X64", CreateMscBuilder); + RegisterBuilder("MSC12", CreateMscBuilder); + RegisterBuilder("MSC12X64", CreateMscBuilder); + RegisterBuilder("MSC14", CreateMscBuilder); + RegisterBuilder("MSC14X64", CreateMscBuilder); + RegisterBuilder("MSC15", CreateMscBuilder); + RegisterBuilder("MSC15X64", CreateMscBuilder); + RegisterBuilder("MSC17", CreateMscBuilder); + RegisterBuilder("MSC17X64", CreateMscBuilder); + RegisterBuilder("MSC19", CreateMscBuilder); + RegisterBuilder("MSC19X64", CreateMscBuilder); + RegisterBuilder("MSC22", CreateMscBuilder); + RegisterBuilder("MSC22X64", CreateMscBuilder); + RegisterBuilder("EVC_ARM", CreateMscBuilder); + RegisterBuilder("EVC_MIPS", CreateMscBuilder); + RegisterBuilder("EVC_SH3", CreateMscBuilder); + RegisterBuilder("EVC_SH4", CreateMscBuilder); + RegisterBuilder("INTEL", CreateMscBuilder); +}