summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBen Boeckel <ben.boeckel@kitware.com>2019-02-20 06:39:55 (GMT)
committerBrad King <brad.king@kitware.com>2019-02-25 15:06:20 (GMT)
commit72f9bb29939f3765216e98e672197b3899d75f7d (patch)
treec2f564228c8c1d4632ca8d446aba3b16b1c4fc82 /Source
parent2dd0cb7aeb2d70dcc6e103c29ce2ce3a02bd381a (diff)
downloadCMake-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.cxx31
-rw-r--r--Source/cmGlobalNinjaGenerator.h3
-rw-r--r--Source/cmNinjaTargetGenerator.cxx21
-rw-r--r--Source/cmNinjaTargetGenerator.h3
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;
};