summaryrefslogtreecommitdiffstats
path: root/Source/cmNinjaTargetGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmNinjaTargetGenerator.cxx')
-rw-r--r--Source/cmNinjaTargetGenerator.cxx157
1 files changed, 102 insertions, 55 deletions
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 82bc5f2..1ad26dd 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -102,6 +102,12 @@ bool cmNinjaTargetGenerator::NeedExplicitPreprocessing(
return lang == "Fortran";
}
+bool cmNinjaTargetGenerator::UsePreprocessedSource(
+ std::string const& lang) const
+{
+ return lang == "Fortran";
+}
+
std::string cmNinjaTargetGenerator::LanguageDyndepRule(
const std::string& lang) const
{
@@ -454,6 +460,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
if (lang == "Swift") {
vars.SwiftAuxiliarySources = "$SWIFT_AUXILIARY_SOURCES";
vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
+ vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
+ vars.SwiftPartialModule = "$SWIFT_PARTIAL_MODULE";
+ vars.SwiftPartialDoc = "$SWIFT_PARTIAL_DOC";
}
// For some cases we do an explicit preprocessor invocation.
@@ -493,7 +502,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
if (explicitPP) {
// Lookup the explicit preprocessing rule.
std::string const ppVar = "CMAKE_" + lang + "_PREPROCESS_SOURCE";
- std::string const ppCmd =
+ std::string const& ppCmd =
this->GetMakefile()->GetRequiredDefinition(ppVar);
// Explicit preprocessing always uses a depfile.
@@ -555,7 +564,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
cmake +
" -E cmake_ninja_depends"
" --tdi=" +
- tdi +
+ tdi + " --lang=" + lang +
" --pp=$out"
" --dep=$DEP_FILE" +
(needDyndep ? " --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE" : ""));
@@ -585,13 +594,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
std::string ddRspContent = "$in";
std::string ddInput = "@" + ddRspFile;
- // Run CMake dependency scanner on preprocessed output.
+ // Run CMake dependency scanner on the source file (using the preprocessed
+ // source if that was performed).
std::string const cmake = this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
ddCmds.push_back(cmake +
" -E cmake_ninja_dyndep"
" --tdi=" +
- tdi +
+ tdi + " --lang=" + lang +
" --dd=$out"
" " +
ddInput);
@@ -671,19 +681,18 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
std::string cmdVar;
if (this->GeneratorTarget->GetPropertyAsBool(
"CUDA_SEPARABLE_COMPILATION")) {
- cmdVar = std::string("CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION");
+ cmdVar = "CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION";
} else if (this->GeneratorTarget->GetPropertyAsBool(
"CUDA_PTX_COMPILATION")) {
- cmdVar = std::string("CMAKE_CUDA_COMPILE_PTX_COMPILATION");
+ cmdVar = "CMAKE_CUDA_COMPILE_PTX_COMPILATION";
} else {
- cmdVar = std::string("CMAKE_CUDA_COMPILE_WHOLE_COMPILATION");
+ cmdVar = "CMAKE_CUDA_COMPILE_WHOLE_COMPILATION";
}
- std::string compileCmd = mf->GetRequiredDefinition(cmdVar);
+ const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
} else {
- const std::string cmdVar =
- std::string("CMAKE_") + lang + "_COMPILE_OBJECT";
- std::string compileCmd = mf->GetRequiredDefinition(cmdVar);
+ const std::string cmdVar = "CMAKE_" + lang + "_COMPILE_OBJECT";
+ const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
}
@@ -866,24 +875,27 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
this->WriteObjectBuildStatement(sf);
}
- if (!this->DDIFiles.empty()) {
+ for (auto const& langDDIFiles : this->DDIFiles) {
+ std::string const& language = langDDIFiles.first;
+ cmNinjaDeps const& ddiFiles = langDDIFiles.second;
+
std::string const ddComment;
- std::string const ddRule = this->LanguageDyndepRule("Fortran");
+ std::string const ddRule = this->LanguageDyndepRule(language);
cmNinjaDeps ddOutputs;
cmNinjaDeps ddImplicitOuts;
- cmNinjaDeps const& ddExplicitDeps = this->DDIFiles;
+ cmNinjaDeps const& ddExplicitDeps = ddiFiles;
cmNinjaDeps ddImplicitDeps;
cmNinjaDeps ddOrderOnlyDeps;
cmNinjaVars ddVars;
- this->WriteTargetDependInfo("Fortran");
+ this->WriteTargetDependInfo(language);
- ddOutputs.push_back(this->GetDyndepFilePath("Fortran"));
+ ddOutputs.push_back(this->GetDyndepFilePath(language));
// Make sure dyndep files for all our dependencies have already
- // been generated so that the 'FortranModules.json' files they
+ // been generated so that the '<LANG>Modules.json' files they
// produced as side-effects are available for us to read.
- // Ideally we should depend on the 'FortranModules.json' files
+ // Ideally we should depend on the '<LANG>Modules.json' files
// from our dependencies directly, but we don't know which of
// our dependencies produces them. Fixing this will require
// refactoring the Ninja generator to generate targets in
@@ -941,6 +953,22 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
} else {
vars["SWIFT_MODULE_NAME"] = this->GeneratorTarget->GetName();
}
+
+ cmGeneratorTarget::Names targetNames =
+ this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
+ vars["SWIFT_LIBRARY_NAME"] = targetNames.Base;
+
+ if (const char* partial = source->GetProperty("SWIFT_PARTIAL_MODULE")) {
+ vars["SWIFT_PARTIAL_MODULE"] = partial;
+ } else {
+ vars["SWIFT_PARTIAL_MODULE"] = objectFileName + ".swiftmodule";
+ }
+
+ if (const char* partial = source->GetProperty("SWIFT_PARTIAL_DOC")) {
+ vars["SWIFT_PARTIAL_DOC"] = partial;
+ } else {
+ vars["SWIFT_PARTIAL_DOC"] = objectFileName + ".swiftdoc";
+ }
}
if (!this->NeedDepTypeMSVC(language)) {
@@ -1014,6 +1042,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// For some cases we do an explicit preprocessor invocation.
bool const explicitPP = this->NeedExplicitPreprocessing(language);
if (explicitPP) {
+ bool const compilePP = this->UsePreprocessedSource(language);
std::string const ppComment;
std::string const ppRule = this->LanguagePreprocessRule(language);
cmNinjaDeps ppOutputs;
@@ -1027,61 +1056,80 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source));
ppOutputs.push_back(ppFileName);
- // Move compilation dependencies to the preprocessing build statement.
- std::swap(ppExplicitDeps, explicitDeps);
- std::swap(ppImplicitDeps, implicitDeps);
- std::swap(ppOrderOnlyDeps, orderOnlyDeps);
- std::swap(ppVars["IN_ABS"], vars["IN_ABS"]);
+ if (compilePP) {
+ // Move compilation dependencies to the preprocessing build statement.
+ std::swap(ppExplicitDeps, explicitDeps);
+ std::swap(ppImplicitDeps, implicitDeps);
+ std::swap(ppOrderOnlyDeps, orderOnlyDeps);
+ std::swap(ppVars["IN_ABS"], vars["IN_ABS"]);
- // The actual compilation will now use the preprocessed source.
- explicitDeps.push_back(ppFileName);
+ // The actual compilation will now use the preprocessed source.
+ explicitDeps.push_back(ppFileName);
+ } else {
+ // Copy compilation dependencies to the preprocessing build statement.
+ ppExplicitDeps = explicitDeps;
+ ppImplicitDeps = implicitDeps;
+ ppOrderOnlyDeps = orderOnlyDeps;
+ ppVars["IN_ABS"] = vars["IN_ABS"];
+ }
// Preprocessing and compilation generally use the same flags.
ppVars["FLAGS"] = vars["FLAGS"];
- // In case compilation requires flags that are incompatible with
- // preprocessing, include them here.
- std::string const postFlag =
- this->Makefile->GetSafeDefinition("CMAKE_Fortran_POSTPROCESS_FLAG");
- this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag);
+ if (compilePP) {
+ // In case compilation requires flags that are incompatible with
+ // preprocessing, include them here.
+ std::string const postFlag = this->Makefile->GetSafeDefinition(
+ "CMAKE_" + language + "_POSTPROCESS_FLAG");
+ this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag);
+ }
- // Move preprocessor definitions to the preprocessor build statement.
- std::swap(ppVars["DEFINES"], vars["DEFINES"]);
+ if (compilePP) {
+ // Move preprocessor definitions to the preprocessor build statement.
+ std::swap(ppVars["DEFINES"], vars["DEFINES"]);
+ } else {
+ // Copy preprocessor definitions to the preprocessor build statement.
+ ppVars["DEFINES"] = vars["DEFINES"];
+ }
// Copy include directories to the preprocessor build statement. The
// Fortran compilation build statement still needs them for the INCLUDE
// directive.
ppVars["INCLUDES"] = vars["INCLUDES"];
- // Prepend source file's original directory as an include directory
- // so e.g. Fortran INCLUDE statements can look for files in it.
- std::vector<std::string> sourceDirectory;
- sourceDirectory.push_back(
- cmSystemTools::GetParentDirectory(source->GetFullPath()));
+ if (compilePP) {
+ // Prepend source file's original directory as an include directory
+ // so e.g. Fortran INCLUDE statements can look for files in it.
+ std::vector<std::string> sourceDirectory;
+ sourceDirectory.push_back(
+ cmSystemTools::GetParentDirectory(source->GetFullPath()));
- std::string sourceDirectoryFlag = this->LocalGenerator->GetIncludeFlags(
- sourceDirectory, this->GeneratorTarget, language, false, false,
- this->GetConfigName());
+ std::string sourceDirectoryFlag = this->LocalGenerator->GetIncludeFlags(
+ sourceDirectory, this->GeneratorTarget, language, false, false,
+ this->GetConfigName());
- vars["INCLUDES"] = sourceDirectoryFlag + " " + vars["INCLUDES"];
+ vars["INCLUDES"] = sourceDirectoryFlag + " " + vars["INCLUDES"];
+ }
// Explicit preprocessing always uses a depfile.
ppVars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- ppFileName + ".d", cmOutputConverter::SHELL);
- // The actual compilation does not need a depfile because it
- // depends on the already-preprocessed source.
- vars.erase("DEP_FILE");
+ objectFileName + ".pp.d", cmOutputConverter::SHELL);
+ if (compilePP) {
+ // The actual compilation does not need a depfile because it
+ // depends on the already-preprocessed source.
+ vars.erase("DEP_FILE");
+ }
if (needDyndep) {
// Tell dependency scanner the object file that will result from
- // compiling the preprocessed source.
+ // compiling the source.
ppVars["OBJ_FILE"] = objectFileName;
// Tell dependency scanner where to store dyndep intermediate results.
- std::string const ddiFile = ppFileName + ".ddi";
+ std::string const ddiFile = objectFileName + ".ddi";
ppVars["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
ppImplicitOuts.push_back(ddiFile);
- this->DDIFiles.push_back(ddiFile);
+ this->DDIFiles[language].push_back(ddiFile);
}
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
@@ -1217,20 +1265,19 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
std::string cmdVar;
if (this->GeneratorTarget->GetPropertyAsBool(
"CUDA_SEPARABLE_COMPILATION")) {
- cmdVar = std::string("CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION");
+ cmdVar = "CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION";
} else if (this->GeneratorTarget->GetPropertyAsBool(
"CUDA_PTX_COMPILATION")) {
- cmdVar = std::string("CMAKE_CUDA_COMPILE_PTX_COMPILATION");
+ cmdVar = "CMAKE_CUDA_COMPILE_PTX_COMPILATION";
} else {
- cmdVar = std::string("CMAKE_CUDA_COMPILE_WHOLE_COMPILATION");
+ cmdVar = "CMAKE_CUDA_COMPILE_WHOLE_COMPILATION";
}
- std::string compileCmd =
+ const std::string& compileCmd =
this->GetMakefile()->GetRequiredDefinition(cmdVar);
cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
} else {
- const std::string cmdVar =
- std::string("CMAKE_") + language + "_COMPILE_OBJECT";
- std::string compileCmd =
+ const std::string cmdVar = "CMAKE_" + language + "_COMPILE_OBJECT";
+ const std::string& compileCmd =
this->GetMakefile()->GetRequiredDefinition(cmdVar);
cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
}