From f80c60df02854b9443a0f73770d2ef7a1bcd72d5 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sat, 24 Feb 2024 16:30:48 -0500 Subject: CMakeDetermineCompilerSupport: construct C++ modules targets Compilers may implement this by implementing a `_cmake_cxx_import_std` function which takes the standard version as an argument (e.g., `23`) and creating a target named `CMake::CXX${std}` that represents how `import std;` should be represented within CMake. --- Modules/CMakeCXXCompiler.cmake.in | 2 ++ Modules/CMakeDetermineCompilerSupport.cmake | 14 ++++++++++ Modules/Compiler/CMakeCommonCompilerMacros.cmake | 35 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index d18e1c8..e0c5f8b 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -91,3 +91,5 @@ set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "@CMAKE_CXX_IMPLICIT_LINK_LIBRARIES@") set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@") set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") set(CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR "@CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR@") + +@CMAKE_CXX_IMPORT_STD@ diff --git a/Modules/CMakeDetermineCompilerSupport.cmake b/Modules/CMakeDetermineCompilerSupport.cmake index 746f04e..d561e7b 100644 --- a/Modules/CMakeDetermineCompilerSupport.cmake +++ b/Modules/CMakeDetermineCompilerSupport.cmake @@ -105,6 +105,19 @@ function(cmake_determine_compiler_support lang) ) endif() + # Create targets for use with `import std;` here. + set(CMAKE_CXX_IMPORT_STD "") + foreach (_cmake_import_std_version IN ITEMS 23 26) + if (CMAKE_CXX${_cmake_import_std_version}_COMPILE_FEATURES) + set(_cmake_cxx_import_std "") + cmake_create_cxx_import_std("${_cmake_import_std_version}" _cmake_cxx_import_std) + if (_cmake_cxx_import_std) + string(APPEND CMAKE_CXX_IMPORT_STD "### Imported target for C++${_cmake_import_std_version} standard library\n") + string(APPEND CMAKE_CXX_IMPORT_STD "${_cmake_cxx_import_std}\n\n") + endif () + endif () + endforeach () + set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CXX98_COMPILE_FEATURES ${CMAKE_CXX98_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE) @@ -113,6 +126,7 @@ function(cmake_determine_compiler_support lang) set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CXX23_COMPILE_FEATURES ${CMAKE_CXX23_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CXX26_COMPILE_FEATURES ${CMAKE_CXX26_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_CXX_IMPORT_STD ${CMAKE_CXX_IMPORT_STD} PARENT_SCOPE) message(CHECK_PASS "done") diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake index 02c2b18..3a91b30 100644 --- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake +++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake @@ -201,3 +201,38 @@ macro(cmake_record_hip_compile_features) _has_compiler_features_hip(11) _has_compiler_features_hip(98) endmacro() + +function(cmake_create_cxx_import_std std variable) + set(_cmake_supported_import_std_features + # Compilers support `import std` in C++20 as an extension. Skip + # for now. + # 20 + 23 + 26) + list(FIND _cmake_supported_import_std_features "${std}" _cmake_supported_import_std_idx) + if (_cmake_supported_import_std_idx EQUAL "-1") + return () + endif () + # If the target exists, skip. A toolchain file may have provided it. + if (TARGET "__CMAKE::CXX${std}") + return () + endif () + # The generator must support imported C++ modules. + if (NOT CMAKE_GENERATOR MATCHES "Ninja") + return () + endif () + # Check if the compiler understands how to `import std;`. + include("${CMAKE_ROOT}/Modules/Compiler/${CMAKE_CXX_COMPILER_ID}-CXX-CXXImportStd.cmake" OPTIONAL RESULT_VARIABLE _cmake_import_std_res) + if (NOT _cmake_import_std_res) + return () + endif () + if (NOT COMMAND _cmake_cxx_import_std) + return () + endif () + _cmake_cxx_import_std("${std}" target_definition) + string(CONCAT guarded_target_definition + "if (NOT TARGET \"__CMAKE::CXX${std}\")\n" + "${target_definition}" + "endif ()\n") + set("${variable}" "${guarded_target_definition}" PARENT_SCOPE) +endfunction() -- cgit v0.12