Просмотр исходного кода

cxximportstd: support setting the `import std` metadata location

Some deployments may not be able to discover the metadata file reliably
(e.g., custom `clang` builds on macOS while using the SDK's stdlib or
distribution bugs). Allow users to force the location so that
compiler-driven detection doesn't have to bend over backwards for
unforeseen bugs.
Ben Boeckel 6 месяцев назад
Родитель
Сommit
2b85541e39

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -45,6 +45,7 @@ Variables that Provide Information
    /variable/CMAKE_CURRENT_LIST_FILE
    /variable/CMAKE_CURRENT_LIST_FILE
    /variable/CMAKE_CURRENT_LIST_LINE
    /variable/CMAKE_CURRENT_LIST_LINE
    /variable/CMAKE_CURRENT_SOURCE_DIR
    /variable/CMAKE_CURRENT_SOURCE_DIR
+   /variable/CMAKE_CXX_STDLIB_MODULES_JSON
    /variable/CMAKE_DEBUG_TARGET_PROPERTIES
    /variable/CMAKE_DEBUG_TARGET_PROPERTIES
    /variable/CMAKE_DIRECTORY_LABELS
    /variable/CMAKE_DIRECTORY_LABELS
    /variable/CMAKE_DL_LIBS
    /variable/CMAKE_DL_LIBS

+ 7 - 0
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.

+ 11 - 0
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.

+ 19 - 15
Modules/Compiler/Clang-CXX-CXXImportStd.cmake

@@ -10,21 +10,25 @@ function (_cmake_cxx_import_std std variable)
     return ()
     return ()
   endif ()
   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 ()
   endif ()
 
 
   # Without this file, we do not have modules installed.
   # Without this file, we do not have modules installed.

+ 19 - 15
Modules/Compiler/GNU-CXX-CXXImportStd.cmake

@@ -6,21 +6,25 @@ function (_cmake_cxx_import_std std variable)
     return ()
     return ()
   endif ()
   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 ()
   endif ()
 
 
   # Without this file, we do not have modules installed.
   # Without this file, we do not have modules installed.

+ 21 - 17
Modules/Compiler/MSVC-CXX-CXXImportStd.cmake

@@ -1,21 +1,25 @@
 function (_cmake_cxx_import_std std variable)
 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 ()
   endif ()
 
 
   file(READ "${_msvc_modules_json_file}" _msvc_modules_json)
   file(READ "${_msvc_modules_json_file}" _msvc_modules_json)

+ 1 - 0
Source/cmCoreTryCompile.cxx

@@ -1095,6 +1095,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
     vars.emplace("CMAKE_MSVC_RUNTIME_CHECKS"_s);
     vars.emplace("CMAKE_MSVC_RUNTIME_CHECKS"_s);
     vars.emplace("CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS"_s);
     vars.emplace("CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS"_s);
     vars.emplace("CMAKE_VS_USE_DEBUG_LIBRARIES"_s);
     vars.emplace("CMAKE_VS_USE_DEBUG_LIBRARIES"_s);
+    vars.emplace("CMAKE_CXX_STDLIB_MODULES_JSON"_s);
 
 
     if (cmValue varListStr = this->Makefile->GetDefinition(
     if (cmValue varListStr = this->Makefile->GetDefinition(
           kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
           kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {