Vector<String> CppBuilder::CustomStep(const String& pf, const String& package_, bool& error) { String package = Nvl(package_, mainpackage); String path = (*pf == '.' && pf[1] != '.') ? target : SourcePath(package, pf); String file = GetHostPath(path); String ext = ToLower(GetFileExt(pf)); if(ext == ".ext") { Vector<String> files; Vector<String> dirs; sGatherAllExt(files, dirs, GetFileFolder(path), ""); Index<String> pkg_files; Package pkg; pkg.Load(PackagePath(package)); for(int i = 0; i < pkg.GetCount(); i++) pkg_files.Add(pkg[i]); Index<String> out; Index<String> include_path; String f = LoadFile(path); try { CParser p(f); while(!p.IsEof()) { if(p.Id("files")) { Vector<String> e = ReadPatterns(p); for(int i = 0; i < files.GetCount(); i++) for(int j = 0; j < e.GetCount(); j++) { String f = files[i]; if(PatternMatch(e[j], f) && pkg_files.Find(f) < 0) out.FindAdd(f); } } if(p.Id("exclude")) { ExtExclude(p, out); } if(p.Id("include_path")) { Vector<String> e = ReadPatterns(p); for(int j = 0; j < e.GetCount(); j++) { String ee = e[j]; if(ee.Find('*') >= 0) for(int i = 0; i < dirs.GetCount(); i++) { String d = dirs[i]; if(PatternMatch(e[j], d)) { include_path.FindAdd(d); } } else include_path.Add(ee); } } if(p.Id("exclude_path")) { ExtExclude(p, include_path); } if(p.Id("includes")) { Vector<String> e = ReadPatterns(p); for(int i = 0; i < files.GetCount(); i++) for(int j = 0; j < e.GetCount(); j++) { String f = files[i]; if(PatternMatch(e[j], f) && pkg_files.Find(f) < 0) include_path.FindAdd(GetFileFolder(f)); } } } } catch(CParser::Error) { PutConsole("Invalid .ext file"); error = true; return Vector<String>(); } for(int i = 0; i < include_path.GetCount(); i++) include.Add(NormalizePath(include_path[i], GetFileFolder(path))); Vector<String> o; for(int i = 0; i < out.GetCount(); i++) o.Add(SourcePath(package, out[i])); return o; } for(int i = 0; i < wspc.GetCount(); i++) { const Array< ::CustomStep >& mv = wspc.GetPackage(i).custom; for(int j = 0; j < mv.GetCount(); j++) { const ::CustomStep& m = mv[j]; if(MatchWhen(m.when, config.GetKeys()) && m.MatchExt(ext)) { VectorMap<String, String> mac; AddPath(mac, "PATH", file); AddPath(mac, "RELPATH", pf); AddPath(mac, "DIR", GetFileFolder(PackagePath(package))); AddPath(mac, "FILEDIR", GetFileFolder(file)); AddPath(mac, "PACKAGE", package); mac.Add("FILE", GetFileName(file)); mac.Add("TITLE", GetFileTitle(file)); AddPath(mac, "EXEPATH", GetHostPath(target)); AddPath(mac, "EXEDIR", GetHostPath(GetFileFolder(target))); mac.Add("EXEFILE", GetFileName(target)); mac.Add("EXETITLE", GetFileTitle(target)); AddPath(mac, "OUTDIR", GetHostPath(outdir)); //BW AddPath(mac, "OUTDIR", GetHostPath(GetFileFolder(target))); AddPath(mac, "OUTFILE", GetHostPath(GetFileName(target))); AddPath(mac, "OUTTITLE", GetHostPath(GetFileTitle(target))); mac.Add("INCLUDE", Join(include, ";")); Vector<String> out = Cuprep(m.output, mac, include); bool dirty = out.IsEmpty(); for(int i = 0; !dirty && i < out.GetCount(); i++) dirty = (GetFileTime(file) > GetFileTime(out[i])); if(dirty) { HdependTimeDirty(); PutConsole(GetFileName(file)); Vector<String> cmd = Cuprep(m.command, mac, include); String cmdtext; for(int c = 0; c < cmd.GetCount(); c++) { PutVerbose(cmd[c]); if(!Cd(cmd[c]) && !Cp(cmd[c], package, error)) { String ctext = cmd[c]; const char *cm = ctext; if(*cm == '?') cm++; if(*ctext != '?' && Execute(cm)) { for(int t = 0; t < out.GetCount(); t++) DeleteFile(out[t]); PutConsole("FAILED: " + ctext); error = true; return Vector<String>(); } } } } return out; } } } Vector<String> out; out.Add(path); return out; }
void CppBuilder::AddMakeFile(MakeFile& makefile, String package, const Vector<String>& all_uses, const Vector<String>& all_libraries, const Index<String>& common_config, bool exporting) { String packagepath = PackagePath(package); Package pkg; pkg.Load(packagepath); String packagedir = GetFileFolder(packagepath); Vector<String> 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<String> 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<String> 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<String> 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<String> 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"; } */ }