From 28333c4516879c88ab04754d5410efe2075211c5 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 30 Apr 2025 13:47:27 +0200 Subject: [PATCH 1/3] Clang/CXXImportStd: support `-stdlib=libstdc++` Fedora 42 ships `clang` with `libstdc++` as the default. Detect and support `import std;` in this configuration. --- Help/manual/cmake-cxxmodules.7.rst | 2 +- Modules/Compiler/Clang-CXX-CXXImportStd.cmake | 49 ++++++++++++------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/Help/manual/cmake-cxxmodules.7.rst b/Help/manual/cmake-cxxmodules.7.rst index 30c7a4a24d..83b7083735 100644 --- a/Help/manual/cmake-cxxmodules.7.rst +++ b/Help/manual/cmake-cxxmodules.7.rst @@ -92,7 +92,7 @@ Compilers which CMake natively supports module dependency scanning include: Support for ``import std`` is limited to the following toolchain and standard library combinations: -* Clang 18.1.2 and newer with ``-stdlib=libc++`` +* Clang 18.1.2 and newer with ``-stdlib=libc++`` or ``-stdlib=libstdc++`` * MSVC toolset 14.36 and newer (provided with Visual Studio 17.6 Preview 2 and newer) diff --git a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake index f58f17ea65..5330eb1a3a 100644 --- a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake +++ b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake @@ -1,7 +1,11 @@ function (_cmake_cxx_import_std std variable) - if (NOT CMAKE_CXX_STANDARD_LIBRARY STREQUAL "libc++") + if (CMAKE_CXX_STANDARD_LIBRARY STREQUAL "libc++") + set(_clang_modules_json_impl "libc++") + elseif (CMAKE_CXX_STANDARD_LIBRARY STREQUAL "libstdc++") + set(_clang_modules_json_impl "libstdc++") + else () set("${variable}" - "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Only `libc++` is supported\")\n" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Only `libc++` and `libstdc++` are supported\")\n" PARENT_SCOPE) return () endif () @@ -10,7 +14,7 @@ function (_cmake_cxx_import_std std variable) COMMAND "${CMAKE_CXX_COMPILER}" ${CMAKE_CXX_COMPILER_ID_ARG1} - -print-file-name=libc++.modules.json + "-print-file-name=${_clang_modules_json_impl}.modules.json" OUTPUT_VARIABLE _clang_libcxx_modules_json_file ERROR_VARIABLE _clang_libcxx_modules_json_file_err RESULT_VARIABLE _clang_libcxx_modules_json_file_res @@ -18,7 +22,7 @@ function (_cmake_cxx_import_std std variable) ERROR_STRIP_TRAILING_WHITESPACE) if (_clang_libcxx_modules_json_file_res) set("${variable}" - "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `libc++.modules.json` resource\")\n" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `${_clang_modules_json_impl}.modules.json` resource\")\n" PARENT_SCOPE) return () endif () @@ -26,17 +30,18 @@ function (_cmake_cxx_import_std std variable) # Without this file, we do not have modules installed. if (NOT EXISTS "${_clang_libcxx_modules_json_file}") set("${variable}" - "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`libc++.modules.json` resource does not exist\")\n" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`${_clang_modules_json_impl}.modules.json` resource does not exist\")\n" PARENT_SCOPE) return () endif () - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "18.1.2") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "18.1.2" AND + CMAKE_CXX_STANDARD_LIBRARY STREQUAL "libc++") # The original PR had a key spelling mismatch internally. Do not support it # and instead require a release known to have the fix. # https://github.com/llvm/llvm-project/pull/83036 set("${variable}" - "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"LLVM 18.1.2 is required for `libc++.modules.json` format fix\")\n" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"LLVM 18.1.2 is required for `${_clang_modules_json_impl}.modules.json` format fix\")\n" PARENT_SCOPE) return () endif () @@ -91,9 +96,15 @@ function (_cmake_cxx_import_std std variable) string(JSON _clang_modules_json_module_source GET "${_clang_modules_json_module}" "source-path") string(JSON _clang_modules_json_module_is_stdlib GET "${_clang_modules_json_module}" "is-std-library") - string(JSON _clang_modules_json_module_local_arguments GET "${_clang_modules_json_module}" "local-arguments") - string(JSON _clang_modules_json_module_nsystem_include_directories LENGTH "${_clang_modules_json_module_local_arguments}" "system-include-directories") + string(JSON _clang_modules_json_module_local_arguments ERROR_VARIABLE _clang_modules_json_module_local_arguments_error GET "${_clang_modules_json_module}" "local-arguments") + string(JSON _clang_modules_json_module_nsystem_include_directories ERROR_VARIABLE _clang_modules_json_module_nsystem_include_directories_error LENGTH "${_clang_modules_json_module_local_arguments}" "system-include-directories") + if (_clang_modules_json_module_local_arguments_error) + set(_clang_modules_json_module_local_arguments "") + endif () + if (_clang_modules_json_module_nsystem_include_directories_error) + set(_clang_modules_json_module_nsystem_include_directories 0) + endif () if (NOT IS_ABSOLUTE "${_clang_modules_json_module_source}") string(PREPEND _clang_modules_json_module_source "${_clang_modules_dir}/") endif () @@ -104,16 +115,18 @@ function (_cmake_cxx_import_std std variable) set(_clang_modules_is_stdlib 1) endif () - math(EXPR _clang_modules_json_module_nsystem_include_directories_range "${_clang_modules_json_module_nsystem_include_directories} - 1") - foreach (_clang_modules_json_modules_system_include_directories_idx RANGE 0 "${_clang_modules_json_module_nsystem_include_directories_range}") - string(JSON _clang_modules_json_module_system_include_directory GET "${_clang_modules_json_module_local_arguments}" "system-include-directories" "${_clang_modules_json_modules_system_include_directories_idx}") + if (_clang_modules_json_module_nsystem_include_directories) + math(EXPR _clang_modules_json_module_nsystem_include_directories_range "${_clang_modules_json_module_nsystem_include_directories} - 1") + foreach (_clang_modules_json_modules_system_include_directories_idx RANGE 0 "${_clang_modules_json_module_nsystem_include_directories_range}") + string(JSON _clang_modules_json_module_system_include_directory GET "${_clang_modules_json_module_local_arguments}" "system-include-directories" "${_clang_modules_json_modules_system_include_directories_idx}") - if (NOT IS_ABSOLUTE "${_clang_modules_json_module_system_include_directory}") - string(PREPEND _clang_modules_json_module_system_include_directory "${_clang_modules_dir}/") - endif () - list(APPEND _clang_modules_include_dirs_list - "${_clang_modules_json_module_system_include_directory}") - endforeach () + if (NOT IS_ABSOLUTE "${_clang_modules_json_module_system_include_directory}") + string(PREPEND _clang_modules_json_module_system_include_directory "${_clang_modules_dir}/") + endif () + list(APPEND _clang_modules_include_dirs_list + "${_clang_modules_json_module_system_include_directory}") + endforeach () + endif () endforeach () # Split the paths into basedirs and module paths. From 52e27850186f357845ad3a62eb4005eaf87b9c6a Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 30 Apr 2025 13:48:13 +0200 Subject: [PATCH 2/3] experimental/CXXModules: recycle the UUID Now that `clang -stdlib=libstdc++` is supported. --- Help/dev/experimental.rst | 2 +- Source/cmExperimental.cxx | 2 +- .../examples/import-std-export-no-std-build/CMakeLists.txt | 2 +- .../examples/import-std-export-no-std-install/CMakeLists.txt | 2 +- .../examples/import-std-no-std-property/CMakeLists.txt | 2 +- .../examples/import-std-not-in-export-build/CMakeLists.txt | 2 +- .../examples/import-std-not-in-export-install/CMakeLists.txt | 2 +- .../CXXModules/examples/import-std-transitive/CMakeLists.txt | 2 +- Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt | 2 +- .../RunCMake/cmake_language/Experimental/CxxImportStd-set.cmake | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index 6ad1a3bcc6..81ddc8c38c 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst @@ -81,7 +81,7 @@ In order to activate support for ``import std`` in C++23 and newer targets, set * variable ``CMAKE_EXPERIMENTAL_CXX_IMPORT_STD`` to -* value ``a9e1cf81-9932-4810-974b-6eccaf14e457``. +* value ``d0edc3af-4c50-42ea-a356-e2862fe7a444``. This UUID may change in future versions of CMake. Be sure to use the value documented here by the source tree of the version of CMake with which you are diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx index 8e4033f43c..9af59b9ee9 100644 --- a/Source/cmExperimental.cxx +++ b/Source/cmExperimental.cxx @@ -39,7 +39,7 @@ cmExperimental::FeatureData LookupTable[] = { false }, // CxxImportStd { "CxxImportStd", - "a9e1cf81-9932-4810-974b-6eccaf14e457", + "d0edc3af-4c50-42ea-a356-e2862fe7a444", "CMAKE_EXPERIMENTAL_CXX_IMPORT_STD", "CMake's support for `import std;` in C++23 and newer is experimental. It " "is meant only for experimentation and feedback to CMake developers.", diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/CMakeLists.txt index 5d41b0edf3..3dfc927ab6 100644 --- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/CMakeLists.txt @@ -1,5 +1,5 @@ set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457") + "d0edc3af-4c50-42ea-a356-e2862fe7a444") cmake_minimum_required(VERSION 3.29) project(cxx_modules_import_std_export_no_std CXX) diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/CMakeLists.txt index fccb8b4fc7..9b25973d12 100644 --- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/CMakeLists.txt @@ -1,5 +1,5 @@ set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457") + "d0edc3af-4c50-42ea-a356-e2862fe7a444") cmake_minimum_required(VERSION 3.29) project(cxx_modules_import_std_export_no_std CXX) diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/CMakeLists.txt index f21da1e6df..52d76f075a 100644 --- a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/CMakeLists.txt @@ -1,5 +1,5 @@ set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457") + "d0edc3af-4c50-42ea-a356-e2862fe7a444") cmake_minimum_required(VERSION 3.29) project(cxx_modules_import_std_no_std_property CXX) diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/CMakeLists.txt index e3e11d166d..204a9db875 100644 --- a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/CMakeLists.txt @@ -1,5 +1,5 @@ set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457") + "d0edc3af-4c50-42ea-a356-e2862fe7a444") cmake_minimum_required(VERSION 3.29) project(cxx_modules_import_std_not_in_export CXX) diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/CMakeLists.txt index 53ef333721..83fc385139 100644 --- a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/CMakeLists.txt @@ -1,5 +1,5 @@ set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457") + "d0edc3af-4c50-42ea-a356-e2862fe7a444") cmake_minimum_required(VERSION 3.29) project(cxx_modules_import_std_not_in_export CXX) diff --git a/Tests/RunCMake/CXXModules/examples/import-std-transitive/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-transitive/CMakeLists.txt index 2f1266285c..943bf8f45a 100644 --- a/Tests/RunCMake/CXXModules/examples/import-std-transitive/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/import-std-transitive/CMakeLists.txt @@ -1,5 +1,5 @@ set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457") + "d0edc3af-4c50-42ea-a356-e2862fe7a444") cmake_minimum_required(VERSION 3.29) diff --git a/Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt index 95b66363e7..fd15455d0d 100644 --- a/Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt @@ -1,5 +1,5 @@ set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457") + "d0edc3af-4c50-42ea-a356-e2862fe7a444") cmake_minimum_required(VERSION 3.29) project(cxx_modules_import_std CXX) diff --git a/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set.cmake b/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set.cmake index 4a9edf4dcc..6cd0f8911c 100644 --- a/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set.cmake +++ b/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set.cmake @@ -1,5 +1,5 @@ set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457") + "d0edc3af-4c50-42ea-a356-e2862fe7a444") cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED "CxxImportStd" From 5750fcd7b4a71b6d197ba030b1def6e433127014 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 30 Apr 2025 17:14:58 +0200 Subject: [PATCH 3/3] ci: enable `import_std23` module compilation with clang This is a stock Fedora 42 which uses a `clang` built with `libstdc++` as the default stdlib. --- .gitlab/ci/configure_fedora42_ninja_clang.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/ci/configure_fedora42_ninja_clang.cmake b/.gitlab/ci/configure_fedora42_ninja_clang.cmake index a1c7fc0d56..c95388fe1d 100644 --- a/.gitlab/ci/configure_fedora42_ninja_clang.cmake +++ b/.gitlab/ci/configure_fedora42_ninja_clang.cmake @@ -1,3 +1,3 @@ -set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "") +set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database,import_std23" CACHE STRING "") include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common_clang.cmake")