From 2dd0cb7aeb2d70dcc6e103c29ce2ce3a02bd381a Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 20 Feb 2019 11:35:47 -0500 Subject: Help: note that Ninja also uses OBJECT_OUTPUTS --- Help/prop_sf/OBJECT_OUTPUTS.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Help/prop_sf/OBJECT_OUTPUTS.rst b/Help/prop_sf/OBJECT_OUTPUTS.rst index 6a28553..1ce4866 100644 --- a/Help/prop_sf/OBJECT_OUTPUTS.rst +++ b/Help/prop_sf/OBJECT_OUTPUTS.rst @@ -1,9 +1,9 @@ OBJECT_OUTPUTS -------------- -Additional outputs for a Makefile rule. +Additional outputs for a Ninja or Makefile rule. Additional outputs created by compilation of this source file. If any of these outputs is missing the object will be recompiled. This is -supported only on Makefile generators and will be ignored on other -generators. +supported only on the Ninja and Makefile generators and will be ignored on +other generators. -- cgit v0.12 From 72f9bb29939f3765216e98e672197b3899d75f7d Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 20 Feb 2019 01:39:55 -0500 Subject: ninja: make dyndep generation language aware A target may have multiple languages with dyndep rules, separate `.dd` files should be generated. --- Source/cmGlobalNinjaGenerator.cxx | 31 ++++++++++++++++++++----------- Source/cmGlobalNinjaGenerator.h | 3 ++- Source/cmNinjaTargetGenerator.cxx | 21 ++++++++++++--------- Source/cmNinjaTargetGenerator.h | 3 ++- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 018606c..5a85963 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1593,7 +1593,7 @@ Compilation of source files within a target is split into the following steps: rule Fortran_DYNDEP command = cmake -E cmake_ninja_dyndep \ - --tdi=FortranDependInfo.json --dd=$out $in + --tdi=FortranDependInfo.json --lang=Fortran --dd=$out $in build Fortran.dd: Fortran_DYNDEP src1.f90-pp.f90.ddi src2.f90-pp.f90.ddi @@ -1755,7 +1755,7 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, return 0; } -struct cmFortranObjectInfo +struct cmDyndepObjectInfo { std::string Object; std::vector Provides; @@ -1767,7 +1767,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( std::string const& dir_cur_src, std::string const& dir_cur_bld, std::string const& arg_dd, std::vector const& arg_ddis, std::string const& module_dir, - std::vector const& linked_target_dirs) + std::vector const& linked_target_dirs, + std::string const& arg_lang) { // Setup path conversions. { @@ -1784,7 +1785,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( this->LocalGenerators.push_back(lgd.release()); } - std::vector objects; + std::vector objects; for (std::string const& arg_ddi : arg_ddis) { // Load the ddi file and compute the module file paths it provides. Json::Value ddio; @@ -1797,7 +1798,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( return false; } - cmFortranObjectInfo info; + cmDyndepObjectInfo info; info.Object = ddi["object"].asString(); Json::Value const& ddi_provides = ddi["provides"]; if (ddi_provides.isArray()) { @@ -1819,7 +1820,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( // Populate the module map with those provided by linked targets first. for (std::string const& linked_target_dir : linked_target_dirs) { - std::string const ltmn = linked_target_dir + "/FortranModules.json"; + std::string const ltmn = + linked_target_dir + "/" + arg_lang + "Modules.json"; Json::Value ltm; cmsys::ifstream ltmf(ltmn.c_str(), std::ios::in | std::ios::binary); Json::Reader reader; @@ -1840,7 +1842,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( // We do this after loading the modules provided by linked targets // in case we have one of the same name that must be preferred. Json::Value tm = Json::objectValue; - for (cmFortranObjectInfo const& object : objects) { + for (cmDyndepObjectInfo const& object : objects) { for (std::string const& p : object.Provides) { std::string const mod = module_dir + p; mod_files[p] = mod; @@ -1851,7 +1853,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( cmGeneratedFileStream ddf(arg_dd); ddf << "ninja_dyndep_version = 1.0\n"; - for (cmFortranObjectInfo const& object : objects) { + for (cmDyndepObjectInfo const& object : objects) { std::string const ddComment; std::string const ddRule = "dyndep"; cmNinjaDeps ddOutputs; @@ -1882,7 +1884,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( // Store the map of modules provided by this target in a file for // use by dependents that reference this target in linked-target-dirs. std::string const target_mods_file = - cmSystemTools::GetFilenamePath(arg_dd) + "/FortranModules.json"; + cmSystemTools::GetFilenamePath(arg_dd) + "/" + arg_lang + "Modules.json"; cmGeneratedFileStream tmf(target_mods_file); tmf << tm; @@ -1896,11 +1898,14 @@ int cmcmd_cmake_ninja_dyndep(std::vector::const_iterator argBeg, cmSystemTools::HandleResponseFile(argBeg, argEnd); std::string arg_dd; + std::string arg_lang; std::string arg_tdi; std::vector arg_ddis; for (std::string const& arg : arg_full) { if (cmHasLiteralPrefix(arg, "--tdi=")) { arg_tdi = arg.substr(6); + } else if (cmHasLiteralPrefix(arg, "--lang=")) { + arg_lang = arg.substr(7); } else if (cmHasLiteralPrefix(arg, "--dd=")) { arg_dd = arg.substr(5); } else if (!cmHasLiteralPrefix(arg, "--") && @@ -1915,6 +1920,10 @@ int cmcmd_cmake_ninja_dyndep(std::vector::const_iterator argBeg, cmSystemTools::Error("-E cmake_ninja_dyndep requires value for --tdi="); return 1; } + if (arg_lang.empty()) { + cmSystemTools::Error("-E cmake_ninja_dyndep requires value for --lang="); + return 1; + } if (arg_dd.empty()) { cmSystemTools::Error("-E cmake_ninja_dyndep requires value for --dd="); return 1; @@ -1955,8 +1964,8 @@ int cmcmd_cmake_ninja_dyndep(std::vector::const_iterator argBeg, static_cast(cm.CreateGlobalGenerator("Ninja"))); if (!ggd || !ggd->WriteDyndepFile(dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld, - arg_dd, arg_ddis, module_dir, - linked_target_dirs)) { + arg_dd, arg_ddis, module_dir, linked_target_dirs, + arg_lang)) { return 1; } return 0; diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index c619e67..69210ec 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -365,7 +365,8 @@ public: std::string const& arg_dd, std::vector const& arg_ddis, std::string const& module_dir, - std::vector const& linked_target_dirs); + std::vector const& linked_target_dirs, + std::string const& arg_lang); protected: void Generate() override; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 6013cd0..6a08d5c 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -594,7 +594,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) ddCmds.push_back(cmake + " -E cmake_ninja_dyndep" " --tdi=" + - tdi + + tdi + " --lang=" + lang + " --dd=$out" " " + ddInput); @@ -868,24 +868,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 '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 '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 @@ -1099,7 +1102,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( std::string const ddiFile = ppFileName + ".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(), diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 373c693..2ffd256 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -10,6 +10,7 @@ #include "cmNinjaTypes.h" #include "cmOSXBundleGenerator.h" +#include #include #include #include @@ -165,7 +166,7 @@ private: cmLocalNinjaGenerator* LocalGenerator; /// List of object files for this target. cmNinjaDeps Objects; - cmNinjaDeps DDIFiles; // TODO: Make per-language. + std::map DDIFiles; std::vector CustomCommands; cmNinjaDeps ExtraFiles; }; -- cgit v0.12 From 2c0a7bc770367e80ce1fc68ea6cb9c9543e854e4 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 20 Feb 2019 04:57:07 -0500 Subject: ninja: pass language to cmake_ninja_depends --- Source/cmGlobalNinjaGenerator.cxx | 119 ++++++++++++++++++++++++++------------ Source/cmNinjaTargetGenerator.cxx | 6 +- 2 files changed, 85 insertions(+), 40 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 5a85963..74d3e8d 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1574,7 +1574,8 @@ Compilation of source files within a target is split into the following steps: command = gfortran -cpp $DEFINES $INCLUDES $FLAGS -E $in -o $out && cmake -E cmake_ninja_depends \ --tdi=FortranDependInfo.json --pp=$out --dep=$DEP_FILE \ - --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE + --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE \ + --lang=Fortran build src.f90-pp.f90 | src.f90-pp.f90.ddi: Fortran_PREPROCESS src.f90 OBJ_FILE = src.f90.o @@ -1633,6 +1634,19 @@ Compilation of source files within a target is split into the following steps: (because the latter consumes the module). */ +struct cmSourceInfo +{ + // Set of provided and required modules. + std::set Provides; + std::set Requires; + + // Set of files included in the translation unit. + std::set Includes; +}; + +static std::unique_ptr cmcmd_cmake_ninja_depends_fortran( + std::string const& arg_tdi, std::string const& arg_pp); + int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, std::vector::const_iterator argEnd) { @@ -1641,6 +1655,7 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, std::string arg_dep; std::string arg_obj; std::string arg_ddi; + std::string arg_lang; for (std::string const& arg : cmMakeRange(argBeg, argEnd)) { if (cmHasLiteralPrefix(arg, "--tdi=")) { arg_tdi = arg.substr(6); @@ -1652,6 +1667,8 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, arg_obj = arg.substr(6); } else if (cmHasLiteralPrefix(arg, "--ddi=")) { arg_ddi = arg.substr(6); + } else if (cmHasLiteralPrefix(arg, "--lang=")) { + arg_lang = arg.substr(7); } else { cmSystemTools::Error("-E cmake_ninja_depends unknown argument: " + arg); return 1; @@ -1677,7 +1694,61 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, cmSystemTools::Error("-E cmake_ninja_depends requires value for --ddi="); return 1; } + if (arg_lang.empty()) { + cmSystemTools::Error("-E cmake_ninja_depends requires value for --lang="); + return 1; + } + + std::unique_ptr info; + if (arg_lang == "Fortran") { + info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_pp); + } else { + cmSystemTools::Error("-E cmake_ninja_depends does not understand the " + + arg_lang + " language"); + return 1; + } + if (!info) { + // The error message is already expected to have been output. + return 1; + } + + { + cmGeneratedFileStream depfile(arg_dep); + depfile << cmSystemTools::ConvertToUnixOutputPath(arg_pp) << ":"; + for (std::string const& include : info->Includes) { + depfile << " \\\n " << cmSystemTools::ConvertToUnixOutputPath(include); + } + depfile << "\n"; + } + + Json::Value ddi(Json::objectValue); + ddi["object"] = arg_obj; + + Json::Value& ddi_provides = ddi["provides"] = Json::arrayValue; + for (std::string const& provide : info->Provides) { + ddi_provides.append(provide); + } + Json::Value& ddi_requires = ddi["requires"] = Json::arrayValue; + for (std::string const& r : info->Requires) { + // Require modules not provided in the same source. + if (!info->Provides.count(r)) { + ddi_requires.append(r); + } + } + + cmGeneratedFileStream ddif(arg_ddi); + ddif << ddi; + if (!ddif) { + cmSystemTools::Error("-E cmake_ninja_depends failed to write " + arg_ddi); + return 1; + } + return 0; +} + +std::unique_ptr cmcmd_cmake_ninja_depends_fortran( + std::string const& arg_tdi, std::string const& arg_pp) +{ cmFortranCompiler fc; std::vector includes; { @@ -1689,7 +1760,7 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, if (!reader.parse(tdif, tdio, false)) { cmSystemTools::Error("-E cmake_ninja_depends failed to parse " + arg_tdi + reader.getFormattedErrorMessages()); - return 1; + return nullptr; } } @@ -1710,49 +1781,23 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, fc.SModExt = tdi_submodule_ext.asString(); } - cmFortranSourceInfo info; + cmFortranSourceInfo finfo; std::set defines; - cmFortranParser parser(fc, includes, defines, info); + cmFortranParser parser(fc, includes, defines, finfo); if (!cmFortranParser_FilePush(&parser, arg_pp.c_str())) { cmSystemTools::Error("-E cmake_ninja_depends failed to open " + arg_pp); - return 1; + return nullptr; } if (cmFortran_yyparse(parser.Scanner) != 0) { // Failed to parse the file. - return 1; - } - - { - cmGeneratedFileStream depfile(arg_dep); - depfile << cmSystemTools::ConvertToUnixOutputPath(arg_pp) << ":"; - for (std::string const& include : info.Includes) { - depfile << " \\\n " << cmSystemTools::ConvertToUnixOutputPath(include); - } - depfile << "\n"; + return nullptr; } - Json::Value ddi(Json::objectValue); - ddi["object"] = arg_obj; - - Json::Value& ddi_provides = ddi["provides"] = Json::arrayValue; - for (std::string const& provide : info.Provides) { - ddi_provides.append(provide); - } - Json::Value& ddi_requires = ddi["requires"] = Json::arrayValue; - for (std::string const& r : info.Requires) { - // Require modules not provided in the same source. - if (!info.Provides.count(r)) { - ddi_requires.append(r); - } - } - - cmGeneratedFileStream ddif(arg_ddi); - ddif << ddi; - if (!ddif) { - cmSystemTools::Error("-E cmake_ninja_depends failed to write " + arg_ddi); - return 1; - } - return 0; + auto info = cm::make_unique(); + info->Provides = finfo.Provides; + info->Requires = finfo.Requires; + info->Includes = finfo.Includes; + return info; } struct cmDyndepObjectInfo diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 6a08d5c..28d4a07 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -558,7 +558,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" : "")); @@ -1062,8 +1062,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( // In case compilation requires flags that are incompatible with // preprocessing, include them here. - std::string const postFlag = - this->Makefile->GetSafeDefinition("CMAKE_Fortran_POSTPROCESS_FLAG"); + 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. -- cgit v0.12 From 933dd9164210a2f08dae6e1333ab7e5c30e3b012 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 20 Feb 2019 12:13:33 -0500 Subject: ninja: do not assume explicit preprocessing uses that output In Fortran, this is OK, but for C++, compiling preprocessed source generally results in poorer diagnostic messages and can also be ill-formed anyways. --- Source/cmNinjaTargetGenerator.cxx | 78 ++++++++++++++++++++++++++------------- Source/cmNinjaTargetGenerator.h | 1 + 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 28d4a07..4998ac8 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 { @@ -1035,6 +1041,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; @@ -1048,50 +1055,69 @@ 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_" + language + "_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 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 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"); + 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 diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 2ffd256..6a42da0 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -65,6 +65,7 @@ protected: bool NeedExplicitPreprocessing(std::string const& lang) const; std::string LanguageDyndepRule(std::string const& lang) const; bool NeedDyndep(std::string const& lang) const; + bool UsePreprocessedSource(std::string const& lang) const; std::string OrderDependsTargetForTarget(); -- cgit v0.12 From 7c78adca8e0285c198e03163c2bb722cd86b389d Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 20 Feb 2019 01:41:26 -0500 Subject: cmNinjaTargetGenerator: remove "preprocessed" mentions in dyndep Not all languages compile the preprocessed source (or even have preprocessed sources at all). --- Source/cmNinjaTargetGenerator.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 4998ac8..6e140fb 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -594,7 +594,8 @@ 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 + @@ -1121,7 +1122,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( 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. -- cgit v0.12 From f22c18b1c1554b573c684efcb5c921c17c9b0f1d Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 20 Feb 2019 13:20:28 -0500 Subject: ninja: name dyndep internal files using the object file Now that preprocessing outputs are not necessarily used all the way through, the output name is a better base name to use for these files. --- Source/cmGlobalNinjaGenerator.cxx | 8 ++++---- Source/cmNinjaTargetGenerator.cxx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 74d3e8d..d21fd35 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1577,10 +1577,10 @@ Compilation of source files within a target is split into the following steps: --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE \ --lang=Fortran - build src.f90-pp.f90 | src.f90-pp.f90.ddi: Fortran_PREPROCESS src.f90 + build src.f90-pp.f90 | src.f90.o.ddi: Fortran_PREPROCESS src.f90 OBJ_FILE = src.f90.o - DEP_FILE = src.f90-pp.f90.d - DYNDEP_INTERMEDIATE_FILE = src.f90-pp.f90.ddi + DEP_FILE = src.f90.o.d + DYNDEP_INTERMEDIATE_FILE = src.f90.o.ddi The ``cmake -E cmake_ninja_depends`` tool reads the preprocessed output and generates the ninja depfile for preprocessor dependencies. It also @@ -1596,7 +1596,7 @@ Compilation of source files within a target is split into the following steps: command = cmake -E cmake_ninja_dyndep \ --tdi=FortranDependInfo.json --lang=Fortran --dd=$out $in - build Fortran.dd: Fortran_DYNDEP src1.f90-pp.f90.ddi src2.f90-pp.f90.ddi + build Fortran.dd: Fortran_DYNDEP src1.f90.o.ddi src2.f90.o.ddi The ``cmake -E cmake_ninja_dyndep`` tool reads the "ddi" files from all sources in the target and the ``FortranModules.json`` files from targets diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 6e140fb..8d11408 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -1113,7 +1113,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( // Explicit preprocessing always uses a depfile. ppVars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat( - ppFileName + ".d", cmOutputConverter::SHELL); + objectFileName + ".d", cmOutputConverter::SHELL); if (compilePP) { // The actual compilation does not need a depfile because it // depends on the already-preprocessed source. @@ -1126,7 +1126,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( 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[language].push_back(ddiFile); -- cgit v0.12