diff options
author | Brad King <brad.king@kitware.com> | 2020-05-22 14:34:53 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-05-22 14:35:10 (GMT) |
commit | 62816ff88c6d1bd8d1c00de5ed448ee915d69e00 (patch) | |
tree | 6f1eb5d7c8b7deee02da84d309b446d5f6f38db5 /Source | |
parent | 1b0049680b09872f01f714c8dcb1ed3c5c21da25 (diff) | |
parent | 3888de23daca814d66a40642d3e369a5c4747131 (diff) | |
download | CMake-62816ff88c6d1bd8d1c00de5ed448ee915d69e00.zip CMake-62816ff88c6d1bd8d1c00de5ed448ee915d69e00.tar.gz CMake-62816ff88c6d1bd8d1c00de5ed448ee915d69e00.tar.bz2 |
Merge topic 'fortran-preprocess-property'
3888de23da Ninja: Skip Fortran preprocessing if Fortran_PREPROCESS is OFF
66c4e87282 Ninja: Add helper functions to generate Fortran build
5cca1ec893 Ninja: Add helper functions to generate Fortran preprocess rule
b0a6161190 Fortran: Add Fortran_PREPROCESS property
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4659
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmCommonTargetGenerator.cxx | 28 | ||||
-rw-r--r-- | Source/cmCommonTargetGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio7Generator.cxx | 27 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 354 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.h | 2 | ||||
-rw-r--r-- | Source/cmOutputConverter.cxx | 11 | ||||
-rw-r--r-- | Source/cmOutputConverter.h | 8 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 1 |
9 files changed, 308 insertions, 127 deletions
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 5414409..32a33ee 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -98,6 +98,34 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags( } } +void cmCommonTargetGenerator::AppendFortranPreprocessFlags( + std::string& flags, cmSourceFile const& source) +{ + const std::string srcpp = source.GetSafeProperty("Fortran_PREPROCESS"); + cmOutputConverter::FortranPreprocess preprocess = + cmOutputConverter::GetFortranPreprocess(srcpp); + if (preprocess == cmOutputConverter::FortranPreprocess::Unset) { + std::string const& tgtpp = + this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS"); + preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp); + } + const char* var = nullptr; + switch (preprocess) { + case cmOutputConverter::FortranPreprocess::Needed: + var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON"; + break; + case cmOutputConverter::FortranPreprocess::NotNeeded: + var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF"; + break; + default: + break; + } + if (var) { + this->LocalCommonGenerator->AppendCompileOptions( + flags, this->Makefile->GetSafeDefinition(var)); + } +} + std::string cmCommonTargetGenerator::GetFlags(const std::string& l, const std::string& config, const std::string& arch) diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h index 78cedf5..c3c3a3a 100644 --- a/Source/cmCommonTargetGenerator.h +++ b/Source/cmCommonTargetGenerator.h @@ -45,6 +45,9 @@ protected: void AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source); + void AppendFortranPreprocessFlags(std::string& flags, + cmSourceFile const& source); + virtual void AddIncludeFlags(std::string& flags, std::string const& lang, const std::string& config) = 0; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 0b02724..5d50e2d 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -283,6 +283,7 @@ void cmLocalVisualStudio7Generator::WriteConfigurations( } cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = { { "Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0 }, + { "Preprocess", "nofpp", "Run Preprocessor on files", "preprocessNo", 0 }, { "SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0 }, { "SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0 }, { "SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0 }, @@ -681,6 +682,18 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( default: break; } + + switch (cmOutputConverter::GetFortranPreprocess( + target->GetSafeProperty("Fortran_PREPROCESS"))) { + case cmOutputConverter::FortranPreprocess::Needed: + flags += " -fpp"; + break; + case cmOutputConverter::FortranPreprocess::NotNeeded: + flags += " -nofpp"; + break; + default: + break; + } } // Get preprocessor definitions for this directory. @@ -1473,6 +1486,20 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo( } if (lg->FortranProject) { + switch (cmOutputConverter::GetFortranPreprocess( + sf.GetSafeProperty("Fortran_PREPROCESS"))) { + case cmOutputConverter::FortranPreprocess::Needed: + fc.CompileFlags = cmStrCat("-fpp ", fc.CompileFlags); + needfc = true; + break; + case cmOutputConverter::FortranPreprocess::NotNeeded: + fc.CompileFlags = cmStrCat("-nofpp ", fc.CompileFlags); + needfc = true; + break; + default: + break; + } + switch (cmOutputConverter::GetFortranFormat( sf.GetSafeProperty("Fortran_FORMAT"))) { case cmOutputConverter::FortranFormatFixed: diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 04d4db7..c98e3a9 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -541,6 +541,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( // Add Fortran format flags. if (lang == "Fortran") { this->AppendFortranFormatFlags(flags, source); + this->AppendFortranPreprocessFlags(flags, source); } // Add flags from source file properties. diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index f4ff51b..c77a85b 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -106,7 +106,16 @@ std::string cmNinjaTargetGenerator::LanguagePreprocessRule( std::string const& lang, const std::string& config) const { return cmStrCat( - lang, "_PREPROCESS__", + lang, "_PREPROCESS_SCAN__", + cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()), + '_', config); +} + +std::string cmNinjaTargetGenerator::LanguageDependencyRule( + std::string const& lang, const std::string& config) const +{ + return cmStrCat( + lang, "_SCAN__", cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()), '_', config); } @@ -183,6 +192,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject( // Add Fortran format flags. if (language == "Fortran") { this->AppendFortranFormatFlags(flags, *source); + this->AppendFortranPreprocessFlags(flags, *source); } // Add source file specific flags. @@ -508,6 +518,91 @@ void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language, this->WriteCompileRule(language, config); } +namespace { +// Create the command to run the dependency scanner +std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi, + const std::string& lang, const std::string& ppFile, + bool needDyndep, const std::string& ddiFile) +{ + std::string ccmd = + cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, " --lang=", lang, + " --pp=", ppFile, " --dep=$DEP_FILE"); + if (needDyndep) { + ccmd = cmStrCat(ccmd, " --obj=$OBJ_FILE --ddi=", ddiFile); + } + return ccmd; +} + +// Helper function to create dependency scanning rule, with optional +// explicit preprocessing step if preprocessCommand is non-empty +cmNinjaRule GetPreprocessScanRule( + const std::string& ruleName, cmRulePlaceholderExpander::RuleVariables& vars, + const std::string& responseFlag, const std::string& flags, + const std::string& launcher, + cmRulePlaceholderExpander* const rulePlaceholderExpander, + std::string scanCommand, cmLocalNinjaGenerator* generator, + const std::string& preprocessCommand = "") +{ + cmNinjaRule rule(ruleName); + // Explicit preprocessing always uses a depfile. + rule.DepType = ""; // no deps= for multiple outputs + rule.DepFile = "$DEP_FILE"; + + cmRulePlaceholderExpander::RuleVariables ppVars; + ppVars.CMTargetName = vars.CMTargetName; + ppVars.CMTargetType = vars.CMTargetType; + ppVars.Language = vars.Language; + ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE + ppVars.PreprocessedSource = "$out"; + ppVars.DependencyFile = rule.DepFile.c_str(); + + // Preprocessing uses the original source, compilation uses + // preprocessed output or original source + ppVars.Source = vars.Source; + vars.Source = "$in"; + + // Copy preprocessor definitions to the preprocessor rule. + ppVars.Defines = vars.Defines; + + // Copy include directories to the preprocessor rule. The Fortran + // compilation rule still needs them for the INCLUDE directive. + ppVars.Includes = vars.Includes; + + // Preprocessing and compilation use the same flags. + std::string ppFlags = flags; + + // If using a response file, move defines, includes, and flags into it. + if (!responseFlag.empty()) { + rule.RspFile = "$RSP_FILE"; + rule.RspContent = + cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags); + ppFlags = cmStrCat(responseFlag, rule.RspFile); + ppVars.Defines = ""; + ppVars.Includes = ""; + } + + ppVars.Flags = ppFlags.c_str(); + + // Rule for preprocessing source file. + std::vector<std::string> ppCmds; + + if (!preprocessCommand.empty()) { + // Lookup the explicit preprocessing rule. + cmExpandList(preprocessCommand, ppCmds); + for (std::string& i : ppCmds) { + i = cmStrCat(launcher, i); + rulePlaceholderExpander->ExpandRuleVariables(generator, i, ppVars); + } + } + + // Run CMake dependency scanner on either preprocessed output or source file + ppCmds.emplace_back(std::move(scanCommand)); + rule.Command = generator->BuildCommandLine(ppCmds); + + return rule; +} +} + void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, const std::string& config) { @@ -565,82 +660,42 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); if (explicitPP) { - cmNinjaRule rule(this->LanguagePreprocessRule(lang, config)); - // Explicit preprocessing always uses a depfile. - rule.DepType = ""; // no deps= for multiple outputs - rule.DepFile = "$DEP_FILE"; + // Combined preprocessing and dependency scanning + const auto ppScanCommand = GetScanCommand( + cmakeCmd, tdi, lang, "$out", needDyndep, "$DYNDEP_INTERMEDIATE_FILE"); + const auto ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE"); - cmRulePlaceholderExpander::RuleVariables ppVars; - ppVars.CMTargetName = vars.CMTargetName; - ppVars.CMTargetType = vars.CMTargetType; - ppVars.Language = vars.Language; - ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE - ppVars.PreprocessedSource = "$out"; - ppVars.DependencyFile = rule.DepFile.c_str(); + auto ppRule = GetPreprocessScanRule( + this->LanguagePreprocessRule(lang, config), vars, responseFlag, flags, + launcher, rulePlaceholderExpander.get(), ppScanCommand, + this->GetLocalGenerator(), mf->GetRequiredDefinition(ppVar)); - // Preprocessing uses the original source, - // compilation uses preprocessed output. - ppVars.Source = vars.Source; - vars.Source = "$in"; + // Write the rule for preprocessing file of the given language. + ppRule.Comment = cmStrCat("Rule for preprocessing ", lang, " files."); + ppRule.Description = cmStrCat("Building ", lang, " preprocessed $out"); - // Preprocessing and compilation use the same flags. - std::string ppFlags = flags; + this->GetGlobalGenerator()->AddRule(ppRule); if (!compilePPWithDefines) { - // Move preprocessor definitions to the preprocessor rule. - ppVars.Defines = vars.Defines; + // Remove preprocessor definitions from compilation step vars.Defines = ""; - } else { - // Copy preprocessor definitions to the preprocessor rule. - ppVars.Defines = vars.Defines; - } - - // Copy include directories to the preprocessor rule. The Fortran - // compilation rule still needs them for the INCLUDE directive. - ppVars.Includes = vars.Includes; - - // If using a response file, move defines, includes, and flags into it. - if (!responseFlag.empty()) { - rule.RspFile = "$RSP_FILE"; - rule.RspContent = - cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags); - ppFlags = cmStrCat(responseFlag, rule.RspFile); - ppVars.Defines = ""; - ppVars.Includes = ""; } - ppVars.Flags = ppFlags.c_str(); + // Just dependency scanning for files that have preprocessing turned off + const auto scanCommand = + GetScanCommand(cmakeCmd, tdi, lang, "$in", needDyndep, "$out"); - // Rule for preprocessing source file. - std::vector<std::string> ppCmds; - { - // Lookup the explicit preprocessing rule. - std::string ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE"); - cmExpandList(this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds); - } + auto scanRule = GetPreprocessScanRule( + this->LanguageDependencyRule(lang, config), vars, "", flags, launcher, + rulePlaceholderExpander.get(), scanCommand, this->GetLocalGenerator()); - for (std::string& i : ppCmds) { - i = cmStrCat(launcher, i); - rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), - i, ppVars); - } + // Write the rule for generating dependencies for the given language. + scanRule.Comment = cmStrCat("Rule for generating ", lang, + " dependencies on non-preprocessed files."); + scanRule.Description = + cmStrCat("Generating ", lang, " dependencies for $in"); - // Run CMake dependency scanner on preprocessed output. - { - std::string ccmd = - cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, - " --lang=", lang, " --pp=$out --dep=$DEP_FILE"); - if (needDyndep) { - ccmd += " --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE"; - } - ppCmds.emplace_back(std::move(ccmd)); - } - rule.Command = this->GetLocalGenerator()->BuildCommandLine(ppCmds); - - // Write the rule for preprocessing file of the given language. - rule.Comment = cmStrCat("Rule for preprocessing ", lang, " files."); - rule.Description = cmStrCat("Building ", lang, " preprocessed $out"); - this->GetGlobalGenerator()->AddRule(rule); + this->GetGlobalGenerator()->AddRule(scanRule); } if (needDyndep) { @@ -996,6 +1051,82 @@ 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"); + if (ppFileName.empty()) { + ppBuild.Outputs.push_back(ddiFile); + } else { + 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) @@ -1134,36 +1265,39 @@ 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)); - std::string const ppFileName = - this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config)); - ppBuild.Outputs.push_back(ppFileName); - - ppBuild.RspFile = cmStrCat(ppFileName, ".rsp"); + // If source/target has preprocessing turned off, we still need to + // generate an explicit dependency step + const auto srcpp = source->GetSafeProperty("Fortran_PREPROCESS"); + cmOutputConverter::FortranPreprocess preprocess = + cmOutputConverter::GetFortranPreprocess(srcpp); + if (preprocess == cmOutputConverter::FortranPreprocess::Unset) { + const auto& tgtpp = + this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS"); + preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp); + } - bool const compilePP = this->UsePreprocessedSource(language); + bool const compilePP = this->UsePreprocessedSource(language) && + (preprocess != cmOutputConverter::FortranPreprocess::NotNeeded); 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"]; - } - // Preprocessing and compilation generally use the same flags. - ppBuild.Variables["FLAGS"] = vars["FLAGS"]; + std::string const ppFileName = compilePP + ? this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config)) + : ""; + + std::string const buildName = compilePP + ? this->LanguagePreprocessRule(language, config) + : this->LanguageDependencyRule(language, config); + + const auto depExtension = compilePP ? ".pp.d" : ".d"; + const std::string depFileName = + this->GetLocalGenerator()->ConvertToOutputFormat( + cmStrCat(objectFileName, depExtension), cmOutputConverter::SHELL); + + cmNinjaBuild ppBuild = GetPreprocessOrScanBuild( + buildName, ppFileName, compilePP, compilePPWithDefines, objBuild, vars, + depFileName, needDyndep, objectFileName); if (compilePP) { // In case compilation requires flags that are incompatible with @@ -1171,22 +1305,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; @@ -1200,28 +1319,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. + if (firstForConfig && needDyndep) { 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); - } + this->Configs[config].DDIFiles[language].push_back(ddiFile); } this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(), diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 1ac5683..8d4372e 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -70,6 +70,8 @@ protected: const std::string& config) const; std::string LanguagePreprocessRule(std::string const& lang, const std::string& config) const; + std::string LanguageDependencyRule(std::string const& lang, + const std::string& config) const; bool NeedExplicitPreprocessing(std::string const& lang) const; std::string LanguageDyndepRule(std::string const& lang, const std::string& config) const; diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index dc324cc..359e9f5 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -170,6 +170,17 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat( return format; } +cmOutputConverter::FortranPreprocess cmOutputConverter::GetFortranPreprocess( + cm::string_view value) +{ + if (value.empty()) { + return FortranPreprocess::Unset; + } + + return cmIsOn(value) ? FortranPreprocess::Needed + : FortranPreprocess::NotNeeded; +} + void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell) { this->LinkScriptShell = linkScriptShell; diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h index 28582df..a8b4528 100644 --- a/Source/cmOutputConverter.h +++ b/Source/cmOutputConverter.h @@ -95,6 +95,14 @@ public: }; static FortranFormat GetFortranFormat(cm::string_view value); + enum class FortranPreprocess + { + Unset, + NotNeeded, + Needed + }; + static FortranPreprocess GetFortranPreprocess(cm::string_view value); + private: cmState* GetState() const; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index e165f4c..4bb48fb 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -307,6 +307,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("Fortran_FORMAT"); initProp("Fortran_MODULE_DIRECTORY"); initProp("Fortran_COMPILER_LAUNCHER"); + initProp("Fortran_PREPROCESS"); initProp("GNUtoMS"); initProp("OSX_ARCHITECTURES"); initProp("IOS_INSTALL_COMBINED"); |