Просмотр исходного кода

Merge topic 'compile-commands-modules' into release-3.27

677b28dc7b Ninja: include module mapper flags in `compile_commands.json`

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !8611
Brad King 2 лет назад
Родитель
Сommit
fbe5f49d63

+ 1 - 1
.gitlab/ci/configure_fedora38_ninja_clang.cmake

@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
 set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "")
 
 include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora38_common_clang.cmake")

+ 1 - 1
.gitlab/ci/configure_fedora38_ninja_multi_clang.cmake

@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
 set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "")
 
 include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora38_common_clang.cmake")

+ 1 - 1
.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake

@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,collation,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
 set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
 
 include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")

+ 1 - 1
.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake

@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,collation,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
 set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
 
 include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")

+ 1 - 1
.gitlab/ci/configure_windows_clang_ninja.cmake

@@ -1,5 +1,5 @@
 if("$ENV{CMAKE_CI_BUILD_NAME}" MATCHES "(^|_)gnu(_|$)")
-  set(CMake_TEST_MODULE_COMPILATION "named,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
+  set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared" CACHE STRING "")
   set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_clang.cmake" CACHE STRING "")
 endif()
 include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_clang_common.cmake")

+ 1 - 1
.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake

@@ -1,2 +1,2 @@
-set(CMake_TEST_MODULE_COMPILATION "named,collation,partitions,internal_partitions,shared,export_bmi,install_bmi" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,shared,export_bmi,install_bmi" CACHE STRING "")
 set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_msvc.cmake" CACHE STRING "")

+ 2 - 1
Source/cmGlobalNinjaGenerator.cxx

@@ -2733,7 +2733,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
         auto mm = CxxModuleMapContent(*modmap_fmt, locs, object, usages);
 
         // XXX(modmap): If changing this path construction, change
-        // `cmNinjaTargetGenerator::WriteObjectBuildStatements` to generate the
+        // `cmNinjaTargetGenerator::WriteObjectBuildStatements` and
+        // `cmNinjaTargetGenerator::ExportObjectCompileCommand` to generate the
         // corresponding file path.
         cmGeneratedFileStream mmf(cmStrCat(object.PrimaryOutput, ".modmap"));
         mmf << mm;

+ 25 - 3
Source/cmNinjaTargetGenerator.cxx

@@ -1428,8 +1428,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
 
     if (!modmapFormat.empty()) {
       // XXX(modmap): If changing this path construction, change
-      // `cmGlobalNinjaGenerator::WriteDyndep` to expect the corresponding file
-      // path.
+      // `cmGlobalNinjaGenerator::WriteDyndep` and
+      // `cmNinjaTargetGenerator::ExportObjectCompileCommand` to expect the
+      // corresponding file path.
       std::string ddModmapFile = cmStrCat(objectFileName, ".modmap");
       vars["DYNDEP_MODULE_MAP_FILE"] = ddModmapFile;
       objBuild.OrderOnlyDeps.push_back(ddModmapFile);
@@ -1688,11 +1689,32 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
   escapedSourceFileName = this->LocalGenerator->ConvertToOutputFormat(
     escapedSourceFileName, cmOutputConverter::SHELL);
 
+  std::string fullFlags = flags;
+  {
+    bool const needDyndep =
+      this->GetGeneratorTarget()->NeedDyndep(language, outputConfig);
+    std::string const modmapFormatVar =
+      cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FORMAT");
+    std::string const modmapFormat =
+      this->Makefile->GetSafeDefinition(modmapFormatVar);
+    if (needDyndep && !modmapFormat.empty()) {
+      std::string modmapFlags = this->GetMakefile()->GetRequiredDefinition(
+        cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FLAG"));
+      // XXX(modmap): If changing this path construction, change
+      // `cmGlobalNinjaGenerator::WriteDyndep` and
+      // `cmNinjaTargetGenerator::WriteObjectBuildStatement` to expect the
+      // corresponding file path.
+      cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>",
+                                   cmStrCat(objectFileName, ".modmap"));
+      fullFlags += cmStrCat(' ', modmapFlags);
+    }
+  }
+
   compileObjectVars.Source = escapedSourceFileName.c_str();
   compileObjectVars.Object = objectFileName.c_str();
   compileObjectVars.ObjectDir = objectDir.c_str();
   compileObjectVars.ObjectFileDir = objectFileDir.c_str();
-  compileObjectVars.Flags = flags.c_str();
+  compileObjectVars.Flags = fullFlags.c_str();
   compileObjectVars.Defines = defines.c_str();
   compileObjectVars.Includes = includes.c_str();
 

+ 5 - 0
Tests/RunCMake/CXXModules/RunCMakeTest.cmake

@@ -152,6 +152,11 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
   run_cxx_module_test(scan_properties)
 endif ()
 
+# Tests which require compile commands support.
+if ("compile_commands" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  run_cxx_module_test(export-compile-commands)
+endif ()
+
 # Tests which require collation work.
 if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION)
   run_cxx_module_test(public-req-private)

+ 25 - 0
Tests/RunCMake/CXXModules/examples/export-compile-commands-check.cmake

@@ -0,0 +1,25 @@
+if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
+  list(APPEND RunCMake_TEST_FAILED
+    "No compile commands database detected.")
+endif ()
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/compile_commands.json" compile_commands)
+
+string(JSON length
+  LENGTH "${compile_commands}")
+math(EXPR length "${length} - 1")
+foreach (item RANGE "${length}")
+  string(JSON entry
+    GET "${compile_commands}"
+    "${item}")
+  string(JSON command
+    GET "${entry}"
+    "command")
+  if (NOT command MATCHES "(@|-fmodule-mapper=).*\\.modmap")
+    string(JSON output
+      GET "${entry}"
+      "output")
+    list(APPEND RunCMake_TEST_FAILED
+      "Missing `.modmap` argument for '${output}'")
+  endif ()
+endforeach ()

+ 4 - 0
Tests/RunCMake/CXXModules/examples/export-compile-commands-stderr.txt

@@ -0,0 +1,4 @@
+CMake Warning \(dev\) at CMakeLists.txt:9 \(target_sources\):
+  CMake's C\+\+ module support is experimental.  It is meant only for
+  experimentation and feedback to CMake developers.
+This warning is for project developers.  Use -Wno-dev to suppress it.

+ 20 - 0
Tests/RunCMake/CXXModules/examples/export-compile-commands/CMakeLists.txt

@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_export_compile_commands CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
+
+add_executable(export-compile-commands)
+target_sources(export-compile-commands
+  PRIVATE
+    main.cxx
+  PRIVATE
+    FILE_SET CXX_MODULES
+      BASE_DIRS
+        "${CMAKE_CURRENT_SOURCE_DIR}"
+      FILES
+        importable.cxx)
+target_compile_features(export-compile-commands PUBLIC cxx_std_20)
+
+add_test(NAME export-compile-commands COMMAND export-compile-commands)

+ 6 - 0
Tests/RunCMake/CXXModules/examples/export-compile-commands/importable.cxx

@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+  return 0;
+}

+ 6 - 0
Tests/RunCMake/CXXModules/examples/export-compile-commands/main.cxx

@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+  return from_import();
+}