summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorPeter Hill <zed.three@gmail.com>2020-05-08 11:02:26 (GMT)
committerBrad King <brad.king@kitware.com>2020-05-21 15:45:58 (GMT)
commit66c4e87282176328bc2764afd53015dffd42d7f5 (patch)
treea7900dc527721c2156e0dde5274a0b6eb4729264 /Source
parent5cca1ec8934d84d9b10a7d891d31012d7aef8feb (diff)
downloadCMake-66c4e87282176328bc2764afd53015dffd42d7f5.zip
CMake-66c4e87282176328bc2764afd53015dffd42d7f5.tar.gz
CMake-66c4e87282176328bc2764afd53015dffd42d7f5.tar.bz2
Ninja: Add helper functions to generate Fortran build
Diffstat (limited to 'Source')
-rw-r--r--Source/cmNinjaTargetGenerator.cxx148
1 files changed, 87 insertions, 61 deletions
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 36fad08..63e95ee 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1026,6 +1026,78 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
}
}
+namespace {
+cmNinjaBuild GetPreprocessOrScanBuild(
+ const std::string& ruleName, const std::string& ppFileName, bool compilePP,
+ bool compilePPWithDefines, cmNinjaBuild& objBuild, cmNinjaVars& vars,
+ const std::string& depFileName, bool needDyndep,
+ const std::string& objectFileName)
+{
+ // Explicit preprocessing and dependency
+ cmNinjaBuild ppBuild(ruleName);
+
+ if (!ppFileName.empty()) {
+ ppBuild.Outputs.push_back(ppFileName);
+ ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
+ } else {
+ ppBuild.RspFile = "$out.rsp";
+ }
+
+ if (compilePP) {
+ // Move compilation dependencies to the preprocessing build statement.
+ std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
+ std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
+ std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
+ std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
+
+ // The actual compilation will now use the preprocessed source.
+ objBuild.ExplicitDeps.push_back(ppFileName);
+ } else {
+ // Copy compilation dependencies to the preprocessing build statement.
+ ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
+ ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
+ ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
+ ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
+ }
+
+ // Preprocessing and compilation generally use the same flags.
+ ppBuild.Variables["FLAGS"] = vars["FLAGS"];
+
+ if (compilePP && !compilePPWithDefines) {
+ // Move preprocessor definitions to the preprocessor build statement.
+ std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
+ } else {
+ // Copy preprocessor definitions to the preprocessor build statement.
+ ppBuild.Variables["DEFINES"] = vars["DEFINES"];
+ }
+
+ // Copy include directories to the preprocessor build statement. The
+ // Fortran compilation build statement still needs them for the INCLUDE
+ // directive.
+ ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
+
+ // Explicit preprocessing always uses a depfile.
+ ppBuild.Variables["DEP_FILE"] = depFileName;
+ 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 source.
+ ppBuild.Variables["OBJ_FILE"] = objectFileName;
+
+ // Tell dependency scanner where to store dyndep intermediate results.
+ std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
+ ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
+ ppBuild.ImplicitOuts.push_back(ddiFile);
+ }
+ return ppBuild;
+}
+}
+
void cmNinjaTargetGenerator::WriteObjectBuildStatement(
cmSourceFile const* source, const std::string& config,
const std::string& fileConfig, bool firstForConfig)
@@ -1164,36 +1236,24 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// For some cases we do an explicit preprocessor invocation.
bool const explicitPP = this->NeedExplicitPreprocessing(language);
if (explicitPP) {
- cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language, config));
+
+ bool const compilePP = this->UsePreprocessedSource(language);
+ bool const compilePPWithDefines =
+ compilePP && this->CompilePreprocessedSourceWithDefines(language);
std::string const ppFileName =
this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config));
- ppBuild.Outputs.push_back(ppFileName);
- ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
+ std::string const buildName =
+ this->LanguagePreprocessRule(language, config);
- bool const compilePP = this->UsePreprocessedSource(language);
- bool const compilePPWithDefines =
- compilePP && this->CompilePreprocessedSourceWithDefines(language);
- if (compilePP) {
- // Move compilation dependencies to the preprocessing build statement.
- std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
- std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
- std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
- std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
-
- // The actual compilation will now use the preprocessed source.
- objBuild.ExplicitDeps.push_back(ppFileName);
- } else {
- // Copy compilation dependencies to the preprocessing build statement.
- ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
- ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
- ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
- ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
- }
+ const std::string depFileName =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmStrCat(objectFileName, ".pp.d"), cmOutputConverter::SHELL);
- // Preprocessing and compilation generally use the same flags.
- ppBuild.Variables["FLAGS"] = vars["FLAGS"];
+ cmNinjaBuild ppBuild = GetPreprocessOrScanBuild(
+ buildName, ppFileName, compilePP, compilePPWithDefines, objBuild, vars,
+ depFileName, needDyndep, objectFileName);
if (compilePP) {
// In case compilation requires flags that are incompatible with
@@ -1201,22 +1261,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string const& postFlag = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", language, "_POSTPROCESS_FLAG"));
this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag);
- }
- if (compilePP && !compilePPWithDefines) {
- // Move preprocessor definitions to the preprocessor build statement.
- std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
- } else {
- // Copy preprocessor definitions to the preprocessor build statement.
- ppBuild.Variables["DEFINES"] = vars["DEFINES"];
- }
-
- // Copy include directories to the preprocessor build statement. The
- // Fortran compilation build statement still needs them for the INCLUDE
- // directive.
- ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
-
- 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;
@@ -1230,28 +1275,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["INCLUDES"] = cmStrCat(sourceDirectoryFlag, ' ', vars["INCLUDES"]);
}
- // Explicit preprocessing always uses a depfile.
- ppBuild.Variables["DEP_FILE"] =
- this->GetLocalGenerator()->ConvertToOutputFormat(
- cmStrCat(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 source.
- ppBuild.Variables["OBJ_FILE"] = objectFileName;
-
- // Tell dependency scanner where to store dyndep intermediate results.
- std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
- ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
- ppBuild.ImplicitOuts.push_back(ddiFile);
- if (firstForConfig) {
- this->Configs[config].DDIFiles[language].push_back(ddiFile);
- }
+ if (firstForConfig && needDyndep) {
+ const std::string& ddiFile = ppBuild.ImplicitOuts.back();
+ this->Configs[config].DDIFiles[language].push_back(ddiFile);
}
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),