cmNinjaTargetGenerator: write out export information for the collator

The collator will use this to know where the target's export information
needs to go so that module properties may be provided.
This commit is contained in:
Ben Boeckel
2022-04-19 10:49:29 -04:00
parent d3e2e61bcd
commit 95402a0bd7
9 changed files with 356 additions and 0 deletions
+79
View File
@@ -21,12 +21,16 @@
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
#include "cmExportBuildFileGenerator.h"
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmInstallExportGenerator.h"
#include "cmInstallFileSetGenerator.h"
#include "cmInstallGenerator.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
@@ -42,6 +46,7 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
#include "cmValue.h"
#include "cmake.h"
@@ -1752,6 +1757,80 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
}
}
tdi["config"] = config;
// Add information about the export sets that this target is a member of.
Json::Value& tdi_exports = tdi["exports"] = Json::arrayValue;
std::string export_name = this->GeneratorTarget->GetExportName();
auto const& all_install_exports =
this->GetGlobalGenerator()->GetExportSets();
for (auto const& exp : all_install_exports) {
// Ignore exports sets which are not for this target.
auto const& targets = exp.second.GetTargetExports();
auto tgt_export =
std::find_if(targets.begin(), targets.end(),
[this](std::unique_ptr<cmTargetExport> const& te) {
return te->Target == this->GeneratorTarget;
});
if (tgt_export == targets.end()) {
continue;
}
auto const* installs = exp.second.GetInstallations();
for (auto const* install : *installs) {
Json::Value tdi_export_info = Json::objectValue;
auto const& ns = install->GetNamespace();
auto const& dest = install->GetDestination();
auto const& cxxm_dir = install->GetCxxModuleDirectory();
auto const& export_prefix = install->GetTempDir();
tdi_export_info["namespace"] = ns;
tdi_export_info["export-name"] = export_name;
tdi_export_info["destination"] = dest;
tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
tdi_export_info["export-prefix"] = export_prefix;
tdi_export_info["install"] = true;
tdi_exports.append(tdi_export_info);
}
}
auto const& all_build_exports =
this->GetMakefile()->GetExportBuildFileGenerators();
for (auto const& exp : all_build_exports) {
std::vector<std::string> targets;
exp->GetTargets(targets);
// Ignore exports sets which are not for this target.
auto const& name = this->GeneratorTarget->GetName();
bool has_current_target =
std::any_of(targets.begin(), targets.end(),
[name](std::string const& tname) { return tname == name; });
if (!has_current_target) {
continue;
}
Json::Value tdi_export_info = Json::objectValue;
auto const& ns = exp->GetNamespace();
auto const& main_fn = exp->GetMainExportFileName();
auto const& cxxm_dir = exp->GetCxxModuleDirectory();
auto dest = cmsys::SystemTools::GetParentDirectory(main_fn);
auto const& export_prefix =
cmSystemTools::GetFilenamePath(exp->GetMainExportFileName());
tdi_export_info["namespace"] = ns;
tdi_export_info["export-name"] = export_name;
tdi_export_info["destination"] = dest;
tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
tdi_export_info["export-prefix"] = export_prefix;
tdi_export_info["install"] = false;
tdi_exports.append(tdi_export_info);
}
std::string const tdin = this->GetTargetDependInfoPath(lang, config);
cmGeneratedFileStream tdif(tdin);
tdif << tdi;
@@ -0,0 +1,34 @@
include("${CMAKE_CURRENT_LIST_DIR}/check-json.cmake")
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(have_file 0)
foreach (config IN ITEMS Release Debug RelWithDebInfo MinSizeRel)
if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-public.dir/${config}/CXXDependInfo.json")
continue ()
endif ()
set(have_file 1)
set(CMAKE_BUILD_TYPE "${config}")
file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-public.dir/${config}/CXXDependInfo.json" actual_contents)
file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoExport-public.json" expect_contents)
check_json("${actual_contents}" "${expect_contents}")
file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-private.dir/${config}/CXXDependInfo.json" actual_contents)
file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoExport-private.json" expect_contents)
check_json("${actual_contents}" "${expect_contents}")
endforeach ()
if (NOT have_file)
list(APPEND RunCMake_TEST_FAILED
"No recognized build configurations found.")
endif ()
else ()
file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-public.dir/CXXDependInfo.json" actual_contents)
file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoExport-public.json" expect_contents)
check_json("${actual_contents}" "${expect_contents}")
file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-private.dir/CXXDependInfo.json" actual_contents)
file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoExport-private.json" expect_contents)
check_json("${actual_contents}" "${expect_contents}")
endif ()
@@ -0,0 +1,11 @@
CMake Warning \(dev\) at NinjaDependInfoExport.cmake:14 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
Call Stack \(most recent call first\):
CMakeLists.txt:6 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\):
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
experimental. It is meant only for compiler developers to try.
This warning is for project developers. Use -Wno-dev to suppress it.
@@ -0,0 +1,85 @@
# Fake out that we have dyndep; we only need to generate, not actually build
# here.
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
enable_language(CXX)
if (NOT CMAKE_GENERATOR MATCHES "Ninja")
message(FATAL_ERROR
"This test requires a 'Ninja' generator to be used.")
endif ()
add_library(ninja-exports-public)
target_sources(ninja-exports-public
PRIVATE
sources/module-impl.cxx
sources/module-internal-part-impl.cxx
sources/module-part-impl.cxx
sources/module-use.cxx
PUBLIC
FILE_SET modules TYPE CXX_MODULES
BASE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/sources"
FILES
sources/module.cxx
sources/module-part.cxx
FILE_SET internal_partitions TYPE CXX_MODULES FILES
sources/module-internal-part.cxx)
target_compile_features(ninja-exports-public
PRIVATE
cxx_std_20)
set_property(TARGET ninja-exports-public
PROPERTY EXPORT_NAME "with-public")
install(TARGETS ninja-exports-public
EXPORT exp
FILE_SET modules
DESTINATION "lib/cxx"
COMPONENT "modules"
FILE_SET internal_partitions
DESTINATION "lib/cxx/internals"
COMPONENT "modules-internal")
add_library(ninja-exports-private)
target_sources(ninja-exports-private
PRIVATE
sources/module-impl.cxx
sources/module-internal-part-impl.cxx
sources/module-part-impl.cxx
sources/module-use.cxx
PRIVATE
FILE_SET modules TYPE CXX_MODULES
BASE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/sources"
FILES
sources/module.cxx
sources/module-part.cxx
FILE_SET internal_partitions TYPE CXX_MODULES FILES
sources/module-internal-part.cxx)
target_compile_features(ninja-exports-private
PRIVATE
cxx_std_20)
set_property(TARGET ninja-exports-private
PROPERTY EXPORT_NAME "with-private")
install(TARGETS ninja-exports-private
EXPORT exp)
# Test multiple build exports.
export(EXPORT exp
FILE "${CMAKE_BINARY_DIR}/lib/cmake/export1/export1-targets.cmake"
NAMESPACE export1::
CXX_MODULES_DIRECTORY "cxx-modules")
export(EXPORT exp
FILE "${CMAKE_BINARY_DIR}/lib/cmake/export2/export2-targets.cmake"
CXX_MODULES_DIRECTORY "cxx-modules")
# Test multiple install exports.
install(EXPORT exp
DESTINATION "lib/cmake/export1"
NAMESPACE export1::
CXX_MODULES_DIRECTORY "cxx-modules")
install(EXPORT exp
DESTINATION "lib/cmake/export2"
CXX_MODULES_DIRECTORY "cxx-modules")
@@ -77,6 +77,7 @@ run_cmake(ExportInstallCxxModules)
# Generator-specific tests.
if (RunCMake_GENERATOR MATCHES "Ninja")
run_cmake(NinjaDependInfoFileSet)
run_cmake(NinjaDependInfoExport)
else ()
message(FATAL_ERROR
"Please add 'DependInfo' tests for the '${RunCMake_GENERATOR}' generator.")
@@ -0,0 +1,72 @@
{
"compiler-id": "<IGNORE>",
"config": "<CONFIG>",
"cxx-modules": {
"CMakeFiles/ninja-exports-private.dir/sources/module-internal-part.cxx.o": {
"destination": null,
"name": "internal_partitions",
"relative-directory": "sources",
"source": "<SOURCE_DIR>/sources/module-internal-part.cxx",
"type": "CXX_MODULES",
"visibility": "PRIVATE"
},
"CMakeFiles/ninja-exports-private.dir/sources/module-part.cxx.o": {
"destination": null,
"name": "modules",
"relative-directory": "",
"source": "<SOURCE_DIR>/sources/module-part.cxx",
"type": "CXX_MODULES",
"visibility": "PRIVATE"
},
"CMakeFiles/ninja-exports-private.dir/sources/module.cxx.o": {
"destination": null,
"name": "modules",
"relative-directory": "",
"source": "<SOURCE_DIR>/sources/module.cxx",
"type": "CXX_MODULES",
"visibility": "PRIVATE"
}
},
"dir-cur-bld": "<BINARY_DIR>",
"dir-cur-src": "<SOURCE_DIR>",
"dir-top-bld": "<BINARY_DIR>",
"dir-top-src": "<SOURCE_DIR>",
"exports": [
{
"cxx-module-info-dir" : "cxx-modules",
"destination" : "lib/cmake/export1",
"export-name" : "with-private",
"export-prefix" : "<BINARY_DIR>/CMakeFiles/Export/d2e2673818fd2bd8c45c0e3ed0e38fcd",
"install" : true,
"namespace" : "export1::"
},
{
"cxx-module-info-dir" : "cxx-modules",
"destination" : "lib/cmake/export2",
"export-name" : "with-private",
"export-prefix" : "<BINARY_DIR>/CMakeFiles/Export/28cd47cb4c96ad5cadaa3fb1b0201ae8",
"install" : true,
"namespace" : ""
},
{
"cxx-module-info-dir" : "cxx-modules",
"destination" : "<BINARY_DIR>/lib/cmake/export1",
"export-name" : "with-private",
"export-prefix" : "<BINARY_DIR>/lib/cmake/export1",
"install" : false,
"namespace" : "export1::"
},
{
"cxx-module-info-dir" : "cxx-modules",
"destination" : "<BINARY_DIR>/lib/cmake/export2",
"export-name" : "with-private",
"export-prefix" : "<BINARY_DIR>/lib/cmake/export2",
"install" : false,
"namespace" : ""
}
],
"include-dirs": [],
"language": "CXX",
"linked-target-dirs": [],
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-exports-private.dir"
}
@@ -0,0 +1,72 @@
{
"compiler-id": "<IGNORE>",
"config": "<CONFIG>",
"cxx-modules": {
"CMakeFiles/ninja-exports-public.dir/sources/module-internal-part.cxx.o": {
"destination": "lib/cxx/internals",
"name": "internal_partitions",
"relative-directory": "sources",
"source": "<SOURCE_DIR>/sources/module-internal-part.cxx",
"type": "CXX_MODULES",
"visibility": "PUBLIC"
},
"CMakeFiles/ninja-exports-public.dir/sources/module-part.cxx.o": {
"destination": "lib/cxx",
"name": "modules",
"relative-directory": "",
"source": "<SOURCE_DIR>/sources/module-part.cxx",
"type": "CXX_MODULES",
"visibility": "PUBLIC"
},
"CMakeFiles/ninja-exports-public.dir/sources/module.cxx.o": {
"destination": "lib/cxx",
"name": "modules",
"relative-directory": "",
"source": "<SOURCE_DIR>/sources/module.cxx",
"type": "CXX_MODULES",
"visibility": "PUBLIC"
}
},
"dir-cur-bld": "<BINARY_DIR>",
"dir-cur-src": "<SOURCE_DIR>",
"dir-top-bld": "<BINARY_DIR>",
"dir-top-src": "<SOURCE_DIR>",
"exports": [
{
"cxx-module-info-dir" : "cxx-modules",
"destination" : "lib/cmake/export1",
"export-name" : "with-public",
"export-prefix" : "<BINARY_DIR>/CMakeFiles/Export/d2e2673818fd2bd8c45c0e3ed0e38fcd",
"install" : true,
"namespace" : "export1::"
},
{
"cxx-module-info-dir" : "cxx-modules",
"destination" : "lib/cmake/export2",
"export-name" : "with-public",
"export-prefix" : "<BINARY_DIR>/CMakeFiles/Export/28cd47cb4c96ad5cadaa3fb1b0201ae8",
"install" : true,
"namespace" : ""
},
{
"cxx-module-info-dir" : "cxx-modules",
"destination" : "<BINARY_DIR>/lib/cmake/export1",
"export-name" : "with-public",
"export-prefix" : "<BINARY_DIR>/lib/cmake/export1",
"install" : false,
"namespace" : "export1::"
},
{
"cxx-module-info-dir" : "cxx-modules",
"destination" : "<BINARY_DIR>/lib/cmake/export2",
"export-name" : "with-public",
"export-prefix" : "<BINARY_DIR>/lib/cmake/export2",
"install" : false,
"namespace" : ""
}
],
"include-dirs": [],
"language": "CXX",
"linked-target-dirs": [],
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-exports-public.dir"
}
@@ -31,6 +31,7 @@
"dir-cur-src": "<SOURCE_DIR>",
"dir-top-bld": "<BINARY_DIR>",
"dir-top-src": "<SOURCE_DIR>",
"exports": [],
"include-dirs": [],
"language": "CXX",
"linked-target-dirs": [],
@@ -31,6 +31,7 @@
"dir-cur-src": "<SOURCE_DIR>",
"dir-top-bld": "<BINARY_DIR>",
"dir-top-src": "<SOURCE_DIR>",
"exports": [],
"include-dirs": [],
"language": "CXX",
"linked-target-dirs": [],