Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development
Optimizing Makefilegenerator
Ceniza:
--- Quote from: Urxae ---But you can still have it be called asynchronously, right? So maybe you could use some mechanism (events?) to tell the main thread to call wxExecute, which can then be activated from other threads?
--- End quote ---
That'd be the hacky idea: You! Yes, you! The one able to call wxExecute! Call it with these parameters for me! Now!
The function could also try to handle it all avoiding the use of threads.
thomas:
It is actually pretty easy to call several compiler instances asynchronously. But it is an awful mess to sort out the compiler's output from several running processes.
mandrav:
I never said it isn't possible ;)
It's just that the last time this subject was brought up, the usage of the thread pool was discussed.
Anyway, this is deliberately not being currently worked on because the compiler will be redesigned so...
rickg22:
I added 15 timers using wxStopwatch (they're static variables, they're reset to 0 when compilation starts). Here are the results:
--- Code: ---SDK Only
----------
Timer 1: 0 ms
Timer 2: 5046 ms
Timer 3: 1312 ms
Timer 4: 0 ms
Timer 5: 1189 ms
Timer 6: 0 ms
Timer 7: 3142 ms
Timer 8: 15 ms
Timer 9: 0 ms
Timer 10: 1577 ms
Timer 11: 16 ms
Timer 12: 0 ms
Timer 13: 218 ms
Timer 14: 48 ms
Timer 15: 0 ms
All Targets
---------------
Timer 1: 0 ms
Timer 2: 17007 ms
Timer 3: 3243 ms
Timer 4: 0 ms
Timer 5: 3733 ms
Timer 6: 16 ms
Timer 7: 10747 ms
Timer 8: 78 ms
Timer 9: 0 ms
Timer 10: 5030 ms
Timer 11: 32 ms
Timer 12: 0 ms
Timer 13: 894 ms
Timer 14: 110 ms
Timer 15: 0 ms
--- End code ---
These times reflect the calculation of the compiling commands ONLY. The actual compilation times are not taken into account. The compilation method was a full rebuild.
And now, the (shameful? :lol: ) modified source code of the routine in question:
--- Code: ---wxString MakefileGenerator::CreateSingleFileCompileCmd(const wxString& command,
ProjectBuildTarget* target,
ProjectFile* pf,
const wxString& file,
const wxString& object,
const wxString& deps)
{
// in case of linking command, deps has resource objects
UpdateCompiler(target);
wxStopWatch sw;
wxString compilerStr;
if (pf)
{
if (pf->compilerVar.Matches(_T("CPP")))
compilerStr = m_CompilerSet->GetPrograms().CPP;
else if (pf->compilerVar.Matches(_T("CC")))
compilerStr = m_CompilerSet->GetPrograms().C;
else if (pf->compilerVar.Matches(_T("WINDRES")))
compilerStr = m_CompilerSet->GetPrograms().WINDRES;
else
return wxEmptyString; // unknown compiler var
}
else
{
wxFileName fname(file);
if (fname.GetExt().Lower().Matches(_T("c")))
compilerStr = m_CompilerSet->GetPrograms().C;
else
compilerStr = m_CompilerSet->GetPrograms().CPP;
}
time1 += sw.Time();
sw.Start();
wxString cflags;
wxString global_cflags;
wxString prj_cflags;
DoAppendCompilerOptions(global_cflags, 0L, true);
DoAppendCompilerOptions(prj_cflags, 0L);
DoGetMakefileCFlags(cflags, target);
time2 += sw.Time();
sw.Start();
if (target)
{
cflags.Replace(_T("$(") + target->GetTitle() + _T("_GLOBAL_CFLAGS)"), global_cflags);
cflags.Replace(_T("$(") + target->GetTitle() + _T("_PROJECT_CFLAGS)"), prj_cflags);
}
else if (!target && !pf) // probably single file compilation
cflags = global_cflags;
wxString ldflags;
wxString global_ldflags;
wxString prj_ldflags;
DoAppendLinkerOptions(global_ldflags, 0L, true);
DoAppendLinkerOptions(prj_ldflags, 0L);
DoGetMakefileLDFlags(ldflags, target);
time3 += sw.Time();
sw.Start();
if (target)
{
ldflags.Replace(_T("$(") + target->GetTitle() + _T("_GLOBAL_LDFLAGS)"), global_ldflags);
ldflags.Replace(_T("$(") + target->GetTitle() + _T("_PROJECT_LDFLAGS)"), prj_ldflags);
}
else if (!target && !pf) // probably single file compilation
ldflags = global_ldflags;
time4 += sw.Time();
sw.Start();
wxString ldadd;
wxString global_ldadd;
wxString prj_ldadd;
DoAppendLinkerLibs(global_ldadd, 0L, true);
DoAppendLinkerLibs(prj_ldadd, 0L);
DoGetMakefileLibs(ldadd, target);
time5 += sw.Time();
sw.Start();
if (target)
{
ldadd.Replace(_T("$(") + target->GetTitle() + _T("_GLOBAL_LIBS)"), global_ldadd);
ldadd.Replace(_T("$(") + target->GetTitle() + _T("_PROJECT_LIBS)"), prj_ldadd);
}
else if (!target && !pf) // probably single file compilation
ldadd = global_ldadd;
time6 += sw.Time();
sw.Start();
wxString global_res_incs;
wxString prj_res_incs;
wxString res_incs;
DoAppendResourceIncludeDirs(global_res_incs, 0L, m_CompilerSet->GetSwitches().includeDirs, true);
DoAppendResourceIncludeDirs(prj_res_incs, 0L, m_CompilerSet->GetSwitches().includeDirs);
res_incs << global_res_incs << _T(" ") << prj_res_incs << _T(" ");
DoAppendResourceIncludeDirs(res_incs, target, m_CompilerSet->GetSwitches().includeDirs);
wxString incs;
wxString global_incs;
wxString prj_incs;
DoAppendIncludeDirs(global_incs, 0L, m_CompilerSet->GetSwitches().includeDirs, true);
DoAppendIncludeDirs(prj_incs, 0L, m_CompilerSet->GetSwitches().includeDirs);
DoGetMakefileIncludes(incs, target);
time7 += sw.Time();
sw.Start();
if (target)
{
incs.Replace(_T("$(") + target->GetTitle() + _T("_GLOBAL_INCS)"), global_incs);
incs.Replace(_T("$(") + target->GetTitle() + _T("_PROJECT_INCS)"), prj_incs);
}
else if (!target && !pf) // probably single file compilation
incs = global_incs;
// for PCH to work, the very first include dir *must* be the object output dir
// *only* if PCH is generated in the object output dir
time8 += sw.Time();
sw.Start();
if (target &&
target->GetParentProject()->GetModeForPCH() == pchObjectDir)
{
wxArrayString includedDirs; // avoid adding duplicate dirs...
wxString sep = wxFILE_SEP_PATH;
// find all PCH in project
int count = target->GetParentProject()->GetFilesCount();
for (int i = 0; i < count; ++i)
{
ProjectFile* f = target->GetParentProject()->GetFile(i);
if (FileTypeOf(f->relativeFilename) == ftHeader &&
f->compile)
{
// it is a PCH; add it's object dir to includes
wxString dir = wxFileName(target->GetObjectOutput() + sep + f->GetObjName()).GetPath();
if (includedDirs.Index(dir) == wxNOT_FOUND)
{
includedDirs.Add(dir);
incs = m_CompilerSet->GetSwitches().includeDirs +
dir +
_T(" ") +
incs;
}
}
}
}
time9 += sw.Time();
sw.Start();
wxString libs;
wxString global_libs;
wxString prj_libs;
DoAppendLibDirs(global_libs, 0L, m_CompilerSet->GetSwitches().libDirs, true);
DoAppendLibDirs(prj_libs, 0L, m_CompilerSet->GetSwitches().libDirs);
DoGetMakefileLibDirs(libs, target);
time10 += sw.Time();
sw.Start();
if (target)
{
libs.Replace(_T("$(") + target->GetTitle() + _T("_GLOBAL_LIBDIRS)"), global_libs);
libs.Replace(_T("$(") + target->GetTitle() + _T("_PROJECT_LIBDIRS)"), prj_libs);
}
else if (!target && !pf) // probably single file compilation
libs = global_libs;
time11 += sw.Time();
sw.Start();
wxString output;
if (target)
output = UnixFilename(target->GetOutputFilename());
else
{
wxString object_unquoted(object);
if (!object_unquoted.IsEmpty() && object_unquoted.GetChar(0) == '"')
object_unquoted.Replace(_T("\""), _T(""));
wxFileName fname(object_unquoted);
fname.SetExt(EXECUTABLE_EXT);
output = fname.GetFullPath();
}
time12 += sw.Time();
sw.Start();
Manager::Get()->GetMacrosManager()->ReplaceEnvVars(output);
ConvertToMakefileFriendly(output);
QuoteStringIfNeeded(output);
wxString linkobjs;
time13 += sw.Time();
sw.Start();
wxString compilerCmd = command;
compilerCmd.Replace(_T("$compiler"), compilerStr);
compilerCmd.Replace(_T("$linker"), m_CompilerSet->GetPrograms().LD);
compilerCmd.Replace(_T("$lib_linker"), m_CompilerSet->GetPrograms().LIB);
compilerCmd.Replace(_T("$rescomp"), m_CompilerSet->GetPrograms().WINDRES);
compilerCmd.Replace(_T("$options"), cflags);
compilerCmd.Replace(_T("$link_options"), ldflags);
compilerCmd.Replace(_T("$includes"), incs);
compilerCmd.Replace(_T("$res_includes"), res_incs);
compilerCmd.Replace(_T("$libdirs"), libs);
compilerCmd.Replace(_T("$libs"), ldadd);
compilerCmd.Replace(_T("$file"), file);
compilerCmd.Replace(_T("$dep_object"), deps);
compilerCmd.Replace(_T("$object"), object);
compilerCmd.Replace(_T("$exe_output"), output);
compilerCmd.Replace(_T("$resource_output"), object);
compilerCmd.Replace(_T("$link_resobjects"), deps);
compilerCmd.Replace(_T("$link_objects"), object);
// the following were added to support the QUICK HACK
// at directcommands.cpp:576
compilerCmd.Replace(_T("$+link_objects"), object);
compilerCmd.Replace(_T("$-link_objects"), object);
compilerCmd.Replace(_T("$-+link_objects"), object);
compilerCmd.Replace(_T("$+-link_objects"), object);
time14 += sw.Time();
sw.Start();
if (target && (target->GetTargetType() == ttStaticLib || target->GetTargetType() == ttDynamicLib))
{
wxFileName fname(target->GetOutputFilename());
if (!fname.GetName().StartsWith(m_CompilerSet->GetSwitches().libPrefix))
fname.SetName(m_CompilerSet->GetSwitches().libPrefix + fname.GetName());
fname.SetExt(m_CompilerSet->GetSwitches().libExtension);
wxString out = UnixFilename(fname.GetFullPath());
ConvertToMakefileFriendly(out);
QuoteStringIfNeeded(out);
if (target->GetTargetType() == ttStaticLib || target->GetCreateStaticLib())
compilerCmd.Replace(_T("$static_output"), out);
else
{
compilerCmd.Replace(_T("-Wl,--out-implib=$static_output"), _T("")); // special gcc case
compilerCmd.Replace(_T("$static_output"), _T(""));
}
if (target->GetCreateDefFile())
{
fname.SetExt(_T("def"));
out = UnixFilename(fname.GetFullPath());
ConvertToMakefileFriendly(out);
QuoteStringIfNeeded(out);
compilerCmd.Replace(_T("$def_output"), out);
}
else
{
compilerCmd.Replace(_T("-Wl,--output-def=$def_output"), _T("")); // special gcc case
compilerCmd.Replace(_T("$def_output"), _T(""));
}
}
time15 += sw.Time();
#ifndef __WXMSW__
// run the command in a shell, so backtick'd expressions can be evaluated
compilerCmd = m_Compiler->GetConsoleShell() + _T(" '") + compilerCmd + _T("'");
#endif
return compilerCmd;
}
--- End code ---
I hope these timings help us determine which takes longer and why.
mandrav:
I 'm sure there is something wrong with the numbers you posted:
--- Quote ---Timer 2: 5046 ms
--- End quote ---
5 seconds for this?
--- Quote ---
--- Code: --- sw.Start();
wxString cflags;
wxString global_cflags;
wxString prj_cflags;
DoAppendCompilerOptions(global_cflags, 0L, true);
DoAppendCompilerOptions(prj_cflags, 0L);
DoGetMakefileCFlags(cflags, target);
time2 += sw.Time();
--- End code ---
--- End quote ---
And you mean to tell me that you 're waiting 40+ seconds only for commands generation when building the project?
What is your PC's specs?
Have you disabled this safe_but_slow tweak of yours?
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version