mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-04 12:49:36 -06:00
cmNinjaTargetGenerator: write out fileset information for the collator
The collator will use this to generate property settings for the imported targets in the build and install export sets.
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalNinjaGenerator.h"
|
||||
#include "cmInstallFileSetGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmLocalNinjaGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
@@ -1653,6 +1654,104 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
|
||||
tdi_linked_target_dirs.append(l);
|
||||
}
|
||||
|
||||
cmTarget* tgt = this->GeneratorTarget->Target;
|
||||
auto all_file_sets = tgt->GetAllFileSetNames();
|
||||
Json::Value& tdi_cxx_module_info = tdi["cxx-modules"] = Json::objectValue;
|
||||
for (auto const& file_set_name : all_file_sets) {
|
||||
auto* file_set = tgt->GetFileSet(file_set_name);
|
||||
if (!file_set) {
|
||||
this->GetMakefile()->IssueMessage(
|
||||
MessageType::INTERNAL_ERROR,
|
||||
cmStrCat("Target \"", tgt->GetName(),
|
||||
"\" is tracked to have file set \"", file_set_name,
|
||||
"\", but it was not found."));
|
||||
continue;
|
||||
}
|
||||
auto fs_type = file_set->GetType();
|
||||
// We only care about C++ module sources here.
|
||||
if (fs_type != "CXX_MODULES"_s) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fileEntries = file_set->CompileFileEntries();
|
||||
auto directoryEntries = file_set->CompileDirectoryEntries();
|
||||
|
||||
auto directories = file_set->EvaluateDirectoryEntries(
|
||||
directoryEntries, this->GeneratorTarget->LocalGenerator, config,
|
||||
this->GeneratorTarget);
|
||||
std::map<std::string, std::vector<std::string>> files_per_dirs;
|
||||
for (auto const& entry : fileEntries) {
|
||||
file_set->EvaluateFileEntry(directories, files_per_dirs, entry,
|
||||
this->GeneratorTarget->LocalGenerator,
|
||||
config, this->GeneratorTarget);
|
||||
}
|
||||
|
||||
std::map<std::string, cmSourceFile const*> sf_map;
|
||||
{
|
||||
std::vector<cmSourceFile const*> objectSources;
|
||||
this->GeneratorTarget->GetObjectSources(objectSources, config);
|
||||
for (auto const* sf : objectSources) {
|
||||
auto full_path = sf->GetFullPath();
|
||||
if (full_path.empty()) {
|
||||
this->GetMakefile()->IssueMessage(
|
||||
MessageType::INTERNAL_ERROR,
|
||||
cmStrCat("Target \"", tgt->GetName(),
|
||||
"\" has a full path-less source file."));
|
||||
continue;
|
||||
}
|
||||
sf_map[full_path] = sf;
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value fs_dest = Json::nullValue;
|
||||
for (auto const& ig : this->GetMakefile()->GetInstallGenerators()) {
|
||||
if (auto const* fsg =
|
||||
dynamic_cast<cmInstallFileSetGenerator const*>(ig.get())) {
|
||||
if (fsg->GetTarget() == this->GeneratorTarget &&
|
||||
fsg->GetFileSet() == file_set) {
|
||||
fs_dest = fsg->GetDestination(config);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& files_per_dir : files_per_dirs) {
|
||||
for (auto const& file : files_per_dir.second) {
|
||||
auto lookup = sf_map.find(file);
|
||||
if (lookup == sf_map.end()) {
|
||||
this->GetMakefile()->IssueMessage(
|
||||
MessageType::INTERNAL_ERROR,
|
||||
cmStrCat("Target \"", tgt->GetName(), "\" has source file \"",
|
||||
file,
|
||||
R"(" which is not in any of its "FILE_SET BASE_DIRS".)"));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto const* sf = lookup->second;
|
||||
|
||||
if (!sf) {
|
||||
this->GetMakefile()->IssueMessage(
|
||||
MessageType::INTERNAL_ERROR,
|
||||
cmStrCat("Target \"", tgt->GetName(), "\" has source file \"",
|
||||
file, "\" which has not been tracked properly."));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto obj_path = this->GetObjectFilePath(sf, config);
|
||||
Json::Value& tdi_module_info = tdi_cxx_module_info[obj_path] =
|
||||
Json::objectValue;
|
||||
|
||||
tdi_module_info["source"] = file;
|
||||
tdi_module_info["relative-directory"] = files_per_dir.first;
|
||||
tdi_module_info["name"] = file_set->GetName();
|
||||
tdi_module_info["type"] = file_set->GetType();
|
||||
tdi_module_info["visibility"] =
|
||||
std::string(cmFileSetVisibilityToName(file_set->GetVisibility()));
|
||||
tdi_module_info["destination"] = fs_dest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string const tdin = this->GetTargetDependInfoPath(lang, config);
|
||||
cmGeneratedFileStream tdif(tdin);
|
||||
tdif << tdi;
|
||||
|
||||
34
Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-check.cmake
Normal file
34
Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-check.cmake
Normal file
@@ -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-file-sets-public.dir/${config}/CXXDependInfo.json")
|
||||
continue ()
|
||||
endif ()
|
||||
set(have_file 1)
|
||||
|
||||
set(CMAKE_BUILD_TYPE "${config}")
|
||||
|
||||
file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-file-sets-public.dir/${config}/CXXDependInfo.json" actual_contents)
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoFileSet-public.json" expect_contents)
|
||||
check_json("${actual_contents}" "${expect_contents}")
|
||||
|
||||
file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-file-sets-private.dir/${config}/CXXDependInfo.json" actual_contents)
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoFileSet-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-file-sets-public.dir/CXXDependInfo.json" actual_contents)
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoFileSet-public.json" expect_contents)
|
||||
check_json("${actual_contents}" "${expect_contents}")
|
||||
|
||||
file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-file-sets-private.dir/CXXDependInfo.json" actual_contents)
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoFileSet-private.json" expect_contents)
|
||||
check_json("${actual_contents}" "${expect_contents}")
|
||||
endif ()
|
||||
11
Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-stderr.txt
Normal file
11
Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-stderr.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
CMake Warning \(dev\) at NinjaDependInfoFileSet.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.
|
||||
59
Tests/RunCMake/CXXModules/NinjaDependInfoFileSet.cmake
Normal file
59
Tests/RunCMake/CXXModules/NinjaDependInfoFileSet.cmake
Normal file
@@ -0,0 +1,59 @@
|
||||
# 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-file-sets-public)
|
||||
target_sources(ninja-file-sets-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-file-sets-public
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
|
||||
install(TARGETS ninja-file-sets-public
|
||||
FILE_SET modules
|
||||
DESTINATION "lib/cxx"
|
||||
COMPONENT "modules"
|
||||
FILE_SET internal_partitions
|
||||
DESTINATION "lib/cxx/internals"
|
||||
COMPONENT "modules-internal")
|
||||
|
||||
add_library(ninja-file-sets-private)
|
||||
target_sources(ninja-file-sets-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-file-sets-private
|
||||
PRIVATE
|
||||
cxx_std_20)
|
||||
@@ -74,6 +74,14 @@ run_cmake(InstallBMIIgnore)
|
||||
run_cmake(ExportBuildCxxModules)
|
||||
run_cmake(ExportInstallCxxModules)
|
||||
|
||||
# Generator-specific tests.
|
||||
if (RunCMake_GENERATOR MATCHES "Ninja")
|
||||
run_cmake(NinjaDependInfoFileSet)
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"Please add 'DependInfo' tests for the '${RunCMake_GENERATOR}' generator.")
|
||||
endif ()
|
||||
|
||||
# Actual compilation tests.
|
||||
if (NOT CMake_TEST_MODULE_COMPILATION)
|
||||
return ()
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"compiler-id": "<IGNORE>",
|
||||
"config": "<CONFIG>",
|
||||
"cxx-modules": {
|
||||
"CMakeFiles/ninja-file-sets-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-file-sets-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-file-sets-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>",
|
||||
"include-dirs": [],
|
||||
"language": "CXX",
|
||||
"linked-target-dirs": [],
|
||||
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-file-sets-private.dir"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"compiler-id": "<IGNORE>",
|
||||
"config": "<CONFIG>",
|
||||
"cxx-modules": {
|
||||
"CMakeFiles/ninja-file-sets-public.dir/<CONFIG_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-file-sets-public.dir/<CONFIG_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-file-sets-public.dir/<CONFIG_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>",
|
||||
"include-dirs": [],
|
||||
"language": "CXX",
|
||||
"linked-target-dirs": [],
|
||||
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-file-sets-public.dir"
|
||||
}
|
||||
Reference in New Issue
Block a user