mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-03 12:49:50 -05:00
fa10dc6c22
Adds a parser and serializer for the EcoStd Module Metadata format RFC: https://github.com/ecostd/rfcs/pull/3 This adapts the existing experimental support for import std; to use the new parser. The CMAKE_CXX_STDLIB_MODULES_JSON is now the canonical variable for controlling how CMake discovers the stdlib module metadata, and is used directly by compiler detection. Toolchains can still override the __CMAKE::CXX## targets if they wish, either in conjunction with CMAKE_CXX_STDLIB_MODULE_JSON or not. It is possible to disable automatic detection of CMAKE_CXX_STDLIB_MODULE_JSON by setting it to the empty string. When available, the CMAKE_CXX_STDLIB_MODULE_JSON will be used to create all requested C++ stdlibs which do not already have targets.
105 lines
3.8 KiB
CMake
105 lines
3.8 KiB
CMake
function (_cmake_cxx_find_modules_json)
|
|
if (DEFINED CMAKE_CXX_STDLIB_MODULES_JSON)
|
|
return ()
|
|
endif ()
|
|
|
|
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(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Could not find `modules.json` resource" PARENT_SCOPE)
|
|
return ()
|
|
endif ()
|
|
|
|
file(READ "${_msvc_modules_json_file}" _msvc_modules_json)
|
|
string(JSON _msvc_json_modules ERROR_VARIABLE _msvc_json_err GET "${_msvc_modules_json}" "modules")
|
|
|
|
# This is probably a conforming module metadata file, use it as is
|
|
if (_msvc_json_modules)
|
|
set(CMAKE_CXX_STDLIB_MODULES_JSON "${_msvc_modules_json_file}" PARENT_SCOPE)
|
|
return ()
|
|
endif ()
|
|
|
|
# Otherwise it's a Microsoft STL-style modules.json, check if we recognize it
|
|
string(JSON _msvc_json_version GET "${_msvc_modules_json}" "version")
|
|
string(JSON _msvc_json_revision GET "${_msvc_modules_json}" "revision")
|
|
# Require version 1.
|
|
if (NOT _msvc_json_version EQUAL "1")
|
|
set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "`modules.json` version ${_msvc_json_version}.${_msvc_json_revision} is not recognized" PARENT_SCOPE)
|
|
return ()
|
|
endif ()
|
|
|
|
string(JSON _msvc_json_library GET "${_msvc_modules_json}" "library")
|
|
# Bail if we don't understand the library.
|
|
if (NOT _msvc_json_library STREQUAL "microsoft/STL")
|
|
set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "`modules.json` library `${_msvc_json_library}` is not recognized" PARENT_SCOPE)
|
|
return ()
|
|
endif ()
|
|
|
|
string(JSON _msvc_json_sources_len LENGTH "${_msvc_modules_json}" "module-sources")
|
|
# Bail if there aren't any sources
|
|
if (NOT _msvc_json_sources_len)
|
|
set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "`modules.json` does not list any available sources" PARENT_SCOPE)
|
|
return ()
|
|
endif ()
|
|
|
|
set(_msvc_module_metadata [=[{
|
|
"version": 1,
|
|
"revision": 1,
|
|
"modules": []
|
|
}]=])
|
|
|
|
cmake_path(GET _msvc_modules_json_file PARENT_PATH _msvc_base_dir)
|
|
math(EXPR _msvc_json_sources_len "${_msvc_json_sources_len}-1")
|
|
foreach (idx RANGE ${_msvc_json_sources_len})
|
|
string(JSON _msvc_source GET "${_msvc_modules_json}" "module-sources" ${idx})
|
|
|
|
set(_msvc_path ${_msvc_source})
|
|
cmake_path(IS_RELATIVE _msvc_path _msvc_is_rel)
|
|
if (_msvc_is_rel)
|
|
cmake_path(ABSOLUTE_PATH _msvc_path BASE_DIRECTORY "${_msvc_base_dir}")
|
|
endif ()
|
|
|
|
if (_msvc_source MATCHES "std.ixx")
|
|
string(JSON _msvc_module_metadata
|
|
SET "${_msvc_module_metadata}" "modules" ${idx}
|
|
"{
|
|
\"logical-name\": \"std\",
|
|
\"source-path\": \"${_msvc_path}\",
|
|
\"is-std-library\": true
|
|
}"
|
|
)
|
|
elseif (_msvc_source MATCHES "std.compat.ixx")
|
|
string(JSON _msvc_module_metadata
|
|
SET "${_msvc_module_metadata}" "modules" ${idx}
|
|
"{
|
|
\"logical-name\": \"std.compat\",
|
|
\"source-path\": \"${_msvc_path}\",
|
|
\"is-std-library\": true
|
|
}"
|
|
)
|
|
endif ()
|
|
endforeach()
|
|
|
|
string(JSON _msvc_module_metadata_modules_len LENGTH ${_msvc_module_metadata} "modules")
|
|
|
|
# Bail if we didn't recognize any of the modules
|
|
if (NOT _msvc_module_metadata_modules_len)
|
|
set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "`modules.json` did not contain any recognized sources (std.ixx, std.compat.ixx)" PARENT_SCOPE)
|
|
return ()
|
|
endif ()
|
|
|
|
file(WRITE "${CMAKE_PLATFORM_INFO_DIR}/msvcstl.modules.json" "${_msvc_module_metadata}")
|
|
set(CMAKE_CXX_STDLIB_MODULES_JSON "${CMAKE_PLATFORM_INFO_DIR}/msvcstl.modules.json" PARENT_SCOPE)
|
|
endfunction ()
|