From 6dad18f0605cd49ddb1283c08fc83e706644dc52 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 1 May 2024 23:06:20 -0400 Subject: cxxmodules: give a reason for unavailability of `import std` If the `CMAKE_CXX_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE` variable is set, include its value in the error message. --- Modules/Compiler/CMakeCommonCompilerMacros.cmake | 15 +++++++++++++++ Modules/Compiler/Clang-CXX-CXXImportStd.cmake | 15 +++++++++++++++ Modules/Compiler/MSVC-CXX-CXXImportStd.cmake | 12 ++++++++++++ Source/cmGeneratorTarget.cxx | 19 +++++++++++++------ .../CXXModules/NoCXX23TargetRequired-stderr.txt | 7 ++++++- 5 files changed, 61 insertions(+), 7 deletions(-) diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake index 9eead20..75a9da2 100644 --- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake +++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake @@ -211,6 +211,9 @@ function(cmake_create_cxx_import_std std variable) 26) list(FIND _cmake_supported_import_std_features "${std}" _cmake_supported_import_std_idx) if (_cmake_supported_import_std_idx EQUAL "-1") + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Unsupported C++ standard: C++${std}\")\n" + PARENT_SCOPE) return () endif () # If the target exists, skip. A toolchain file may have provided it. @@ -219,14 +222,23 @@ function(cmake_create_cxx_import_std std variable) endif () # The generator must support imported C++ modules. if (NOT CMAKE_GENERATOR MATCHES "Ninja") + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Unsupported generator: ${CMAKE_GENERATOR}\")\n" + PARENT_SCOPE) 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) + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Toolchain does not support discovering `import std` support\")\n" + PARENT_SCOPE) return () endif () if (NOT COMMAND _cmake_cxx_import_std) + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Toolchain does not provide `import std` discovery command\")\n" + PARENT_SCOPE) return () endif () @@ -237,6 +249,9 @@ function(cmake_create_cxx_import_std std variable) "CxxImportStd" _cmake_supported_import_std_experimental) if (NOT _cmake_supported_import_std_experimental) + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Experimental `import std` support not enabled when detecting toolchain\")\n" + PARENT_SCOPE) return () endif () diff --git a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake index 3934db9..55dbfb8 100644 --- a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake +++ b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake @@ -14,11 +14,17 @@ function (_cmake_cxx_import_std std variable) OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE) if (_clang_libcxx_modules_json_file_res) + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `libc++.modules.json` resource\")\n" + PARENT_SCOPE) return () endif () # Without this file, we do not have modules installed. if (NOT EXISTS "${_clang_libcxx_modules_json_file}") + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`libc++.modules.json` resource does not exist\")\n" + PARENT_SCOPE) return () endif () @@ -26,6 +32,9 @@ function (_cmake_cxx_import_std std variable) # The original PR had a key spelling mismatch internally. Do not support it # and instead require a release known to have the fix. # https://github.com/llvm/llvm-project/pull/83036 + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"LLVM 18.1.2 is required for `libc++.modules.json` format fix\")\n" + PARENT_SCOPE) return () endif () @@ -34,12 +43,18 @@ function (_cmake_cxx_import_std std variable) string(JSON _clang_modules_json_revision GET "${_clang_libcxx_modules_json}" "revision") # Require version 1. if (NOT _clang_modules_json_version EQUAL "1") + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`libc++.modules.json` version ${_clang_modules_json_version}.${_clang_modules_json_revision} is not recognized\")\n" + PARENT_SCOPE) return () endif () string(JSON _clang_modules_json_nmodules LENGTH "${_clang_libcxx_modules_json}" "modules") # Don't declare the target without any modules. if (NOT _clang_modules_json_nmodules) + set("${variable}" + "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`libc++.modules.json` does not list any available modules\")\n" + PARENT_SCOPE) return () endif () diff --git a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake index f253f9e..08199f7 100644 --- a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake +++ b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake @@ -12,6 +12,9 @@ function (_cmake_cxx_import_std std variable) 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 () @@ -20,18 +23,27 @@ function (_cmake_cxx_import_std std variable) 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 () diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index c14ff3a..fba4924 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -8569,15 +8569,22 @@ bool cmGeneratorTarget::ApplyCXXStdTargets() continue; } - auto const targetName = cmStrCat( - "__CMAKE::CXX", standardResolver.GetLevelString("CXX", *explicitLevel)); + auto const stdLevel = + standardResolver.GetLevelString("CXX", *explicitLevel); + auto const targetName = cmStrCat("__CMAKE::CXX", stdLevel); if (!this->Makefile->FindTargetToUse(targetName)) { + auto basicReason = this->Makefile->GetDefinition(cmStrCat( + "CMAKE_CXX", stdLevel, "_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE")); + std::string reason; + if (!basicReason.IsEmpty()) { + reason = cmStrCat(" Reason:\n ", basicReason); + } this->Makefile->IssueMessage( MessageType::FATAL_ERROR, - cmStrCat( - R"(The "CXX_MODULE_STD" property on the target ")", this->GetName(), - "\" requires that the \"", targetName, - "\" target exist, but it was not provided by the toolchain.")); + cmStrCat(R"(The "CXX_MODULE_STD" property on the target ")", + this->GetName(), "\" requires that the \"", targetName, + "\" target exist, but it was not provided by the toolchain.", + reason)); break; } diff --git a/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt index 56468d0..e3d31c5 100644 --- a/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt +++ b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt @@ -1,4 +1,9 @@ CMake Error in CMakeLists.txt: The "CXX_MODULE_STD" property on the target "nocxx23target" requires that the "__CMAKE::CXX23" target exist, but it was not provided by the - toolchain. + toolchain. Reason: + + (Toolchain does not support discovering `import std` support|Experimental `import std` support not enabled when detecting toolchain|Unsupported generator: [^\n]*) + + +CMake Generate step failed. Build files cannot be regenerated correctly. -- cgit v0.12