Ninja: include module mapper flags in compile_commands.json

Fixes: #24618
This commit is contained in:
Ben Boeckel
2023-07-02 18:44:17 -04:00
parent b384058e4b
commit 677b28dc7b
14 changed files with 99 additions and 10 deletions

View File

@@ -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")

View File

@@ -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")

View File

@@ -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")

View File

@@ -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")

View File

@@ -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")

View File

@@ -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 "")

View File

@@ -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;

View File

@@ -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();

View File

@@ -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)

View File

@@ -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 ()

View File

@@ -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.

View File

@@ -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)

View File

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

View File

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