Merge topic 'module-mapper-clang-transitive'

57ef353d22 cmExperimental: refresh the C++ modules UUID
7b05724ac8 cmCxxModuleMapper: give transitive usages to Clang as well
c9df4568da cmCxxModuleMapper: factor out transitive usage computation
71f1483aac Tests/RunCMake/CXXModules: require transitive usages
e39b6ebc19 cmCxxModuleMapper: use a `char` for streaming single bytes

Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !8610
This commit is contained in:
Brad King
2023-07-14 12:39:27 +00:00
committed by Kitware Robot
15 changed files with 87 additions and 52 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ C++20 Module APIs
=================
Variable: ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
Value: ``aa1f7df0-828a-4fcd-9afc-2dc80491aca7``
Value: ``bf70d4b0-9fb7-465c-9803-34014e70d112``
In order to support C++20 modules, there are a number of behaviors that have
CMake APIs to provide the required features to build and export them from a
+66 -39
View File
@@ -74,8 +74,62 @@ CxxBmiLocation CxxModuleLocations::BmiGeneratorPathForModule(
namespace {
struct TransitiveUsage
{
TransitiveUsage(std::string name, std::string location, LookupMethod method)
: LogicalName(std::move(name))
, Location(std::move(location))
, Method(method)
{
}
std::string LogicalName;
std::string Location;
LookupMethod Method;
};
std::vector<TransitiveUsage> GetTransitiveUsages(
CxxModuleLocations const& loc, std::vector<cmSourceReqInfo> const& required,
CxxModuleUsage const& usages)
{
std::set<std::string> transitive_usage_directs;
std::set<std::string> transitive_usage_names;
std::vector<TransitiveUsage> all_usages;
for (auto const& r : required) {
auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName);
if (bmi_loc.IsKnown()) {
all_usages.emplace_back(r.LogicalName, bmi_loc.Location(), r.Method);
transitive_usage_directs.insert(r.LogicalName);
// Insert transitive usages.
auto transitive_usages = usages.Usage.find(r.LogicalName);
if (transitive_usages != usages.Usage.end()) {
transitive_usage_names.insert(transitive_usages->second.begin(),
transitive_usages->second.end());
}
}
}
for (auto const& transitive_name : transitive_usage_names) {
if (transitive_usage_directs.count(transitive_name)) {
continue;
}
auto module_ref = usages.Reference.find(transitive_name);
if (module_ref != usages.Reference.end()) {
all_usages.emplace_back(transitive_name, module_ref->second.Path,
module_ref->second.Method);
}
}
return all_usages;
}
std::string CxxModuleMapContentClang(CxxModuleLocations const& loc,
cmScanDepInfo const& obj)
cmScanDepInfo const& obj,
CxxModuleUsage const& usages)
{
std::stringstream mm;
@@ -98,12 +152,11 @@ std::string CxxModuleMapContentClang(CxxModuleLocations const& loc,
break;
}
}
for (auto const& r : obj.Requires) {
auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName);
if (bmi_loc.IsKnown()) {
mm << "-fmodule-file=" << r.LogicalName << "=" << bmi_loc.Location()
<< '\n';
}
auto all_usages = GetTransitiveUsages(loc, obj.Requires, usages);
for (auto const& usage : all_usages) {
mm << "-fmodule-file=" << usage.LogicalName << '=' << usage.Location
<< '\n';
}
return mm.str();
@@ -122,7 +175,7 @@ std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc,
// generate any).
// Write the root directory to use for module paths.
mm << "$root " << loc.RootDirectory << "\n";
mm << "$root " << loc.RootDirectory << '\n';
for (auto const& p : obj.Provides) {
auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName);
@@ -180,37 +233,11 @@ std::string CxxModuleMapContentMsvc(CxxModuleLocations const& loc,
}
}
std::set<std::string> transitive_usage_directs;
std::set<std::string> transitive_usage_names;
auto all_usages = GetTransitiveUsages(loc, obj.Requires, usages);
for (auto const& usage : all_usages) {
auto flag = flag_for_method(usage.Method);
for (auto const& r : obj.Requires) {
auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName);
if (bmi_loc.IsKnown()) {
auto flag = flag_for_method(r.Method);
mm << flag << ' ' << r.LogicalName << '=' << bmi_loc.Location() << "\n";
transitive_usage_directs.insert(r.LogicalName);
// Insert transitive usages.
auto transitive_usages = usages.Usage.find(r.LogicalName);
if (transitive_usages != usages.Usage.end()) {
transitive_usage_names.insert(transitive_usages->second.begin(),
transitive_usages->second.end());
}
}
}
for (auto const& transitive_name : transitive_usage_names) {
if (transitive_usage_directs.count(transitive_name)) {
continue;
}
auto module_ref = usages.Reference.find(transitive_name);
if (module_ref != usages.Reference.end()) {
auto flag = flag_for_method(module_ref->second.Method);
mm << flag << ' ' << transitive_name << '=' << module_ref->second.Path
<< "\n";
}
mm << flag << ' ' << usage.LogicalName << '=' << usage.Location << '\n';
}
return mm.str();
@@ -393,7 +420,7 @@ std::string CxxModuleMapContent(CxxModuleMapFormat format,
{
switch (format) {
case CxxModuleMapFormat::Clang:
return CxxModuleMapContentClang(loc, obj);
return CxxModuleMapContentClang(loc, obj, usages);
case CxxModuleMapFormat::Gcc:
return CxxModuleMapContentGcc(loc, obj);
case CxxModuleMapFormat::Msvc:
+1 -1
View File
@@ -27,7 +27,7 @@ struct FeatureData
bool Warned;
} LookupTable[] = {
// CxxModuleCMakeApi
{ "aa1f7df0-828a-4fcd-9afc-2dc80491aca7",
{ "bf70d4b0-9fb7-465c-9803-34014e70d112",
"CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API",
"CMake's C++ module support is experimental. It is meant only for "
"experimentation and feedback to CMake developers.",
+1 -1
View File
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.23)
project(${RunCMake_TEST} NONE)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
include(${RunCMake_TEST}.cmake)
@@ -1,4 +1,4 @@
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
if (NOT EXISTS "${CMake_TEST_MODULE_COMPILATION_RULES}")
message(FATAL_ERROR
@@ -1,4 +1,4 @@
CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
CMake Warning \(dev\) at CMakeLists.txt:15 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
@@ -3,6 +3,14 @@ project(cxx_modules_deep_chain CXX)
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
include(CheckCompilerFlag)
check_compiler_flag(CXX "-Wread-modules-implicitly" have_implicit_module_warning)
if (have_implicit_module_warning)
add_compile_options(-Werror=read-modules-implicitly)
endif ()
endif ()
add_library(a STATIC)
target_sources(a
PUBLIC
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
find_package(export_bmi_and_interfaces REQUIRED)
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
find_package(export_bmi_and_interfaces REQUIRED)
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
find_package(export_interfaces REQUIRED)
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
find_package(export_interfaces REQUIRED)
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
find_package(export_interfaces_no_properties REQUIRED)
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library NONE)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
find_package(export_interfaces_no_properties REQUIRED)
@@ -1,6 +1,6 @@
enable_language(C)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
add_library(lib1 STATIC empty.c)
target_sources(lib1 PRIVATE FILE_SET UNKNOWN)
@@ -1,6 +1,6 @@
enable_language(C)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "bf70d4b0-9fb7-465c-9803-34014e70d112")
add_library(lib1 STATIC empty.c)
target_sources(lib1 PRIVATE FILE_SET a TYPE UNKNOWN)