MSVC-CXX-CXXImportStd.cmake 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. function (_cmake_cxx_import_std std variable)
  2. find_file(_msvc_modules_json_file
  3. NAME modules.json
  4. HINTS
  5. "$ENV{VCToolsInstallDir}/modules"
  6. PATHS
  7. "$ENV{INCLUDE}"
  8. "${CMAKE_CXX_COMPILER}/../../.."
  9. "${CMAKE_CXX_COMPILER}/../.." # msvc-wine layout
  10. PATH_SUFFIXES
  11. ../modules
  12. NO_CACHE)
  13. # Without this file, we do not have modules installed.
  14. if (NOT EXISTS "${_msvc_modules_json_file}")
  15. return ()
  16. endif ()
  17. file(READ "${_msvc_modules_json_file}" _msvc_modules_json)
  18. string(JSON _msvc_json_version GET "${_msvc_modules_json}" "version")
  19. string(JSON _msvc_json_revision GET "${_msvc_modules_json}" "revision")
  20. # Require version 1.
  21. if (NOT _msvc_json_version EQUAL "1")
  22. return ()
  23. endif ()
  24. string(JSON _msvc_json_library GET "${_msvc_modules_json}" "library")
  25. # Bail if we don't understand the library.
  26. if (NOT _msvc_json_library STREQUAL "microsoft/STL")
  27. return ()
  28. endif ()
  29. string(JSON _msvc_json_nmodules LENGTH "${_msvc_modules_json}" "module-sources")
  30. # Don't declare the target without any modules.
  31. if (NOT _msvc_json_nmodules)
  32. return ()
  33. endif ()
  34. # Declare the target.
  35. set(_msvc_std_target "")
  36. string(APPEND _msvc_std_target
  37. "add_library(__cmake_cxx${std} STATIC)\n")
  38. string(APPEND _msvc_std_target
  39. "target_sources(__cmake_cxx${std} INTERFACE \"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,STATIC_LIBRARY>:$<TARGET_OBJECTS:__cmake_cxx${std}>>\")\n")
  40. string(APPEND _msvc_std_target
  41. "set_property(TARGET __cmake_cxx${std} PROPERTY EXCLUDE_FROM_ALL 1)\n")
  42. string(APPEND _msvc_std_target
  43. "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_SCAN_FOR_MODULES 1)\n")
  44. string(APPEND _msvc_std_target
  45. "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_MODULE_STD 0)\n")
  46. string(APPEND _msvc_std_target
  47. "target_compile_features(__cmake_cxx${std} PUBLIC cxx_std_${std})\n")
  48. set(_msvc_modules_module_paths "")
  49. get_filename_component(_msvc_modules_dir "${_msvc_modules_json_file}" DIRECTORY)
  50. # Add module sources.
  51. math(EXPR _msvc_modules_json_nmodules_range "${_msvc_json_nmodules} - 1")
  52. foreach (_msvc_modules_json_modules_idx RANGE 0 "${_msvc_modules_json_nmodules_range}")
  53. string(JSON _msvc_modules_json_module_source GET "${_msvc_modules_json}" "module-sources" "${_msvc_modules_json_modules_idx}")
  54. if (NOT IS_ABSOLUTE "${_msvc_modules_json_module_source}")
  55. string(PREPEND _msvc_modules_json_module_source "${_msvc_modules_dir}/")
  56. endif ()
  57. list(APPEND _msvc_modules_module_paths
  58. "${_msvc_modules_json_module_source}")
  59. endforeach ()
  60. # Split the paths into basedirs and module paths.
  61. set(_msvc_modules_base_dirs_list "")
  62. set(_msvc_modules_files "")
  63. foreach (_msvc_modules_module_path IN LISTS _msvc_modules_module_paths)
  64. get_filename_component(_msvc_module_dir "${_msvc_modules_module_path}" DIRECTORY)
  65. list(APPEND _msvc_modules_base_dirs_list
  66. "${_msvc_module_dir}")
  67. string(APPEND _msvc_modules_files
  68. " \"${_msvc_modules_module_path}\"")
  69. endforeach ()
  70. list(REMOVE_DUPLICATES _msvc_modules_base_dirs_list)
  71. set(_msvc_modules_base_dirs "")
  72. foreach (_msvc_modules_base_dir IN LISTS _msvc_modules_base_dirs_list)
  73. string(APPEND _msvc_modules_base_dirs
  74. " \"${_msvc_modules_base_dir}\"")
  75. endforeach ()
  76. # Create the file set for the modules.
  77. string(APPEND _msvc_std_target
  78. "target_sources(__cmake_cxx${std}
  79. PUBLIC
  80. FILE_SET std TYPE CXX_MODULES
  81. BASE_DIRS ${_msvc_modules_base_dirs}
  82. FILES ${_msvc_modules_files})\n")
  83. # Wrap the `__cmake_cxx${std}` target in a check.
  84. string(PREPEND _msvc_std_target
  85. "if (NOT TARGET \"__cmake_cxx${std}\")\n")
  86. string(APPEND _msvc_std_target
  87. "endif ()\n")
  88. string(APPEND _msvc_std_target
  89. "add_library(__CMAKE::CXX${std} ALIAS __cmake_cxx${std})\n")
  90. set("${variable}" "${_msvc_std_target}" PARENT_SCOPE)
  91. endfunction ()