mirror of
https://github.com/Kitware/CMake.git
synced 2026-06-30 19:57:41 +00:00
cxxmodules: support command templates for BMI compilation
Some compilers (Clang) warn when using their BMI-only flag with `-c`. Support a complete template for BMI compilation rather than an additional flag to support such toolchains. Fixes: #27600
This commit is contained in:
@@ -470,13 +470,18 @@ Additionally, toolchains should set the following variables:
|
||||
* ``CMAKE_CXX_MODULE_MAP_FLAG``: The arguments used to inform the compiler of
|
||||
the :term:`module map` file. It should use the ``<MODULE_MAP_FILE>``
|
||||
placeholder.
|
||||
* ``CMAKE_CXX_COMPILE_BMI``: The command template to compile a :term:`BMI`
|
||||
file from a :term:`module interface unit`. Used when
|
||||
``CMAKE_CXX_MODULE_BMI_ONLY_FLAG`` is not completely additive to an
|
||||
object compilation template.
|
||||
* ``CMAKE_CXX_MODULE_BMI_ONLY_FLAG``: The arguments used to compile only a
|
||||
:term:`BMI` file from a :term:`module interface unit`. This is used when
|
||||
consuming modules from external projects to compile :term:`BMI` files for
|
||||
use within the current build.
|
||||
|
||||
If a toolchain does not provide the ``CMAKE_CXX_MODULE_BMI_ONLY_FLAG``, it
|
||||
will not be able to consume modules provided by ``IMPORTED`` targets.
|
||||
If a toolchain does not provide the ``CMAKE_CXX_COMPILE_BMI`` or
|
||||
``CMAKE_CXX_MODULE_BMI_ONLY_FLAG`` variables, it will not be able to consume
|
||||
modules provided by ``IMPORTED`` targets.
|
||||
|
||||
Configure
|
||||
^^^^^^^^^
|
||||
|
||||
@@ -56,6 +56,7 @@ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
|
||||
unset(_clang_scan_deps_mv)
|
||||
set(CMAKE_CXX_MODULE_MAP_FORMAT "clang")
|
||||
set(CMAKE_CXX_MODULE_MAP_FLAG "@<MODULE_MAP_FILE>")
|
||||
set(CMAKE_CXX_MODULE_BMI_ONLY_FLAG "--precompile")
|
||||
set(CMAKE_CXX_COMPILE_BMI
|
||||
"<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> --precompile <SOURCE>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -2335,6 +2335,7 @@ cmGeneratorTarget::GetClassifiedFlagsForSource(cmSourceFile const* sf,
|
||||
}
|
||||
|
||||
// C++ module flags.
|
||||
bool useBmiTemplate = false;
|
||||
if (lang == "CXX"_s) {
|
||||
FlagClassification cls = FlagClassification::LocationFlag;
|
||||
FlagKind kind = FlagKind::BuildSystem;
|
||||
@@ -2353,13 +2354,17 @@ cmGeneratorTarget::GetClassifiedFlagsForSource(cmSourceFile const* sf,
|
||||
}
|
||||
|
||||
if (!this->Target->IsNormal()) {
|
||||
auto flag = mf->GetSafeDefinition("CMAKE_CXX_MODULE_BMI_ONLY_FLAG");
|
||||
cmRulePlaceholderExpander::RuleVariables compileObjectVars;
|
||||
compileObjectVars.Object = sfVars.ObjectFileDir.c_str();
|
||||
auto rulePlaceholderExpander = lg->CreateRulePlaceholderExpander();
|
||||
rulePlaceholderExpander->ExpandRuleVariables(lg, flag,
|
||||
compileObjectVars);
|
||||
lg->AppendCompileOptions(bmiFlags, flag);
|
||||
if (!mf->GetDefinition("CMAKE_CXX_COMPILE_BMI").IsEmpty()) {
|
||||
useBmiTemplate = true;
|
||||
} else {
|
||||
auto flag = mf->GetSafeDefinition("CMAKE_CXX_MODULE_BMI_ONLY_FLAG");
|
||||
cmRulePlaceholderExpander::RuleVariables compileObjectVars;
|
||||
compileObjectVars.Object = sfVars.ObjectFileDir.c_str();
|
||||
auto rulePlaceholderExpander = lg->CreateRulePlaceholderExpander();
|
||||
rulePlaceholderExpander->ExpandRuleVariables(lg, flag,
|
||||
compileObjectVars);
|
||||
lg->AppendCompileOptions(bmiFlags, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2382,7 +2387,8 @@ cmGeneratorTarget::GetClassifiedFlagsForSource(cmSourceFile const* sf,
|
||||
FlagClassification cls = FlagClassification::ExecutionFlag;
|
||||
FlagKind kind = FlagKind::NotAFlag;
|
||||
|
||||
std::string const cmdVar = cmStrCat("CMAKE_", lang, "_COMPILE_OBJECT");
|
||||
std::string const cmdVar =
|
||||
cmStrCat("CMAKE_", lang, "_COMPILE_", useBmiTemplate ? "BMI" : "OBJECT");
|
||||
std::string const& compileCmd = mf->GetRequiredDefinition(cmdVar);
|
||||
cmList compileCmds(compileCmd); // FIXME: which command to use?
|
||||
std::string& cmd = compileCmds[0];
|
||||
|
||||
@@ -265,15 +265,19 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
}
|
||||
|
||||
if (!this->GeneratorTarget->Target->IsNormal()) {
|
||||
auto flag = this->GetMakefile()->GetSafeDefinition(
|
||||
"CMAKE_CXX_MODULE_BMI_ONLY_FLAG");
|
||||
cmRulePlaceholderExpander::RuleVariables compileObjectVars;
|
||||
compileObjectVars.Object = objectFileName.c_str();
|
||||
auto rulePlaceholderExpander =
|
||||
this->GetLocalGenerator()->CreateRulePlaceholderExpander();
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
|
||||
flag, compileObjectVars);
|
||||
this->LocalGenerator->AppendCompileOptions(flags, flag);
|
||||
if (this->GetMakefile()
|
||||
->GetDefinition("CMAKE_CXX_COMPILE_BMI")
|
||||
.IsEmpty()) {
|
||||
auto flag = this->GetMakefile()->GetSafeDefinition(
|
||||
"CMAKE_CXX_MODULE_BMI_ONLY_FLAG");
|
||||
cmRulePlaceholderExpander::RuleVariables compileObjectVars;
|
||||
compileObjectVars.Object = objectFileName.c_str();
|
||||
auto rulePlaceholderExpander =
|
||||
this->GetLocalGenerator()->CreateRulePlaceholderExpander();
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
|
||||
flag, compileObjectVars);
|
||||
this->LocalGenerator->AppendCompileOptions(flags, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,6 +656,19 @@ void cmNinjaTargetGenerator::WriteCompileRule(std::string const& lang,
|
||||
this->WriteCompileRule(lang, config, WithScanning::No);
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::GetCompileTemplateVar(
|
||||
std::string const& lang) const
|
||||
{
|
||||
std::string cmdVar = cmStrCat("CMAKE_", lang, "_COMPILE_OBJECT");
|
||||
if (!this->GetGeneratorTarget()->IsNormal()) {
|
||||
std::string bmiCmdVar = cmStrCat("CMAKE_", lang, "_COMPILE_BMI");
|
||||
if (!this->GetMakefile()->GetDefinition(bmiCmdVar).IsEmpty()) {
|
||||
cmdVar = std::move(bmiCmdVar);
|
||||
}
|
||||
}
|
||||
return cmdVar;
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteCompileRule(std::string const& lang,
|
||||
std::string const& config,
|
||||
WithScanning withScanning)
|
||||
@@ -928,7 +945,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(std::string const& lang,
|
||||
}
|
||||
|
||||
// Rule for compiling object file.
|
||||
std::string const cmdVar = cmStrCat("CMAKE_", lang, "_COMPILE_OBJECT");
|
||||
std::string const cmdVar = this->GetCompileTemplateVar(lang);
|
||||
std::string const& compileCmd = mf->GetRequiredDefinition(cmdVar);
|
||||
cmList compileCmds(compileCmd);
|
||||
|
||||
@@ -2313,7 +2330,7 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
|
||||
compileObjectVars.CudaCompileMode = cudaCompileMode.c_str();
|
||||
}
|
||||
|
||||
std::string const cmdVar = cmStrCat("CMAKE_", language, "_COMPILE_OBJECT");
|
||||
std::string const cmdVar = this->GetCompileTemplateVar(language);
|
||||
std::string const& compileCmd =
|
||||
this->Makefile->GetRequiredDefinition(cmdVar);
|
||||
cmList compileCmds(compileCmd);
|
||||
|
||||
@@ -168,6 +168,7 @@ protected:
|
||||
|
||||
void WriteLanguageRules(std::string const& language,
|
||||
std::string const& config);
|
||||
std::string GetCompileTemplateVar(std::string const& lang) const;
|
||||
void WriteCompileRule(std::string const& language,
|
||||
std::string const& config);
|
||||
void WriteCompileRule(std::string const& language, std::string const& config,
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
"REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
|
||||
"REGEX:<BMI_ONLY_FLAG>",
|
||||
"REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
|
||||
"-c",
|
||||
"REGEX:-[cv]",
|
||||
"PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
|
||||
],
|
||||
"baseline-arguments": [
|
||||
@@ -229,7 +229,7 @@
|
||||
"REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_OTHER_DIR>/.d\"",
|
||||
"REGEX:<BMI_ONLY_FLAG>",
|
||||
"REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_OTHER_DIR>/",
|
||||
"-c",
|
||||
"REGEX:-[cv]",
|
||||
"PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
|
||||
],
|
||||
"baseline-arguments": [
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
|
||||
"REGEX:<BMI_ONLY_FLAG>",
|
||||
"REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
|
||||
"-c",
|
||||
"REGEX:-[cv]",
|
||||
"PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
|
||||
],
|
||||
"baseline-arguments": [
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
|
||||
"REGEX:<BMI_ONLY_FLAG>",
|
||||
"REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
|
||||
"-c",
|
||||
"REGEX:-[cv]",
|
||||
"PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
|
||||
],
|
||||
"baseline-arguments": [
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
|
||||
"REGEX:<BMI_ONLY_FLAG>",
|
||||
"REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
|
||||
"-c",
|
||||
"REGEX:-[cv]",
|
||||
"PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
|
||||
],
|
||||
"baseline-arguments": [
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
"REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
|
||||
"REGEX:<BMI_ONLY_FLAG>",
|
||||
"REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
|
||||
"-c",
|
||||
"REGEX:-[cv]",
|
||||
"PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
|
||||
],
|
||||
"baseline-arguments": [
|
||||
@@ -229,7 +229,7 @@
|
||||
"REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_OTHER_DIR>/.d\"",
|
||||
"REGEX:<BMI_ONLY_FLAG>",
|
||||
"REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_OTHER_DIR>/",
|
||||
"-c",
|
||||
"REGEX:-[cv]",
|
||||
"PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
|
||||
],
|
||||
"baseline-arguments": [
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
"REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
|
||||
"REGEX:<BMI_ONLY_FLAG>",
|
||||
"REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
|
||||
"-c",
|
||||
"REGEX:-[cv]",
|
||||
"PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
|
||||
],
|
||||
"baseline-arguments": [
|
||||
|
||||
@@ -36,6 +36,10 @@ if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
|
||||
else ()
|
||||
set(output_flag "-o")
|
||||
endif ()
|
||||
if (CMAKE_CXX_COMPILE_BMI) # Only `clang` does this today.
|
||||
set(CMAKE_CXX_COMPILE_BMI
|
||||
"<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> --precompile ${output_flag}<OBJECT> -v <SOURCE>")
|
||||
endif ()
|
||||
set(CMAKE_CXX_COMPILE_OBJECT
|
||||
"<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> ${output_flag}<OBJECT> -c <SOURCE>")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user