I added 15 timers using wxStopwatch (they're static variables, they're reset to 0 when compilation starts). Here are the results:
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.
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;
}
I hope these timings help us determine which takes longer and why.