summaryrefslogtreecommitdiffstats
path: root/Source/cmNinjaTargetGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmNinjaTargetGenerator.cxx')
-rw-r--r--Source/cmNinjaTargetGenerator.cxx191
1 files changed, 118 insertions, 73 deletions
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 3220fba..816e6d8 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -91,26 +91,26 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
return this->LocalGenerator->GetGlobalNinjaGenerator();
}
-const char* cmNinjaTargetGenerator::GetConfigName() const
+std::string const& cmNinjaTargetGenerator::GetConfigName() const
{
return this->LocalGenerator->GetConfigName();
}
// TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
-const char* cmNinjaTargetGenerator::GetFeature(const char* feature)
+const char* cmNinjaTargetGenerator::GetFeature(const std::string& feature)
{
return this->Target->GetFeature(feature, this->GetConfigName());
}
// TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
-bool cmNinjaTargetGenerator::GetFeatureAsBool(const char* feature)
+bool cmNinjaTargetGenerator::GetFeatureAsBool(const std::string& feature)
{
- return cmSystemTools::IsOn(this->GetFeature(feature));
+ return this->Target->GetFeatureAsBool(feature, this->GetConfigName());
}
// TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
void cmNinjaTargetGenerator::AddFeatureFlags(std::string& flags,
- const char* lang)
+ const std::string& lang)
{
// Add language-specific flags.
this->LocalGenerator->AddLanguageFlags(flags, lang, this->GetConfigName());
@@ -121,12 +121,18 @@ void cmNinjaTargetGenerator::AddFeatureFlags(std::string& flags,
}
}
+std::string
+cmNinjaTargetGenerator::OrderDependsTargetForTarget()
+{
+ return "cmake_order_depends_target_" + this->GetTargetName();
+}
+
// TODO: Most of the code is picked up from
// void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink),
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
// Refactor it.
std::string
-cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
+cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile const* source,
const std::string& language)
{
// TODO: Fortran support.
@@ -140,11 +146,11 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
std::string& languageFlags = this->LanguageFlags[language];
if(!hasLangCached)
{
- this->AddFeatureFlags(languageFlags, language.c_str());
+ this->AddFeatureFlags(languageFlags, language);
this->GetLocalGenerator()->AddArchitectureFlags(languageFlags,
this->GeneratorTarget,
- language.c_str(),
+ language,
this->GetConfigName());
// Add shared-library flags if needed.
@@ -153,23 +159,23 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
this->GetConfigName());
this->LocalGenerator->AddVisibilityPresetFlags(languageFlags, this->Target,
- language.c_str());
+ language);
std::vector<std::string> includes;
this->LocalGenerator->GetIncludeDirectories(includes,
this->GeneratorTarget,
- language.c_str(),
+ language,
this->GetConfigName());
// Add include directory flags.
std::string includeFlags =
this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget,
- language.c_str(),
+ language,
language == "RC" ? true : false); // full include paths for RC
// needed by cmcldeps
if(cmGlobalNinjaGenerator::IsMinGW())
cmSystemTools::ReplaceString(includeFlags, "\\", "/");
- this->LocalGenerator->AppendFlags(languageFlags, includeFlags.c_str());
+ this->LocalGenerator->AppendFlags(languageFlags, includeFlags);
// Append old-style preprocessor definition flags.
this->LocalGenerator->AppendFlags(languageFlags,
@@ -177,7 +183,7 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
// Add target-specific flags.
this->LocalGenerator->AddCompileOptions(languageFlags, this->Target,
- language.c_str(),
+ language,
this->GetConfigName());
}
@@ -211,7 +217,7 @@ bool cmNinjaTargetGenerator::needsDepFile(const std::string& lang)
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
std::string
cmNinjaTargetGenerator::
-ComputeDefines(cmSourceFile *source, const std::string& language)
+ComputeDefines(cmSourceFile const* source, const std::string& language)
{
std::set<std::string> defines;
@@ -232,12 +238,12 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
defPropName += cmSystemTools::UpperCase(this->GetConfigName());
this->LocalGenerator->AppendDefines
(defines,
- source->GetProperty(defPropName.c_str()));
+ source->GetProperty(defPropName));
}
std::string definesString;
this->LocalGenerator->JoinDefines(defines, definesString,
- language.c_str());
+ language);
return definesString;
}
@@ -269,14 +275,14 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
std::string
cmNinjaTargetGenerator
-::GetSourceFilePath(cmSourceFile* source) const
+::GetSourceFilePath(cmSourceFile const* source) const
{
return ConvertToNinjaPath(source->GetFullPath().c_str());
}
std::string
cmNinjaTargetGenerator
-::GetObjectFilePath(cmSourceFile* source) const
+::GetObjectFilePath(cmSourceFile const* source) const
{
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if(!path.empty())
@@ -320,6 +326,7 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID"))
{
std::string pdbPath;
+ std::string compilePdbPath;
if(this->Target->GetType() == cmTarget::EXECUTABLE ||
this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
@@ -329,11 +336,25 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
pdbPath += "/";
pdbPath += this->Target->GetPDBName(this->GetConfigName());
}
+ if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
+ {
+ compilePdbPath = this->Target->GetCompilePDBPath(this->GetConfigName());
+ if(compilePdbPath.empty())
+ {
+ compilePdbPath = this->Target->GetSupportDirectory() + "/";
+ }
+ }
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- ConvertToNinjaPath(pdbPath.c_str()).c_str(),
+ ConvertToNinjaPath(pdbPath.c_str()),
cmLocalGenerator::SHELL);
+ vars["TARGET_COMPILE_PDB"] =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ ConvertToNinjaPath(compilePdbPath.c_str()),
+ cmLocalGenerator::SHELL);
+
EnsureParentDirectoryExists(pdbPath);
+ EnsureParentDirectoryExists(compilePdbPath);
return true;
}
return false;
@@ -362,7 +383,9 @@ cmNinjaTargetGenerator
vars.Object = "$out";
vars.Defines = "$DEFINES";
vars.TargetPDB = "$TARGET_PDB";
+ vars.TargetCompilePDB = "$TARGET_COMPILE_PDB";
vars.ObjectDir = "$OBJECT_DIR";
+ vars.ObjectFileDir = "$OBJECT_FILE_DIR";
cmMakefile* mf = this->GetMakefile();
@@ -404,9 +427,14 @@ cmNinjaTargetGenerator
else
{
deptype = "gcc";
+ const char* langdeptype = mf->GetDefinition("CMAKE_NINJA_DEPTYPE_" + lang);
+ if (langdeptype)
+ {
+ deptype = langdeptype;
+ }
depfile = "$DEP_FILE";
const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang;
- std::string depfileFlags = mf->GetSafeDefinition(flagsName.c_str());
+ std::string depfileFlags = mf->GetSafeDefinition(flagsName);
if (!depfileFlags.empty())
{
cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE");
@@ -422,7 +450,7 @@ cmNinjaTargetGenerator
// Rule for compiling object file.
const std::string cmdVar = std::string("CMAKE_") + lang + "_COMPILE_OBJECT";
- std::string compileCmd = mf->GetRequiredDefinition(cmdVar.c_str());
+ std::string compileCmd = mf->GetRequiredDefinition(cmdVar);
std::vector<std::string> compileCmds;
cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
@@ -466,63 +494,86 @@ cmNinjaTargetGenerator
<< this->GetTargetName()
<< "\n\n";
- std::vector<cmSourceFile*> customCommands;
- this->GeneratorTarget->GetCustomCommands(customCommands);
- for(std::vector<cmSourceFile*>::const_iterator
+ std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ std::vector<cmSourceFile const*> customCommands;
+ this->GeneratorTarget->GetCustomCommands(customCommands, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
si = customCommands.begin();
si != customCommands.end(); ++si)
{
cmCustomCommand const* cc = (*si)->GetCustomCommand();
this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
+ // Record the custom commands for this target. The container is used
+ // in WriteObjectBuildStatement when called in a loop below.
+ this->CustomCommands.push_back(cc);
}
- std::vector<cmSourceFile*> headerSources;
- this->GeneratorTarget->GetHeaderSources(headerSources);
+ std::vector<cmSourceFile const*> headerSources;
+ this->GeneratorTarget->GetHeaderSources(headerSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
headerSources,
this->MacOSXContentGenerator);
- std::vector<cmSourceFile*> extraSources;
- this->GeneratorTarget->GetExtraSources(extraSources);
+ std::vector<cmSourceFile const*> extraSources;
+ this->GeneratorTarget->GetExtraSources(extraSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
extraSources,
this->MacOSXContentGenerator);
- std::vector<cmSourceFile*> externalObjects;
- this->GeneratorTarget->GetExternalObjects(externalObjects);
- for(std::vector<cmSourceFile*>::const_iterator
+ std::vector<cmSourceFile const*> externalObjects;
+ this->GeneratorTarget->GetExternalObjects(externalObjects, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
si = externalObjects.begin();
si != externalObjects.end(); ++si)
{
this->Objects.push_back(this->GetSourceFilePath(*si));
}
- std::vector<cmSourceFile*> objectSources;
- this->GeneratorTarget->GetObjectSources(objectSources);
- for(std::vector<cmSourceFile*>::const_iterator
- si = objectSources.begin(); si != objectSources.end(); ++si)
+
+ cmNinjaDeps orderOnlyDeps;
+ this->GetLocalGenerator()->AppendTargetDepends(this->Target, orderOnlyDeps);
+
+ // Add order-only dependencies on custom command outputs.
+ for(std::vector<cmCustomCommand const*>::const_iterator
+ cci = this->CustomCommands.begin();
+ cci != this->CustomCommands.end(); ++cci)
+ {
+ cmCustomCommand const* cc = *cci;
+ cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
+ this->GetMakefile());
+ const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
+ std::transform(ccoutputs.begin(), ccoutputs.end(),
+ std::back_inserter(orderOnlyDeps), MapToNinjaPath());
+ }
+
+ if (!orderOnlyDeps.empty())
{
- this->WriteObjectBuildStatement(*si);
+ cmNinjaDeps orderOnlyTarget;
+ orderOnlyTarget.push_back(this->OrderDependsTargetForTarget());
+ this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(),
+ "Order-only phony target for "
+ + this->GetTargetName(),
+ orderOnlyTarget,
+ cmNinjaDeps(),
+ cmNinjaDeps(),
+ orderOnlyDeps);
}
- if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+ std::vector<cmSourceFile const*> objectSources;
+ this->GeneratorTarget->GetObjectSources(objectSources, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = objectSources.begin(); si != objectSources.end(); ++si)
{
- this->ModuleDefinitionFile = this->ConvertToNinjaPath(
- this->GeneratorTarget->ModuleDefinitionFile.c_str());
+ this->WriteObjectBuildStatement(*si, !orderOnlyDeps.empty());
}
-
- {
- // Add object library contents as external objects.
- std::vector<std::string> objs;
- this->GeneratorTarget->UseObjectLibraries(objs);
- for(std::vector<std::string>::iterator oi = objs.begin();
- oi != objs.end(); ++oi)
+ std::string def = this->GeneratorTarget->GetModuleDefinitionFile(config);
+ if(!def.empty())
{
- this->Objects.push_back(ConvertToNinjaPath(oi->c_str()));
+ this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str());
}
- }
this->GetBuildFileStream() << "\n";
}
void
cmNinjaTargetGenerator
-::WriteObjectBuildStatement(cmSourceFile* source)
+::WriteObjectBuildStatement(
+ cmSourceFile const* source, bool writeOrderDependsTargetForTarget)
{
std::string comment;
const std::string language = source->GetLanguage();
@@ -542,11 +593,6 @@ cmNinjaTargetGenerator
sourceFileName = this->GetSourceFilePath(source);
explicitDeps.push_back(sourceFileName);
- // Ensure that the target dependencies are built before any source file in
- // the target, using order-only dependencies.
- cmNinjaDeps orderOnlyDeps;
- this->GetLocalGenerator()->AppendTargetDepends(this->Target, orderOnlyDeps);
-
cmNinjaDeps implicitDeps;
if(const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
std::vector<std::string> depList;
@@ -555,17 +601,10 @@ cmNinjaTargetGenerator
std::back_inserter(implicitDeps), MapToNinjaPath());
}
- // Add order-only dependencies on custom command outputs.
- std::vector<cmSourceFile*> customCommands;
- this->GeneratorTarget->GetCustomCommands(customCommands);
- for(std::vector<cmSourceFile*>::const_iterator
- si = customCommands.begin();
- si != customCommands.end(); ++si)
+ cmNinjaDeps orderOnlyDeps;
+ if (writeOrderDependsTargetForTarget)
{
- cmCustomCommand const* cc = (*si)->GetCustomCommand();
- const std::vector<std::string>& ccoutputs = cc->GetOutputs();
- std::transform(ccoutputs.begin(), ccoutputs.end(),
- std::back_inserter(orderOnlyDeps), MapToNinjaPath());
+ orderOnlyDeps.push_back(this->OrderDependsTargetForTarget());
}
// If the source file is GENERATED and does not have a custom command
@@ -589,8 +628,12 @@ cmNinjaTargetGenerator
std::string objectDir = this->Target->GetSupportDirectory();
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- ConvertToNinjaPath(objectDir.c_str()).c_str(),
+ ConvertToNinjaPath(objectDir.c_str()),
cmLocalGenerator::SHELL);
+ std::string objectFileDir = cmSystemTools::GetFilenamePath(objectFileName);
+ vars["OBJECT_FILE_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ ConvertToNinjaPath(objectFileDir.c_str()),
+ cmLocalGenerator::SHELL);
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetTarget(), vars);
@@ -614,11 +657,12 @@ cmNinjaTargetGenerator
escapedSourceFileName =
this->LocalGenerator->ConvertToOutputFormat(
- escapedSourceFileName.c_str(), cmLocalGenerator::SHELL);
+ escapedSourceFileName, cmLocalGenerator::SHELL);
compileObjectVars.Source = escapedSourceFileName.c_str();
compileObjectVars.Object = objectFileName.c_str();
compileObjectVars.ObjectDir = objectDir.c_str();
+ compileObjectVars.ObjectFileDir = objectFileDir.c_str();
compileObjectVars.Flags = vars["FLAGS"].c_str();
compileObjectVars.Defines = vars["DEFINES"].c_str();
@@ -627,7 +671,7 @@ cmNinjaTargetGenerator
compileCmdVar += language;
compileCmdVar += "_COMPILE_OBJECT";
std::string compileCmd =
- this->GetMakefile()->GetRequiredDefinition(compileCmdVar.c_str());
+ this->GetMakefile()->GetRequiredDefinition(compileCmdVar);
std::vector<std::string> compileCmds;
cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
@@ -685,8 +729,8 @@ cmNinjaTargetGenerator
// vs6's "cl -link" pass it to the linker.
std::string flag = defFileFlag;
flag += (this->LocalGenerator->ConvertToLinkReference(
- this->ModuleDefinitionFile.c_str()));
- this->LocalGenerator->AppendFlags(flags, flag.c_str());
+ this->ModuleDefinitionFile));
+ this->LocalGenerator->AppendFlags(flags, flag);
}
void
@@ -717,7 +761,7 @@ cmNinjaTargetGenerator
//----------------------------------------------------------------------------
void
cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
- cmSourceFile& source, const char* pkgloc)
+ cmSourceFile const& source, const char* pkgloc)
{
// Skip OS X content when not building a Framework or Bundle.
if(!this->Generator->GetTarget()->IsBundleOnApple())
@@ -748,9 +792,10 @@ cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
this->Generator->GetGlobalGenerator()->AddDependencyToAll(output);
}
-void cmNinjaTargetGenerator::addPoolNinjaVariable(const char* pool_property,
- cmTarget* target,
- cmNinjaVars& vars)
+void cmNinjaTargetGenerator::addPoolNinjaVariable(
+ const std::string& pool_property,
+ cmTarget* target,
+ cmNinjaVars& vars)
{
const char* pool = target->GetProperty(pool_property);
if (pool)