| function (_cmake_cxx_find_modules_json) |
| if (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 () |