diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index aabf61365f..989246e956 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -45,6 +45,7 @@ Variables that Provide Information /variable/CMAKE_CURRENT_LIST_FILE /variable/CMAKE_CURRENT_LIST_LINE /variable/CMAKE_CURRENT_SOURCE_DIR + /variable/CMAKE_CXX_STDLIB_MODULES_JSON /variable/CMAKE_DEBUG_TARGET_PROPERTIES /variable/CMAKE_DIRECTORY_LABELS /variable/CMAKE_DL_LIBS diff --git a/Help/release/dev/cxxmodules-custom-import-std-metadata-file.rst b/Help/release/dev/cxxmodules-custom-import-std-metadata-file.rst new file mode 100644 index 0000000000..104f9178ad --- /dev/null +++ b/Help/release/dev/cxxmodules-custom-import-std-metadata-file.rst @@ -0,0 +1,7 @@ +cxxmodules-custom-import-std-metadata-file +------------------------------------------ + +* The ``import std`` support learned to use the + :variable:`CMAKE_CXX_STDLIB_MODULES_JSON` variable to set the path to the + metadata file for the standard library rather than using the compiler to + discover its location. diff --git a/Help/variable/CMAKE_CXX_STDLIB_MODULES_JSON.rst b/Help/variable/CMAKE_CXX_STDLIB_MODULES_JSON.rst new file mode 100644 index 0000000000..134e8d60bc --- /dev/null +++ b/Help/variable/CMAKE_CXX_STDLIB_MODULES_JSON.rst @@ -0,0 +1,11 @@ +CMAKE_CXX_STDLIB_MODULES_JSON +----------------------------- + +.. versionadded:: 4.2 + +This variable may be used to set the path to a metadata file for CMake to +understand how the ``import std`` target for the active CXX compiler should be +constructed. + +This should only be used when the compiler does not know how to discover the +relevant module metadata file without such assistance. diff --git a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake index 5330eb1a3a..9061e006f7 100644 --- a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake +++ b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake @@ -10,21 +10,25 @@ function (_cmake_cxx_import_std std variable) return () endif () - execute_process( - COMMAND - "${CMAKE_CXX_COMPILER}" - ${CMAKE_CXX_COMPILER_ID_ARG1} - "-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 - OUTPUT_STRIP_TRAILING_WHITESPACE - 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 `${_clang_modules_json_impl}.modules.json` resource\")\n" - PARENT_SCOPE) - return () + if (CMAKE_CXX_STDLIB_MODULES_JSON) + set(_clang_libcxx_modules_json_file "${CMAKE_CXX_STDLIB_MODULES_JSON}") + else () + execute_process( + COMMAND + "${CMAKE_CXX_COMPILER}" + ${CMAKE_CXX_COMPILER_ID_ARG1} + "-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 + OUTPUT_STRIP_TRAILING_WHITESPACE + 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 `${_clang_modules_json_impl}.modules.json` resource\")\n" + PARENT_SCOPE) + return () + endif () endif () # Without this file, we do not have modules installed. diff --git a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake index 965e25a929..834e99912e 100644 --- a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake +++ b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake @@ -6,21 +6,25 @@ function (_cmake_cxx_import_std std variable) return () endif () - execute_process( - COMMAND - "${CMAKE_CXX_COMPILER}" - ${CMAKE_CXX_COMPILER_ID_ARG1} - -print-file-name=libstdc++.modules.json - OUTPUT_VARIABLE _gnu_libstdcxx_modules_json_file - ERROR_VARIABLE _gnu_libstdcxx_modules_json_file_err - RESULT_VARIABLE _gnu_libstdcxx_modules_json_file_res - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE) - if (_gnu_libstdcxx_modules_json_file_res) - set("${variable}" - "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `libstdc++.modules.json` resource\")\n" - PARENT_SCOPE) - return () + if (CMAKE_CXX_STDLIB_MODULES_JSON) + set(_gnu_libstdcxx_modules_json_file "${CMAKE_CXX_STDLIB_MODULES_JSON}") + else () + execute_process( + COMMAND + "${CMAKE_CXX_COMPILER}" + ${CMAKE_CXX_COMPILER_ID_ARG1} + -print-file-name=libstdc++.modules.json + OUTPUT_VARIABLE _gnu_libstdcxx_modules_json_file + ERROR_VARIABLE _gnu_libstdcxx_modules_json_file_err + RESULT_VARIABLE _gnu_libstdcxx_modules_json_file_res + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE) + if (_gnu_libstdcxx_modules_json_file_res) + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `libstdc++.modules.json` resource\")\n" + PARENT_SCOPE) + return () + endif () endif () # Without this file, we do not have modules installed. diff --git a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake index 08199f7e6c..ff01263246 100644 --- a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake +++ b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake @@ -1,21 +1,25 @@ function (_cmake_cxx_import_std std variable) - find_file(_msvc_modules_json_file - NAME modules.json - HINTS - "$ENV{VCToolsInstallDir}/modules" - PATHS - "$ENV{INCLUDE}" - "${CMAKE_CXX_COMPILER}/../../.." - "${CMAKE_CXX_COMPILER}/../.." # msvc-wine layout - PATH_SUFFIXES - ../modules - NO_CACHE) - # Without this file, we do not have modules installed. - if (NOT EXISTS "${_msvc_modules_json_file}") - set("${variable}" - "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `modules.json` resource\")\n" - PARENT_SCOPE) - return () + if (CMAKE_CXX_STDLIB_MODULES_JSON) + set(_msvc_modules_json_file "${CMAKE_CXX_STDLIB_MODULES_JSON}") + else () + find_file(_msvc_modules_json_file + NAME modules.json + HINTS + "$ENV{VCToolsInstallDir}/modules" + PATHS + "$ENV{INCLUDE}" + "${CMAKE_CXX_COMPILER}/../../.." + "${CMAKE_CXX_COMPILER}/../.." # msvc-wine layout + PATH_SUFFIXES + ../modules + NO_CACHE) + # Without this file, we do not have modules installed. + if (NOT EXISTS "${_msvc_modules_json_file}") + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `modules.json` resource\")\n" + PARENT_SCOPE) + return () + endif () endif () file(READ "${_msvc_modules_json_file}" _msvc_modules_json) diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 721f29ff81..eab2ad340d 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -1095,6 +1095,7 @@ cm::optional cmCoreTryCompile::TryCompileCode( vars.emplace("CMAKE_MSVC_RUNTIME_CHECKS"_s); vars.emplace("CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS"_s); vars.emplace("CMAKE_VS_USE_DEBUG_LIBRARIES"_s); + vars.emplace("CMAKE_CXX_STDLIB_MODULES_JSON"_s); if (cmValue varListStr = this->Makefile->GetDefinition( kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {