From 2e0a930119c618268887a687f705b291970d89a4 Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 8 Jun 2021 21:58:26 +0000 Subject: [PATCH] umk: CCJ support git-svn-id: svn://ultimatepp.org/upp/trunk@15987 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/ide/Builders/Build.h | 9 +- uppsrc/ide/Builders/Builders.h | 15 +- uppsrc/ide/Builders/Builders.upp | 1 + uppsrc/ide/Builders/CCJ.cpp | 272 +++++++++++++++++++++++++++++++ uppsrc/ide/Builders/MakeFile.cpp | 23 ++- uppsrc/ide/Core/Core.h | 24 ++- uppsrc/ide/Core/Workspace.cpp | 10 +- uppsrc/umk/umake.cpp | 14 +- 8 files changed, 341 insertions(+), 27 deletions(-) create mode 100644 uppsrc/ide/Builders/CCJ.cpp diff --git a/uppsrc/ide/Builders/Build.h b/uppsrc/ide/Builders/Build.h index 3fdacdd1f..8b5be2663 100644 --- a/uppsrc/ide/Builders/Build.h +++ b/uppsrc/ide/Builders/Build.h @@ -64,7 +64,7 @@ public: String main_conf; Index cfg; FileTime start_time; - + bool makefile_svn_revision = true; void CreateHost(Host& host, bool darkmode = false, bool disable_uhd = false); @@ -91,11 +91,12 @@ public: void Clean(); void RebuildAll(); void SaveMakeFile(const String& fn, bool exporting); - + void SaveCCJ(const String& fn, bool exporting); + MakeBuild(); - + private: static String GetInvalidBuildMethodError(const String& method); }; -extern bool output_per_assembly; +extern bool output_per_assembly; \ No newline at end of file diff --git a/uppsrc/ide/Builders/Builders.h b/uppsrc/ide/Builders/Builders.h index af3f08ca8..dfbe23876 100644 --- a/uppsrc/ide/Builders/Builders.h +++ b/uppsrc/ide/Builders/Builders.h @@ -14,12 +14,16 @@ String BrcToC(CParser& binscript, String basedir); Vector SvnInfo(const String& package); +String MakeIdent(const char *name); + struct CppBuilder : Builder { virtual String GetTargetExt() const; virtual void CleanPackage(const String& package, const String& outdir); - + const Workspace& wspc; Time targettime; + Vector CFLAGS; + Vector CXXFLAGS; String GetSharedLibPath(const String& package) const; int AllocSlot(); @@ -40,7 +44,7 @@ struct CppBuilder : Builder { String GetMakePath(String fn) const; Point ExtractVersion() const; - + // POSIX lib files has names in form of libXXXXXX.so.ver.minver(.rel) // so we can't simply get file extension String GetSrcType(String fn) const; @@ -57,6 +61,9 @@ struct CppBuilder : Builder { const Vector& all_uses, const Vector& all_libraries, const Index& common_config, bool exporting); + virtual void AddCCJ(MakeFile& mfinfo, String package, + const Index& common_config, bool exporting, bool last_ws); + CppBuilder() : wspc(GetIdeWorkspace()) {} }; @@ -88,7 +95,7 @@ struct OwcBuilder : CppBuilder { String& linkoptions, const Vector& all_uses, const Vector& all_libraries, int optimize); virtual bool Link(const Vector& linkfile, const String& linkoptions, bool createmap); virtual bool Preprocess(const String& package, const String& file, const String& target, bool asmout); - + String IncludesDefinesTargetTime(const String& package, const Package& pkg); String CompilerName(bool isCpp = true) const; @@ -180,4 +187,4 @@ INITIALIZE(JavaBuilder) INITIALIZE(AndroidBuilder) INITIALIZE(ScriptBuilder) -#endif +#endif \ No newline at end of file diff --git a/uppsrc/ide/Builders/Builders.upp b/uppsrc/ide/Builders/Builders.upp index 3ed9f3650..aa51fd879 100644 --- a/uppsrc/ide/Builders/Builders.upp +++ b/uppsrc/ide/Builders/Builders.upp @@ -16,6 +16,7 @@ file Builders.h options(BUILDER_OPTION) PCH, CppBuilder.cpp, MakeFile.cpp, + CCJ.cpp, coff.h, Builders readonly separator, GccBuilder.cpp, diff --git a/uppsrc/ide/Builders/CCJ.cpp b/uppsrc/ide/Builders/CCJ.cpp new file mode 100644 index 000000000..8dcff7070 --- /dev/null +++ b/uppsrc/ide/Builders/CCJ.cpp @@ -0,0 +1,272 @@ +#include "Builders.h" + +inline +String SString(const String& s) { + if (s.Find(' ') >= 0) + return "\"" << s << "\""; + return s; +} + +inline +String SAppend(String l, const String& r) { + return l << SString(r); +} + +void CppBuilder::AddCCJ( + MakeFile& makefile, + String package, + const Index& common_config, + bool exporting, + bool last_ws) +{ + const char* eol = "\n"; + const char* tab = "\t"; + + 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); + Vector macdef; + String objext = (HasFlag("MSC") || HasFlag("EVC") ? ".obj" : ".o"); + + macdef.Append(Macro); + + Vector x(config.GetKeys(), 1); + Sort(x); + for(int i = 0; i < x.GetCount(); i++) { + if(common_config.Find(x[i]) < 0) { + String str; + str << "-Dflag" << x[i]; + macdef << str; + } + x[i] = InitCaps(x[i]); + } + + makefile.outdir << outdir << "/"; + + if(main) { + Vector 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.Append(GatherV(pkg.option, config.GetKeys())); + + CFLAGS = clone(flags); + CXXFLAGS = pick(flags); + + CFLAGS << c_options; + CXXFLAGS << cpp_options; + } + +// String cmplr = Sys("which " + compiler); +// cmplr.TrimEnd("\n"); + String cmplr = compiler; + + const String inc_outdir = SAppend("-I", makefile.outdir); + for(int count = pkg.GetCount(), last = count - 1, i = 0; i < count; 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"; + const bool ish = ext == ".h"; + const bool isrc = (ext == ".rc" && HasFlag("WIN32")); + const bool iscpp = (ext == ".cpp" || ext == ".cc" || ext == ".cxx"); + const bool ishpp = (ext == ".hpp" || ext == ".hh" || ext == ".hxx"); + const bool isicpp = (ext == ".icpp"); + if(ext == ".brc") { + isc = true; + fn << "c"; + } + if(isc || ish || isrc || iscpp || ishpp || isicpp) { + String outfile; + const String srcfile = SString(fn); + outfile << makefile.outdir << AdjustMakePath(GetFileTitle(fn)); + if (isrc) + outfile << "_rc"; + else if (ish || ishpp) + outfile << "_hpp"; + else + outfile << "_cpp"; + outfile << objext; + outfile = SString(outfile); + +#if 0 + Json j; + JsonArray ja; + ja << cmplr; + ja << "-c"; + ja << "-x"; + if (isc) + ja << "c" << CFLAGS; + else + ja << "c++" << CXXFLAGS; + ja << CINC ; + ja << inc_outdir; + ja << macdef; + // ja << gop; // ??? + ja << srcfile << "-o" << outfile; + // j("arguments", ja)("directory", GetFileFolder(fn))("file", GetFileName(fn)); + // j("arguments", ja)("directory", GetFileFolder(fn))("file", fn); + j("arguments", ja)("directory", SString(GetFileFolder(fn)))("file", srcfile); + makefile.rules << tab << j; + if (i == last && last_ws) + makefile.rules << eol; + else + makefile.rules << "," << eol; +#else + Json j; + String ja; + ja << cmplr; + ja << " -c"; + ja << " -x"; + if (isc) + ja << " c " << Join(CFLAGS, " "); + else + ja << " c++ " << Join(CXXFLAGS, " "); + MergeWith(ja, " ", Join(CINC, " ")); + MergeWith(ja, " ", inc_outdir); + MergeWith(ja, " ", Join(macdef, " ")); + ja << ' ' << srcfile << " -o" << outfile; + j("command", ja)("directory", SString(GetFileFolder(fn)))("file", srcfile); + makefile.rules << tab << j; + if (i == last && last_ws) + makefile.rules << eol; + else + makefile.rules << "," << eol; +#endif + } + } +} + +void MakeBuild::SaveCCJ(const String& fn, bool exporting) +{ + const char* eol = "\n"; + const char* tab = "\t"; + + BeginBuilding(true); + + VectorMap bm = GetMethodVars(method); + Host host; + CreateHost(host, false, false); + One b = CreateBuilder(&host); + + if(!b) + return; + + const TargetMode& tm = GetTargetMode(); + + String makefile; + + Vector uppdirs = GetUppDirs(); + String uppout = exporting ? GetVar("OUTPUT") : ".cache/upp.out"; + + Index allconfig = PackageConfig(GetIdeWorkspace(), 0, bm, mainconfigparam, host, *b); + bool win32 = allconfig.Find("WIN32") >= 0; + + Workspace wspc; + wspc.Scan(GetMain(), allconfig.GetKeys()); + + Index pkg_config; + for(int i = 0; i < wspc.GetCount(); i++) { + Index modconfig = PackageConfig(wspc, i, bm, mainconfigparam, host, *b); + PkgConfig(wspc, modconfig, pkg_config); + if(i) + for(int a = allconfig.GetCount(); --a >= 0;) + if(modconfig.Find(allconfig[a]) < 0) + allconfig.Remove(a); + } + + makefile << "[" << eol; + + Index oi; + if(!exporting) + for(int i = 0; i < uppdirs.GetCount(); i++) { + String s; + s << "-I" << uppdirs[i]; + oi.FindAdd(s); + } + + for(const String& s: pkg_config) { + String str; + String out; + str << "pkg-config --cflags " << s; + if (Sys(str, out) < 0) + continue; + out.TrimEnd("\n"); + if (out.IsEmpty()) + continue; + Vector l = Split(out, ' '); + for(const String& s1: l) + oi.FindAdd(s1); + } + + Vector includes = SplitDirs(bm.Get("INCLUDE","")); + for(int i = 0; i < includes.GetCount(); i++) { + String str; + str << SAppend("-I", includes[i]); + oi.FindAdd(str); + } + + for (const String& s: allconfig) { + String str; + str << "-Dflag" << s; + b->Macro << str; + } + + String UPPOUT("-I"); + if (exporting) + UPPOUT << "_out/"; + else + UPPOUT << GetMakePath(AdjustMakePath(AppendFileName(uppout, "")), win32); + oi.FindAdd(pick(UPPOUT)); + + b->CINC.Append(oi.PickKeys()); + + String config, rules; + + for(int count = wspc.GetCount(), last = count - 1, i = 0; i < count; i++) { + const String package = wspc[i]; + b->config = PackageConfig(wspc, i, bm, mainconfigparam, host, *b); + b->version = tm.version; + b->method = method; + b->outdir = OutDir(b->config, package, bm); + MakeFile mf; + b->AddCCJ(mf, package, allconfig, exporting, i == last); + config << mf.config; + rules << mf.rules; + if(i == 0) // main package + b->SaveBuildInfo(package); + } + + makefile + << config + << rules + << "]" + ; + + bool sv = ::SaveFile(fn, makefile); + if(!exporting) { + if(sv) + PutConsole(NFormat("%s(1): compile_commands.json generation complete", fn)); + else + PutConsole(NFormat("%s: error writing compile_commands.json", fn)); + } +} diff --git a/uppsrc/ide/Builders/MakeFile.cpp b/uppsrc/ide/Builders/MakeFile.cpp index c39959e10..00020b102 100644 --- a/uppsrc/ide/Builders/MakeFile.cpp +++ b/uppsrc/ide/Builders/MakeFile.cpp @@ -1,6 +1,6 @@ #include "Builders.h" -static String MakeIdent(const char *name) +String MakeIdent(const char *name) { String out; for(; *name; name++) @@ -153,7 +153,7 @@ void CppBuilder::AddMakeFile(MakeFile& makefile, String package, 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()); @@ -222,6 +222,17 @@ void CppBuilder::AddMakeFile(MakeFile& makefile, String package, */ } +JsonArray& operator<<(JsonArray& array, const Vector& v) { + for (const String& s: v) + array << s; + return array; +} + +Vector& operator<<(Vector& array, const Vector& v) { + array.Append(v); + return array; +} + Point CppBuilder::ExtractVersion() const { Point v = Point(Null, Null); @@ -263,10 +274,10 @@ void MakeBuild::SaveMakeFile(const String& fn, bool exporting) Host host; CreateHost(host, false, false); One b = CreateBuilder(&host); - + if(!b) return; - + const TargetMode& tm = GetTargetMode(); String makefile; @@ -307,7 +318,7 @@ void MakeBuild::SaveMakeFile(const String& fn, bool exporting) inclist << " -I./"; inclist << " -I$(UPPOUT)"; // build_info.h is created there - + makefile << "\n" "UPPOUT = " << (exporting ? "_out/" : GetMakePath(AdjustMakePath(AppendFileName(uppout, "")), win32)) << "\n" "CINC = " << inclist << "\n" @@ -386,7 +397,7 @@ void MakeBuild::SaveMakeFile(const String& fn, bool exporting) linkfiles << mf.linkfiles; linkfileend << mf.linkfileend; } - + makefile << config << install diff --git a/uppsrc/ide/Core/Core.h b/uppsrc/ide/Core/Core.h index 160be4603..0c4977330 100644 --- a/uppsrc/ide/Core/Core.h +++ b/uppsrc/ide/Core/Core.h @@ -90,7 +90,7 @@ public: virtual String GetDefaultMethod(); virtual VectorMap GetMethodVars(const String& method); virtual String GetMethodName(const String& method); - + virtual bool IsPersistentFindReplace() = 0; virtual int IdeGetHydraThreads() = 0; @@ -272,7 +272,7 @@ String AsStringWhen(const String& when); struct OptItem { String when; String text; - + String ToString() const { return when + ": " + text ; } }; @@ -291,6 +291,7 @@ struct CustomStep { Vector Combine(const Vector& conf, const char *flags); String Gather(const Array& set, const Vector& conf, bool nospace = false); +Vector GatherV(const Array& set, const Vector& conf); bool HasFlag(const Vector& conf, const char *flag); @@ -432,7 +433,7 @@ struct Builder { Host *host; Index config; String method; - + String compiler; String outdir; Vector include; @@ -446,16 +447,18 @@ struct Builder { String debug_link; String release_link; String version; - + String script; String mainpackage; - + bool doall; bool main_conf; bool allow_pch; FileTime start_time; - + Index pkg_config; // names of packages for pkg-config + Vector CINC; + Vector Macro; VectorMap tmpfilei; // for naming automatic response files @@ -474,11 +477,14 @@ struct Builder { virtual void AddMakeFile(MakeFile& mfinfo, String package, const Vector& all_uses, const Vector& all_libraries, const Index& common_config, bool exporting) {} + virtual void AddCCJ(MakeFile& mfinfo, String package, + const Index& common_config, bool exporting, bool last_ws) {} virtual String GetTargetExt() const = 0; + virtual void SaveBuildInfo(const String& package) {} Builder() { doall = false; main_conf = false; } virtual ~Builder() {} - + // TODO: move other methods if needed void ChDir(const String& path); String GetPathQ(const String& path) const; @@ -540,7 +546,7 @@ public: int offset; int off_meta_offset; int len_meta_offset; - + void Compress(String& data); }; @@ -552,4 +558,4 @@ void DeletePCHFiles(); String GetLineEndings(const String& data, const String& default_eol = "\r\n"); -#endif +#endif \ No newline at end of file diff --git a/uppsrc/ide/Core/Workspace.cpp b/uppsrc/ide/Core/Workspace.cpp index 7e76aa8e7..4de53cc74 100644 --- a/uppsrc/ide/Core/Workspace.cpp +++ b/uppsrc/ide/Core/Workspace.cpp @@ -172,6 +172,14 @@ String Gather(const Array& set, const Vector& conf, bool nospac return s; } +Vector GatherV(const Array& set, const Vector& conf) { + Vector s; + for(int i = 0; i < set.GetCount(); i++) + if(MatchWhen(set[i].when, conf)) + s << set[i].text; + return s; +} + int GetType(const Vector& conf, const char *flags) { Vector f = SplitFlags(flags); int q = FLAG_UNDEFINED; @@ -261,4 +269,4 @@ Vector Workspace::GetAllAccepts(int pk) const } } return accepts.PickKeys(); -} +} \ No newline at end of file diff --git a/uppsrc/umk/umake.cpp b/uppsrc/umk/umake.cpp index 3ee93e72d..cdfeb8fec 100644 --- a/uppsrc/umk/umake.cpp +++ b/uppsrc/umk/umake.cpp @@ -81,13 +81,14 @@ CONSOLE_APP_MAIN ide.makefile_svn_revision = false; bool clean = false; bool makefile = false; + bool ccfile = false; bool deletedir = true; int exporting = 0; bool run = false; String mkf; Vector param, runargs; - + const Vector& args = CommandLine(); for(int i = 0; i < args.GetCount(); i++) { String a = args[i]; @@ -107,6 +108,7 @@ CONSOLE_APP_MAIN case 'X': exporting = 2; break; case 'k': deletedir = false; break; case 'u': ide.use_target = true; break; + case 'j': ccfile = true; break; case 'M': { makefile = true; if(s[1] == '=') { @@ -154,7 +156,7 @@ CONSOLE_APP_MAIN else param.Add(a); } - + if(param.GetCount() >= 2) { String v = GetUmkFile(param[0] + ".var"); if(IsNull(v)) { @@ -232,6 +234,12 @@ CONSOLE_APP_MAIN ide.method = m; + if(ccfile) { + ide.SaveCCJ(GetFileDirectory(PackagePath(ide.main)) + "compile_commands.json", false); + SetExitCode(0); + return; + } + if(clean) ide.Clean(); if(exporting) { @@ -277,4 +285,4 @@ CONSOLE_APP_MAIN "See https://www.ultimatepp.org/app$ide$umk$en-us.html for details\n"); } -#endif +#endif \ No newline at end of file