void Ide::CleanUppOut() { String out = GetVar("OUTPUT"); if(!PromptYesNo(NFormat("Erase the whole output directory [* \1%s\1]?", out))) return; console.Clear(); PutConsole("UPPOUT cleanup..."); DeleteFolderDeep(out); PutConsole("(done)"); HideBottom(); }
void ESC_cout(EscEscape& e) { if(e[0].IsArray()) PutConsole((String) e[0]); else if(e[0].IsNumber()) { String str; str << e[0].GetNumber(); PutConsole(str); } else if(!e[0].IsVoid()) e.ThrowError("invalid argument to 'cout'" + e.DumpType(0)); }
void Ide::Preprocess(bool asmout) { if(editfile.IsEmpty()) return; int pi = GetPackageIndex(); if(pi < 0) return; SwitchHeader(); String pfn = ConfigFile(GetFileTitle(editfile) + ".i.tmp"); DeleteFile(pfn); const Workspace& wspc = IdeWorkspace(); if(pi >= wspc.GetCount()) return; One<Host> host = CreateHost(true); One<Builder> b = CreateBuilder(~host); Vector<String> linkfile; String linkopt; b->config = PackageConfig(wspc, pi, GetMethodVars(method), mainconfigparam, *host, *b); console.Clear(); PutConsole((asmout ? "Compiling " : "Preprocessing ") + editfile); b->Preprocess(wspc[pi], editfile, pfn, asmout); HideBottom(); if(FileExists(pfn)) { EditFile(pfn); if(!editor.IsReadOnly()) ToggleReadOnly(); } }
One<Builder> MakeBuild::CreateBuilder(Host *host) { SetupDefaultMethod(); VectorMap<String, String> bm = GetMethodVars(method); String builder = bm.Get("BUILDER", "GCC"); int q = BuilderMap().Find(builder); if(q < 0) { PutConsole("Invalid builder " + builder); ConsoleShow(); return NULL; } One<Builder> b = (*BuilderMap().Get(builder))(); b->host = host; b->compiler = bm.Get("COMPILER", ""); b->include = SplitDirs(GetVar("UPP") + ';' + bm.Get("INCLUDE", "") + ';' + add_includes); const Workspace& wspc = GetIdeWorkspace(); for(int i = 0; i < wspc.GetCount(); i++) { const Package& pkg = wspc.GetPackage(i); for(int j = 0; j < pkg.include.GetCount(); j++) b->include.Add(SourcePath(wspc[i], pkg.include[j].text)); } b->libpath = SplitDirs(bm.Get("LIB", "")); b->debug_options = bm.Get("DEBUG_OPTIONS", ""); b->release_options = bm.Get("RELEASE_OPTIONS", ""); b->release_size_options = bm.Get("RELEASE_SIZE_OPTIONS", ""); b->debug_link = bm.Get("DEBUG_LINK", ""); b->release_link = bm.Get("RELEASE_LINK", ""); b->script = bm.Get("SCRIPT", ""); b->main_conf = !!main_conf.GetCount(); return b; }
void Ide::StopBuild() { if(idestate == BUILDING) { console.Kill(); PutConsole("User break."); SetIdeState(EDITING); } }
void MakeBuild::Clean() { ConsoleClear(); const Workspace& wspc = GetIdeWorkspace(); for(int i = 0; i < wspc.GetCount(); i++) CleanPackage(wspc, i); PutConsole("...done"); }
void Ide::BuildAndExecute() { if(Build()) { int time = msecs(); One<Host> h = CreateHostRunDir(); h->ChDir(Nvl(rundir, GetFileFolder(target))); String cmdline; if(!runexternal) cmdline << '\"' << h->GetHostPath(target) << "\" "; cmdline << ToSystemCharset(runarg); int exitcode; switch(runmode) { case RUN_WINDOW: HideBottom(); h->Launch(cmdline, FindIndex(SplitFlags(mainconfigparam, true), "GUI") < 0); break; case RUN_CONSOLE: ShowConsole(); PutConsole(String().Cat() << "Executing: " << cmdline); console.Sync(); exitcode = h->ExecuteWithInput(cmdline); PutConsole("Finished in " + GetPrintTime(time) + ", exit code: " + AsString(exitcode)); break; case RUN_FILE: { HideBottom(); String fn; if(IsNull(stdout_file)) fn = ForceExt(target, ".ol"); else fn = stdout_file; FileOut out(fn); if(!out) { PromptOK("Unable to open output file [* " + DeQtf(stdout_file) + "] !"); return; } if(h->Execute(cmdline, out) >= 0) { out.Close(); EditFile(fn); } } } } }
void Ide::EndBuilding(bool ok) { console.EndGroup(); console.Wait(); Vector<String> errors = console.PickErrors(); CreateHost(false)->DeleteFile(errors); if(!errors.IsEmpty()) ok = false; PutConsole(""); PutConsole((ok ? "OK. " : "There were errors. ") + GetPrintTime(build_time)); SetIdeState(EDITING); if(GetTopWindow()->IsOpen()) { if(ok) BeepMuteInformation(); else BeepMuteExclamation(); } ShowConsole(); }
void MakeBuild::CleanPackage(const Workspace& wspc, int package) { PutConsole(NFormat("Cleaning %s", wspc[package])); One<Host> host = CreateHost(false); One<Builder> builder = CreateBuilder(~host); if(!builder) return; host->DeleteFolderDeep(OutDir(PackageConfig(wspc, package, GetMethodVars(method), mainconfigparam, *host, *builder), wspc[package], GetMethodVars(method))); }
static void ReadMacro(CParser& p) { IdeMacro macro; if(p.IsString()) { macro.menu = p.ReadString(); if(p.Char(':')) macro.submenu = p.ReadString(); } if(!p.IsChar('{')) macro.hotkey = ParseKeyDesc(p); EscLambda& l = macro.code.CreateLambda(); const char *t = p.GetPtr(); l.filename = p.GetFileName(); l.line = p.GetLine(); if(!p.Char('{')) p.ThrowError("missing '{'"); SkipBlock(p); l.code = String(t, p.GetPtr()); Array<IdeMacro>& mlist = UscMacros(); if(macro.hotkey) { int f = FindFieldIndex(mlist, &IdeMacro::hotkey, macro.hotkey); if(f >= 0) { PutConsole(NFormat("%s(%d): duplicate macro hotkey %s\n", l.filename, l.line, GetKeyDesc(macro.hotkey))); const EscLambda& lambda = UscMacros()[f].code.GetLambda(); PutConsole(NFormat("%s(%d): previously defined here\n", lambda.filename, lambda.line)); } } if(!IsNull(macro.menu)) { for(int i = 0; i < mlist.GetCount(); i++) if(mlist[i].menu == macro.menu && mlist[i].submenu == macro.submenu) { PutConsole(NFormat("%s(%d): duplicate macro menu item (%s:%s)\n", l.filename, l.line, macro.menu, macro.submenu)); const EscLambda& lambda = UscMacros()[i].code.GetLambda(); PutConsole(NFormat("%s(%d): previously defined here\n", lambda.filename, lambda.line)); break; } } mlist.Add(macro); }
void Ide::CreateMakefile() { const Workspace& wspc = IdeWorkspace(); if(wspc.GetCount() == 0) { PutConsole("Project is empty!"); return; } FileSel mfout; mfout.AllFilesType(); mfout <<= AppendFileName(GetFileDirectory(PackagePath(wspc[0])), "Makefile"); if(!mfout.ExecuteSaveAs("Save makefile as")) return; SaveMakeFile(~mfout, true); }
bool CppBuilder::Cp(const String& cmd, const String& package, bool& error) { if(cmd.GetLength() > 2 && ToLower(cmd.Mid(0, 3)) == "cp ") { Vector<String> path = Split(cmd.Mid(3), ' '); if(path.GetCount() == 2) { String p = GetFileFolder(PackagePath(package)); String p1 = NormalizePath(path[0], p); String p2 = NormalizePath(path[1], p); RealizePath(p2); if(!FileExists(p1)) { PutConsole("FAILED: " + cmd); error = true; } SaveFile(p2, LoadFile(p1)); } return true; } return false; }
bool MakeBuild::Build() { VectorMap<String, String> bm = GetMethodVars(method); if(bm.GetCount() == 0) { PutConsole("Invalid build method"); ConsoleShow(); return false; } One<Host> host = CreateHost(false); One<Builder> builder = CreateBuilder(~host); if(!builder) return false; Index<String> p = PackageConfig(GetIdeWorkspace(), 0, bm, mainconfigparam, *host, *builder); Workspace wspc; wspc.Scan(GetMain(), p.GetKeys()); return Build(wspc, mainconfigparam, Null); }
Vector<String> MakeBuild::GetAllUses(const Workspace& wspc, int f) { // Warning: This does not seem to do what it is supposed to do... String package = wspc[f]; Index<String> all_uses; bool warn = true; int n = 0; while(f >= 0) { const Package& p = wspc.package[f]; for(int fu = 0; fu < p.uses.GetCount(); fu++) if(p.uses[fu].text != package) all_uses.FindAdd(p.uses[fu].text); else if(warn) { PutConsole(NFormat("%s: circular 'uses' chain", package)); warn = false; } f = -1; while(n < all_uses.GetCount() && (f = wspc.package.Find(all_uses[n++])) < 0) ; } return all_uses.PickKeys(); }
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)); }
void PutCompileTime(int time, int count) { PutConsole(String().Cat() << count << " file(s) compiled in " << GetPrintTime(time) << " " << int(GetTickCount() - time) / count << " msec/file"); }
void MakeBuild::SaveMakeFile(const String& fn, bool exporting) { BeginBuilding(false, true); VectorMap<String, String> bm = GetMethodVars(method); One<Host> host = CreateHost(false); One<Builder> b = CreateBuilder(~host); if(!b) return; const TargetMode& tm = GetTargetMode(); String makefile; Vector<String> uppdirs = GetUppDirs(); String uppout = exporting ? host->GetHostPath(GetVar("OUTPUT")) : "_out/"; String inclist; Index<String> allconfig = PackageConfig(GetIdeWorkspace(), 0, bm, mainconfigparam, *host, *b); bool win32 = allconfig.Find("WIN32") >= 0; Workspace wspc; wspc.Scan(GetMain(), allconfig.GetKeys()); for(int i = 1; i < wspc.GetCount(); i++) { Index<String> modconfig = PackageConfig(wspc, i, bm, mainconfigparam, *host, *b); for(int a = allconfig.GetCount(); --a >= 0;) if(modconfig.Find(allconfig[a]) < 0) allconfig.Remove(a); } if(!exporting) for(int i = 0; i < uppdirs.GetCount(); i++) { String srcdir = GetMakePath(AdjustMakePath(host->GetHostPath(AppendFileName(uppdirs[i], ""))), win32); makefile << "UPPDIR" << (i + 1) << " = " << srcdir << "\n"; inclist << " -I$(UPPDIR" << (i + 1) << ")"; } else inclist << "-I./"; Vector<String> includes = SplitDirs(bm.Get("INCLUDE","")); for(int i = 0; i < includes.GetCount(); i++) inclist << " -I" << includes[i]; makefile << "\n" "UPPOUT = " << (exporting ? "_out/" : GetMakePath(AdjustMakePath(host->GetHostPath(AppendFileName(uppout, ""))), win32)) << "\n" "CINC = " << inclist << "\n" "Macro = "; for(int i = 0; i < allconfig.GetCount(); i++) makefile << " -Dflag" << allconfig[i]; makefile << "\n"; String output, config, install, rules, linkdep, linkfiles, linkfileend; for(int i = 0; i < wspc.GetCount(); i++) { b->config = PackageConfig(wspc, i, bm, mainconfigparam, *host, *b); b->version = tm.version; b->method = method; MakeFile mf; b->AddMakeFile(mf, wspc[i], GetAllUses(wspc, i), GetAllLibraries(wspc, i, bm, mainconfigparam, *host, *b), allconfig, exporting); if(!i) { String tdir = mf.outdir; String trg; if(tm.target_override) { trg = GetMakePath(AdjustMakePath(tm.target), win32); if(!trg.IsEmpty() && *trg.Last() == (win32 ? '\\' : '/')) trg << mf.outfile; else if(trg.Find(win32 ? '\\' : '/') < 0) trg.Insert(0, "$(OutDir)"); } output = Nvl(trg, mf.output); if(exporting) output = wspc[i] + ".out"; install << "\n" "OutDir = " << tdir << "\n" "OutFile = " << output << "\n" "\n" ".PHONY: all\n" "all: prepare $(OutFile)\n" "\n" ".PHONY: prepare\n" "prepare:\n"; } config << mf.config; install << mf.install; rules << mf.rules; linkdep << mf.linkdep; linkfiles << mf.linkfiles; linkfileend << mf.linkfileend; } makefile << config << install << "\n" "$(OutFile): " << linkdep << "\n\t" << linkfiles << linkfileend << " -Wl,--end-group\n\n" << rules << ".PHONY: clean\n" << "clean:\n" << "\tif [ -d $(UPPOUT) ]; then rm -rf $(UPPOUT); fi;\n"; bool sv = ::SaveFile(fn, makefile); if(!exporting) if(sv) PutConsole(NFormat("%s(1): makefile generation complete", fn)); else PutConsole(NFormat("%s: error writing makefile", fn)); EndBuilding(true); }
void ESC_dump(EscEscape& e) { PutConsole(e[0].ToString()); }
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; }
bool MakeBuild::BuildPackage(const Workspace& wspc, int pkindex, int pknumber, int pkcount, String mainparam, String outfile, Vector<String>& linkfile, String& linkopt, bool link) { String package = wspc[pkindex]; String mainpackage = wspc[0]; const Package& pkg = wspc.package[pkindex]; VectorMap<String, String> bm = GetMethodVars(method); if(bm.GetCount() == 0) { PutConsole("Invalid build method"); ConsoleShow(); return false; } One<Host> host = CreateHost(false); if(!IsNull(onefile)) { OneFileHost *h = new OneFileHost; h->host = host; h->onefile = onefile; host = h; } One<Builder> b = CreateBuilder(~host); if(!b) return false; b->config = PackageConfig(wspc, pkindex, bm, mainparam, *host, *b); const TargetMode& m = targetmode == 0 ? debug : release; b->version = m.version; b->method = method; b->outdir = OutDir(b->config, package, bm); host->RealizeDir(b->outdir); String mainfn = Null; Index<String> mcfg = PackageConfig(wspc, 0, bm, mainparam, *host, *b, &mainfn); HdependClearDependencies(); for(int i = 0; i < pkg.GetCount(); i++) { const Array<OptItem>& f = pkg[i].depends; for(int j = 0; j < f.GetCount(); j++) if(MatchWhen(f[j].when, mcfg.GetKeys())) HdependAddDependency(SourcePath(package, pkg[i]), SourcePath(package, f[j].text)); } String tout = OutDir(mcfg, mainpackage, bm, use_target); host->RealizeDir(tout); if(IsNull(mainfn)) mainfn = GetFileTitle(mainpackage) + b->GetTargetExt(); if(!IsNull(outfile)) target = NormalizePath(outfile, tout); else { if(m.target_override && !IsNull(m.target) && IsFolder(m.target)) target = host->NormalizePath(AppendFileName(m.target, mainfn)); else if(m.target_override && (IsFullPath(m.target) || *m.target == '/' || *m.target == '\\')) target = m.target; else if(m.target_override && !IsNull(m.target)) target = host->NormalizePath(AppendFileName(tout, m.target)); else if(IsFullPath(mainfn)) target = mainfn; else target = host->NormalizePath(AppendFileName(tout, mainfn)); } b->target = target; b->mainpackage = mainpackage; if(IsNull(onefile)) { String out; out << "----- " << package << " ( " << Join(b->config.GetKeys(), " ") << " )"; if(pkcount > 1) out << " (" << (pknumber + 1) << " / " << pkcount << ')'; PutConsole(out); } else b->config.FindAdd("NOLIB"); bool ok = b->BuildPackage(package, linkfile, linkopt, GetAllUses(wspc, pkindex), GetAllLibraries(wspc, pkindex, bm, mainparam, *host, *b), targetmode - 1); Vector<String> errors = PickErrors(); host->DeleteFile(errors); if(!ok || !errors.IsEmpty()) return false; if(link) { ok = b->Link(linkfile, linkopt, GetTargetMode().createmap); errors = PickErrors(); host->DeleteFile(errors); if(!ok || !errors.IsEmpty()) return false; } return true; }
void Ide::Valgrind() { if(!IsValgrind()) return; static String ValgrindLogFile; if(IsNull(ValgrindLogFile)) { StringStream ss; CreateHostRunDir()->Execute("valgrind --help", ss); String txt = ss; if(txt.Find("--log-file-exactly") > 0) ValgrindLogFile = "--log-file-exactly="; else ValgrindLogFile = "--log-file="; if(txt.Find("--xml-file") > 0) ValgrindLogFile = "--xml-file="; } if(!Build()) return; One<Host> h = CreateHostRunDir(); h->ChDir(Nvl(rundir, GetFileFolder(target))); String cmdline; String fn = GetTempFileName(); cmdline << "valgrind --xml=yes --num-callers=40 " << ValgrindLogFile << fn << ' '; String ValgSupp = ConfigFile("valgrind.supp"); if(!IsNull(LoadFile(ValgSupp))) cmdline << "--suppressions=" << ValgSupp << ' '; cmdline << '\"' << h->GetHostPath(target) << "\" "; cmdline << runarg; ConsoleClear(); PutConsole("Valgrind.."); if(IsNull(h->Execute(cmdline))) { PutConsole("Error executing valgrind"); return; } PutConsole("Parsing valgrind output.."); Sync(); String txt = LoadFile(fn); DeleteFile(fn); try { XmlParser p(txt); while(!p.IsTag()) p.Skip(); p.PassTag("valgrindoutput"); while(!p.End()) { if(p.Tag("error")) { String hdr = "Error (missing description)"; String pos; Vector<String> ln; bool src = false; while(!p.End()) { if(p.Tag("what")) { hdr = p.ReadText(); p.SkipEnd(); } else if(p.Tag("stack")) { while(!p.End()) { String ip = "?"; String obj; String fn; String dir; String file; String line; if(p.Tag("frame")) { bool hasdir = false; bool hasfile = false; bool hasline = false; bool haspos = false; while(!p.End()) { if(p.Tag("ip")) { ip = p.ReadText(); p.SkipEnd(); } else if(p.Tag("obj")) { obj = p.ReadText(); p.SkipEnd(); haspos = true; } else if(p.Tag("fn")) { fn = p.ReadText(); p.SkipEnd(); } else if(p.Tag("dir")) { dir = p.ReadText(); p.SkipEnd(); hasdir = true; } else if(p.Tag("file")) { file = p.ReadText(); p.SkipEnd(); hasfile = true; } else if(p.Tag("line")) { line = p.ReadText(); p.SkipEnd(); hasline = true; } else p.Skip(); } src = src || hasline && hasdir && hasfile; if(pos.IsEmpty() && haspos) pos << fn << ' ' << ip << ' '<< obj; if(hasline && hasdir && hasfile) ln.Add(AppendFileName(dir, file) + ':' + line); else { String h; h << fn << ' ' << ip << ' ' << obj; if(hasdir && hasfile) h << AppendFileName(dir, file); else h << file << ' '; h << line; ln.Add(h); } } else p.Skip(); } } else p.Skip(); } PutConsole(hdr); PutConsole(" " + pos); if(src) for(int i = 0; i < ln.GetCount(); i++) PutConsole(" " + ln[i]); } else p.Skip(); } } catch(XmlError) { PutConsole("Error parsing valgrind output"); } }
bool MakeBuild::Build(const Workspace& wspc, String mainparam, String outfile, bool clear_console) { String hfile = outfile + ".xxx"; SaveFile(hfile, ""); FileTime start_time = GetFileTime(hfile); // Defensive way to get correct filetime of start DeleteFile(hfile); ClearErrorEditor(); BeginBuilding(true, clear_console); bool ok = true; if(wspc.GetCount()) { for(int i = 0; i < wspc.GetCount(); i++) { const Package& pk = wspc.package[i]; for(int j = 0; j < pk.GetCount(); j++) if(pk[j] == "main.conf") { String pn = wspc[i]; String p = SourcePath(pn, "main.conf"); main_conf << "// " << pn << "\r\n" << LoadFile(p) << "\r\n"; PutConsole("Found " + p); } } if(main_conf.GetCount()) { VectorMap<String, String> bm = GetMethodVars(method); One<Host> host = CreateHost(false); One<Builder> b = CreateBuilder(~host); if(b) { Index<String> mcfg = PackageConfig(wspc, 0, bm, mainparam, *host, *b, NULL); String outdir = OutDir(mcfg, wspc[0], bm, false); String path = AppendFileName(outdir, "main.conf.h"); RealizePath(path); SaveChangedFile(path, main_conf); PutConsole("Saving " + path); add_includes << outdir << ';'; } } Vector<int> build_order; if(GetTargetMode().linkmode != 2) { for(int i = 1; i < wspc.GetCount(); i++) build_order.Add(i); } else { Index<int> remaining; for(int i = 1; i < wspc.GetCount(); i++) remaining.Add(i); while(!remaining.IsEmpty()) { int t; for(t = 0; t < remaining.GetCount(); t++) { const Package& pk = wspc.package[remaining[t]]; bool delay = false; for(int u = 0; u < pk.uses.GetCount(); u++) if(remaining.Find(wspc.package.Find(pk.uses[u].text)) >= 0) { delay = true; break; } if(!delay) break; } if(t >= remaining.GetCount()) t = 0; build_order.Add(remaining[t]); remaining.Remove(t); } } String mainpackage = wspc[0]; Vector<String> linkfile; String linkopt = GetMethodVars(method).Get(targetmode ? "RELEASE_LINK" : "DEBUG_LINK", Null); if(linkopt.GetCount()) linkopt << ' '; ok = true; int ms = msecs(); for(int i = 0; i < build_order.GetCount() && (ok || !stoponerrors); i++) { int px = build_order[i]; ok = BuildPackage(wspc, px, i, build_order.GetCount() + 1, mainparam, Null, linkfile, linkopt) && ok; if(msecs() - ms >= 200) { DoProcessEvents(); ms = msecs(); } } if(ok || !stoponerrors) { ok = BuildPackage(wspc, 0, build_order.GetCount(), build_order.GetCount() + 1, mainparam, outfile, linkfile, linkopt, ok) && ok; // Set the time of target to start-time, so that if any file changes during // compilation, it is recompiled during next build SetFileTime(target, start_time); } } EndBuilding(ok); ReQualifyCodeBase(); SetErrorEditor(); return ok; }