diff --git a/uppsrc/ide/Builders/Builders.h b/uppsrc/ide/Builders/Builders.h index fc6257d4f..27d021869 100644 --- a/uppsrc/ide/Builders/Builders.h +++ b/uppsrc/ide/Builders/Builders.h @@ -17,6 +17,8 @@ struct Blitz { String info; }; +String BrcToC(CParser& binscript, String basedir); + struct CppBuilder : Builder { virtual String GetTargetExt() const; @@ -58,8 +60,6 @@ struct CppBuilder : Builder { void ShowTime(int count, int start_time); - String BrcToC(String objfile, CParser& binscript, String basedir, const String& package, const Package& pkg); - Blitz BlitzStep(Vector& sfile, Vector& soptions, Vector& obj, const char *objext, Vector& optimize); diff --git a/uppsrc/ide/Builders/CppBuilder.cpp b/uppsrc/ide/Builders/CppBuilder.cpp index d185c3464..ce1ba5a05 100644 --- a/uppsrc/ide/Builders/CppBuilder.cpp +++ b/uppsrc/ide/Builders/CppBuilder.cpp @@ -396,101 +396,3 @@ String CppBuilder::IncludesDefinesTargetTime(const String& package, const Packag targettime = GetFileTime(target); return cc; } - -static void WriteByteArray(StringBuffer& fo, const String& data) -{ - int pos = 0; - for(int p = 0; p < data.GetLength(); p++) { - if(pos >= 70) { - fo << '\n'; - pos = 0; - } - if(pos == 0) - fo << '\t'; - String part = FormatInt((byte)data[p]); - fo << part << ", "; - pos += part.GetLength() + 2; - } -} - -String CppBuilder::BrcToC(String objfile, CParser& binscript, String basedir, - const String& package, const Package& pkg) -{ - BinObjInfo info; - info.Parse(binscript, basedir); - StringBuffer fo; - for(int i = 0; i < info.blocks.GetCount(); i++) { - String ident = info.blocks.GetKey(i); - ArrayMap& belem = info.blocks[i]; - if(belem[0].flags & (BinObjInfo::Block::FLG_ARRAY | BinObjInfo::Block::FLG_MASK)) { - int count = Max(belem.GetKeys()) + 1; - Vector blockref; - blockref.SetCount(count, 0); - for(int a = 0; a < belem.GetCount(); a++) { - BinObjInfo::Block& b = belem[a]; - blockref[b.index] = &b; - } - for(int i = 0; i < blockref.GetCount(); i++) - if(blockref[i]) { - BinObjInfo::Block& b = *blockref[i]; - fo << "static char " << ident << "_" << i << "[] = {\n"; - String data = ::LoadFile(b.file); - if(data.IsVoid()) - throw Exc(NFormat("Error reading file '%s'", b.file)); - if(data.GetLength() != b.length) - throw Exc(NFormat("length of file '%s' changed (%d -> %d) during object creation", - b.file, b.length, data.GetLength())); - switch(b.encoding) { - case BinObjInfo::Block::ENC_BZ2: data = BZ2Compress(data); break; - case BinObjInfo::Block::ENC_ZIP: data = ZCompress(data); break; - } - b.length = data.GetLength(); - data.Cat('\0'); - WriteByteArray(fo, data); - fo << "\n};\n\n"; -// fo << AsCString(data, 70, "\t", ASCSTRING_OCTALHI | ASCSTRING_SMART) << ";\n\n"; - } - - fo << "int " << ident << "_count = " << blockref.GetCount() << ";\n\n" - "int " << ident << "_length[] = {\n"; - for(int i = 0; i < blockref.GetCount(); i++) - fo << '\t' << (blockref[i] ? blockref[i]->length : -1) << ",\n"; - fo << "};\n\n" - "char *" << ident << "[] = {\n"; - for(int i = 0; i < blockref.GetCount(); i++) - if(blockref[i]) - fo << '\t' << ident << '_' << i << ",\n"; - else - fo << "\t0,\n"; - fo << "};\n\n"; - if(belem[0].flags & BinObjInfo::Block::FLG_MASK) { - fo << "char *" << ident << "_files[] = {\n"; - for(int i = 0; i < blockref.GetCount(); i++) - fo << '\t' << AsCString(blockref[i] ? GetFileName(blockref[i]->file) : String(Null)) << ",\n"; - fo << "\n};\n\n"; - } - } - else { - BinObjInfo::Block& b = belem[0]; - fo << "static char " << ident << "_[] = {\n"; - String data = ::LoadFile(b.file); - if(data.IsVoid()) - throw Exc(NFormat("Error reading file '%s'", b.file)); - if(data.GetLength() != b.length) - throw Exc(NFormat("length of file '%s' changed (%d -> %d) during object creation", - b.file, b.length, data.GetLength())); - switch(b.encoding) { - case BinObjInfo::Block::ENC_BZ2: data = BZ2Compress(data); break; - case BinObjInfo::Block::ENC_ZIP: data = ZCompress(data); break; - } - int b_length = data.GetLength(); - data.Cat('\0'); - WriteByteArray(fo, data); - fo << "\n};\n\n" - "char *" << ident << " = " << ident << "_;\n\n" -// fo << AsCString(data, 70) << ";\n\n" - "int " << ident << "_length = " << b_length << ";\n\n"; - } - } - return fo; -} diff --git a/uppsrc/ide/Builders/GccBuilder.icpp b/uppsrc/ide/Builders/GccBuilder.icpp index 0edd4c0eb..08dca3b76 100644 --- a/uppsrc/ide/Builders/GccBuilder.icpp +++ b/uppsrc/ide/Builders/GccBuilder.icpp @@ -23,7 +23,7 @@ String GccBuilder::CmdLine(const String& package, const Package& pkg) void GccBuilder::BinaryToObject(String objfile, CParser& binscript, String basedir, const String& package, const Package& pkg) { - String fo = BrcToC(objfile, binscript, basedir, package, pkg); + String fo = BrcToC(binscript, basedir); String tmpfile = ForceExt(objfile, ".c"); SaveFile(tmpfile, fo); String cc = CmdLine(package, pkg); diff --git a/uppsrc/ide/Builders/MakeFile.cpp b/uppsrc/ide/Builders/MakeFile.cpp index b75e990a1..0c1799262 100644 --- a/uppsrc/ide/Builders/MakeFile.cpp +++ b/uppsrc/ide/Builders/MakeFile.cpp @@ -1,248 +1,252 @@ -#include "Builders.h" - -static String MakeIdent(const char *name) -{ - String out; - for(; *name; name++) - out << (iscid(*name) ? *name : '_'); - return out; -} - -static String MakeSourcePath(const Vector& dirs, String fn, bool raw, bool exporting) -{ - fn = UnixPath(fn); - for(int i = 0; i < dirs.GetCount(); i++) - { - int dl = dirs[i].GetLength(); - if(fn.GetLength() >= dl + 2 && !memcmp(fn, dirs[i], dl) && fn[dl] == '/') { - String s; - if(!exporting) - s << "$(UPPDIR" << (i + 1) << ")"; - s << AdjustMakePath(fn.GetIter(dl + 1)); - return s; - } - } - return raw ? String() : AdjustMakePath(fn); -} - -String CppBuilder::GetMakePath(String fn) const -{ - return ::GetMakePath(fn, HasFlag("WIN32")); -} - -void CppBuilder::AddMakeFile(MakeFile& makefile, String package, - const Vector& all_uses, const Vector& all_libraries, - const Index& common_config, bool exporting) -{ - String packagepath = PackagePath(package); - Package pkg; - pkg.Load(packagepath); - String packagedir = GetFileFolder(packagepath); - Vector src = GetUppDirs(); - for(int i = 0; i < src.GetCount(); i++) - src[i] = UnixPath(src[i]); - - bool main = HasFlag("MAIN"); - bool is_shared = HasFlag("SO"); - bool libout = !main && !HasFlag("NOLIB"); - bool win32 = HasFlag("WIN32"); - - String pack_ident = MakeIdent(package); - String outdir = "OutDir_" + pack_ident; - String macros = "Macro_" + pack_ident; - String macdef = "$(Macro)"; - String objext = (HasFlag("MSC") || HasFlag("EVC") ? ".obj" : ".o"); - - Vector x(config.GetKeys(), 1); - Sort(x); - for(int i = 0; i < x.GetCount(); i++) { - if(common_config.Find(x[i]) < 0) - macdef << " -Dflag" << x[i]; - x[i] = InitCaps(x[i]); - } - - makefile.outdir << "$(" << outdir << ")"; - makefile.outfile << AdjustMakePath(GetFileTitle(NativePath(package))); - if(main) - makefile.outfile << GetTargetExt(); - else if(is_shared) - makefile.outfile << (win32 ? ".dll" : ".so"); - else - makefile.outfile << (win32 && HasFlag("MSC") ? ".lib" : ".a"); - makefile.output << (main ? String("$(OutDir)") : makefile.outdir) << makefile.outfile; - - if(main) { - makefile.config << "CXX = c++\n" - "LINKER = $(CXX)\n"; - String flags; - if(HasFlag("DEBUG")) - flags << " -D_DEBUG " << debug_options; - else - flags << ' ' << release_options; - if(HasFlag("DEBUG_MINIMAL")) - flags << " -ggdb -g1"; - if(HasFlag("DEBUG_FULL")) - flags << " -ggdb -g2"; - if(is_shared && !win32) - flags << " -fPIC "; - flags << ' ' << Gather(pkg.option, config.GetKeys()); - makefile.config << "CFLAGS =" << flags << "\n" - "CXXFLAGS =" << flags << "\n" - "LDFLAGS = " << (HasFlag("DEBUG") ? debug_link : release_link) << " $(LINKOPTIONS)\n" - "LIBPATH ="; - for(int i = 0; i < libpath.GetCount(); i++) - makefile.config << " -L" << GetMakePath(AdjustMakePath(GetHostPathQ(libpath[i]))); - makefile.config << "\n" - "AR = ar -sr\n\n"; - makefile.install << "\t-mkdir -p $(OutDir)\n"; - Vector lib; - String lnk; - lnk << "$(LINKER)"; - if(!HasFlag("SHARED")) - lnk << " -static"; - if(HasFlag("WIN32")) { - lnk << " -mwindows"; - if(!HasFlag("GUI")) - makefile.linkfiles << " -mconsole"; - } - lnk << " -o $(OutFile)"; - if(HasFlag("DEBUG") || HasFlag("DEBUG_MINIMAL") || HasFlag("DEBUG_FULL")) - lnk << " -ggdb"; - else - lnk << (!HasFlag("OSX11") ? " -Wl,-s" : ""); - - lnk << " $(LIBPATH)"; - if (!HasFlag("OSX11")) - lnk << " -Wl,-O,2"; - lnk << " $(LDFLAGS) -Wl,--start-group "; - - makefile.linkfiles = lnk; - } - - makefile.config << outdir << " = $(UPPOUT)" - << GetMakePath(AdjustMakePath(String().Cat() << package << '/' << method << '-' << Join(x, "-") << '/')) << "\n" - << macros << " = " << macdef << "\n"; - - makefile.install << "\t-mkdir -p $(" << outdir << ")\n"; - - String libdep, libfiles; - - libdep << makefile.output << ":"; - if(is_shared) - { - libfiles = "c++ -shared -fPIC"; // -v"; - Point p = ExtractVersion(); - if(!IsNull(p.x)) { - libfiles << " -Xlinker --major-image-version -Xlinker " << p.x; - if(!IsNull(p.y)) - libfiles << " -Xlinker --minor-image-version -Xlinker " << p.y; - } - libfiles << " -o "; - } - else - libfiles = "$(AR) "; - libfiles << makefile.output; - - Vector libs = Split(Gather(pkg.library, config.GetKeys()), ' '); - for(int i = 0; i < libs.GetCount(); i++) { - String ln = libs[i]; - String ext = ToLower(GetFileExt(ln)); - if(ext == ".a" || ext == ".so" || ext == ".dll") - makefile.linkfileend << " \\\n\t\t\t" << GetHostPathQ(FindInDirs(libpath, ln)); - else - makefile.linkfileend << " \\\n\t\t\t-l" << ln; - } - - for(int i = 0; i < pkg.GetCount(); i++) - if(!pkg[i].separator) { - String gop = Gather(pkg[i].option, config.GetKeys()); - String fn = SourcePath(package, pkg[i]); - String ext = ToLower(GetFileExt(fn)); - bool isc = ext == ".c"; - bool isrc = (ext == ".rc" && HasFlag("WIN32")); - bool iscpp = (ext == ".cpp" || ext == ".cc" || ext == ".cxx"); - bool isicpp = (ext == ".icpp"); - if(isc || isrc || iscpp || isicpp) { - String outfile; - outfile << makefile.outdir << AdjustMakePath(GetFileTitle(fn)) << (isrc ? "_rc" : "") << objext; - String srcfile = GetMakePath(MakeSourcePath(src, fn, false, exporting)); - makefile.rules << outfile << ": " << srcfile; - Vector dep = HdependGetDependencies(fn); - Sort(dep, GetLanguageInfo()); - for(int d = 0; d < dep.GetCount(); d++) { - String dfn = MakeSourcePath(src, dep[d], true, exporting); - if(!IsNull(dfn)) - makefile.rules << " \\\n\t" << GetMakePath(dfn); - } - makefile.rules << "\n" - "\t$(CXX) -c " << (isc ? "-x c $(CFLAGS)" : "-x c++ $(CXXFLAGS)") << " $(CINC) $(" << macros << ") " - << gop << " " << srcfile << " -o " << outfile << "\n\n"; - if(!libout || isicpp) { - makefile.linkdep << " \\\n\t" << outfile; - makefile.linkfiles << " \\\n\t\t" << outfile; - } - else { - libdep << " \\\n\t" << outfile; - libfiles << " \\\n\t\t" << outfile; - } - } - else - if(ext == ".o" || ext == ".obj" || ext == ".a" || ext == ".so" || ext == ".lib" || ext == ".dll") { - makefile.linkdep << " \\\n\t" << fn; - makefile.linkfiles << ' ' << fn; - } - } - - if(libout) { - makefile.rules << libdep << "\n\t" << libfiles << "\n\n"; - makefile.linkdep << " \\\n\t" << makefile.output; - makefile.linkfiles << " \\\n\t\t\t" << makefile.output; - } -/* - if(main) { - if(!HasFlag("SOLARIS")&&!HasFlag("OSX11")) - makefile.linkfiles << " \\\n\t\t-Wl,--start-group "; - DDUMPC(all_libraries); - for(int i = 0; i < all_libraries.GetCount(); i++) { - String ln = all_libraries[i]; - String ext = ToLower(GetFileExt(ln)); - if(ext == ".a" || ext == ".so" || ext == ".dll") - makefile.linkfileend << " \\\n\t\t\t" << GetHostPathQ(FindInDirs(libpath, ln)); - else - makefile.linkfileend << " \\\n\t\t\t-l" << ln; - } - if(!HasFlag("SOLARIS")&&!HasFlag("OSX11")) - makefile.linkfileend << " \\\n\t\t-Wl,--end-group\n\n"; - } -*/ -} - -Point CppBuilder::ExtractVersion() -{ - Point v = Point(Null, Null); - CParser p(version); - while(!p.IsEof()) { - if(p.IsNumber()) { - v.x = p.ReadNumber(); - break; - } - p.GetChar(); - p.Spaces(); - } - while(!p.IsEof()) { - if(p.IsNumber()) { - v.y = p.ReadNumber(); - break; - } - p.GetChar(); - p.Spaces(); - } - return v; -} - -void CppBuilder::ShowTime(int count, int start_time) -{ - if(count) - PutConsole(NFormat("%d file(s) compiled in %s %d msec/file", - count, GetPrintTime(start_time), msecs(start_time) / count)); -} +#include "Builders.h" + +static String MakeIdent(const char *name) +{ + String out; + for(; *name; name++) + out << (iscid(*name) ? *name : '_'); + return out; +} + +static String MakeSourcePath(const Vector& dirs, String fn, bool raw, bool exporting) +{ + fn = UnixPath(fn); + for(int i = 0; i < dirs.GetCount(); i++) + { + int dl = dirs[i].GetLength(); + if(fn.GetLength() >= dl + 2 && !memcmp(fn, dirs[i], dl) && fn[dl] == '/') { + String s; + if(!exporting) + s << "$(UPPDIR" << (i + 1) << ")"; + s << AdjustMakePath(fn.GetIter(dl + 1)); + return s; + } + } + return raw ? String() : AdjustMakePath(fn); +} + +String CppBuilder::GetMakePath(String fn) const +{ + return ::GetMakePath(fn, HasFlag("WIN32")); +} + +void CppBuilder::AddMakeFile(MakeFile& makefile, String package, + const Vector& all_uses, const Vector& all_libraries, + const Index& common_config, bool exporting) +{ + String packagepath = PackagePath(package); + Package pkg; + pkg.Load(packagepath); + String packagedir = GetFileFolder(packagepath); + Vector src = GetUppDirs(); + for(int i = 0; i < src.GetCount(); i++) + src[i] = UnixPath(src[i]); + + bool main = HasFlag("MAIN"); + bool is_shared = HasFlag("SO"); + bool libout = !main && !HasFlag("NOLIB"); + bool win32 = HasFlag("WIN32"); + + String pack_ident = MakeIdent(package); + String outdir = "OutDir_" + pack_ident; + String macros = "Macro_" + pack_ident; + String macdef = "$(Macro)"; + String objext = (HasFlag("MSC") || HasFlag("EVC") ? ".obj" : ".o"); + + Vector x(config.GetKeys(), 1); + Sort(x); + for(int i = 0; i < x.GetCount(); i++) { + if(common_config.Find(x[i]) < 0) + macdef << " -Dflag" << x[i]; + x[i] = InitCaps(x[i]); + } + + makefile.outdir << "$(" << outdir << ")"; + makefile.outfile << AdjustMakePath(GetFileTitle(NativePath(package))); + if(main) + makefile.outfile << GetTargetExt(); + else if(is_shared) + makefile.outfile << (win32 ? ".dll" : ".so"); + else + makefile.outfile << (win32 && HasFlag("MSC") ? ".lib" : ".a"); + makefile.output << (main ? String("$(OutDir)") : makefile.outdir) << makefile.outfile; + + if(main) { + makefile.config << "CXX = c++\n" + "LINKER = $(CXX)\n"; + String flags; + if(HasFlag("DEBUG")) + flags << " -D_DEBUG " << debug_options; + else + flags << ' ' << release_options; + if(HasFlag("DEBUG_MINIMAL")) + flags << " -ggdb -g1"; + if(HasFlag("DEBUG_FULL")) + flags << " -ggdb -g2"; + if(is_shared && !win32) + flags << " -fPIC "; + flags << ' ' << Gather(pkg.option, config.GetKeys()); + makefile.config << "CFLAGS =" << flags << "\n" + "CXXFLAGS =" << flags << "\n" + "LDFLAGS = " << (HasFlag("DEBUG") ? debug_link : release_link) << " $(LINKOPTIONS)\n" + "LIBPATH ="; + for(int i = 0; i < libpath.GetCount(); i++) + makefile.config << " -L" << GetMakePath(AdjustMakePath(GetHostPathQ(libpath[i]))); + makefile.config << "\n" + "AR = ar -sr\n\n"; + makefile.install << "\t-mkdir -p $(OutDir)\n"; + Vector lib; + String lnk; + lnk << "$(LINKER)"; + if(!HasFlag("SHARED")) + lnk << " -static"; + if(HasFlag("WIN32")) { + lnk << " -mwindows"; + if(!HasFlag("GUI")) + makefile.linkfiles << " -mconsole"; + } + lnk << " -o $(OutFile)"; + if(HasFlag("DEBUG") || HasFlag("DEBUG_MINIMAL") || HasFlag("DEBUG_FULL")) + lnk << " -ggdb"; + else + lnk << (!HasFlag("OSX11") ? " -Wl,-s" : ""); + + lnk << " $(LIBPATH)"; + if (!HasFlag("OSX11")) + lnk << " -Wl,-O,2"; + lnk << " $(LDFLAGS) -Wl,--start-group "; + + makefile.linkfiles = lnk; + } + + makefile.config << outdir << " = $(UPPOUT)" + << GetMakePath(AdjustMakePath(String().Cat() << package << '/' << method << '-' << Join(x, "-") << '/')) << "\n" + << macros << " = " << macdef << "\n"; + + makefile.install << "\t-mkdir -p $(" << outdir << ")\n"; + + String libdep, libfiles; + + libdep << makefile.output << ":"; + if(is_shared) + { + libfiles = "c++ -shared -fPIC"; // -v"; + Point p = ExtractVersion(); + if(!IsNull(p.x)) { + libfiles << " -Xlinker --major-image-version -Xlinker " << p.x; + if(!IsNull(p.y)) + libfiles << " -Xlinker --minor-image-version -Xlinker " << p.y; + } + libfiles << " -o "; + } + else + libfiles = "$(AR) "; + libfiles << makefile.output; + + Vector libs = Split(Gather(pkg.library, config.GetKeys()), ' '); + for(int i = 0; i < libs.GetCount(); i++) { + String ln = libs[i]; + String ext = ToLower(GetFileExt(ln)); + if(ext == ".a" || ext == ".so" || ext == ".dll") + makefile.linkfileend << " \\\n\t\t\t" << GetHostPathQ(FindInDirs(libpath, ln)); + else + makefile.linkfileend << " \\\n\t\t\t-l" << ln; + } + + for(int i = 0; i < pkg.GetCount(); i++) + if(!pkg[i].separator) { + String gop = Gather(pkg[i].option, config.GetKeys()); + String fn = SourcePath(package, pkg[i]); + String ext = ToLower(GetFileExt(fn)); + bool isc = ext == ".c"; + bool isrc = (ext == ".rc" && HasFlag("WIN32")); + bool iscpp = (ext == ".cpp" || ext == ".cc" || ext == ".cxx"); + bool isicpp = (ext == ".icpp"); + if(ext == ".brc") { + isc = true; + fn << "c"; + } + if(isc || isrc || iscpp || isicpp) { + String outfile; + outfile << makefile.outdir << AdjustMakePath(GetFileTitle(fn)) << (isrc ? "_rc" : "") << objext; + String srcfile = GetMakePath(MakeSourcePath(src, fn, false, exporting)); + makefile.rules << outfile << ": " << srcfile; + Vector dep = HdependGetDependencies(fn); + Sort(dep, GetLanguageInfo()); + for(int d = 0; d < dep.GetCount(); d++) { + String dfn = MakeSourcePath(src, dep[d], true, exporting); + if(!IsNull(dfn)) + makefile.rules << " \\\n\t" << GetMakePath(dfn); + } + makefile.rules << "\n" + "\t$(CXX) -c " << (isc ? "-x c $(CFLAGS)" : "-x c++ $(CXXFLAGS)") << " $(CINC) $(" << macros << ") " + << gop << " " << srcfile << " -o " << outfile << "\n\n"; + if(!libout || isicpp) { + makefile.linkdep << " \\\n\t" << outfile; + makefile.linkfiles << " \\\n\t\t" << outfile; + } + else { + libdep << " \\\n\t" << outfile; + libfiles << " \\\n\t\t" << outfile; + } + } + else + if(ext == ".o" || ext == ".obj" || ext == ".a" || ext == ".so" || ext == ".lib" || ext == ".dll") { + makefile.linkdep << " \\\n\t" << fn; + makefile.linkfiles << ' ' << fn; + } + } + + if(libout) { + makefile.rules << libdep << "\n\t" << libfiles << "\n\n"; + makefile.linkdep << " \\\n\t" << makefile.output; + makefile.linkfiles << " \\\n\t\t\t" << makefile.output; + } +/* + if(main) { + if(!HasFlag("SOLARIS")&&!HasFlag("OSX11")) + makefile.linkfiles << " \\\n\t\t-Wl,--start-group "; + DDUMPC(all_libraries); + for(int i = 0; i < all_libraries.GetCount(); i++) { + String ln = all_libraries[i]; + String ext = ToLower(GetFileExt(ln)); + if(ext == ".a" || ext == ".so" || ext == ".dll") + makefile.linkfileend << " \\\n\t\t\t" << GetHostPathQ(FindInDirs(libpath, ln)); + else + makefile.linkfileend << " \\\n\t\t\t-l" << ln; + } + if(!HasFlag("SOLARIS")&&!HasFlag("OSX11")) + makefile.linkfileend << " \\\n\t\t-Wl,--end-group\n\n"; + } +*/ +} + +Point CppBuilder::ExtractVersion() +{ + Point v = Point(Null, Null); + CParser p(version); + while(!p.IsEof()) { + if(p.IsNumber()) { + v.x = p.ReadNumber(); + break; + } + p.GetChar(); + p.Spaces(); + } + while(!p.IsEof()) { + if(p.IsNumber()) { + v.y = p.ReadNumber(); + break; + } + p.GetChar(); + p.Spaces(); + } + return v; +} + +void CppBuilder::ShowTime(int count, int start_time) +{ + if(count) + PutConsole(NFormat("%d file(s) compiled in %s %d msec/file", + count, GetPrintTime(start_time), msecs(start_time) / count)); +} diff --git a/uppsrc/ide/Builders/MscBuilder.icpp b/uppsrc/ide/Builders/MscBuilder.icpp index cc9fef4f2..fd693b5b1 100644 --- a/uppsrc/ide/Builders/MscBuilder.icpp +++ b/uppsrc/ide/Builders/MscBuilder.icpp @@ -1,612 +1,612 @@ -#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(GetHostPath(objfile), parser, GetFileDirectory(fn), package, pkg); - String tmpfile = ForceExt(objfile, ".c"); - SaveFile(tmpfile, fo); - int slot = AllocSlot(); - if(slot < 0 || !Run(cc + " -Tc " + GetHostPathQ(tmpfile) + " -Fo" + GetHostPath(objfile), - 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) { -// ShowTime(ccount, time); - 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(); + if(slot < 0 || !Run(cc + " -Tc " + GetHostPathQ(tmpfile) + " -Fo" + GetHostPath(objfile), + 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) { +// ShowTime(ccount, time); + 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); +} diff --git a/uppsrc/ide/Core/Core.cpp b/uppsrc/ide/Core/Core.cpp index 2207b2cb7..8fe0cbeff 100644 --- a/uppsrc/ide/Core/Core.cpp +++ b/uppsrc/ide/Core/Core.cpp @@ -1,417 +1,535 @@ -#include "Core.h" - -typedef VectorMap BuilderMapType; -GLOBAL_VAR(BuilderMapType, BuilderMap) - -void RegisterBuilder(const char *name, Builder *(*create)()) -{ - ASSERT(BuilderMap().Find(name) < 0); - BuilderMap().Add(name, create); -} - -String FindInDirs(const Vector& dir, const String& file) -{ - if(!IsFullPath(file)) - for(int i = 0; i < dir.GetCount(); i++) { - String ef = CatAnyPath(dir[i], file); - if(FileExists(ef)) - return ef; - } - return file; -} - -String FindCommand(const Vector& exedir, const String& cmdline) -{ - String app; - const char *s = cmdline; - while(*s && (byte)*s <= ' ') - s++; - if(*s == '\"') - { - const char *b = ++s; - while(*s && *s != '\"') - s++; - app = String(b, s); - if(*s) - s++; - } - else - { - const char *b = s; - while(*s && (byte)*s > ' ') - s++; - app = String(b, s); - } - String tail = s; - String fn = FindInDirs(exedir, app); - if(!FileExists(fn)) -#ifdef PLATFORM_WIN32 - fn = FindInDirs(exedir, ForceExt(app, ".exe")); -#endif -#ifdef PLATFORM_POSIX - fn = FindInDirs(exedir, app); -#endif - if(fn.Find(' ') >= 0) - fn = '\"' + fn + '\"'; - return fn + tail; -} - -String GetMakePath(String fn, bool win32) -{ - fn = UnixPath(fn); - if(!win32) - return fn; - String out; - for(const char *p = fn; *p; p++) - if(*p == '/') - out << "\\\\"; - else - out.Cat(*p); - return out; -} - -String AdjustMakePath(const char *fn) -{ - String out; - for(; *fn; fn++) - if(*fn == '$') - out << '$' << '$'; - else - out << *fn; - return out; -} - -static IdeContext *the_ide; - -IdeContext *TheIde() { return the_ide; } -void TheIde(IdeContext *context) { the_ide = context; } - -void PutConsole(const char *s) { if(the_ide) the_ide->PutConsole(s); } -void PutVerbose(const char *s) { if(the_ide) the_ide->PutVerbose(s); } - -const Workspace& GetIdeWorkspace() -{ - if(the_ide) - return the_ide->IdeWorkspace(); - static Workspace x; - return x; -} - -String IdeContext::GetDefaultMethod() -{ - return LoadFile(ConfigFile("default_method")); -} - -VectorMap IdeContext::GetMethodVars(const String& method) -{ - VectorMap map; - LoadVarFile(ConfigFile((String)~method + ".bm"), map); - return map; -} - - -String GetDefaultMethod() -{ - return the_ide ? the_ide->GetDefaultMethod() : String(); -} - -VectorMap GetMethodVars(const String& method) -{ - return the_ide ? the_ide->GetMethodVars(method) : VectorMap(); -} - -bool IdeIsBuilding() -{ - return the_ide && the_ide->IdeIsBuilding(); -} - -void IdeSetBar() -{ - if(the_ide) - the_ide->IdeSetBar(); -} - -String IdeGetOneFile() -{ - return the_ide ? the_ide->IdeGetOneFile() : String(Null); -} - -int IdeConsoleExecute(const char *cmdline, Stream *out, const char *envptr, bool quiet) -{ - return the_ide ? the_ide->IdeConsoleExecute(cmdline, out, envptr, quiet) : -1; -} - -int IdeConsoleExecuteWithInput(const char *cmdline, Stream *out, const char *envptr, bool quiet) -{ - return the_ide ? the_ide->IdeConsoleExecuteWithInput(cmdline, out, envptr, quiet) : -1; -} - -int IdeConsoleExecute(One process, const char *cmdline, Stream *out, bool quiet) -{ - return the_ide ? the_ide->IdeConsoleExecute(process, cmdline, out, quiet) : -1; -} - -int IdeConsoleAllocSlot() -{ - return the_ide ? the_ide->IdeConsoleAllocSlot() : 0; -} - -bool IdeConsoleRun(const char *cmdline, Stream *out, const char *envptr, bool quiet, int slot, String key, int blitz_count) -{ - return the_ide && the_ide->IdeConsoleRun(cmdline, out, envptr, quiet, slot, key, blitz_count); -} - -bool IdeConsoleRun(One process, const char *cmdline, Stream *out, bool quiet, int slot, String key, int blitz_count) -{ - return the_ide && the_ide->IdeConsoleRun(process, cmdline, out, quiet, slot, key, blitz_count); -} - -void IdeConsoleFlush() -{ - if(the_ide) the_ide->IdeConsoleFlush(); -} - -void IdeConsoleBeginGroup(String group) -{ - if(the_ide) the_ide->IdeConsoleBeginGroup(group); -} - -void IdeConsoleEndGroup() -{ - if(the_ide) the_ide->IdeConsoleEndGroup(); -} - -bool IdeConsoleWait() -{ - return the_ide && the_ide->IdeConsoleWait(); -} - -void IdeGotoCodeRef(String s) -{ - if(the_ide) the_ide->IdeGotoCodeRef(s); -} - -void IdeSetBottom(Ctrl& ctrl) -{ - if(the_ide) the_ide->IdeSetBottom(ctrl); -} - -void IdeActivateBottom() { - if(the_ide) the_ide->IdeActivateBottom(); -} - - -void IdeRemoveBottom(Ctrl& ctrl) -{ - if(the_ide) the_ide->IdeRemoveBottom(ctrl); -} - -void IdeSetRight(Ctrl& ctrl) -{ - if(the_ide) the_ide->IdeSetRight(ctrl); -} - -void IdeRemoveRight(Ctrl& ctrl) -{ - if(the_ide) the_ide->IdeRemoveRight(ctrl); -} - -bool IdeIsDebug() -{ - return the_ide && the_ide->IdeIsDebug(); -} - -void IdeEndDebug() -{ - if(the_ide) - the_ide->IdeEndDebug(); -} - -void IdeSetDebugPos(const String& file, int line, const Image& img, int i) -{ - if(the_ide) - the_ide->IdeSetDebugPos(file, line, img, i); -} - -void IdeHidePtr() -{ - if(the_ide) - the_ide->IdeHidePtr(); -} - -bool IdeDebugLock() -{ - return the_ide && the_ide->IdeDebugLock(); -} - -bool IdeDebugUnLock() -{ - return the_ide && the_ide->IdeDebugUnLock(); -} - -bool IdeIsDebugLock() -{ - return the_ide && the_ide->IdeIsDebugLock(); -} - -String IdeGetFileName() -{ - return the_ide ? the_ide->IdeGetFileName() : String(Null); -} - -int IdeGetFileLine() -{ - return the_ide ? the_ide->IdeGetFileLine() : 0; -} - -String IdeGetLine(int i) -{ - return the_ide ? the_ide->IdeGetLine(i) : String(Null); -} - -bool SaveChangedFile(const char *path, String data, bool delete_empty) -{ - if(LoadFile(path) == data) - return true; - if(delete_empty && IsNull(data)) - return FileDelete(path); - else - return SaveFile(path, data); -} - -static int sReadCharc(CParser& p) -{ - p.PassChar('\''); - if(!IsAlpha(p.PeekChar())) - p.ThrowError("language code alphabetic character expected"); - char c = p.GetChar(); - p.PassChar('\''); - return c; -} - -static void sReadLNG(CParser& p, char *c) -{ - p.PassChar('('); - c[0] = sReadCharc(p); - p.PassChar(','); - c[1] = sReadCharc(p); - p.PassChar(','); - c[2] = sReadCharc(p); - p.PassChar(','); - c[3] = sReadCharc(p); -} - -int ReadLNG(CParser& p) { - char c[4]; - if(p.Id("LNG_CZECH")) - return LNG_CZECH; - else - if(p.Id("LNG_ENGLISH")) - return LNG_ENGLISH; - else - if(p.Id("LNG_")) { - sReadLNG(p, c); - p.PassChar(')'); - return LNG_(c[0], c[1], c[2], c[3]); - } - else - if(p.Id("LNGC_")) { - sReadLNG(p, c); - p.PassChar(','); - dword l = LNGC_(c[0], c[1], c[2], c[3], p.ReadInt()); - p.PassChar(')'); - return l; - } - else - p.ThrowError("invalid language code"); - return 0; -} - -String MakeLNG(int lang) -{ - int cs = GetLNGCharset(lang); - String str; - if(cs) - return str << "LNGC_('" - << char(((lang >> 15) & 31) + 'A' - 1) << "', '" - << char(((lang >> 10) & 31) + 'A' - 1) << "', '" - << char(((lang >> 5) & 31) + 'A' - 1) << "', '" - << char((lang & 31) + 'A' - 1) << "', " << cs << ")"; - else - return str << "LNG_('" - << char(((lang >> 15) & 31) + 'A' - 1) << "', '" - << char(((lang >> 10) & 31) + 'A' - 1) << "', '" - << char(((lang >> 5) & 31)+ 'A' - 1) << "', '" - << char((lang & 31) + 'A' - 1) << "')"; -} - -String PrintTime(int time) { - int q = time % 1000 / 10; - time /= 1000; - return Format("(%d:%02d.%02d)", time / 60, time % 60, q); -} - -Point ReadNums(CParser& p) { - Point pt; - pt.x = p.ReadInt(); - p.PassChar(','); - pt.y = p.ReadInt(); - return pt; -} - -Point ReadPoint(CParser& p) -{ - Point pt; - p.PassChar('('); - pt = ReadNums(p); - p.PassChar(')'); - return pt; -} - -bool OldLang() { - static int q = -1; - if(q < 0) - q = FileExists(ConfigFile("oldlang")); - return q; -} - -int CharFilterCid(int c) -{ - return IsAlNum(c) || c == '_' ? c : 0; -} - - -bool IsDoc(String s) -{ - s = ToLower(s); - if(s.Find("svn") >= 0) - return false; - return s.Find("readme") >= 0 || s.Find("copying") >= 0 || s.Find("license") >= 0 || - s.Find("authors") >= 0; -} - -void CopyFolder(const char *_dst, const char *_src, Index& used, bool all) -{ - String dst = NativePath(_dst); - String src = NativePath(_src); - if(dst == src) - return; - FindFile ff(AppendFileName(src, "*")); - bool realize = true; - while(ff) { - String s = AppendFileName(src, ff.GetName()); - String d = AppendFileName(dst, ff.GetName()); - if(ff.IsFolder()) - CopyFolder(d, s, used, all); - else - if(ff.IsFile() && (all || IsDoc(s) || used.Find(s) >= 0)) { - if(realize) { - RealizeDirectory(dst); - realize = false; - } - SaveFile(d, LoadFile(s)); - SetFileTime(d, ff.GetLastWriteTime()); - } - ff.Next(); - } -} +#include "Core.h" + +typedef VectorMap BuilderMapType; +GLOBAL_VAR(BuilderMapType, BuilderMap) + +void RegisterBuilder(const char *name, Builder *(*create)()) +{ + ASSERT(BuilderMap().Find(name) < 0); + BuilderMap().Add(name, create); +} + +String FindInDirs(const Vector& dir, const String& file) +{ + if(!IsFullPath(file)) + for(int i = 0; i < dir.GetCount(); i++) { + String ef = CatAnyPath(dir[i], file); + if(FileExists(ef)) + return ef; + } + return file; +} + +String FindCommand(const Vector& exedir, const String& cmdline) +{ + String app; + const char *s = cmdline; + while(*s && (byte)*s <= ' ') + s++; + if(*s == '\"') + { + const char *b = ++s; + while(*s && *s != '\"') + s++; + app = String(b, s); + if(*s) + s++; + } + else + { + const char *b = s; + while(*s && (byte)*s > ' ') + s++; + app = String(b, s); + } + String tail = s; + String fn = FindInDirs(exedir, app); + if(!FileExists(fn)) +#ifdef PLATFORM_WIN32 + fn = FindInDirs(exedir, ForceExt(app, ".exe")); +#endif +#ifdef PLATFORM_POSIX + fn = FindInDirs(exedir, app); +#endif + if(fn.Find(' ') >= 0) + fn = '\"' + fn + '\"'; + return fn + tail; +} + +String GetMakePath(String fn, bool win32) +{ + fn = UnixPath(fn); + if(!win32) + return fn; + String out; + for(const char *p = fn; *p; p++) + if(*p == '/') + out << "\\\\"; + else + out.Cat(*p); + return out; +} + +String AdjustMakePath(const char *fn) +{ + String out; + for(; *fn; fn++) + if(*fn == '$') + out << '$' << '$'; + else + out << *fn; + return out; +} + +static IdeContext *the_ide; + +IdeContext *TheIde() { return the_ide; } +void TheIde(IdeContext *context) { the_ide = context; } + +void PutConsole(const char *s) { if(the_ide) the_ide->PutConsole(s); } +void PutVerbose(const char *s) { if(the_ide) the_ide->PutVerbose(s); } + +const Workspace& GetIdeWorkspace() +{ + if(the_ide) + return the_ide->IdeWorkspace(); + static Workspace x; + return x; +} + +String IdeContext::GetDefaultMethod() +{ + return LoadFile(ConfigFile("default_method")); +} + +VectorMap IdeContext::GetMethodVars(const String& method) +{ + VectorMap map; + LoadVarFile(ConfigFile((String)~method + ".bm"), map); + return map; +} + + +String GetDefaultMethod() +{ + return the_ide ? the_ide->GetDefaultMethod() : String(); +} + +VectorMap GetMethodVars(const String& method) +{ + return the_ide ? the_ide->GetMethodVars(method) : VectorMap(); +} + +bool IdeIsBuilding() +{ + return the_ide && the_ide->IdeIsBuilding(); +} + +void IdeSetBar() +{ + if(the_ide) + the_ide->IdeSetBar(); +} + +String IdeGetOneFile() +{ + return the_ide ? the_ide->IdeGetOneFile() : String(Null); +} + +int IdeConsoleExecute(const char *cmdline, Stream *out, const char *envptr, bool quiet) +{ + return the_ide ? the_ide->IdeConsoleExecute(cmdline, out, envptr, quiet) : -1; +} + +int IdeConsoleExecuteWithInput(const char *cmdline, Stream *out, const char *envptr, bool quiet) +{ + return the_ide ? the_ide->IdeConsoleExecuteWithInput(cmdline, out, envptr, quiet) : -1; +} + +int IdeConsoleExecute(One process, const char *cmdline, Stream *out, bool quiet) +{ + return the_ide ? the_ide->IdeConsoleExecute(process, cmdline, out, quiet) : -1; +} + +int IdeConsoleAllocSlot() +{ + return the_ide ? the_ide->IdeConsoleAllocSlot() : 0; +} + +bool IdeConsoleRun(const char *cmdline, Stream *out, const char *envptr, bool quiet, int slot, String key, int blitz_count) +{ + return the_ide && the_ide->IdeConsoleRun(cmdline, out, envptr, quiet, slot, key, blitz_count); +} + +bool IdeConsoleRun(One process, const char *cmdline, Stream *out, bool quiet, int slot, String key, int blitz_count) +{ + return the_ide && the_ide->IdeConsoleRun(process, cmdline, out, quiet, slot, key, blitz_count); +} + +void IdeConsoleFlush() +{ + if(the_ide) the_ide->IdeConsoleFlush(); +} + +void IdeConsoleBeginGroup(String group) +{ + if(the_ide) the_ide->IdeConsoleBeginGroup(group); +} + +void IdeConsoleEndGroup() +{ + if(the_ide) the_ide->IdeConsoleEndGroup(); +} + +bool IdeConsoleWait() +{ + return the_ide && the_ide->IdeConsoleWait(); +} + +void IdeGotoCodeRef(String s) +{ + if(the_ide) the_ide->IdeGotoCodeRef(s); +} + +void IdeSetBottom(Ctrl& ctrl) +{ + if(the_ide) the_ide->IdeSetBottom(ctrl); +} + +void IdeActivateBottom() { + if(the_ide) the_ide->IdeActivateBottom(); +} + + +void IdeRemoveBottom(Ctrl& ctrl) +{ + if(the_ide) the_ide->IdeRemoveBottom(ctrl); +} + +void IdeSetRight(Ctrl& ctrl) +{ + if(the_ide) the_ide->IdeSetRight(ctrl); +} + +void IdeRemoveRight(Ctrl& ctrl) +{ + if(the_ide) the_ide->IdeRemoveRight(ctrl); +} + +bool IdeIsDebug() +{ + return the_ide && the_ide->IdeIsDebug(); +} + +void IdeEndDebug() +{ + if(the_ide) + the_ide->IdeEndDebug(); +} + +void IdeSetDebugPos(const String& file, int line, const Image& img, int i) +{ + if(the_ide) + the_ide->IdeSetDebugPos(file, line, img, i); +} + +void IdeHidePtr() +{ + if(the_ide) + the_ide->IdeHidePtr(); +} + +bool IdeDebugLock() +{ + return the_ide && the_ide->IdeDebugLock(); +} + +bool IdeDebugUnLock() +{ + return the_ide && the_ide->IdeDebugUnLock(); +} + +bool IdeIsDebugLock() +{ + return the_ide && the_ide->IdeIsDebugLock(); +} + +String IdeGetFileName() +{ + return the_ide ? the_ide->IdeGetFileName() : String(Null); +} + +int IdeGetFileLine() +{ + return the_ide ? the_ide->IdeGetFileLine() : 0; +} + +String IdeGetLine(int i) +{ + return the_ide ? the_ide->IdeGetLine(i) : String(Null); +} + +bool SaveChangedFile(const char *path, String data, bool delete_empty) +{ + if(LoadFile(path) == data) + return true; + if(delete_empty && IsNull(data)) + return FileDelete(path); + else + return SaveFile(path, data); +} + +static int sReadCharc(CParser& p) +{ + p.PassChar('\''); + if(!IsAlpha(p.PeekChar())) + p.ThrowError("language code alphabetic character expected"); + char c = p.GetChar(); + p.PassChar('\''); + return c; +} + +static void sReadLNG(CParser& p, char *c) +{ + p.PassChar('('); + c[0] = sReadCharc(p); + p.PassChar(','); + c[1] = sReadCharc(p); + p.PassChar(','); + c[2] = sReadCharc(p); + p.PassChar(','); + c[3] = sReadCharc(p); +} + +int ReadLNG(CParser& p) { + char c[4]; + if(p.Id("LNG_CZECH")) + return LNG_CZECH; + else + if(p.Id("LNG_ENGLISH")) + return LNG_ENGLISH; + else + if(p.Id("LNG_")) { + sReadLNG(p, c); + p.PassChar(')'); + return LNG_(c[0], c[1], c[2], c[3]); + } + else + if(p.Id("LNGC_")) { + sReadLNG(p, c); + p.PassChar(','); + dword l = LNGC_(c[0], c[1], c[2], c[3], p.ReadInt()); + p.PassChar(')'); + return l; + } + else + p.ThrowError("invalid language code"); + return 0; +} + +String MakeLNG(int lang) +{ + int cs = GetLNGCharset(lang); + String str; + if(cs) + return str << "LNGC_('" + << char(((lang >> 15) & 31) + 'A' - 1) << "', '" + << char(((lang >> 10) & 31) + 'A' - 1) << "', '" + << char(((lang >> 5) & 31) + 'A' - 1) << "', '" + << char((lang & 31) + 'A' - 1) << "', " << cs << ")"; + else + return str << "LNG_('" + << char(((lang >> 15) & 31) + 'A' - 1) << "', '" + << char(((lang >> 10) & 31) + 'A' - 1) << "', '" + << char(((lang >> 5) & 31)+ 'A' - 1) << "', '" + << char((lang & 31) + 'A' - 1) << "')"; +} + +String PrintTime(int time) { + int q = time % 1000 / 10; + time /= 1000; + return Format("(%d:%02d.%02d)", time / 60, time % 60, q); +} + +Point ReadNums(CParser& p) { + Point pt; + pt.x = p.ReadInt(); + p.PassChar(','); + pt.y = p.ReadInt(); + return pt; +} + +Point ReadPoint(CParser& p) +{ + Point pt; + p.PassChar('('); + pt = ReadNums(p); + p.PassChar(')'); + return pt; +} + +bool OldLang() { + static int q = -1; + if(q < 0) + q = FileExists(ConfigFile("oldlang")); + return q; +} + +int CharFilterCid(int c) +{ + return IsAlNum(c) || c == '_' ? c : 0; +} + + +bool IsDoc(String s) +{ + s = ToLower(s); + if(s.Find("svn") >= 0) + return false; + return s.Find("readme") >= 0 || s.Find("copying") >= 0 || s.Find("license") >= 0 || + s.Find("authors") >= 0; +} + +static void WriteByteArray(StringBuffer& fo, const String& data) +{ + int pos = 0; + for(int p = 0; p < data.GetLength(); p++) { + if(pos >= 70) { + fo << '\n'; + pos = 0; + } + if(pos == 0) + fo << '\t'; + String part = FormatInt((byte)data[p]); + fo << part << ", "; + pos += part.GetLength() + 2; + } +} + +String BrcToC(CParser& binscript, String basedir) +{ + BinObjInfo info; + info.Parse(binscript, basedir); + StringBuffer fo; + for(int i = 0; i < info.blocks.GetCount(); i++) { + String ident = info.blocks.GetKey(i); + ArrayMap& belem = info.blocks[i]; + if(belem[0].flags & (BinObjInfo::Block::FLG_ARRAY | BinObjInfo::Block::FLG_MASK)) { + int count = Max(belem.GetKeys()) + 1; + Vector blockref; + blockref.SetCount(count, 0); + for(int a = 0; a < belem.GetCount(); a++) { + BinObjInfo::Block& b = belem[a]; + blockref[b.index] = &b; + } + for(int i = 0; i < blockref.GetCount(); i++) + if(blockref[i]) { + BinObjInfo::Block& b = *blockref[i]; + fo << "static char " << ident << "_" << i << "[] = {\n"; + String data = ::LoadFile(b.file); + if(data.IsVoid()) + throw Exc(NFormat("Error reading file '%s'", b.file)); + if(data.GetLength() != b.length) + throw Exc(NFormat("length of file '%s' changed (%d -> %d) during object creation", + b.file, b.length, data.GetLength())); + switch(b.encoding) { + case BinObjInfo::Block::ENC_BZ2: data = BZ2Compress(data); break; + case BinObjInfo::Block::ENC_ZIP: data = ZCompress(data); break; + } + b.length = data.GetLength(); + data.Cat('\0'); + WriteByteArray(fo, data); + fo << "\n};\n\n"; +// fo << AsCString(data, 70, "\t", ASCSTRING_OCTALHI | ASCSTRING_SMART) << ";\n\n"; + } + + fo << "int " << ident << "_count = " << blockref.GetCount() << ";\n\n" + "int " << ident << "_length[] = {\n"; + for(int i = 0; i < blockref.GetCount(); i++) + fo << '\t' << (blockref[i] ? blockref[i]->length : -1) << ",\n"; + fo << "};\n\n" + "char *" << ident << "[] = {\n"; + for(int i = 0; i < blockref.GetCount(); i++) + if(blockref[i]) + fo << '\t' << ident << '_' << i << ",\n"; + else + fo << "\t0,\n"; + fo << "};\n\n"; + if(belem[0].flags & BinObjInfo::Block::FLG_MASK) { + fo << "char *" << ident << "_files[] = {\n"; + for(int i = 0; i < blockref.GetCount(); i++) + fo << '\t' << AsCString(blockref[i] ? GetFileName(blockref[i]->file) : String(Null)) << ",\n"; + fo << "\n};\n\n"; + } + } + else { + BinObjInfo::Block& b = belem[0]; + fo << "static char " << ident << "_[] = {\n"; + String data = ::LoadFile(b.file); + if(data.IsVoid()) + throw Exc(NFormat("Error reading file '%s'", b.file)); + if(data.GetLength() != b.length) + throw Exc(NFormat("length of file '%s' changed (%d -> %d) during object creation", + b.file, b.length, data.GetLength())); + switch(b.encoding) { + case BinObjInfo::Block::ENC_BZ2: data = BZ2Compress(data); break; + case BinObjInfo::Block::ENC_ZIP: data = ZCompress(data); break; + } + int b_length = data.GetLength(); + data.Cat('\0'); + WriteByteArray(fo, data); + fo << "\n};\n\n" + "char *" << ident << " = " << ident << "_;\n\n" +// fo << AsCString(data, 70) << ";\n\n" + "int " << ident << "_length = " << b_length << ";\n\n"; + } + } + return fo; +} + +void CopyFile(const String& d, const String& s, bool brc) +{ + FindFile ff(s); + if(ff) { + String ext = ToLower(GetFileExt(s)); + if(brc && ext == ".brc") { + try { + String brcdata = LoadFile(s); + if(brcdata.IsVoid()) + throw Exc(Format("error reading file '%s'", s)); + CParser parser(brcdata, s); + Upp::SaveFile(d + "c", BrcToC(parser, GetFileDirectory(s))); + } + catch(Exc e) { + PutConsole(e); + } + } + SaveFile(d, LoadFile(s)); + SetFileTime(d, ff.GetLastWriteTime()); + } +} + +void CopyFolder(const char *_dst, const char *_src, Index& used, bool all, bool brc) +{ + String dst = NativePath(_dst); + String src = NativePath(_src); + if(dst == src) + return; + FindFile ff(AppendFileName(src, "*")); + bool realize = true; + while(ff) { + String s = AppendFileName(src, ff.GetName()); + String d = AppendFileName(dst, ff.GetName()); + if(ff.IsFolder()) + CopyFolder(d, s, used, all, brc); + else + if(ff.IsFile() && (all || IsDoc(s) || used.Find(s) >= 0)) { + if(realize) { + RealizeDirectory(dst); + realize = false; + } + CopyFile(d, s, brc); + } + ff.Next(); + } +} diff --git a/uppsrc/ide/Core/Core.h b/uppsrc/ide/Core/Core.h index f3912d2a8..10a1d89f4 100644 --- a/uppsrc/ide/Core/Core.h +++ b/uppsrc/ide/Core/Core.h @@ -3,6 +3,8 @@ #include #include +#include +#include using namespace Upp; @@ -19,7 +21,9 @@ inline String GetPrintTime(dword time0) { return PrintTime(msecs(time0)); } bool SaveChangedFile(const char *path, String data, bool delete_empty = false); bool IsDoc(String s); -void CopyFolder(const char *_dst, const char *_src, Index& used, bool all); + +void CopyFile(const String& dst, const String& src, bool brc = false); +void CopyFolder(const char *_dst, const char *_src, Index& used, bool all, bool brc = false); class Workspace; diff --git a/uppsrc/ide/Core/Core.upp b/uppsrc/ide/Core/Core.upp index 4aeddfcf7..7e9a75e01 100644 --- a/uppsrc/ide/Core/Core.upp +++ b/uppsrc/ide/Core/Core.upp @@ -2,7 +2,9 @@ description "TheIDE - common library\377B"; uses Esc, - Web; + Web, + coff/binobj, + plugin/bz2; file Core.h, diff --git a/uppsrc/ide/Core/init b/uppsrc/ide/Core/init index 020bd944b..4866b1550 100644 --- a/uppsrc/ide/Core/init +++ b/uppsrc/ide/Core/init @@ -2,4 +2,6 @@ #define _ide_Core_icpp_init_stub #include "Esc/init" #include "Web/init" +#include "coff/binobj/init" +#include "plugin/bz2/init" #endif diff --git a/uppsrc/ide/Export.cpp b/uppsrc/ide/Export.cpp index dd91daa89..0c1680d5c 100644 --- a/uppsrc/ide/Export.cpp +++ b/uppsrc/ide/Export.cpp @@ -1,68 +1,68 @@ -#include "ide.h" - -void Ide::ExportMakefile(const String& ep) -{ - SaveMakeFile(AppendFileName(ep, "Makefile"), true); -} - -void Ide::ExportProject(const String& ep, bool all, bool gui) -{ - SaveFile(false); - ::Workspace wspc; - wspc.Scan(main); - Index used; - HdependClearDependencies(); - for(int i = 0; i < wspc.GetCount(); i++) { - const Package& p = wspc.GetPackage(i); - String pn = wspc[i]; - for(int j = 0; j < p.GetCount(); j++) { - const Package::File& f = p[j]; - if(!f.separator) { - String p = SourcePath(pn, f); - used.FindAdd(p); - Vector d = HdependGetDependencies(p); - for(int q = 0; q < d.GetCount(); q++) - used.FindAdd(d[q]); - for(int q = 0; q < f.depends.GetCount(); q++) - used.FindAdd(SourcePath(pn, f.depends[q].text)); - } - } - used.FindAdd(SourcePath(pn, "init")); - } - if(FileExists(ep)) { - if(gui && !PromptYesNo(DeQtf(ep) + " is existing file.&" - "Do you want to delete it?")) return; - FileDelete(ep); - } - if(DirectoryExists(ep)) { - if(gui && !PromptYesNo(DeQtf(ep) + " is existing directory.&" - "Do you want to replace it?")) return; - DeleteFolderDeep(ep); - } - - Progress pi("Exporting project"); - pi.SetTotal(wspc.GetCount()); - for(int i = 0; i < wspc.GetCount(); i++) { - if(gui && pi.StepCanceled()) - return; - CopyFolder(AppendFileName(ep, wspc[i]), PackageDirectory(wspc[i]), used, all); - } - Vector upp = GetUppDirs(); - for(int i = 0; i < upp.GetCount(); i++) { - if(gui && pi.StepCanceled()) - return; - String d = upp[i]; - FindFile ff(AppendFileName(d, "*")); - while(ff) { - if(ff.IsFile()) { - String fn = ff.GetName(); - String path = AppendFileName(d, fn); - if(all || used.Find(path) >= 0) - Upp::SaveFile(AppendFileName(ep, fn), LoadFile(path)); - } - ff.Next(); - } - CopyFolder(AppendFileName(ep, wspc[i]), PackageDirectory(wspc[i]), used, all); - } - ExportMakefile(ep); -} +#include "ide.h" + +void Ide::ExportMakefile(const String& ep) +{ + SaveMakeFile(AppendFileName(ep, "Makefile"), true); +} + +void Ide::ExportProject(const String& ep, bool all, bool gui) +{ + SaveFile(false); + ::Workspace wspc; + wspc.Scan(main); + Index used; + HdependClearDependencies(); + for(int i = 0; i < wspc.GetCount(); i++) { + const Package& p = wspc.GetPackage(i); + String pn = wspc[i]; + for(int j = 0; j < p.GetCount(); j++) { + const Package::File& f = p[j]; + if(!f.separator) { + String p = SourcePath(pn, f); + used.FindAdd(p); + Vector d = HdependGetDependencies(p); + for(int q = 0; q < d.GetCount(); q++) + used.FindAdd(d[q]); + for(int q = 0; q < f.depends.GetCount(); q++) + used.FindAdd(SourcePath(pn, f.depends[q].text)); + } + } + used.FindAdd(SourcePath(pn, "init")); + } + if(FileExists(ep)) { + if(gui && !PromptYesNo(DeQtf(ep) + " is existing file.&" + "Do you want to delete it?")) return; + FileDelete(ep); + } + if(DirectoryExists(ep)) { + if(gui && !PromptYesNo(DeQtf(ep) + " is existing directory.&" + "Do you want to replace it?")) return; + DeleteFolderDeep(ep); + } + + Progress pi("Exporting project"); + pi.SetTotal(wspc.GetCount()); + for(int i = 0; i < wspc.GetCount(); i++) { + if(gui && pi.StepCanceled()) + return; + CopyFolder(AppendFileName(ep, wspc[i]), PackageDirectory(wspc[i]), used, all, true); + } + Vector upp = GetUppDirs(); + for(int i = 0; i < upp.GetCount(); i++) { + if(gui && pi.StepCanceled()) + return; + String d = upp[i]; + FindFile ff(AppendFileName(d, "*")); + while(ff) { + if(ff.IsFile()) { + String fn = ff.GetName(); + String path = AppendFileName(d, fn); + if(all || used.Find(path) >= 0) + CopyFile(AppendFileName(ep, fn), path, true); + } + ff.Next(); + } + CopyFolder(AppendFileName(ep, wspc[i]), PackageDirectory(wspc[i]), used, all, true); + } + ExportMakefile(ep); +}