From 1690e451f7a640fbdd7bc693ea8010ebc52639bc Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sun, 23 Jul 2023 13:36:53 -0400 Subject: cmGeneratorTarget: support better errors when checking for C++20 modules Some callers have their own error reporting mechanisms which give more context. Support handing off the error string for these use cases. --- Source/cmGeneratorTarget.cxx | 36 ++++++++++++++++++++---------------- Source/cmGeneratorTarget.h | 5 ++++- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index eb4ba90..c6b2718 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -8930,24 +8930,28 @@ bool cmGeneratorTarget::HaveFortranSources(std::string const& config) const }); } -bool cmGeneratorTarget::HaveCxx20ModuleSources() const +bool cmGeneratorTarget::HaveCxx20ModuleSources(std::string* errorMessage) const { auto const& fs_names = this->Target->GetAllFileSetNames(); - return std::any_of(fs_names.begin(), fs_names.end(), - [this](std::string const& name) -> bool { - auto const* file_set = this->Target->GetFileSet(name); - if (!file_set) { - this->Makefile->IssueMessage( - MessageType::INTERNAL_ERROR, - cmStrCat("Target \"", this->Target->GetName(), - "\" is tracked to have file set \"", name, - "\", but it was not found.")); - return false; - } - - auto const& fs_type = file_set->GetType(); - return fs_type == "CXX_MODULES"_s; - }); + return std::any_of( + fs_names.begin(), fs_names.end(), + [this, errorMessage](std::string const& name) -> bool { + auto const* file_set = this->Target->GetFileSet(name); + if (!file_set) { + auto message = cmStrCat("Target \"", this->Target->GetName(), + "\" is tracked to have file set \"", name, + "\", but it was not found."); + if (errorMessage) { + *errorMessage = std::move(message); + } else { + this->Makefile->IssueMessage(MessageType::INTERNAL_ERROR, message); + } + return false; + } + + auto const& fs_type = file_set->GetType(); + return fs_type == "CXX_MODULES"_s; + }); } cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport( diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index a32e742..844454f 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -1264,8 +1264,11 @@ public: * * This will inspect the target itself to see if C++20 module * support is expected to work based on its sources. + * + * If `errorMessage` is given a non-`nullptr`, any error message will be + * stored in it, otherwise the error will be reported directly. */ - bool HaveCxx20ModuleSources() const; + bool HaveCxx20ModuleSources(std::string* errorMessage = nullptr) const; enum class Cxx20SupportLevel { -- cgit v0.12 From 249cd3efad6967ec3195b7e24d031eecfc42eba7 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 24 Jan 2023 21:42:47 -0500 Subject: cmExportFileGenerator: export private compile info for C++ modules When consuming exported targets which contain C++ modules, the consuming project must be able to recompile BMI files using the original target's flags. This is because a module source may use some private target usage requirement but not want to propagate it to consumers. To facilitate this, export the private information as necessary for consumers to be able to perform the BMI compilations. --- Help/manual/cmake-properties.7.rst | 5 + .../IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS.rst | 14 +++ .../IMPORTED_CXX_MODULES_COMPILE_FEATURES.rst | 13 +++ .../IMPORTED_CXX_MODULES_COMPILE_OPTIONS.rst | 13 +++ .../IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES.rst | 14 +++ .../IMPORTED_CXX_MODULES_LINK_LIBRARIES.rst | 11 ++ Source/cmExportBuildFileGenerator.cxx | 9 ++ Source/cmExportFileGenerator.cxx | 72 +++++++++++++ Source/cmExportFileGenerator.h | 3 + Source/cmExportInstallFileGenerator.cxx | 7 ++ Tests/RunCMake/CXXModules/RunCMakeTest.cmake | 2 + .../examples/export-usage-build-stderr.txt | 4 + .../examples/export-usage-build/CMakeLists.txt | 110 ++++++++++++++++++++ .../examples/export-usage-build/forward.cxx | 6 ++ .../examples/export-usage-build/importable.cxx | 8 ++ .../examples/export-usage-build/private.cxx | 6 ++ .../export-usage-build/test/CMakeLists.txt | 69 +++++++++++++ .../examples/export-usage-install-stderr.txt | 4 + .../examples/export-usage-install/CMakeLists.txt | 114 +++++++++++++++++++++ .../examples/export-usage-install/forward.cxx | 6 ++ .../examples/export-usage-install/importable.cxx | 8 ++ .../examples/export-usage-install/private.cxx | 6 ++ .../export-usage-install/test/CMakeLists.txt | 69 +++++++++++++ 23 files changed, 573 insertions(+) create mode 100644 Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS.rst create mode 100644 Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES.rst create mode 100644 Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS.rst create mode 100644 Help/prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES.rst create mode 100644 Help/prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES.rst create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-build-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-install-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx create mode 100644 Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index c8a433d..fa1d297 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -240,6 +240,11 @@ Properties on Targets /prop_tgt/IMPORTED /prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME /prop_tgt/IMPORTED_CONFIGURATIONS + /prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS + /prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES + /prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS + /prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES + /prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES /prop_tgt/IMPORTED_GLOBAL /prop_tgt/IMPORTED_IMPLIB /prop_tgt/IMPORTED_IMPLIB_CONFIG diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS.rst new file mode 100644 index 0000000..88687b2 --- /dev/null +++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS.rst @@ -0,0 +1,14 @@ +IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS +---------------------------------------- + +.. versionadded:: 3.28 + +.. note :: + + Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` + +Preprocessor definitions for compiling an ``IMPORTED`` target's C++ module +sources. + +CMake will automatically drop some definitions that are not supported +by the native build tool. diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES.rst new file mode 100644 index 0000000..c3eb7fb --- /dev/null +++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_FEATURES.rst @@ -0,0 +1,13 @@ +IMPORTED_CXX_MODULES_COMPILE_FEATURES +------------------------------------- + +.. versionadded:: 3.28 + +.. note :: + + Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` + +Compiler features enabled for this ``IMPORTED`` target's C++ modules. + +The value of this property is used by the generators to set the include +paths for the compiler. diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS.rst new file mode 100644 index 0000000..5c62c77 --- /dev/null +++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_COMPILE_OPTIONS.rst @@ -0,0 +1,13 @@ +IMPORTED_CXX_MODULES_COMPILE_OPTIONS +------------------------------------ + +.. versionadded:: 3.28 + +.. note :: + + Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` + +List of options to pass to the compiler for this ``IMPORTED`` target's C++ +modules. + +.. include:: ../command/OPTIONS_SHELL.txt diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES.rst new file mode 100644 index 0000000..08a993d --- /dev/null +++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES.rst @@ -0,0 +1,14 @@ +IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES +---------------------------------------- + +.. versionadded:: 3.28 + +.. note :: + + Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` + +List of preprocessor include file search directories when compiling C++ +modules for ``IMPORTED`` targets. + +The value of this property is used by the generators to set the include +paths for the compiler. diff --git a/Help/prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES.rst b/Help/prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES.rst new file mode 100644 index 0000000..5111dc5 --- /dev/null +++ b/Help/prop_tgt/IMPORTED_CXX_MODULES_LINK_LIBRARIES.rst @@ -0,0 +1,11 @@ +IMPORTED_CXX_MODULES_LINK_LIBRARIES +----------------------------------- + +.. versionadded:: 3.28 + +.. note :: + + Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` + +List of direct dependencies to use for usage requirements for C++ modules in +the target's C++ modules. diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index fd35786..69572f4 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -126,6 +126,15 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) properties); std::string errorMessage; + if (!this->PopulateCxxModuleExportProperties( + gte, properties, cmGeneratorExpression::BuildInterface, + errorMessage)) { + this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage( + MessageType::FATAL_ERROR, errorMessage, + this->LG->GetMakefile()->GetBacktrace()); + return false; + } + if (!this->PopulateExportProperties(gte, properties, errorMessage)) { this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage( MessageType::FATAL_ERROR, errorMessage, diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 41234f4..5a12297 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -9,6 +9,7 @@ #include #include +#include #include "cmsys/FStream.hxx" @@ -1255,6 +1256,77 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode( os << ")\n\n"; } +bool cmExportFileGenerator::PopulateCxxModuleExportProperties( + cmGeneratorTarget const* gte, ImportPropertyMap& properties, + cmGeneratorExpression::PreprocessContext ctx, std::string& errorMessage) +{ + if (!gte->HaveCxx20ModuleSources(&errorMessage)) { + return true; + } + + const cm::static_string_view exportedDirectModuleProperties[] = { + "CXX_EXTENSIONS"_s, + }; + for (auto const& propName : exportedDirectModuleProperties) { + auto const propNameStr = std::string(propName); + cmValue prop = gte->Target->GetComputedProperty( + propNameStr, *gte->Target->GetMakefile()); + if (!prop) { + prop = gte->Target->GetProperty(propNameStr); + } + if (prop) { + properties[propNameStr] = cmGeneratorExpression::Preprocess(*prop, ctx); + } + } + + const cm::static_string_view exportedModuleProperties[] = { + "INCLUDE_DIRECTORIES"_s, + "COMPILE_DEFINITIONS"_s, + "COMPILE_OPTIONS"_s, + "COMPILE_FEATURES"_s, + }; + for (auto const& propName : exportedModuleProperties) { + auto const propNameStr = std::string(propName); + cmValue prop = gte->Target->GetComputedProperty( + propNameStr, *gte->Target->GetMakefile()); + if (!prop) { + prop = gte->Target->GetProperty(propNameStr); + } + if (prop) { + auto const exportedPropName = + cmStrCat("IMPORTED_CXX_MODULES_", propName); + properties[exportedPropName] = + cmGeneratorExpression::Preprocess(*prop, ctx); + } + } + + const cm::static_string_view exportedLinkModuleProperties[] = { + "LINK_LIBRARIES"_s, + }; + for (auto const& propName : exportedLinkModuleProperties) { + auto const propNameStr = std::string(propName); + cmValue prop = gte->Target->GetComputedProperty( + propNameStr, *gte->Target->GetMakefile()); + if (!prop) { + prop = gte->Target->GetProperty(propNameStr); + } + if (prop) { + auto const exportedPropName = + cmStrCat("IMPORTED_CXX_MODULES_", propName); + auto value = cmGeneratorExpression::Preprocess(*prop, ctx); + this->ResolveTargetsInGeneratorExpressions( + value, gte, cmExportFileGenerator::ReplaceFreeTargets); + std::vector wrappedValues; + for (auto& item : cmList{ value }) { + wrappedValues.push_back(cmStrCat("$')); + } + properties[exportedPropName] = cmJoin(wrappedValues, ";"); + } + } + + return true; +} + bool cmExportFileGenerator::PopulateExportProperties( cmGeneratorTarget const* gte, ImportPropertyMap& properties, std::string& errorMessage) diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index fdda878..6fa19ee 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -175,6 +175,9 @@ protected: virtual void GenerateRequiredCMakeVersion(std::ostream& os, const char* versionString); + bool PopulateCxxModuleExportProperties( + cmGeneratorTarget const* gte, ImportPropertyMap& properties, + cmGeneratorExpression::PreprocessContext ctx, std::string& errorMessage); bool PopulateExportProperties(cmGeneratorTarget const* gte, ImportPropertyMap& properties, std::string& errorMessage); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 6cf3a09..908bb31 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -126,6 +126,13 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) gt, cmGeneratorExpression::InstallInterface, properties); std::string errorMessage; + if (!this->PopulateCxxModuleExportProperties( + gt, properties, cmGeneratorExpression::InstallInterface, + errorMessage)) { + cmSystemTools::Error(errorMessage); + return false; + } + if (!this->PopulateExportProperties(gt, properties, errorMessage)) { cmSystemTools::Error(errorMessage); return false; diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake index 25670bd..d2fb11f 100644 --- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake +++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake @@ -187,6 +187,7 @@ endif () if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION) run_cxx_module_test(export-interface-no-properties-build) run_cxx_module_test(export-interface-build) + run_cxx_module_test(export-usage-build) run_cxx_module_test(export-bmi-and-interface-build) endif () @@ -201,6 +202,7 @@ if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION) if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION) run_cxx_module_test(export-interface-no-properties-install) run_cxx_module_test(export-interface-install) + run_cxx_module_test(export-usage-install) run_cxx_module_test(export-bmi-and-interface-install) endif () endif () diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/export-usage-build-stderr.txt new file mode 100644 index 0000000..78bdf2b --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-build-stderr.txt @@ -0,0 +1,4 @@ +CMake Warning \(dev\) at CMakeLists.txt:7 \(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. diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt new file mode 100644 index 0000000..86a608b --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt @@ -0,0 +1,110 @@ +cmake_minimum_required(VERSION 3.24) +project(cxx_modules_export_usage CXX) + +include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") + +add_library(export_usage STATIC) +target_sources(export_usage + PRIVATE + forward.cxx + PRIVATE + FILE_SET modules_private TYPE CXX_MODULES + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + private.cxx + PUBLIC + FILE_SET modules TYPE CXX_MODULES + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + importable.cxx) +target_compile_features(export_usage PUBLIC cxx_std_20) + +list(APPEND CMAKE_CXX_KNOWN_FEATURES + exported + buildiface + installiface + buildlocaliface) + +target_include_directories(export_usage + PRIVATE + "/usr/exported" + "$" + "$" + "$") +target_compile_definitions(export_usage + PRIVATE + "exported" + "$" + "$" + "$") +target_compile_features(export_usage + PRIVATE + "cxx_std_11" + "$" + "$" + "$") + +if (MSVC) + set(variable_flag "-constexpr:depth") +else () + set(variable_flag "-fconstexpr-depth=") +endif () + +target_compile_options(export_usage + PRIVATE + "${variable_flag}100" + "$" + "$" + "$") + +add_library(export_used INTERFACE) +add_library(export_build INTERFACE) +add_library(export_install INTERFACE) +add_library(export_never INTERFACE) + +target_link_libraries(export_usage + PRIVATE + "export_used" + "$" + "$" + "$") + +install(TARGETS export_usage + EXPORT CXXModules + FILE_SET modules DESTINATION "lib/cxx/miu") +export(EXPORT CXXModules + NAMESPACE CXXModules:: + FILE "${CMAKE_CURRENT_BINARY_DIR}/export_usage-targets.cmake") +install(TARGETS export_used export_build export_install + EXPORT CXXModulesDeps) +export(EXPORT CXXModulesDeps + NAMESPACE CXXModules:: + FILE "${CMAKE_CURRENT_BINARY_DIR}/export_usage-dep-targets.cmake") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_usage-config.cmake" + "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_usage-dep-targets.cmake\") +include(\"\${CMAKE_CURRENT_LIST_DIR}/export_usage-targets.cmake\") +set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1) +") + +set(generator + -G "${CMAKE_GENERATOR}") +if (CMAKE_GENERATOR_TOOLSET) + list(APPEND generator + -T "${CMAKE_GENERATOR_TOOLSET}") +endif () +if (CMAKE_GENERATOR_PLATFORM) + list(APPEND generator + -A "${CMAKE_GENERATOR_PLATFORM}") +endif () + +add_test(NAME export_usage_build + COMMAND + "${CMAKE_COMMAND}" + "-Dexpected_dir=${CMAKE_CURRENT_SOURCE_DIR}" + "-Dexport_interfaces_flag=${variable_flag}" + "-Dexport_usage_DIR=${CMAKE_CURRENT_BINARY_DIR}" + ${generator} + -S "${CMAKE_CURRENT_SOURCE_DIR}/test" + -B "${CMAKE_CURRENT_BINARY_DIR}/test") diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx new file mode 100644 index 0000000..7f53271 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx @@ -0,0 +1,6 @@ +import priv; + +int forwarding() +{ + return from_private(); +} diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx new file mode 100644 index 0000000..e0b1872 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx @@ -0,0 +1,8 @@ +export module importable; + +int forwarding(); + +export int from_import() +{ + return forwarding(); +} diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx new file mode 100644 index 0000000..c5b719a --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx @@ -0,0 +1,6 @@ +export module priv; + +export int from_private() +{ + return 0; +} diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt new file mode 100644 index 0000000..88bda88 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt @@ -0,0 +1,69 @@ +cmake_minimum_required(VERSION 3.24) +project(cxx_modules_library NONE) + +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") + +find_package(export_usage REQUIRED) + +if (NOT TARGET CXXModules::export_usage) + message(FATAL_ERROR + "Missing imported target") +endif () + +if (NOT TARGET CXXModules::export_used) + message(FATAL_ERROR + "Missing imported target") +endif () + +if (NOT TARGET CXXModules::export_build) + message(FATAL_ERROR + "Missing imported target") +endif () + +if (NOT TARGET CXXModules::export_install) + message(FATAL_ERROR + "Missing imported target") +endif () + +if (TARGET CXXModules::export_never) + message(FATAL_ERROR + "Extra imported target") +endif () + +function (check_property expected property) + get_property(actual TARGET CXXModules::export_usage + PROPERTY "${property}") + if (NOT actual STREQUAL expected) + message(SEND_ERROR + "Mismatch for ${property}:\n expected: ${expected}\n actual: ${actual}") + endif () +endfunction () + +check_property("/usr/exported;/usr/buildiface" "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES") +check_property("exported;buildiface" "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS") +check_property("cxx_std_20;cxx_std_11;cxx_std_14" "IMPORTED_CXX_MODULES_COMPILE_FEATURES") +check_property("${export_interfaces_flag}100;${export_interfaces_flag}200" "IMPORTED_CXX_MODULES_COMPILE_OPTIONS") +check_property("$;$" "IMPORTED_CXX_MODULES_LINK_LIBRARIES") + +# Extract the export-dependent targets from the export file. +file(STRINGS "${export_usage_DIR}/export_usage-targets.cmake" usage_dependent_targets + REGEX "foreach._target ") +# Rudimentary argument splitting. +string(REPLACE " " ";" usage_dependent_targets "${usage_dependent_targets}") +# Keep only "target" names. +list(FILTER usage_dependent_targets INCLUDE REGEX "CXXModules::") +# Strip quotes. +string(REPLACE "\"" "" usage_dependent_targets "${usage_dependent_targets}") + +if (NOT "CXXModules::export_used" IN_LIST usage_dependent_targets) + message(SEND_ERROR + "The main export does not require the 'CXXModules::export_used' target") +endif () +if (NOT "CXXModules::export_build" IN_LIST usage_dependent_targets) + message(SEND_ERROR + "The main export does not require the 'CXXModules::export_build' target") +endif () +if ("CXXModules::export_install" IN_LIST usage_dependent_targets) + message(SEND_ERROR + "The main export requires the 'CXXModules::export_install' target") +endif () diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/export-usage-install-stderr.txt new file mode 100644 index 0000000..78bdf2b --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-install-stderr.txt @@ -0,0 +1,4 @@ +CMake Warning \(dev\) at CMakeLists.txt:7 \(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. diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt new file mode 100644 index 0000000..11f53b0 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt @@ -0,0 +1,114 @@ +cmake_minimum_required(VERSION 3.24) +project(cxx_modules_export_usage CXX) + +include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") + +add_library(export_usage STATIC) +target_sources(export_usage + PRIVATE + forward.cxx + PRIVATE + FILE_SET modules_private TYPE CXX_MODULES + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + private.cxx + PUBLIC + FILE_SET modules TYPE CXX_MODULES + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + importable.cxx) +target_compile_features(export_usage PUBLIC cxx_std_20) + +list(APPEND CMAKE_CXX_KNOWN_FEATURES + exported + buildiface + installiface + buildlocaliface) + +target_include_directories(export_usage + PRIVATE + "/usr/exported" + "$" + "$" + "$") +target_compile_definitions(export_usage + PRIVATE + "exported" + "$" + "$" + "$") +target_compile_features(export_usage + PRIVATE + "cxx_std_11" + "$" + "$" + "$") + +if (MSVC) + set(variable_flag "-constexpr:depth") +else () + set(variable_flag "-fconstexpr-depth=") +endif () + +target_compile_options(export_usage + PRIVATE + "${variable_flag}100" + "$" + "$" + "$") + +add_library(export_used INTERFACE) +add_library(export_build INTERFACE) +add_library(export_install INTERFACE) +add_library(export_never INTERFACE) + +target_link_libraries(export_usage + PRIVATE + "export_used" + "$" + "$" + "$") + +install(TARGETS export_usage + EXPORT CXXModules + FILE_SET modules DESTINATION "lib/cxx/miu") +install(EXPORT CXXModules + NAMESPACE CXXModules:: + DESTINATION "lib/cmake/export_usage" + FILE "export_usage-targets.cmake") +install(TARGETS export_used export_build export_install + EXPORT CXXModulesDeps) +install(EXPORT CXXModulesDeps + NAMESPACE CXXModules:: + DESTINATION "lib/cmake/export_usage" + FILE "export_usage-dep-targets.cmake") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_usage-config.cmake" + "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_usage-dep-targets.cmake\") +include(\"\${CMAKE_CURRENT_LIST_DIR}/export_usage-targets.cmake\") +set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1) +") +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/export_usage-config.cmake" + DESTINATION "lib/cmake/export_usage") + +set(generator + -G "${CMAKE_GENERATOR}") +if (CMAKE_GENERATOR_TOOLSET) + list(APPEND generator + -T "${CMAKE_GENERATOR_TOOLSET}") +endif () +if (CMAKE_GENERATOR_PLATFORM) + list(APPEND generator + -A "${CMAKE_GENERATOR_PLATFORM}") +endif () + +add_test(NAME export_usage_build + COMMAND + "${CMAKE_COMMAND}" + "-Dexpected_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu" + "-Dexport_interfaces_flag=${variable_flag}" + "-Dexport_usage_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_usage" + ${generator} + -S "${CMAKE_CURRENT_SOURCE_DIR}/test" + -B "${CMAKE_CURRENT_BINARY_DIR}/test") diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx new file mode 100644 index 0000000..7f53271 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx @@ -0,0 +1,6 @@ +import priv; + +int forwarding() +{ + return from_private(); +} diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx new file mode 100644 index 0000000..e0b1872 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx @@ -0,0 +1,8 @@ +export module importable; + +int forwarding(); + +export int from_import() +{ + return forwarding(); +} diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx new file mode 100644 index 0000000..c5b719a --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx @@ -0,0 +1,6 @@ +export module priv; + +export int from_private() +{ + return 0; +} diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt new file mode 100644 index 0000000..bdc2898 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt @@ -0,0 +1,69 @@ +cmake_minimum_required(VERSION 3.24) +project(cxx_modules_library NONE) + +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") + +find_package(export_usage REQUIRED) + +if (NOT TARGET CXXModules::export_usage) + message(FATAL_ERROR + "Missing imported target") +endif () + +if (NOT TARGET CXXModules::export_used) + message(FATAL_ERROR + "Missing imported target") +endif () + +if (NOT TARGET CXXModules::export_build) + message(FATAL_ERROR + "Missing imported target") +endif () + +if (NOT TARGET CXXModules::export_install) + message(FATAL_ERROR + "Missing imported target") +endif () + +if (TARGET CXXModules::export_never) + message(FATAL_ERROR + "Extra imported target") +endif () + +function (check_property expected property) + get_property(actual TARGET CXXModules::export_usage + PROPERTY "${property}") + if (NOT actual STREQUAL expected) + message(SEND_ERROR + "Mismatch for ${property}:\n expected: ${expected}\n actual : ${actual}") + endif () +endfunction () + +check_property("/usr/exported;/usr/installiface" "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES") +check_property("exported;installiface" "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS") +check_property("cxx_std_20;cxx_std_11;cxx_std_17" "IMPORTED_CXX_MODULES_COMPILE_FEATURES") +check_property("${export_interfaces_flag}100;${export_interfaces_flag}300" "IMPORTED_CXX_MODULES_COMPILE_OPTIONS") +check_property("$;$" "IMPORTED_CXX_MODULES_LINK_LIBRARIES") + +# Extract the export-dependent targets from the export file. +file(STRINGS "${export_usage_DIR}/export_usage-targets.cmake" usage_dependent_targets + REGEX "foreach._target ") +# Rudimentary argument splitting. +string(REPLACE " " ";" usage_dependent_targets "${usage_dependent_targets}") +# Keep only "target" names. +list(FILTER usage_dependent_targets INCLUDE REGEX "CXXModules::") +# Strip quotes. +string(REPLACE "\"" "" usage_dependent_targets "${usage_dependent_targets}") + +if (NOT "CXXModules::export_used" IN_LIST usage_dependent_targets) + message(SEND_ERROR + "The main export does not require the 'CXXModules::export_used' target") +endif () +if ("CXXModules::export_build" IN_LIST usage_dependent_targets) + message(SEND_ERROR + "The main export requires the 'CXXModules::export_build' target") +endif () +if (NOT "CXXModules::export_install" IN_LIST usage_dependent_targets) + message(SEND_ERROR + "The main export does not require the 'CXXModules::export_install' target") +endif () -- cgit v0.12 From 7b069510c5440f0193f1626be5000cf5efe90442 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 2 Feb 2023 15:53:28 -0500 Subject: cmImportedCxxModuleInfo: introduce code to parse exported BMI properties --- Source/CMakeLists.txt | 2 + Source/cmImportedCxxModuleInfo.cxx | 76 ++++++++++++++++++++++++++++++++++++++ Source/cmImportedCxxModuleInfo.h | 37 +++++++++++++++++++ bootstrap | 1 + 4 files changed, 116 insertions(+) create mode 100644 Source/cmImportedCxxModuleInfo.cxx create mode 100644 Source/cmImportedCxxModuleInfo.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3690357..12af5d0 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -298,6 +298,8 @@ add_library( cmGraphAdjacencyList.h cmGraphVizWriter.cxx cmGraphVizWriter.h + cmImportedCxxModuleInfo.cxx + cmImportedCxxModuleInfo.h cmInstallGenerator.h cmInstallGenerator.cxx cmInstallGetRuntimeDependenciesGenerator.h diff --git a/Source/cmImportedCxxModuleInfo.cxx b/Source/cmImportedCxxModuleInfo.cxx new file mode 100644 index 0000000..9e3ac9a --- /dev/null +++ b/Source/cmImportedCxxModuleInfo.cxx @@ -0,0 +1,76 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmImportedCxxModuleInfo.h" + +#include +#include +#include +#include +#include + +#include "cmCryptoHash.h" +#include "cmList.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" + +bool ImportedCxxModuleLookup::Initialized() const +{ + return this->DoneInit; +} + +void ImportedCxxModuleLookup::Initialize(std::string const& importedModules) +{ + for (auto const& entry : cmList{ importedModules }) { + auto nameSep = entry.find('='); + if (nameSep == std::string::npos) { + // Invalid entry; ignore. + continue; + } + + auto name = entry.substr(0, nameSep); + + auto sourceSep = entry.find(',', nameSep); + std::string source; + if (sourceSep == std::string::npos) { + source = entry.substr(nameSep + 1); + } else { + source = entry.substr(nameSep + 1, sourceSep - nameSep - 1); + } + + std::vector bmis; + if (sourceSep != std::string::npos) { + auto bmiPaths = entry.substr(sourceSep + 1); + bmis = cmSystemTools::SplitString(bmiPaths, ','); + } + + this->ImportedInfo.emplace(source, + ImportedCxxModuleInfo{ name, std::move(bmis) }); + } + + this->DoneInit = true; +} + +std::string ImportedCxxModuleLookup::BmiNameForSource(std::string const& path) +{ + auto genit = this->GeneratorInfo.find(path); + if (genit != this->GeneratorInfo.end()) { + return genit->second.BmiName; + } + + auto importit = this->ImportedInfo.find(path); + std::string bmiName; + auto hasher = cmCryptoHash::New("SHA3_512"); + constexpr size_t HASH_TRUNCATION = 12; + if (importit != this->ImportedInfo.end()) { + auto safename = hasher->HashString(importit->second.Name); + bmiName = cmStrCat(safename.substr(0, HASH_TRUNCATION), ".bmi"); + } else { + auto dirhash = hasher->HashString(path); + bmiName = cmStrCat(dirhash.substr(0, HASH_TRUNCATION), ".bmi"); + } + + this->GeneratorInfo.emplace( + path, ImportedCxxModuleGeneratorInfo{ &importit->second, bmiName }); + return bmiName; +} diff --git a/Source/cmImportedCxxModuleInfo.h b/Source/cmImportedCxxModuleInfo.h new file mode 100644 index 0000000..e052283 --- /dev/null +++ b/Source/cmImportedCxxModuleInfo.h @@ -0,0 +1,37 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include +#include +#include + +struct ImportedCxxModuleInfo +{ + std::string const Name; + std::vector const AvailableBmis; +}; + +struct ImportedCxxModuleGeneratorInfo +{ + ImportedCxxModuleInfo const* ImportedInfo; + std::string const BmiName; +}; + +struct ImportedCxxModuleLookup +{ + ImportedCxxModuleLookup() = default; + ~ImportedCxxModuleLookup() = default; + + bool Initialized() const; + void Initialize(std::string const& importedModules); + + std::string BmiNameForSource(std::string const& path); + +private: + bool DoneInit = false; + std::map ImportedInfo; + std::map GeneratorInfo; +}; diff --git a/bootstrap b/bootstrap index 8b43d20..2c54dbf 100755 --- a/bootstrap +++ b/bootstrap @@ -392,6 +392,7 @@ CMAKE_CXX_SOURCES="\ cmGlobVerificationManager \ cmHexFileConverter \ cmIfCommand \ + cmImportedCxxModuleInfo \ cmIncludeCommand \ cmIncludeGuardCommand \ cmIncludeDirectoryCommand \ -- cgit v0.12 From 159585967a0e4ab99f39de4eec311bac7d0ee0d0 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 2 Feb 2023 15:54:43 -0500 Subject: cmGeneratorTarget: classify BMI-only C++ module sources --- Source/cmFileAPICodemodel.cxx | 1 + Source/cmGeneratorTarget.cxx | 10 ++++++++++ Source/cmGeneratorTarget.h | 3 +++ Source/cmVisualStudio10TargetGenerator.cxx | 1 + 4 files changed, 15 insertions(+) diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 812b1b5..3c1bc14 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -1678,6 +1678,7 @@ Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk, } switch (sk.Kind) { + case cmGeneratorTarget::SourceKindCxxModuleSource: case cmGeneratorTarget::SourceKindObjectSource: { source["compileGroupIndex"] = this->AddSourceCompileGroup(sk.Source.Value, si); diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index c6b2718..c15db5b 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1071,6 +1071,12 @@ void cmGeneratorTarget::GetHeaderSources( IMPLEMENT_VISIT(SourceKindHeader); } +void cmGeneratorTarget::GetCxxModuleSources( + std::vector& data, const std::string& config) const +{ + IMPLEMENT_VISIT(SourceKindCxxModuleSource); +} + void cmGeneratorTarget::GetExtraSources(std::vector& data, const std::string& config) const { @@ -1953,8 +1959,12 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, // Compute the kind (classification) of this source file. SourceKind kind; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); + cmFileSet const* fs = this->GetFileSetForSource(config, sf); if (sf->GetCustomCommand()) { kind = SourceKindCustomCommand; + } else if (!this->Target->IsNormal() && !this->Target->IsImported() && + fs && (fs->GetType() == "CXX_MODULES"_s)) { + kind = SourceKindCxxModuleSource; } else if (this->Target->GetType() == cmStateEnums::UTILITY || this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 844454f..3adf5b8 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -116,6 +116,7 @@ public: SourceKindCertificate, SourceKindCustomCommand, SourceKindExternalObject, + SourceKindCxxModuleSource, SourceKindExtra, SourceKindHeader, SourceKindIDL, @@ -186,6 +187,8 @@ public: const std::string& config) const; void GetHeaderSources(std::vector&, const std::string& config) const; + void GetCxxModuleSources(std::vector&, + const std::string& config) const; void GetExtraSources(std::vector&, const std::string& config) const; void GetCustomCommands(std::vector&, diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 48f3197..1bd4c57 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2517,6 +2517,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) case cmGeneratorTarget::SourceKindModuleDefinition: tool = "None"; break; + case cmGeneratorTarget::SourceKindCxxModuleSource: case cmGeneratorTarget::SourceKindUnityBatched: case cmGeneratorTarget::SourceKindObjectSource: { const std::string& lang = si.Source->GetLanguage(); -- cgit v0.12 From 1ccf25b049a8d1c8ebbbb0969e74469ed3ca4432 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sat, 28 Jan 2023 17:29:03 -0500 Subject: cmTarget: track and store `IMPORTED_CXX_MODULES_` usage properties While not "usage requirements" directly, when applied to a target that will eventually have the BMI compile rules attached to them, they need tracked as such. --- Source/cmTarget.cxx | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 7cc5d2e..5ecee0d 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -673,6 +673,11 @@ public: UsageRequirementProperty InterfaceLinkLibraries; UsageRequirementProperty InterfaceLinkLibrariesDirect; UsageRequirementProperty InterfaceLinkLibrariesDirectExclude; + UsageRequirementProperty ImportedCxxModulesIncludeDirectories; + UsageRequirementProperty ImportedCxxModulesCompileDefinitions; + UsageRequirementProperty ImportedCxxModulesCompileFeatures; + UsageRequirementProperty ImportedCxxModulesCompileOptions; + UsageRequirementProperty ImportedCxxModulesLinkLibraries; FileSetType HeadersFileSets; FileSetType CxxModulesFileSets; @@ -723,6 +728,14 @@ cmTargetInternals::cmTargetInternals() , InterfaceLinkLibrariesDirect("INTERFACE_LINK_LIBRARIES_DIRECT"_s) , InterfaceLinkLibrariesDirectExclude( "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"_s) + , ImportedCxxModulesIncludeDirectories( + "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES"_s) + , ImportedCxxModulesCompileDefinitions( + "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS"_s) + , ImportedCxxModulesCompileFeatures( + "IMPORTED_CXX_MODULES_COMPILE_FEATURES"_s) + , ImportedCxxModulesCompileOptions("IMPORTED_CXX_MODULES_COMPILE_OPTIONS"_s) + , ImportedCxxModulesLinkLibraries("IMPORTED_CXX_MODULES_LINK_LIBRARIES"_s) , HeadersFileSets("HEADERS"_s, "HEADER_DIRS"_s, "HEADER_SET"_s, "HEADER_DIRS_"_s, "HEADER_SET_"_s, "Header"_s, "The default header set"_s, "Header set"_s, @@ -1777,6 +1790,11 @@ MAKE_PROP(IMPORTED); MAKE_PROP(IMPORTED_GLOBAL); MAKE_PROP(INCLUDE_DIRECTORIES); MAKE_PROP(LINK_OPTIONS); +MAKE_PROP(IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES); +MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS); +MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_FEATURES); +MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_OPTIONS); +MAKE_PROP(IMPORTED_CXX_MODULES_LINK_LIBRARIES); MAKE_PROP(LINK_DIRECTORIES); MAKE_PROP(LINK_LIBRARIES); MAKE_PROP(MANUALLY_ADDED_DEPENDENCIES); @@ -1846,6 +1864,11 @@ void cmTarget::SetProperty(const std::string& prop, cmValue value) &this->impl->InterfaceLinkLibraries, &this->impl->InterfaceLinkLibrariesDirect, &this->impl->InterfaceLinkLibrariesDirectExclude, + &this->impl->ImportedCxxModulesIncludeDirectories, + &this->impl->ImportedCxxModulesCompileDefinitions, + &this->impl->ImportedCxxModulesCompileFeatures, + &this->impl->ImportedCxxModulesCompileOptions, + &this->impl->ImportedCxxModulesLinkLibraries, }; for (auto* usageRequirement : usageRequirements) { @@ -2019,6 +2042,11 @@ void cmTarget::AppendProperty(const std::string& prop, &this->impl->InterfaceLinkLibraries, &this->impl->InterfaceLinkLibrariesDirect, &this->impl->InterfaceLinkLibrariesDirectExclude, + &this->impl->ImportedCxxModulesIncludeDirectories, + &this->impl->ImportedCxxModulesCompileDefinitions, + &this->impl->ImportedCxxModulesCompileFeatures, + &this->impl->ImportedCxxModulesCompileOptions, + &this->impl->ImportedCxxModulesLinkLibraries, }; for (auto* usageRequirement : usageRequirements) { @@ -2445,6 +2473,11 @@ cmValue cmTarget::GetProperty(const std::string& prop) const propINTERFACE_LINK_LIBRARIES, propINTERFACE_LINK_LIBRARIES_DIRECT, propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, + propIMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES, + propIMPORTED_CXX_MODULES_COMPILE_DEFINITIONS, + propIMPORTED_CXX_MODULES_COMPILE_FEATURES, + propIMPORTED_CXX_MODULES_COMPILE_OPTIONS, + propIMPORTED_CXX_MODULES_LINK_LIBRARIES, }; if (specialProps.count(prop)) { if (prop == propC_STANDARD || prop == propCXX_STANDARD || @@ -2470,6 +2503,11 @@ cmValue cmTarget::GetProperty(const std::string& prop) const &this->impl->InterfaceLinkLibraries, &this->impl->InterfaceLinkLibrariesDirect, &this->impl->InterfaceLinkLibrariesDirectExclude, + &this->impl->ImportedCxxModulesIncludeDirectories, + &this->impl->ImportedCxxModulesCompileDefinitions, + &this->impl->ImportedCxxModulesCompileFeatures, + &this->impl->ImportedCxxModulesCompileOptions, + &this->impl->ImportedCxxModulesLinkLibraries, }; for (auto const* usageRequirement : usageRequirements) { -- cgit v0.12 From 3a8ea5c3a0216d3e9ecedc7fbd1d6adaff0ee7c5 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sat, 28 Jan 2023 17:28:22 -0500 Subject: cmTarget: rename entry copying method It will also be used to copy from other targets, not just directories. --- Source/cmTarget.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 5ecee0d..5d67d60 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -246,9 +246,9 @@ struct UsageRequirementProperty { } - void CopyFromDirectory(cmBTStringRange directoryEntries) + void CopyFromEntries(cmBTStringRange entries) { - return cm::append(this->Entries, directoryEntries); + return cm::append(this->Entries, entries); } enum class Action @@ -964,7 +964,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, if (this->IsNormal()) { // Initialize the INCLUDE_DIRECTORIES property based on the current value // of the same directory property: - this->impl->IncludeDirectories.CopyFromDirectory( + this->impl->IncludeDirectories.CopyFromEntries( this->impl->Makefile->GetIncludeDirectoriesEntries()); { @@ -973,11 +973,11 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, sysInc.end()); } - this->impl->CompileOptions.CopyFromDirectory( + this->impl->CompileOptions.CopyFromEntries( this->impl->Makefile->GetCompileOptionsEntries()); - this->impl->LinkOptions.CopyFromDirectory( + this->impl->LinkOptions.CopyFromEntries( this->impl->Makefile->GetLinkOptionsEntries()); - this->impl->LinkDirectories.CopyFromDirectory( + this->impl->LinkDirectories.CopyFromEntries( this->impl->Makefile->GetLinkDirectoriesEntries()); } -- cgit v0.12 From caf5971c8a628b29c2d5c56cb08cbe54b0449f35 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 21 Jul 2023 15:40:54 -0400 Subject: cmTarget: report that synthetic targets can compile sources --- Source/cmTarget.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 5d67d60..7d4b497 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2713,6 +2713,9 @@ bool cmTarget::CanCompileSources() const if (this->IsImported()) { return false; } + if (this->IsSynthetic()) { + return true; + } switch (this->GetType()) { case cmStateEnums::EXECUTABLE: case cmStateEnums::STATIC_LIBRARY: -- cgit v0.12 From 9840bfdab0542fdbecc3787fb6cad9f4fb861519 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 2 Feb 2023 16:06:46 -0500 Subject: cmDyndepCollation: support BMI-only collation --- Source/cmDyndepCollation.cxx | 38 ++++++++++++++++++++++++++++++-------- Source/cmDyndepCollation.h | 2 ++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx index 80e1357..bdf6b44 100644 --- a/Source/cmDyndepCollation.cxx +++ b/Source/cmDyndepCollation.cxx @@ -73,20 +73,36 @@ Json::Value CollationInformationCxxModules( gt->LocalGenerator, config, gt); } - std::map sf_map; + enum class CompileType { - std::vector objectSources; - gt->GetObjectSources(objectSources, config); - for (auto const* sf : objectSources) { + ObjectAndBmi, + BmiOnly, + }; + std::map> sf_map; + { + auto fill_sf_map = [gt, tgt, &sf_map](cmSourceFile const* sf, + CompileType type) { auto full_path = sf->GetFullPath(); if (full_path.empty()) { gt->Makefile->IssueMessage( MessageType::INTERNAL_ERROR, cmStrCat("Target \"", tgt->GetName(), "\" has a full path-less source file.")); - continue; + return; } - sf_map[full_path] = sf; + sf_map[full_path] = std::make_pair(sf, type); + }; + + std::vector objectSources; + gt->GetObjectSources(objectSources, config); + for (auto const* sf : objectSources) { + fill_sf_map(sf, CompileType::ObjectAndBmi); + } + + std::vector cxxModuleSources; + gt->GetCxxModuleSources(cxxModuleSources, config); + for (auto const* sf : cxxModuleSources) { + fill_sf_map(sf, CompileType::BmiOnly); } } @@ -113,7 +129,8 @@ Json::Value CollationInformationCxxModules( continue; } - auto const* sf = lookup->second; + auto const* sf = lookup->second.first; + CompileType const ct = lookup->second.second; if (!sf) { gt->Makefile->IssueMessage( @@ -123,11 +140,14 @@ Json::Value CollationInformationCxxModules( continue; } - auto obj_path = cb.ObjectFilePath(sf, config); + auto obj_path = ct == CompileType::ObjectAndBmi + ? cb.ObjectFilePath(sf, config) + : cb.BmiFilePath(sf, config); Json::Value& tdi_module_info = tdi_cxx_module_info[obj_path] = Json::objectValue; tdi_module_info["source"] = file; + tdi_module_info["bmi-only"] = ct == CompileType::BmiOnly; tdi_module_info["relative-directory"] = files_per_dir.first; tdi_module_info["name"] = file_set->GetName(); tdi_module_info["type"] = file_set->GetType(); @@ -269,6 +289,7 @@ void cmDyndepCollation::AddCollationInformation( struct CxxModuleFileSet { std::string Name; + bool BmiOnly; std::string RelativeDirectory; std::string SourcePath; std::string Type; @@ -356,6 +377,7 @@ cmDyndepCollation::ParseExportInfo(Json::Value const& tdi) CxxModuleFileSet& fsi = export_info->ObjectToFileSet[i.key().asString()]; auto const& tdi_cxx_module_info = *i; fsi.Name = tdi_cxx_module_info["name"].asString(); + fsi.BmiOnly = tdi_cxx_module_info["bmi-only"].asBool(); fsi.RelativeDirectory = tdi_cxx_module_info["relative-directory"].asString(); if (!fsi.RelativeDirectory.empty() && diff --git a/Source/cmDyndepCollation.h b/Source/cmDyndepCollation.h index 48afe2b..21f1fe9 100644 --- a/Source/cmDyndepCollation.h +++ b/Source/cmDyndepCollation.h @@ -23,6 +23,8 @@ struct cmDyndepGeneratorCallbacks { std::function ObjectFilePath; + std::function + BmiFilePath; }; struct cmDyndepMetadataCallbacks -- cgit v0.12 From a53748e31906b5821f3aedeb848ac53dcdd6389d Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 7 Feb 2023 17:57:16 -0500 Subject: cmDyndepCollation: add a query for whether an object is BMI-only The collator needs to know that the object *is* a BMI so that it can just use the location directly. --- Source/cmDyndepCollation.cxx | 13 +++++++++++++ Source/cmDyndepCollation.h | 3 +++ 2 files changed, 16 insertions(+) diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx index bdf6b44..bd2f546 100644 --- a/Source/cmDyndepCollation.cxx +++ b/Source/cmDyndepCollation.cxx @@ -666,3 +666,16 @@ bool cmDyndepCollation::IsObjectPrivate( auto const& file_set = fileset_info_itr->second; return !cmFileSetVisibilityIsForInterface(file_set.Visibility); } + +bool cmDyndepCollation::IsBmiOnly(cmCxxModuleExportInfo const& exportInfo, + std::string const& object) +{ +#ifdef _WIN32 + auto object_path = object; + cmSystemTools::ConvertToUnixSlashes(object_path); +#else + auto const& object_path = object; +#endif + auto fs = exportInfo.ObjectToFileSet.find(object_path); + return (fs != exportInfo.ObjectToFileSet.end()) && fs->second.BmiOnly; +} diff --git a/Source/cmDyndepCollation.h b/Source/cmDyndepCollation.h index 21f1fe9..b193467 100644 --- a/Source/cmDyndepCollation.h +++ b/Source/cmDyndepCollation.h @@ -53,4 +53,7 @@ struct cmDyndepCollation cmDyndepMetadataCallbacks const& cb); static bool IsObjectPrivate(std::string const& object, cmCxxModuleExportInfo const& export_info); + + static bool IsBmiOnly(cmCxxModuleExportInfo const& exportInfo, + std::string const& object); }; -- cgit v0.12 From c1defd9dd3e9cacd4a40fcbc9f52e36493dd1d0b Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 17 Jul 2023 16:37:13 -0400 Subject: cmDyndepCollation: add initializers for POD types This avoids invalid states from existing. --- Source/cmDyndepCollation.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx index bd2f546..dfab975 100644 --- a/Source/cmDyndepCollation.cxx +++ b/Source/cmDyndepCollation.cxx @@ -289,11 +289,11 @@ void cmDyndepCollation::AddCollationInformation( struct CxxModuleFileSet { std::string Name; - bool BmiOnly; + bool BmiOnly = false; std::string RelativeDirectory; std::string SourcePath; std::string Type; - cmFileSetVisibility Visibility; + cmFileSetVisibility Visibility = cmFileSetVisibility::Private; cm::optional Destination; }; -- cgit v0.12 From cb356b540c0ed500383c7681ec7594ed58d517a5 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 30 Jan 2023 10:24:41 -0500 Subject: cmCxxModuleUsageEffects: add a class to capture module usage effects When importing a C++ module, there may be requirements imposed by the importer so that the compiler can reliably read the BMI. For example, the standard used in the importer may need to also apply to the imported BMI. Right now, there are no tracked requirements. As we learn more, this class can start tracking more information. See: https://wg21.link/p2581r2 --- Source/CMakeLists.txt | 2 ++ Source/cmCxxModuleUsageEffects.cxx | 21 +++++++++++++++++++++ Source/cmCxxModuleUsageEffects.h | 22 ++++++++++++++++++++++ bootstrap | 1 + 4 files changed, 46 insertions(+) create mode 100644 Source/cmCxxModuleUsageEffects.cxx create mode 100644 Source/cmCxxModuleUsageEffects.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 12af5d0..67d3d8d 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -170,6 +170,8 @@ add_library( cmCustomCommandTypes.h cmCxxModuleMapper.cxx cmCxxModuleMapper.h + cmCxxModuleUsageEffects.cxx + cmCxxModuleUsageEffects.h cmDefinitions.cxx cmDefinitions.h cmDependencyProvider.h diff --git a/Source/cmCxxModuleUsageEffects.cxx b/Source/cmCxxModuleUsageEffects.cxx new file mode 100644 index 0000000..eea5245 --- /dev/null +++ b/Source/cmCxxModuleUsageEffects.cxx @@ -0,0 +1,21 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmCxxModuleUsageEffects.h" + +cmCxxModuleUsageEffects::cmCxxModuleUsageEffects( + cmGeneratorTarget const* /*gt*/) + : Hash("0000000000000000000000000000000000000000") +{ + // TODO: collect information from the generator target as to what might + // affect module consumption. +} + +void cmCxxModuleUsageEffects::ApplyToTarget(cmTarget* /*tgt*/) +{ + // TODO: apply the information collected in the constructor +} + +std::string const& cmCxxModuleUsageEffects::GetHash() const +{ + return this->Hash; +} diff --git a/Source/cmCxxModuleUsageEffects.h b/Source/cmCxxModuleUsageEffects.h new file mode 100644 index 0000000..a63919c --- /dev/null +++ b/Source/cmCxxModuleUsageEffects.h @@ -0,0 +1,22 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include + +class cmGeneratorTarget; +class cmTarget; + +class cmCxxModuleUsageEffects +{ +public: + cmCxxModuleUsageEffects(cmGeneratorTarget const* gt); + + void ApplyToTarget(cmTarget* tgt); + std::string const& GetHash() const; + +private: + std::string Hash; +}; diff --git a/bootstrap b/bootstrap index 2c54dbf..68885b3 100755 --- a/bootstrap +++ b/bootstrap @@ -333,6 +333,7 @@ CMAKE_CXX_SOURCES="\ cmCustomCommandGenerator \ cmCustomCommandLines \ cmCxxModuleMapper \ + cmCxxModuleUsageEffects \ cmDefinePropertyCommand \ cmDefinitions \ cmDocumentationFormatter \ -- cgit v0.12 From 3dc6676ecc4ef8a74b057f284f123fd54e867fa4 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 7 Feb 2023 17:56:56 -0500 Subject: cmSyntheticTargetCache: add a struct for synthetic target caching --- Source/CMakeLists.txt | 1 + Source/cmSyntheticTargetCache.h | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 Source/cmSyntheticTargetCache.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 67d3d8d..a8abb60 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -426,6 +426,7 @@ add_library( cmStateTypes.h cmStringAlgorithms.cxx cmStringAlgorithms.h + cmSyntheticTargetCache.h cmSystemTools.cxx cmSystemTools.h cmTarget.cxx diff --git a/Source/cmSyntheticTargetCache.h b/Source/cmSyntheticTargetCache.h new file mode 100644 index 0000000..22d1533 --- /dev/null +++ b/Source/cmSyntheticTargetCache.h @@ -0,0 +1,15 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include +#include + +class cmGeneratorTarget; + +struct cmSyntheticTargetCache +{ + std::map CxxModuleTargets; +}; -- cgit v0.12 From 80d65443982ca1b2c98c84ae86e2bfccdbdd7678 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 7 Feb 2023 18:01:00 -0500 Subject: cxxmodules: generate synthetic targets as an initial pass We need to be able to construct BMIs that will be usable from the client modules for the target importing the module, so create BMI-only compilation rules for `IMPORTED` targets to create these BMIs. --- Source/cmFileSet.cxx | 7 ++ Source/cmFileSet.h | 2 + Source/cmGeneratorTarget.cxx | 104 ++++++++++++++++++++++++- Source/cmGeneratorTarget.h | 6 ++ Source/cmGlobalGenerator.cxx | 40 ++++++++++ Source/cmGlobalGenerator.h | 2 + Source/cmTarget.cxx | 180 +++++++++++++++++++++++++++++++++++++++++++ Source/cmTarget.h | 4 + 8 files changed, 344 insertions(+), 1 deletion(-) diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx index 48a2570..bcf7fba 100644 --- a/Source/cmFileSet.cxx +++ b/Source/cmFileSet.cxx @@ -7,6 +7,7 @@ #include #include +#include #include #include "cmsys/RegularExpression.hxx" @@ -88,6 +89,12 @@ cmFileSet::cmFileSet(cmake& cmakeInstance, std::string name, std::string type, { } +void cmFileSet::CopyEntries(cmFileSet const* fs) +{ + cm::append(this->DirectoryEntries, fs->DirectoryEntries); + cm::append(this->FileEntries, fs->FileEntries); +} + void cmFileSet::ClearDirectoryEntries() { this->DirectoryEntries.clear(); diff --git a/Source/cmFileSet.h b/Source/cmFileSet.h index 54d430c..c508e2b 100644 --- a/Source/cmFileSet.h +++ b/Source/cmFileSet.h @@ -41,6 +41,8 @@ public: const std::string& GetType() const { return this->Type; } cmFileSetVisibility GetVisibility() const { return this->Visibility; } + void CopyEntries(cmFileSet const* fs); + void ClearDirectoryEntries(); void AddDirectoryEntry(BT directories); const std::vector>& GetDirectoryEntries() const diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index c15db5b..70f51b0 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -27,7 +27,9 @@ #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" +#include "cmCryptoHash.h" #include "cmCustomCommandGenerator.h" +#include "cmCxxModuleUsageEffects.h" #include "cmEvaluatedTargetProperty.h" #include "cmExperimental.h" #include "cmFileSet.h" @@ -52,6 +54,7 @@ #include "cmStandardLevelResolver.h" #include "cmState.h" #include "cmStringAlgorithms.h" +#include "cmSyntheticTargetCache.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" @@ -8230,6 +8233,96 @@ void ComputeLinkImplTransitive(cmGeneratorTarget const* self, } } +bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache, + std::string const& config) +{ + cmOptionalLinkImplementation impl; + this->ComputeLinkImplementationLibraries(config, impl, this, + LinkInterfaceFor::Link); + + cmCxxModuleUsageEffects usage(this); + + auto& SyntheticDeps = this->Configs[config].SyntheticDeps; + + for (auto const& entry : impl.Libraries) { + auto const* gt = entry.Target; + if (!gt || !gt->IsImported()) { + continue; + } + + if (gt->HaveCxx20ModuleSources()) { + auto hasher = cmCryptoHash::New("SHA3_512"); + constexpr size_t HASH_TRUNCATION = 12; + auto dirhash = hasher->HashString( + gt->GetLocalGenerator()->GetCurrentBinaryDirectory()); + std::string safeName = gt->GetName(); + cmSystemTools::ReplaceString(safeName, ":", "_"); + auto targetIdent = + hasher->HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash())); + std::string targetName = + cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION)); + + // Check the cache to see if this instance of the imported target has + // already been created. + auto cached = cache.CxxModuleTargets.find(targetName); + cmGeneratorTarget const* synthDep = nullptr; + if (cached == cache.CxxModuleTargets.end()) { + auto const* model = gt->Target; + auto* mf = gt->Makefile; + auto* lg = gt->GetLocalGenerator(); + auto* tgt = mf->AddSynthesizedTarget(cmStateEnums::INTERFACE_LIBRARY, + targetName); + + // Copy relevant information from the existing IMPORTED target. + + // Copy policies to the target. + tgt->CopyPolicyStatuses(model); + + // Copy file sets. + { + auto fsNames = model->GetAllFileSetNames(); + for (auto const& fsName : fsNames) { + auto const* fs = model->GetFileSet(fsName); + if (!fs) { + mf->IssueMessage(MessageType::INTERNAL_ERROR, + cmStrCat("Failed to find file set named '", + fsName, "' on target '", + tgt->GetName(), '\'')); + continue; + } + auto* newFs = tgt + ->GetOrCreateFileSet(fs->GetName(), fs->GetType(), + fs->GetVisibility()) + .first; + newFs->CopyEntries(fs); + } + } + + // Copy imported C++ module properties. + tgt->CopyImportedCxxModulesEntries(model); + + // Copy other properties which may affect the C++ module BMI + // generation. + tgt->CopyImportedCxxModulesProperties(model); + + // Apply usage requirements to the target. + usage.ApplyToTarget(tgt); + + // Create the generator target and attach it to the local generator. + auto gtp = cm::make_unique(tgt, lg); + synthDep = gtp.get(); + lg->AddGeneratorTarget(std::move(gtp)); + } else { + synthDep = cached->second; + } + + SyntheticDeps[gt].push_back(synthDep); + } + } + + return true; +} + void cmGeneratorTarget::ComputeLinkImplementationLibraries( const std::string& config, cmOptionalLinkImplementation& impl, cmGeneratorTarget const* head, LinkInterfaceFor implFor) const @@ -8237,6 +8330,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( cmLocalGenerator const* lg = this->LocalGenerator; cmMakefile const* mf = lg->GetMakefile(); cmBTStringRange entryRange = this->Target->GetLinkImplementationEntries(); + auto const& synthTargetsForConfig = this->Configs[config].SyntheticDeps; // Collect libraries directly linked in this configuration. for (auto const& entry : entryRange) { // Keep this logic in sync with ExpandLinkItems. @@ -8326,7 +8420,15 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( // The entry is meant for this configuration. cmLinkItem item = this->ResolveLinkItem(BT(name, entry.Backtrace), lg); - if (!item.Target) { + if (item.Target) { + auto depsForTarget = synthTargetsForConfig.find(item.Target); + if (depsForTarget != synthTargetsForConfig.end()) { + for (auto const* depForTarget : depsForTarget->second) { + cmLinkItem synthItem(depForTarget, item.Cross, item.Backtrace); + impl.Libraries.emplace_back(std::move(synthItem), false); + } + } + } else { // Report explicitly linked object files separately. std::string const& maybeObj = item.AsStr(); if (cmSystemTools::FileIsFullPath(maybeObj)) { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 3adf5b8..f347133 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -31,6 +31,7 @@ class cmGlobalGenerator; class cmLocalGenerator; class cmMakefile; class cmSourceFile; +struct cmSyntheticTargetCache; class cmTarget; struct cmGeneratorExpressionContext; @@ -932,6 +933,9 @@ public: std::string GetImportedXcFrameworkPath(const std::string& config) const; + bool DiscoverSyntheticTargets(cmSyntheticTargetCache& cache, + std::string const& config); + private: void AddSourceCommon(const std::string& src, bool before = false); @@ -1307,6 +1311,8 @@ private: { bool BuiltFileSetCache = false; std::map FileSetCache; + std::map> + SyntheticDeps; }; mutable std::map Configs; }; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 9af6e9b..d5099ee 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -55,6 +55,7 @@ #include "cmStateDirectory.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" +#include "cmSyntheticTargetCache.h" #include "cmSystemTools.h" #include "cmValue.h" #include "cmVersion.h" @@ -1560,6 +1561,17 @@ bool cmGlobalGenerator::Compute() } #endif + // Iterate through all targets and set up C++20 module targets. + // Create target templates for each imported target with C++20 modules. + // INTERFACE library with BMI-generating rules and a collation step? + // Maybe INTERFACE libraries with modules files should just do BMI-only? + // Make `add_dependencies(imported_target + // $<$:synth1> + // $<$:synth2>)` + if (!this->DiscoverSyntheticTargets()) { + return false; + } + // Add generator specific helper commands for (const auto& localGen : this->LocalGenerators) { localGen->AddHelperCommands(); @@ -1784,6 +1796,34 @@ void cmGlobalGenerator::ComputeTargetOrder(cmGeneratorTarget const* gt, entry->second = index++; } +bool cmGlobalGenerator::DiscoverSyntheticTargets() +{ + cmSyntheticTargetCache cache; + + for (auto const& gen : this->LocalGenerators) { + // Because DiscoverSyntheticTargets() adds generator targets, we need to + // cache the existing list of generator targets before starting. + std::vector genTargets; + genTargets.reserve(gen->GetGeneratorTargets().size()); + for (auto const& tgt : gen->GetGeneratorTargets()) { + genTargets.push_back(tgt.get()); + } + + for (auto* tgt : genTargets) { + std::vector const& configs = + tgt->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); + + for (auto const& config : configs) { + if (!tgt->DiscoverSyntheticTargets(cache, config)) { + return false; + } + } + } + } + + return true; +} + bool cmGlobalGenerator::AddHeaderSetVerification() { for (auto const& gen : this->LocalGenerators) { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 563ebb6..6d29dc1 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -662,6 +662,8 @@ protected: virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const; + bool DiscoverSyntheticTargets(); + bool AddHeaderSetVerification(); bool AddAutomaticSources(); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 7d4b497..ace93e8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1748,6 +1748,186 @@ cmBTStringRange cmTarget::GetLinkInterfaceDirectExcludeEntries() const return cmMakeRange(this->impl->InterfaceLinkLibrariesDirectExclude.Entries); } +void cmTarget::CopyPolicyStatuses(cmTarget const* tgt) +{ + // Normal targets cannot be the target of a copy. + assert(!this->IsNormal()); + // Imported targets cannot be the target of a copy. + assert(!this->IsImported()); + // Only imported targets can be the source of a copy. + assert(tgt->IsImported()); + + this->impl->PolicyMap = tgt->impl->PolicyMap; +} + +void cmTarget::CopyImportedCxxModulesEntries(cmTarget const* tgt) +{ + // Normal targets cannot be the target of a copy. + assert(!this->IsNormal()); + // Imported targets cannot be the target of a copy. + assert(!this->IsImported()); + // Only imported targets can be the source of a copy. + assert(tgt->IsImported()); + + this->impl->IncludeDirectories.Entries.clear(); + this->impl->IncludeDirectories.CopyFromEntries( + cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries)); + this->impl->CompileDefinitions.Entries.clear(); + this->impl->CompileDefinitions.CopyFromEntries( + cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries)); + this->impl->CompileFeatures.Entries.clear(); + this->impl->CompileFeatures.CopyFromEntries( + cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries)); + this->impl->CompileOptions.Entries.clear(); + this->impl->CompileOptions.CopyFromEntries( + cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries)); + this->impl->LinkLibraries.Entries.clear(); + this->impl->LinkLibraries.CopyFromEntries( + cmMakeRange(tgt->impl->LinkLibraries.Entries)); + + // Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this + // target's `PRIVATE`. + this->impl->CxxModulesFileSets.SelfEntries.Entries.clear(); + this->impl->CxxModulesFileSets.SelfEntries.Entries = + tgt->impl->CxxModulesFileSets.InterfaceEntries.Entries; +} + +void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt) +{ + // Normal targets cannot be the target of a copy. + assert(!this->IsNormal()); + // Imported targets cannot be the target of a copy. + assert(!this->IsImported()); + // Only imported targets can be the source of a copy. + assert(tgt->IsImported()); + + // The list of properties that are relevant here include: + // - compilation-specific properties for any language or platform + // - compilation-specific properties for C++ + // - build graph-specific properties that affect compilation + // - IDE metadata properties + // - static analysis properties + + static const std::string propertiesToCopy[] = { + // Compilation properties + "DEFINE_SYMBOL", + "DEPRECATION", + "NO_SYSTEM_FROM_IMPORTED", + "POSITION_INDEPENDENT_CODE", + "VISIBILITY_INLINES_HIDDEN", + // -- Platforms + // ---- Android + "ANDROID_API", + "ANDROID_API_MIN", + "ANDROID_ARCH", + "ANDROID_STL_TYPE", + // ---- macOS + "OSX_ARCHITECTURES", + // ---- Windows + "MSVC_DEBUG_INFORMATION_FORMAT", + "MSVC_RUNTIME_LIBRARY", + "VS_PLATFORM_TOOLSET", + // ---- OpenWatcom + "WATCOM_RUNTIME_LIBRARY", + // -- Language + // ---- C++ + "CXX_COMPILER_LAUNCHER", + "CXX_STANDARD", + "CXX_STANDARD_REQUIRED", + "CXX_EXTENSIONS", + "CXX_VISIBILITY_PRESET", + + // Static analysis + "CXX_CLANG_TIDY", + "CXX_CLANG_TIDY_EXPORT_FIXES_DIR", + "CXX_CPPLINT", + "CXX_CPPCHECK", + "CXX_INCLUDE_WHAT_YOU_USE", + + // Build graph properties + "EXCLUDE_FROM_ALL", + "EXCLUDE_FROM_DEFAULT_BUILD", + "OPTIMIZE_DEPENDENCIES", + // -- Ninja + "JOB_POOL_COMPILE", + // -- Visual Studio + "VS_NO_COMPILE_BATCHING", + "VS_PROJECT_IMPORT", + + // Metadata + "EchoString", + "EXPORT_COMPILE_COMMANDS", + "FOLDER", + "LABELS", + "PROJECT_LABEL", + "SYSTEM", + }; + + auto copyProperty = [this, tgt](std::string const& prop) -> cmValue { + cmValue value = tgt->GetProperty(prop); + // Always set the property; it may have been explicitly unset. + this->SetProperty(prop, value); + return value; + }; + + for (auto const& prop : propertiesToCopy) { + copyProperty(prop); + } + + static const cm::static_string_view perConfigPropertiesToCopy[] = { + "EXCLUDE_FROM_DEFAULT_BUILD_"_s, + "IMPORTED_CXX_MODULES_"_s, + "MAP_IMPORTED_CONFIG_"_s, + "OSX_ARCHITECTURES_"_s, + }; + + std::vector configNames = + this->impl->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig); + for (std::string const& configName : configNames) { + std::string configUpper = cmSystemTools::UpperCase(configName); + for (auto const& perConfigProp : perConfigPropertiesToCopy) { + copyProperty(cmStrCat(perConfigProp, configUpper)); + } + } + + if (this->GetGlobalGenerator()->IsXcode()) { + cmValue xcodeGenerateScheme = copyProperty("XCODE_GENERATE_SCHEME"); + + // TODO: Make sure these show up on the imported target in the first place + // XCODE_ATTRIBUTE_??? + + if (xcodeGenerateScheme.IsOn()) { +#ifdef __APPLE__ + static const std::string xcodeSchemePropertiesToCopy[] = { + // FIXME: Do all of these apply? Do they matter? + "XCODE_SCHEME_ADDRESS_SANITIZER", + "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN", + "XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER", + "XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS", + "XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE", + "XCODE_SCHEME_ENABLE_GPU_API_VALIDATION", + "XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION", + "XCODE_SCHEME_GUARD_MALLOC", + "XCODE_SCHEME_LAUNCH_CONFIGURATION", + "XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP", + "XCODE_SCHEME_MALLOC_GUARD_EDGES", + "XCODE_SCHEME_MALLOC_SCRIBBLE", + "XCODE_SCHEME_MALLOC_STACK", + "XCODE_SCHEME_THREAD_SANITIZER", + "XCODE_SCHEME_THREAD_SANITIZER_STOP", + "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER", + "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP", + "XCODE_SCHEME_ZOMBIE_OBJECTS", + }; + + for (auto const& xcodeProperty : xcodeSchemePropertiesToCopy) { + copyProperty(xcodeProperty); + } +#endif + } + } +} + cmBTStringRange cmTarget::GetHeaderSetsEntries() const { return cmMakeRange(this->impl->HeadersFileSets.SelfEntries.Entries); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index dae997f..b77ea0c 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -291,6 +291,10 @@ public: cmBTStringRange GetLinkInterfaceDirectEntries() const; cmBTStringRange GetLinkInterfaceDirectExcludeEntries() const; + void CopyPolicyStatuses(cmTarget const* tgt); + void CopyImportedCxxModulesEntries(cmTarget const* tgt); + void CopyImportedCxxModulesProperties(cmTarget const* tgt); + cmBTStringRange GetHeaderSetsEntries() const; cmBTStringRange GetCxxModuleSetsEntries() const; -- cgit v0.12 From 80ef50a1919d62acb82a6423c40042a94edeac60 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 21 Nov 2022 13:36:47 -0500 Subject: CXXModules: add a variable for BMI-only compilation This will be required when dealing with imported targets which contain modules. --- .gitlab/ci/cxx_modules_rules_gcc.cmake | 1 + Help/dev/experimental.rst | 6 ++++++ Modules/Compiler/Clang-CXX.cmake | 1 + Modules/Compiler/MSVC-CXX.cmake | 1 + 4 files changed, 9 insertions(+) diff --git a/.gitlab/ci/cxx_modules_rules_gcc.cmake b/.gitlab/ci/cxx_modules_rules_gcc.cmake index 3726f6d..020cb1f 100644 --- a/.gitlab/ci/cxx_modules_rules_gcc.cmake +++ b/.gitlab/ci/cxx_modules_rules_gcc.cmake @@ -17,3 +17,4 @@ string(CONCAT CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG " -fdeps-format=p1689r5" # Force C++ as a language. " -x c++") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG "-fmodule-only") diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index 5bfbf8d..89ebb3f 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst @@ -99,6 +99,10 @@ dependencies to the file specified by the ```` placeholder. The ``CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT`` file may be set to ``msvc`` for scandep rules which use ``msvc``-style dependency reporting. +In order to support ``IMPORTED`` targets with associated C++20 module sources, +the ``CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG`` variable must be provided +to have the compiler only output a BMI instead of a BMI and an object file. + The module dependencies should be written in the format described by the `P1689r5`_ paper. @@ -113,6 +117,8 @@ For compilers that generate module maps, tell CMake as follows: set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc") set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "${compiler_flags_for_module_map} -fmodule-mapper=") + set(CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG + "-fmodule-only") Currently, the only supported formats are, ``clang``, ``gcc``, and ``msvc``. The ``gcc`` format is described in the GCC documentation, but the relevant diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index a74e90b..1167ba8 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/Modules/Compiler/Clang-CXX.cmake @@ -43,5 +43,6 @@ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0) " > ") set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "clang") set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "@") + set(CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG "--precompile") endif() endif() diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake index 10a9073..b03f826 100644 --- a/Modules/Compiler/MSVC-CXX.cmake +++ b/Modules/Compiler/MSVC-CXX.cmake @@ -87,4 +87,5 @@ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.34") set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT "msvc") set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "msvc") set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "@") + set(CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG "-ifcOnly;-ifcOutput;") endif () -- cgit v0.12 From 9b9ec70b5421e8cf91e000d8b6636d7b0b721d1a Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 1 Feb 2023 10:40:19 -0500 Subject: Ninja: generate scanning and build rules for C++20 module synthetic targets --- Source/cmGlobalNinjaGenerator.cxx | 12 +- Source/cmNinjaNormalTargetGenerator.cxx | 97 ++++++++++++-- Source/cmNinjaNormalTargetGenerator.h | 3 + Source/cmNinjaTargetGenerator.cxx | 222 ++++++++++++++++++++++++++++++-- Source/cmNinjaTargetGenerator.h | 12 +- 5 files changed, 322 insertions(+), 24 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 9ca1b2e..54c3737 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -2643,7 +2643,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( for (cmScanDepInfo const& object : objects) { for (auto const& p : object.Provides) { std::string mod; - if (!p.CompiledModulePath.empty()) { + if (cmDyndepCollation::IsBmiOnly(export_info, object.PrimaryOutput)) { + mod = object.PrimaryOutput; + } else if (!p.CompiledModulePath.empty()) { // The scanner provided the path to the module file. mod = p.CompiledModulePath; if (!cmSystemTools::FileIsFullPath(mod)) { @@ -2714,8 +2716,12 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( build.Outputs[0] = this->ConvertToNinjaPath(object.PrimaryOutput); build.ImplicitOuts.clear(); for (auto const& p : object.Provides) { - build.ImplicitOuts.push_back( - this->ConvertToNinjaPath(mod_files[p.LogicalName].BmiPath)); + auto const implicitOut = + this->ConvertToNinjaPath(mod_files[p.LogicalName].BmiPath); + // Ignore the `provides` when the BMI is the output. + if (implicitOut != build.Outputs[0]) { + build.ImplicitOuts.emplace_back(implicitOut); + } } build.ImplicitDeps.clear(); for (auto const& r : object.Requires) { diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 089498b..48c30b6 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -62,12 +62,15 @@ cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default; void cmNinjaNormalTargetGenerator::Generate(const std::string& config) { - std::string lang = this->GeneratorTarget->GetLinkerLanguage(config); - if (this->TargetLinkLanguage(config).empty()) { - cmSystemTools::Error( - cmStrCat("CMake can not determine linker language for target: ", - this->GetGeneratorTarget()->GetName())); - return; + if (this->GetGeneratorTarget()->GetType() != + cmStateEnums::INTERFACE_LIBRARY) { + std::string lang = this->GeneratorTarget->GetLinkerLanguage(config); + if (this->TargetLinkLanguage(config).empty()) { + cmSystemTools::Error( + cmStrCat("CMake can not determine linker language for target: ", + this->GetGeneratorTarget()->GetName())); + return; + } } // Write the rules for each language. @@ -87,6 +90,34 @@ void cmNinjaNormalTargetGenerator::Generate(const std::string& config) if (this->GetGeneratorTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) { this->WriteObjectLibStatement(config); + } else if (this->GetGeneratorTarget()->GetType() == + cmStateEnums::INTERFACE_LIBRARY) { + bool haveCxxModuleSources = false; + if (this->GetGeneratorTarget()->HaveCxx20ModuleSources()) { + haveCxxModuleSources = true; + } + + if (!haveCxxModuleSources) { + cmSystemTools::Error(cmStrCat( + "Ninja does not support INTERFACE libraries without C++ module " + "sources as a normal target: ", + this->GetGeneratorTarget()->GetName())); + return; + } + + firstForConfig = true; + for (auto const& fileConfig : this->GetConfigNames()) { + if (!this->GetGlobalGenerator() + ->GetCrossConfigs(fileConfig) + .count(config)) { + continue; + } + if (haveCxxModuleSources) { + this->WriteCxxModuleLibraryStatement(config, fileConfig, + firstForConfig); + } + firstForConfig = false; + } } else { firstForConfig = true; for (auto const& fileConfig : this->GetConfigNames()) { @@ -123,12 +154,26 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules( #endif // Write rules for languages compiled in this target. - std::set languages; - std::vector sourceFiles; - this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config); - if (this->HaveRequiredLanguages(sourceFiles, languages)) { - for (std::string const& language : languages) { - this->WriteLanguageRules(language, config); + { + std::set languages; + std::vector sourceFiles; + this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config); + if (this->HaveRequiredLanguages(sourceFiles, languages)) { + for (std::string const& language : languages) { + this->WriteLanguageRules(language, config); + } + } + } + + // Write rules for languages in BMI-only rules. + { + std::set languages; + std::vector sourceFiles; + this->GetGeneratorTarget()->GetCxxModuleSources(sourceFiles, config); + if (this->HaveRequiredLanguages(sourceFiles, languages)) { + for (std::string const& language : languages) { + this->WriteLanguageRules(language, config); + } } } } @@ -1637,6 +1682,34 @@ void cmNinjaNormalTargetGenerator::WriteObjectLibStatement( this->GetTargetName(), this->GetGeneratorTarget(), config); } +void cmNinjaNormalTargetGenerator::WriteCxxModuleLibraryStatement( + const std::string& config, const std::string& /*fileConfig*/, + bool firstForConfig) +{ + // TODO: How to use `fileConfig` properly? + + // Write a phony output that depends on the scanning output. + { + cmNinjaBuild build("phony"); + build.Comment = + cmStrCat("Imported C++ module library ", this->GetTargetName()); + this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(), + build.Outputs, config); + if (firstForConfig) { + this->GetLocalGenerator()->AppendTargetOutputs( + this->GetGeneratorTarget(), + this->GetGlobalGenerator()->GetByproductsForCleanTarget(config), + config); + } + build.ExplicitDeps.emplace_back(this->GetDyndepFilePath("CXX", config)); + this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), build); + } + + // Add aliases for the target name. + this->GetGlobalGenerator()->AddTargetAlias( + this->GetTargetName(), this->GetGeneratorTarget(), config); +} + cmGeneratorTarget::Names cmNinjaNormalTargetGenerator::TargetNames( const std::string& config) const { diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h index 187ea46..3ef0230 100644 --- a/Source/cmNinjaNormalTargetGenerator.h +++ b/Source/cmNinjaNormalTargetGenerator.h @@ -49,6 +49,9 @@ private: const std::string& output); void WriteObjectLibStatement(const std::string& config); + void WriteCxxModuleLibraryStatement(const std::string& config, + const std::string& fileConfig, + bool firstForConfig); std::vector ComputeLinkCmd(const std::string& config); std::vector ComputeDeviceLinkCmd(); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 6792cd7..09f8495 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -28,6 +28,7 @@ #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" +#include "cmGlobalCommonGenerator.h" #include "cmGlobalNinjaGenerator.h" #include "cmList.h" #include "cmLocalGenerator.h" @@ -59,8 +60,13 @@ std::unique_ptr cmNinjaTargetGenerator::New( case cmStateEnums::OBJECT_LIBRARY: return cm::make_unique(target); - case cmStateEnums::UTILITY: case cmStateEnums::INTERFACE_LIBRARY: + if (target->HaveCxx20ModuleSources()) { + return cm::make_unique(target); + } + CM_FALLTHROUGH; + + case cmStateEnums::UTILITY: case cmStateEnums::GLOBAL_TARGET: return cm::make_unique(target); @@ -167,7 +173,7 @@ std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget( // Refactor it. std::string cmNinjaTargetGenerator::ComputeFlagsForObject( cmSourceFile const* source, const std::string& language, - const std::string& config) + const std::string& config, const std::string& objectFileName) { std::unordered_map pchSources; std::vector architectures = @@ -247,6 +253,18 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject( "\nin a file set of type \"", fs->GetType(), R"(" but the source is not classified as a "CXX" source.)")); } + + if (!this->GeneratorTarget->Target->IsNormal()) { + auto flag = this->GetMakefile()->GetSafeDefinition( + "CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG"); + cmRulePlaceholderExpander::RuleVariables compileObjectVars; + compileObjectVars.Object = objectFileName.c_str(); + auto rulePlaceholderExpander = + this->GetLocalGenerator()->CreateRulePlaceholderExpander(); + rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), + flag, compileObjectVars); + this->LocalGenerator->AppendCompileOptions(flags, flag); + } } return flags; @@ -394,6 +412,31 @@ std::string cmNinjaTargetGenerator::GetObjectFilePath( return path; } +std::string cmNinjaTargetGenerator::GetBmiFilePath( + cmSourceFile const* source, const std::string& config) const +{ + std::string path = this->LocalGenerator->GetHomeRelativeOutputPath(); + if (!path.empty()) { + path += '/'; + } + + auto& importedConfigInfo = this->Configs.at(config).ImportedCxxModules; + if (!importedConfigInfo.Initialized()) { + std::string configUpper = cmSystemTools::UpperCase(config); + std::string propName = cmStrCat("IMPORTED_CXX_MODULES_", configUpper); + auto value = this->GeneratorTarget->GetSafeProperty(propName); + importedConfigInfo.Initialize(value); + } + + std::string bmiName = + importedConfigInfo.BmiNameForSource(source->GetFullPath()); + + path += cmStrCat( + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), + this->GetGlobalGenerator()->ConfigDirectory(config), '/', bmiName); + return path; +} + std::string cmNinjaTargetGenerator::GetClangTidyReplacementsFilePath( std::string const& directory, cmSourceFile const& source, std::string const& config) const @@ -1027,6 +1070,16 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements( } } + { + std::vector bmiOnlySources; + this->GeneratorTarget->GetCxxModuleSources(bmiOnlySources, config); + + for (cmSourceFile const* sf : bmiOnlySources) { + this->WriteCxxModuleBmiBuildStatement(sf, config, fileConfig, + firstForConfig); + } + } + for (auto const& langScanningFiles : this->Configs[config].ScanningInfo) { std::string const& language = langScanningFiles.first; std::vector const& scanningFiles = langScanningFiles.second; @@ -1149,22 +1202,22 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName, scanBuild.Variables["OBJ_FILE"] = objectFileName; // Tell dependency scanner where to store dyndep intermediate results. - std::string const& ddiFile = cmStrCat(objectFileName, ".ddi"); - scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile; + std::string ddiFileName = cmStrCat(objectFileName, ".ddi"); + scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFileName; // Outputs of the scan/preprocessor build statement. if (compilePP) { scanBuild.Outputs.push_back(ppFileName); - scanBuild.ImplicitOuts.push_back(ddiFile); + scanBuild.ImplicitOuts.push_back(ddiFileName); } else { - scanBuild.Outputs.push_back(ddiFile); + scanBuild.Outputs.push_back(ddiFileName); scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName; if (!compilationPreprocesses) { // Compilation does not preprocess and we are not compiling an // already-preprocessed source. Make compilation depend on the scan // results to honor implicit dependencies discovered during scanning // (such as Fortran INCLUDE directives). - objBuild.ImplicitDeps.emplace_back(ddiFile); + objBuild.ImplicitDeps.emplace_back(ddiFileName); } } @@ -1214,7 +1267,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( cmNinjaBuild objBuild(this->LanguageCompilerRule( language, config, needDyndep ? WithScanning::Yes : WithScanning::No)); cmNinjaVars& vars = objBuild.Variables; - vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config); + vars["FLAGS"] = + this->ComputeFlagsForObject(source, language, config, objectFileName); vars["DEFINES"] = this->ComputeDefines(source, language, config); vars["INCLUDES"] = this->ComputeIncludes(source, language, config); @@ -1545,6 +1599,155 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( } } +void cmNinjaTargetGenerator::WriteCxxModuleBmiBuildStatement( + cmSourceFile const* source, const std::string& config, + const std::string& fileConfig, bool firstForConfig) +{ + std::string const language = source->GetLanguage(); + if (language != "CXX"_s) { + this->GetMakefile()->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Source file '", source->GetFullPath(), "' of target '", + this->GetTargetName(), "' is a '", language, + "' source but must be 'CXX' in order to have a BMI build " + "statement generated.")); + return; + } + + std::string const sourceFilePath = this->GetCompiledSourceNinjaPath(source); + std::string const bmiDir = this->ConvertToNinjaPath( + cmStrCat(this->GeneratorTarget->GetSupportDirectory(), + this->GetGlobalGenerator()->ConfigDirectory(config))); + std::string const bmiFileName = + this->ConvertToNinjaPath(this->GetBmiFilePath(source, config)); + std::string const bmiFileDir = cmSystemTools::GetFilenamePath(bmiFileName); + + int const commandLineLengthLimit = this->ForceResponseFile() ? -1 : 0; + + cmNinjaBuild bmiBuild( + this->LanguageCompilerRule(language, config, WithScanning::Yes)); + cmNinjaVars& vars = bmiBuild.Variables; + vars["FLAGS"] = + this->ComputeFlagsForObject(source, language, config, bmiFileName); + vars["DEFINES"] = this->ComputeDefines(source, language, config); + vars["INCLUDES"] = this->ComputeIncludes(source, language, config); + + if (this->GetMakefile()->GetSafeDefinition( + cmStrCat("CMAKE_", language, "_DEPFILE_FORMAT")) != "msvc"_s) { + bool replaceExt(false); + if (!language.empty()) { + std::string repVar = + cmStrCat("CMAKE_", language, "_DEPFILE_EXTENSION_REPLACE"); + replaceExt = this->Makefile->IsOn(repVar); + } + if (!replaceExt) { + // use original code + vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat( + cmStrCat(bmiFileName, ".d"), cmOutputConverter::SHELL); + } else { + // Replace the original source file extension with the + // depend file extension. + std::string dependFileName = cmStrCat( + cmSystemTools::GetFilenameWithoutLastExtension(bmiFileName), ".d"); + vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat( + cmStrCat(bmiFileDir, '/', dependFileName), cmOutputConverter::SHELL); + } + } + + std::string d = + this->GeneratorTarget->GetClangTidyExportFixesDirectory(language); + if (!d.empty()) { + this->GlobalCommonGenerator->AddClangTidyExportFixesDir(d); + std::string fixesFile = + this->GetClangTidyReplacementsFilePath(d, *source, config); + this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile); + cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(fixesFile)); + fixesFile = this->ConvertToNinjaPath(fixesFile); + vars["CLANG_TIDY_EXPORT_FIXES"] = fixesFile; + } + + if (firstForConfig) { + this->ExportObjectCompileCommand( + language, sourceFilePath, bmiDir, bmiFileName, bmiFileDir, vars["FLAGS"], + vars["DEFINES"], vars["INCLUDES"], config); + } + + bmiBuild.Outputs.push_back(bmiFileName); + bmiBuild.ExplicitDeps.push_back(sourceFilePath); + + std::vector depList; + + std::vector architectures = + this->GeneratorTarget->GetAppleArchs(config, language); + if (architectures.empty()) { + architectures.emplace_back(); + } + + bmiBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget(config)); + + // For some cases we scan to dynamically discover dependencies. + std::string modmapFormat; + if (true) { + std::string const modmapFormatVar = + cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FORMAT"); + modmapFormat = this->Makefile->GetSafeDefinition(modmapFormatVar); + } + + { + bool const compilePPWithDefines = this->CompileWithDefines(language); + + std::string scanRuleName = this->LanguageScanRule(language, config); + std::string ppFileName = cmStrCat(bmiFileName, ".ddi.i"); + + cmNinjaBuild ppBuild = GetScanBuildStatement( + scanRuleName, ppFileName, false, compilePPWithDefines, true, bmiBuild, + vars, bmiFileName, this->LocalGenerator); + + ScanningFiles scanningFiles; + + if (firstForConfig) { + scanningFiles.ScanningOutput = cmStrCat(bmiFileName, ".ddi"); + } + + this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(), + ppBuild.Variables); + + this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig), + ppBuild, commandLineLengthLimit); + + std::string const dyndep = this->GetDyndepFilePath(language, config); + bmiBuild.OrderOnlyDeps.push_back(dyndep); + vars["dyndep"] = dyndep; + + if (!modmapFormat.empty()) { + std::string ddModmapFile = cmStrCat(bmiFileName, ".modmap"); + vars["DYNDEP_MODULE_MAP_FILE"] = ddModmapFile; + scanningFiles.ModuleMapFile = std::move(ddModmapFile); + } + + if (!scanningFiles.IsEmpty()) { + this->Configs[config].ScanningInfo[language].emplace_back(scanningFiles); + } + } + + this->EnsureParentDirectoryExists(bmiFileName); + + vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat( + bmiDir, cmOutputConverter::SHELL); + vars["OBJECT_FILE_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat( + bmiFileDir, cmOutputConverter::SHELL); + + this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(), + vars); + + this->SetMsvcTargetPdbVariable(vars, config); + + bmiBuild.RspFile = cmStrCat(bmiFileName, ".rsp"); + + this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig), + bmiBuild, commandLineLengthLimit); +} + void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang, const std::string& config) { @@ -1605,6 +1808,9 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang, cb.ObjectFilePath = [this](cmSourceFile const* sf, std::string const& cnf) { return this->GetObjectFilePath(sf, cnf); }; + cb.BmiFilePath = [this](cmSourceFile const* sf, std::string const& cnf) { + return this->GetBmiFilePath(sf, cnf); + }; #if !defined(CMAKE_BOOTSTRAP) cmDyndepCollation::AddCollationInformation(tdi, this->GeneratorTarget, diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 8c38499..49e7018 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -15,6 +15,7 @@ #include "cmCommonTargetGenerator.h" #include "cmGlobalNinjaGenerator.h" +#include "cmImportedCxxModuleInfo.h" #include "cmNinjaTypes.h" #include "cmOSXBundleGenerator.h" @@ -91,7 +92,8 @@ protected: */ std::string ComputeFlagsForObject(cmSourceFile const* source, const std::string& language, - const std::string& config); + const std::string& config, + const std::string& objectFileName); void AddIncludeFlags(std::string& flags, std::string const& lang, const std::string& config) override; @@ -129,6 +131,8 @@ protected: /// @return the object file path for the given @a source. std::string GetObjectFilePath(cmSourceFile const* source, const std::string& config) const; + std::string GetBmiFilePath(cmSourceFile const* source, + const std::string& config) const; /// @return the preprocessed source file path for the given @a source. std::string GetPreprocessedFilePath(cmSourceFile const* source, @@ -163,6 +167,10 @@ protected: void WriteObjectBuildStatements(const std::string& config, const std::string& fileConfig, bool firstForConfig); + void WriteCxxModuleBmiBuildStatement(cmSourceFile const* source, + const std::string& config, + const std::string& fileConfig, + bool firstForConfig); void WriteObjectBuildStatement(cmSourceFile const* source, const std::string& config, const std::string& fileConfig, @@ -239,6 +247,8 @@ private: cmNinjaDeps Objects; // Dyndep Support std::map> ScanningInfo; + // Imported C++ module info. + mutable ImportedCxxModuleLookup ImportedCxxModules; // Swift Support Json::Value SwiftOutputMap; std::vector CustomCommands; -- cgit v0.12 From 457a12f3f9b68a548dd44d1dcb6f531e46a98314 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 18 Nov 2022 19:44:44 -0500 Subject: Tests/RunCMake/CXXModules: add tests which use modules from imported targets --- Tests/RunCMake/CXXModules/RunCMakeTest.cmake | 26 ++++++++++++++++++++++ .../examples/export-usage-build/importable.cxx | 2 ++ .../examples/export-usage-install/importable.cxx | 2 ++ ...dules-export-bmi-and-interface-build-stderr.txt | 7 ++++++ ...les-export-bmi-and-interface-install-stderr.txt | 7 ++++++ ...mport-modules-export-interface-build-stderr.txt | 7 ++++++ ...ort-modules-export-interface-install-stderr.txt | 7 ++++++ ...export-interface-no-properties-build-stderr.txt | 7 ++++++ ...port-interface-no-properties-install-stderr.txt | 7 ++++++ .../examples/import-modules/CMakeLists.txt | 24 ++++++++++++++++++++ .../CXXModules/examples/import-modules/use.cxx | 6 +++++ 11 files changed, 102 insertions(+) create mode 100644 Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-build-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-install-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/examples/import-modules-export-interface-build-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/examples/import-modules-export-interface-install-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-build-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-install-stderr.txt create mode 100644 Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt create mode 100644 Tests/RunCMake/CXXModules/examples/import-modules/use.cxx diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake index d2fb11f..0ca9945 100644 --- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake +++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake @@ -189,6 +189,18 @@ if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION) run_cxx_module_test(export-interface-build) run_cxx_module_test(export-usage-build) run_cxx_module_test(export-bmi-and-interface-build) + + if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND + "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION) + set(test_suffix export-interface-build) + run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build") + + set(test_suffix export-interface-no-properties-build) + run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build" -DNO_PROPERTIES=1) + + set(test_suffix export-bmi-and-interface-build) + run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-build" -DWITH_BMIS=1) + endif () endif () # All of the following tests perform installation. @@ -204,5 +216,19 @@ if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION) run_cxx_module_test(export-interface-install) run_cxx_module_test(export-usage-install) run_cxx_module_test(export-bmi-and-interface-install) + + if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND + "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION) + set(RunCMake_CXXModules_INSTALL 0) + set(test_suffix export-interface-install) + run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install") + + set(test_suffix export-interface-no-properties-install) + run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install" -DNO_PROPERTIES=1) + + set(test_suffix export-bmi-and-interface-install) + run_cxx_module_test(import-modules "import-modules-${test_suffix}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${test_suffix}-install" -DWITH_BMIS=1) + set(RunCMake_CXXModules_INSTALL 1) + endif () endif () endif () diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx index e0b1872..8dfc41b 100644 --- a/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx +++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx @@ -1,6 +1,8 @@ export module importable; +extern "C++" { int forwarding(); +} export int from_import() { diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx index e0b1872..8dfc41b 100644 --- a/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx +++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx @@ -1,6 +1,8 @@ export module importable; +extern "C++" { int forwarding(); +} export int from_import() { diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-build-stderr.txt new file mode 100644 index 0000000..71ee795 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-build-stderr.txt @@ -0,0 +1,7 @@ +CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build-build/export_bmi_and_interfaces-targets.cmake:[0-9]* \(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\): + .*/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build-build/export_bmi_and_interfaces-config.cmake:1 \(include\) + CMakeLists.txt:15 \(find_package\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-install-stderr.txt new file mode 100644 index 0000000..d22b2a1 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-bmi-and-interface-install-stderr.txt @@ -0,0 +1,7 @@ +CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install-install/lib/cmake/export_bmi_and_interfaces/export_bmi_and_interfaces-targets.cmake:[0-9]* \(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\): + .*/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install-install/lib/cmake/export_bmi_and_interfaces/export_bmi_and_interfaces-config.cmake:1 \(include\) + CMakeLists.txt:15 \(find_package\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-build-stderr.txt new file mode 100644 index 0000000..f79abbc --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-build-stderr.txt @@ -0,0 +1,7 @@ +CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-interface-build-build/export_interfaces-targets.cmake:[0-9]* \(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\): + .*/Tests/RunCMake/CXXModules/examples/export-interface-build-build/export_interfaces-config.cmake:1 \(include\) + CMakeLists.txt:15 \(find_package\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-install-stderr.txt new file mode 100644 index 0000000..32f9452 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-install-stderr.txt @@ -0,0 +1,7 @@ +CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-interface-install-install/lib/cmake/export_interfaces/export_interfaces-targets.cmake:[0-9]* \(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\): + .*/Tests/RunCMake/CXXModules/examples/export-interface-install-install/lib/cmake/export_interfaces/export_interfaces-config.cmake:1 \(include\) + CMakeLists.txt:15 \(find_package\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-build-stderr.txt new file mode 100644 index 0000000..9254936 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-build-stderr.txt @@ -0,0 +1,7 @@ +CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build-build/export_interfaces_no_properties-targets.cmake:[0-9]* \(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\): + .*/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build-build/export_interfaces_no_properties-config.cmake:1 \(include\) + CMakeLists.txt:15 \(find_package\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-install-stderr.txt new file mode 100644 index 0000000..71269f4 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/import-modules-export-interface-no-properties-install-stderr.txt @@ -0,0 +1,7 @@ +CMake Warning \(dev\) at .*/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install-install/lib/cmake/export_interfaces_no_properties/export_interfaces_no_properties-targets.cmake:[0-9]* \(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\): + .*/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install-install/lib/cmake/export_interfaces_no_properties/export_interfaces_no_properties-config.cmake:1 \(include\) + CMakeLists.txt:15 \(find_package\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt new file mode 100644 index 0000000..3e6f379 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.24) +project(cxx_modules_import_interfaces CXX) + +include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") + +if (NO_PROPERTIES) + set(package_name "export_interfaces_no_properties") +elseif (WITH_BMIS) + set(package_name "export_bmi_and_interfaces") +else () + set(package_name "export_interfaces") +endif () +set(target_name "CXXModules::${package_name}") + +find_package("${package_name}" REQUIRED) + +add_executable(use_import_interfaces) +target_sources(use_import_interfaces + PRIVATE + use.cxx) +target_compile_features(use_import_interfaces PRIVATE cxx_std_20) +target_link_libraries(use_import_interfaces PRIVATE "${target_name}") + +add_test(NAME use_import_interfaces COMMAND use_import_interfaces) diff --git a/Tests/RunCMake/CXXModules/examples/import-modules/use.cxx b/Tests/RunCMake/CXXModules/examples/import-modules/use.cxx new file mode 100644 index 0000000..feb38d2 --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/import-modules/use.cxx @@ -0,0 +1,6 @@ +import importable; + +int main(int argc, char* argv[]) +{ + return from_import(); +} -- cgit v0.12 From 1a1806a71b72f12928dca52478db079713ee0eb5 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 6 Jun 2023 14:02:35 -0400 Subject: gitlab-ci: declare `bmionly` support for modules where possible GCC and Clang both have the settings. --- .gitlab/ci/configure_fedora38_ninja_clang.cmake | 2 +- .gitlab/ci/configure_fedora38_ninja_multi_clang.cmake | 2 +- .gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake | 2 +- .gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake | 2 +- .gitlab/ci/configure_windows_clang_ninja.cmake | 2 +- .gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitlab/ci/configure_fedora38_ninja_clang.cmake b/.gitlab/ci/configure_fedora38_ninja_clang.cmake index 4454647..848c5b6 100644 --- a/.gitlab/ci/configure_fedora38_ninja_clang.cmake +++ b/.gitlab/ci/configure_fedora38_ninja_clang.cmake @@ -1,4 +1,4 @@ -set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "") +set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly" CACHE STRING "") set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "") include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora38_common_clang.cmake") diff --git a/.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake b/.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake index 4454647..848c5b6 100644 --- a/.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake +++ b/.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake @@ -1,4 +1,4 @@ -set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "") +set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly" CACHE STRING "") set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "") include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora38_common_clang.cmake") diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake index e9121ae..8342db6 100644 --- a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake +++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake @@ -1,4 +1,4 @@ -set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "") +set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,bmionly" CACHE STRING "") set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "") include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake") diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake index e9121ae..8342db6 100644 --- a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake +++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake @@ -1,4 +1,4 @@ -set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "") +set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,bmionly" CACHE STRING "") set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "") include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake") diff --git a/.gitlab/ci/configure_windows_clang_ninja.cmake b/.gitlab/ci/configure_windows_clang_ninja.cmake index d1f0f52..8a65eef 100644 --- a/.gitlab/ci/configure_windows_clang_ninja.cmake +++ b/.gitlab/ci/configure_windows_clang_ninja.cmake @@ -1,5 +1,5 @@ if("$ENV{CMAKE_CI_BUILD_NAME}" MATCHES "(^|_)gnu(_|$)") - set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "") + set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly" CACHE STRING "") set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "") endif() include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_clang_common.cmake") diff --git a/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake b/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake index 5f2a215..2349bfd 100644 --- a/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake +++ b/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake @@ -1,2 +1,2 @@ -set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,shared,export_bmi,install_bmi" CACHE STRING "") +set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,shared,export_bmi,install_bmi,bmionly" CACHE STRING "") set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_msvc.cmake" CACHE STRING "") -- cgit v0.12 From 48ee946fdcb8a610653e7ba42e9b8dba6942dbfb Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 7 Aug 2023 17:38:32 -0400 Subject: cmExperimental: recycle the C++ modules API UUID Supporting modules on IMPORTED targets is worth an update. --- Help/dev/experimental.rst | 2 +- Source/cmExperimental.cxx | 2 +- Tests/RunCMake/CXXModules/CMakeLists.txt | 2 +- Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake | 2 +- .../examples/export-bmi-and-interface-build/test/CMakeLists.txt | 2 +- .../examples/export-bmi-and-interface-install/test/CMakeLists.txt | 2 +- .../CXXModules/examples/export-interface-build/test/CMakeLists.txt | 2 +- .../CXXModules/examples/export-interface-install/test/CMakeLists.txt | 2 +- .../examples/export-interface-no-properties-build/test/CMakeLists.txt | 2 +- .../examples/export-interface-no-properties-install/test/CMakeLists.txt | 2 +- .../RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt | 2 +- .../CXXModules/examples/export-usage-install/test/CMakeLists.txt | 2 +- Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake | 2 +- Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index 89ebb3f..046d214 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst @@ -18,7 +18,7 @@ C++20 Module APIs ================= Variable: ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` -Value: ``a816ed09-43d1-40e5-bc8c-1a2824ee194e`` +Value: ``ac01f462-0f5f-432a-86aa-acef252918a6`` 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 diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx index dd8f16e..104ab81 100644 --- a/Source/cmExperimental.cxx +++ b/Source/cmExperimental.cxx @@ -21,7 +21,7 @@ namespace { cmExperimental::FeatureData LookupTable[] = { // CxxModuleCMakeApi { "CxxModuleCMakeApi", - "a816ed09-43d1-40e5-bc8c-1a2824ee194e", + "ac01f462-0f5f-432a-86aa-acef252918a6", "CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API", "CMake's C++ module support is experimental. It is meant only for " "experimentation and feedback to CMake developers.", diff --git a/Tests/RunCMake/CXXModules/CMakeLists.txt b/Tests/RunCMake/CXXModules/CMakeLists.txt index ecc66b6..e23023d 100644 --- a/Tests/RunCMake/CXXModules/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.23) project(${RunCMake_TEST} NONE) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake b/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake index 6238d37..5f32364 100644 --- a/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake +++ b/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake @@ -1,4 +1,4 @@ -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") if (NOT EXISTS "${CMake_TEST_MODULE_COMPILATION_RULES}") message(FATAL_ERROR diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt index 4d7a85b..c17577c 100644 --- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(cxx_modules_library NONE) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") find_package(export_bmi_and_interfaces REQUIRED) diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt index b96328f..d608d67 100644 --- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(cxx_modules_library NONE) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") find_package(export_bmi_and_interfaces REQUIRED) diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt index 74f16a6..106bd1e 100644 --- a/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(cxx_modules_library NONE) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") find_package(export_interfaces REQUIRED) diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt index a4c9225..c19283b 100644 --- a/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(cxx_modules_library NONE) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") find_package(export_interfaces REQUIRED) diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt index 7f145ba2..fba05f4 100644 --- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(cxx_modules_library NONE) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") find_package(export_interfaces_no_properties REQUIRED) diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt index 7f145ba2..fba05f4 100644 --- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(cxx_modules_library NONE) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") find_package(export_interfaces_no_properties REQUIRED) diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt index 88bda88..adec9e7 100644 --- a/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(cxx_modules_library NONE) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") find_package(export_usage REQUIRED) diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt index bdc2898..9ccd63a 100644 --- a/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(cxx_modules_library NONE) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") find_package(export_usage REQUIRED) diff --git a/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake index 0826686..9a8429d 100644 --- a/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake +++ b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake @@ -1,6 +1,6 @@ enable_language(C) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") add_library(lib1 STATIC empty.c) target_sources(lib1 PRIVATE FILE_SET UNKNOWN) diff --git a/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake index 7935178..f63308c 100644 --- a/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake +++ b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake @@ -1,6 +1,6 @@ enable_language(C) -set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "a816ed09-43d1-40e5-bc8c-1a2824ee194e") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "ac01f462-0f5f-432a-86aa-acef252918a6") add_library(lib1 STATIC empty.c) target_sources(lib1 PRIVATE FILE_SET a TYPE UNKNOWN) -- cgit v0.12