diff options
author | Ben Boeckel <ben.boeckel@kitware.com> | 2019-02-20 06:39:55 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2019-02-25 15:06:20 (GMT) |
commit | 72f9bb29939f3765216e98e672197b3899d75f7d (patch) | |
tree | c2f564228c8c1d4632ca8d446aba3b16b1c4fc82 /Source | |
parent | 2dd0cb7aeb2d70dcc6e103c29ce2ce3a02bd381a (diff) | |
download | CMake-72f9bb29939f3765216e98e672197b3899d75f7d.zip CMake-72f9bb29939f3765216e98e672197b3899d75f7d.tar.gz CMake-72f9bb29939f3765216e98e672197b3899d75f7d.tar.bz2 |
ninja: make dyndep generation language aware
A target may have multiple languages with dyndep rules, separate `.dd`
files should be generated.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 31 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 21 | ||||
-rw-r--r-- | 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<std::string>::const_iterator argBeg, return 0; } -struct cmFortranObjectInfo +struct cmDyndepObjectInfo { std::string Object; std::vector<std::string> 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<std::string> const& arg_ddis, std::string const& module_dir, - std::vector<std::string> const& linked_target_dirs) + std::vector<std::string> 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<cmFortranObjectInfo> objects; + std::vector<cmDyndepObjectInfo> 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<std::string>::const_iterator argBeg, cmSystemTools::HandleResponseFile(argBeg, argEnd); std::string arg_dd; + std::string arg_lang; std::string arg_tdi; std::vector<std::string> 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<std::string>::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<std::string>::const_iterator argBeg, static_cast<cmGlobalNinjaGenerator*>(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<std::string> const& arg_ddis, std::string const& module_dir, - std::vector<std::string> const& linked_target_dirs); + std::vector<std::string> 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 '<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 @@ -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 <map> #include <set> #include <string> #include <vector> @@ -165,7 +166,7 @@ private: cmLocalNinjaGenerator* LocalGenerator; /// List of object files for this target. cmNinjaDeps Objects; - cmNinjaDeps DDIFiles; // TODO: Make per-language. + std::map<std::string, cmNinjaDeps> DDIFiles; std::vector<cmCustomCommand const*> CustomCommands; cmNinjaDeps ExtraFiles; }; |