cmGlobalNinjaGenerator: use cmModuleMapper implementation

This commit is contained in:
Ben Boeckel
2022-06-02 17:22:57 -04:00
parent b43bdaff3c
commit 4151547e2f

View File

@@ -5,6 +5,7 @@
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <functional>
#include <sstream>
#include <utility>
@@ -21,6 +22,7 @@
#include "cmsys/FStream.hxx"
#include "cmCxxModuleMapper.h"
#include "cmDocumentationEntry.h"
#include "cmFortranParser.h"
#include "cmGeneratedFileStream.h"
@@ -2534,11 +2536,20 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
}
}
const char* module_ext = "";
if (arg_modmapfmt == "gcc") {
module_ext = ".gcm";
cm::optional<CxxModuleMapFormat> modmap_fmt;
if (arg_modmapfmt.empty()) {
// nothing to do.
} else if (arg_modmapfmt == "gcc") {
modmap_fmt = CxxModuleMapFormat::Gcc;
} else {
cmSystemTools::Error(
cmStrCat("-E cmake_ninja_dyndep does not understand the ", arg_modmapfmt,
" module map format"));
return false;
}
auto module_ext = CxxModuleMapExtension(modmap_fmt);
// Extend the module map with those provided by this target.
// We do this after loading the modules provided by linked targets
// in case we have one of the same name that must be preferred.
@@ -2569,6 +2580,20 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
ddf << "ninja_dyndep_version = 1.0\n";
{
CxxModuleLocations locs;
locs.RootDirectory = ".";
locs.PathForGenerator = [this](std::string const& path) -> std::string {
return this->ConvertToNinjaPath(path);
};
locs.BmiLocationForModule =
[&mod_files](std::string const& logical) -> cm::optional<std::string> {
auto m = mod_files.find(logical);
if (m != mod_files.end()) {
return m->second;
}
return {};
};
cmNinjaBuild build("dyndep");
build.Outputs.emplace_back("");
for (cmScanDepInfo const& object : objects) {
@@ -2590,46 +2615,14 @@ 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;
}
if (modmap_fmt) {
auto mm = CxxModuleMapContent(*modmap_fmt, locs, object);
// 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();
mmf << mm;
}
this->WriteBuild(ddf, build);