blob: b7bd5254e55edb382e9771f4c5dd28007ccf7e9c [file] [log] [blame] [edit]
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 ()