summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalNinjaGenerator.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2021-01-07 13:26:21 (GMT)
committerKitware Robot <kwrobot@kitware.com>2021-01-07 13:26:28 (GMT)
commit05f4248e3d89bf9d779140cf60f511126756ab02 (patch)
tree89ecb61830144a8885b2d7e79841d3d6784a6e23 /Source/cmGlobalNinjaGenerator.cxx
parent520df2880b7f172371de5a6adc6d6ada0e45ac8d (diff)
parent39cbbb59a52c63cd90eebaecea64fd42c3fad1d8 (diff)
downloadCMake-05f4248e3d89bf9d779140cf60f511126756ab02.zip
CMake-05f4248e3d89bf9d779140cf60f511126756ab02.tar.gz
CMake-05f4248e3d89bf9d779140cf60f511126756ab02.tar.bz2
Merge topic 'cpp-modules'
39cbbb59a5 ninja: add experimental infrastructure to generate gcc-format modmap files 791b4d26d6 ninja: add experimental infrastructure to generate modmap files with dyndep 4b23359117 ninja: Add experimental infrastructure for C++20 module dependency scanning f814d3b3c6 cmNinjaTargetGenerator: use $OBJ_FILE for the object b0fc2993e1 Treat the '.mpp' file extension as C++ code 988f997100 cmScanDepFormat: Fix name of our internal tool in parse errors dacd93a2db ninja: De-duplicate version numbers required for ninja features 533386ca29 cmStandardLevelResolver: Factor out helper to capture stoi exceptions Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Ben Boeckel <ben.boeckel@kitware.com> Acked-by: Robert Maynard <robert.maynard@kitware.com> Acked-by: Shannon Booth <shannon.ml.booth@gmail.com> Merge-request: !5562
Diffstat (limited to 'Source/cmGlobalNinjaGenerator.cxx')
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx88
1 files changed, 84 insertions, 4 deletions
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index a95ab25..4f17408 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -555,6 +555,7 @@ void cmGlobalNinjaGenerator::Generate()
this->TargetAll = this->NinjaOutputPath("all");
this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt");
this->DisableCleandead = false;
+ this->DiagnosedCxxModuleSupport = false;
this->PolicyCMP0058 =
this->LocalGenerators[0]->GetMakefile()->GetPolicyStatus(
@@ -755,6 +756,37 @@ bool cmGlobalNinjaGenerator::CheckLanguages(
return true;
}
+bool cmGlobalNinjaGenerator::CheckCxxModuleSupport()
+{
+ bool const diagnose = !this->DiagnosedCxxModuleSupport &&
+ !this->CMakeInstance->GetIsInTryCompile();
+ if (diagnose) {
+ this->DiagnosedCxxModuleSupport = true;
+ this->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP "
+ "is experimental. It is meant only for compiler developers to try.");
+ }
+ if (this->NinjaSupportsDyndeps) {
+ return true;
+ }
+ if (diagnose) {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "The Ninja generator does not support C++20 modules "
+ "using Ninja version \n"
+ " " << this->NinjaVersion << "\n"
+ "due to lack of required features. "
+ "Ninja " << RequiredNinjaVersionForDyndeps() << " or higher is required."
+ ;
+ /* clang-format on */
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ return false;
+}
+
bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
{
if (this->NinjaSupportsDyndeps) {
@@ -766,7 +798,8 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
e <<
"The Ninja generator does not support Fortran using Ninja version\n"
" " << this->NinjaVersion << "\n"
- "due to lack of required features. Ninja 1.10 or higher is required."
+ "due to lack of required features. "
+ "Ninja " << RequiredNinjaVersionForDyndeps() << " or higher is required."
;
/* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
@@ -785,7 +818,9 @@ bool cmGlobalNinjaGenerator::CheckISPC(cmMakefile* mf) const
e <<
"The Ninja generator does not support ISPC using Ninja version\n"
" " << this->NinjaVersion << "\n"
- "due to lack of required features. Ninja 1.10 or higher is required."
+ "due to lack of required features. "
+ "Ninja " << RequiredNinjaVersionForMultipleOutputs() <<
+ " or higher is required."
;
/* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
@@ -2336,7 +2371,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
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::string const& arg_lang)
+ std::string const& arg_lang, std::string const& arg_modmapfmt)
{
// Setup path conversions.
{
@@ -2423,6 +2458,48 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
build.Variables.emplace("restat", "1");
}
+ if (arg_modmapfmt.empty()) {
+ // nothing to do.
+ } else {
+ std::stringstream mm;
+ if (arg_modmapfmt == "gcc") {
+ // Documented in GCC's documentation. The format is a series of lines
+ // with a module name and the associated filename separated by
+ // spaces. The first line may use `$root` as the module name to
+ // specify a "repository root". That is used to anchor any relative
+ // paths present in the file (CMake should never generate any).
+
+ // Write the root directory to use for module paths.
+ mm << "$root .\n";
+
+ for (auto const& l : object.Provides) {
+ auto m = mod_files.find(l.LogicalName);
+ if (m != mod_files.end()) {
+ mm << l.LogicalName << " " << this->ConvertToNinjaPath(m->second)
+ << "\n";
+ }
+ }
+ for (auto const& r : object.Requires) {
+ auto m = mod_files.find(r.LogicalName);
+ if (m != mod_files.end()) {
+ mm << r.LogicalName << " " << this->ConvertToNinjaPath(m->second)
+ << "\n";
+ }
+ }
+ } else {
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep does not understand the ",
+ arg_modmapfmt, " module map format"));
+ return false;
+ }
+
+ // XXX(modmap): If changing this path construction, change
+ // `cmNinjaTargetGenerator::WriteObjectBuildStatements` to generate the
+ // corresponding file path.
+ cmGeneratedFileStream mmf(cmStrCat(object.PrimaryOutput, ".modmap"));
+ mmf << mm.str();
+ }
+
this->WriteBuild(ddf, build);
}
}
@@ -2446,6 +2523,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
std::string arg_dd;
std::string arg_lang;
std::string arg_tdi;
+ std::string arg_modmapfmt;
std::vector<std::string> arg_ddis;
for (std::string const& arg : arg_full) {
if (cmHasLiteralPrefix(arg, "--tdi=")) {
@@ -2454,6 +2532,8 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
arg_lang = arg.substr(7);
} else if (cmHasLiteralPrefix(arg, "--dd=")) {
arg_dd = arg.substr(5);
+ } else if (cmHasLiteralPrefix(arg, "--modmapfmt=")) {
+ arg_modmapfmt = arg.substr(12);
} else if (!cmHasLiteralPrefix(arg, "--") &&
cmHasLiteralSuffix(arg, ".ddi")) {
arg_ddis.push_back(arg);
@@ -2512,7 +2592,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
if (!ggd ||
!cm::static_reference_cast<cmGlobalNinjaGenerator>(ggd).WriteDyndepFile(
dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld, arg_dd, arg_ddis,
- module_dir, linked_target_dirs, arg_lang)) {
+ module_dir, linked_target_dirs, arg_lang, arg_modmapfmt)) {
return 1;
}
return 0;