ninja: add experimental infrastructure to generate gcc-format modmap files

This commit is contained in:
Ben Boeckel
2019-03-12 15:36:12 -04:00
committed by Brad King
parent 791b4d26d6
commit 39cbbb59a5
2 changed files with 44 additions and 1 deletions

View File

@@ -45,6 +45,26 @@ Compiler writers may try out their scanning functionality using
the `cxx-modules-sandbox`_ test project, modified to set variables
as above for their compiler.
For compilers that generate module maps, tell CMake as follows:
.. code-block:: cmake
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG
"${compiler_flags_for_module_map} -fmodule-mapper=<MODULE_MAP_FILE>")
Currently, the only supported format is ``gcc``. The format is described in
the GCC documentation, but the relevant section for the purposes of CMake is:
A mapping file consisting of space-separated module-name, filename
pairs, one per line. Only the mappings for the direct imports and any
module export name need be provided. If other mappings are provided,
they override those stored in any imported CMI files. A repository
root may be specified in the mapping file by using ``$root`` as the
module name in the first active line.
-- GCC module mapper documentation
.. _`D1483r1`: https://mathstuf.fedorapeople.org/fortran-modules/fortran-modules.html
.. _`P1689r3`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1689r3.html
.. _`cxx-modules-sandbox`: https://github.com/mathstuf/cxx-modules-sandbox

View File

@@ -2460,7 +2460,30 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
// nothing to do.
} else {
std::stringstream mm;
if (false) {
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 ",