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 () endif () file(READ "${_msvc_modules_json_file}" _msvc_modules_json) 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("${variable}" "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`modules.json` version ${_msvc_json_version}.${_msvc_json_revision} is not recognized\")\n" 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("${variable}" "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`modules.json` library `${_msvc_json_library}` is not recognized\")\n" PARENT_SCOPE) return () endif () string(JSON _msvc_json_nmodules LENGTH "${_msvc_modules_json}" "module-sources") # Don't declare the target without any modules. if (NOT _msvc_json_nmodules) set("${variable}" "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`modules.json` does not list any available modules\")\n" PARENT_SCOPE) return () endif () # Declare the target. set(_msvc_std_target "") string(APPEND _msvc_std_target "add_library(__cmake_cxx${std} STATIC)\n") string(APPEND _msvc_std_target "target_sources(__cmake_cxx${std} INTERFACE \"$<$,STATIC_LIBRARY>:$>\")\n") string(APPEND _msvc_std_target "set_property(TARGET __cmake_cxx${std} PROPERTY EXCLUDE_FROM_ALL 1)\n") string(APPEND _msvc_std_target "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_SCAN_FOR_MODULES 1)\n") string(APPEND _msvc_std_target "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_MODULE_STD 0)\n") string(APPEND _msvc_std_target "target_compile_features(__cmake_cxx${std} PUBLIC cxx_std_${std})\n") set(_msvc_modules_module_paths "") get_filename_component(_msvc_modules_dir "${_msvc_modules_json_file}" DIRECTORY) # Add module sources. math(EXPR _msvc_modules_json_nmodules_range "${_msvc_json_nmodules} - 1") foreach (_msvc_modules_json_modules_idx RANGE 0 "${_msvc_modules_json_nmodules_range}") string(JSON _msvc_modules_json_module_source GET "${_msvc_modules_json}" "module-sources" "${_msvc_modules_json_modules_idx}") if (NOT IS_ABSOLUTE "${_msvc_modules_json_module_source}") string(PREPEND _msvc_modules_json_module_source "${_msvc_modules_dir}/") endif () list(APPEND _msvc_modules_module_paths "${_msvc_modules_json_module_source}") endforeach () # Split the paths into basedirs and module paths. set(_msvc_modules_base_dirs_list "") set(_msvc_modules_files "") foreach (_msvc_modules_module_path IN LISTS _msvc_modules_module_paths) get_filename_component(_msvc_module_dir "${_msvc_modules_module_path}" DIRECTORY) list(APPEND _msvc_modules_base_dirs_list "${_msvc_module_dir}") string(APPEND _msvc_modules_files " \"${_msvc_modules_module_path}\"") endforeach () list(REMOVE_DUPLICATES _msvc_modules_base_dirs_list) set(_msvc_modules_base_dirs "") foreach (_msvc_modules_base_dir IN LISTS _msvc_modules_base_dirs_list) string(APPEND _msvc_modules_base_dirs " \"${_msvc_modules_base_dir}\"") endforeach () # Create the file set for the modules. string(APPEND _msvc_std_target "target_sources(__cmake_cxx${std} PUBLIC FILE_SET std TYPE CXX_MODULES BASE_DIRS ${_msvc_modules_base_dirs} FILES ${_msvc_modules_files})\n") # Wrap the `__cmake_cxx${std}` target in a check. string(PREPEND _msvc_std_target "if (NOT TARGET \"__cmake_cxx${std}\")\n") string(APPEND _msvc_std_target "endif ()\n") string(APPEND _msvc_std_target "add_library(__CMAKE::CXX${std} ALIAS __cmake_cxx${std})\n") set("${variable}" "${_msvc_std_target}" PARENT_SCOPE) endfunction ()