c++modules: Fully revert implementation of per-importer BMIs for 4.3

Since commit 5898c8d2e0 (cxxmodules: Generate per-importer BMIs for
native targets, 2025-12-29, v4.3.0-rc1~43^2~1) we use synthetic targets
to perform per-importer BMI-only compilation of modules even from
in-project targets.  However, our BMI-only compile lines are still
generated from the `CMAKE_CXX_COMPILE_OBJECT` rule variable, which
contains `-c` or equivalent.  Clang expects `-c` and `--precompile` to
be mutually exclusive, leading to warnings, or errors with `-Werror`.

Follow up commit e5b1a23f27 (c++modules: Revert partial implementation
of per-importer BMIs for 4.3, 2026-02-27, v4.3.0-rc2~9^2) by reverting
the rest of the implementation from the 4.3 release.  Work toward fixing
the implementation will proceed in post-4.3 development.

Issue: #25539
Issue: #27600
Issue: #27597
This commit is contained in:
Brad King committed 2026-03-24 11:13:05 -04:00
1 parent 7178780043
commit c68b587abe
12 files changed
+145 -344

No files matched your search

+27 -82
View File
@@ -180,90 +180,35 @@ cmCommonTargetGenerator::GetLinkedTargetDirectories(
if (cmComputeLinkInformation* cli =
this->GeneratorTarget->GetLinkInformation(config)) {
auto findSyntheticTarget =
[this,
&config](cmGeneratorTarget const* linkee) -> cmGeneratorTarget const* {
if (!linkee) {
return nullptr;
}
// Check the map of direct synthetic dependencies for a substitute
auto const& synthDeps = this->GeneratorTarget->GetSyntheticDeps(config);
auto it = synthDeps.find(linkee);
if (it != synthDeps.end() && !it->second.empty()) {
return it->second.front();
}
// Check linked targets to finding synthetic targets for transitive deps
std::vector<cmGeneratorTarget const*> pending;
std::set<cmGeneratorTarget const*> visited;
for (auto const& dep : synthDeps) {
for (auto const* synth : dep.second) {
if (synth && visited.insert(synth).second) {
pending.push_back(synth);
auto addLinkedTarget =
[this, &lang, &config, &dirs, &direct_emitted, &forward_emitted,
gg](cmGeneratorTarget const* linkee, Forwarding forward) {
if (linkee &&
!linkee->IsImported()
// Skip targets that build after this one in a static lib cycle.
&& gg->TargetOrderIndexLess(linkee, this->GeneratorTarget)
// We can ignore the INTERFACE_LIBRARY items because
// Target->GetLinkInformation already processed their
// link interface and they don't have any output themselves.
&& (linkee->GetType() != cmStateEnums::INTERFACE_LIBRARY
// Synthesized targets may have relevant rules.
|| linkee->IsSynthetic()) &&
((lang == "CXX"_s && linkee->HaveCxx20ModuleSources()) ||
(lang == "Fortran"_s && linkee->HaveFortranSources(config)))) {
cmLocalGenerator* lg = linkee->GetLocalGenerator();
std::string di = linkee->GetSupportDirectory();
if (lg->GetGlobalGenerator()->IsMultiConfig()) {
di = cmStrCat(di, '/', config);
}
if (forward == Forwarding::Yes &&
forward_emitted.insert(linkee).second) {
dirs.Forward.push_back(di);
}
if (direct_emitted.insert(linkee).second) {
dirs.Direct.emplace_back(di);
}
}
}
while (!pending.empty()) {
auto const* current = pending.back();
pending.pop_back();
auto const& transitiveSynthDeps = current->GetSyntheticDeps(config);
auto itLinkeeSynth = transitiveSynthDeps.find(linkee);
if (itLinkeeSynth != transitiveSynthDeps.end() &&
!itLinkeeSynth->second.empty()) {
return itLinkeeSynth->second.front();
}
for (auto const& entry : transitiveSynthDeps) {
for (auto const* synth : entry.second) {
if (synth && visited.insert(synth).second) {
pending.push_back(synth);
}
}
}
}
return nullptr;
};
auto addLinkedTarget = [this, &lang, &config, &dirs, &direct_emitted,
&forward_emitted, &findSyntheticTarget,
gg](cmGeneratorTarget const* linkee,
Forwarding forward) {
// Check if the linkee has a synthetic target to use for importing
cmGeneratorTarget const* mappedLinkee = linkee;
if (auto const* synth = findSyntheticTarget(linkee)) {
mappedLinkee = synth;
}
if (mappedLinkee &&
!mappedLinkee->IsImported()
// Skip targets that build after this one in a static lib cycle.
&& gg->TargetOrderIndexLess(mappedLinkee, this->GeneratorTarget)
// We can ignore the INTERFACE_LIBRARY items because
// Target->GetLinkInformation already processed their
// link interface and they don't have any output themselves.
&& (mappedLinkee->GetType() != cmStateEnums::INTERFACE_LIBRARY
// Synthesized targets may have relevant rules.
|| mappedLinkee->IsSynthetic()) &&
((lang == "CXX"_s && mappedLinkee->HaveCxx20ModuleSources()) ||
(lang == "Fortran"_s &&
mappedLinkee->HaveFortranSources(config)))) {
cmLocalGenerator* lg = mappedLinkee->GetLocalGenerator();
std::string di = mappedLinkee->GetSupportDirectory();
if (lg->GetGlobalGenerator()->IsMultiConfig()) {
di = cmStrCat(di, '/', config);
}
if (forward == Forwarding::Yes &&
forward_emitted.insert(mappedLinkee).second) {
dirs.Forward.push_back(di);
}
if (direct_emitted.insert(mappedLinkee).second) {
dirs.Direct.emplace_back(di);
}
}
};
};
for (auto const& item : cli->GetItems()) {
if (item.Target) {
addLinkedTarget(item.Target, Forwarding::No);
-5
View File
@@ -108,11 +108,6 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
if (fs_type != "CXX_MODULES"_s) {
continue;
}
// Synthetic (BMI-only) targets do not build private C++ modules.
if (tgt->IsSynthetic() &&
file_set->GetVisibility() == cmFileSetVisibility::Private) {
continue;
}
auto fileEntries = file_set->CompileFileEntries();
auto directoryEntries = file_set->CompileDirectoryEntries();
+84 -101
View File
@@ -5327,135 +5327,118 @@ bool cmGeneratorTarget::ApplyCXXStdTargets()
return true;
}
bool cmGeneratorTarget::DiscoverSyntheticTargets(
cmSyntheticTargetCache& cache, std::string const& config,
cmGeneratorTarget const* bmiConsumer)
bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
std::string const& config)
{
std::vector<std::string> allConfigs =
this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
cmOptionalLinkImplementation impl;
this->ComputeLinkImplementationLibraries(config, impl, UseTo::Link);
if (!bmiConsumer) {
bmiConsumer = this;
}
cmCxxModuleUsageEffects usage(bmiConsumer);
cmCxxModuleUsageEffects usage(this);
auto& SyntheticDeps = this->Configs[config].SyntheticDeps;
for (auto const& entry : impl.Libraries) {
auto const* gt = entry.Target;
if (!gt || !gt->HaveCxx20ModuleSources()) {
if (!gt || !gt->IsImported()) {
continue;
}
// Visual Studio generators do not currently support BMI-only compilation,
// so they can't generate synthetic targets. For consuming native modules,
// skip so that the native target is used directly. For imported modules,
// create the synth target anyway and diagnose later, in the VS generator.
if (!gt->IsImported() && this->GlobalGenerator->IsVisualStudio()) {
continue;
}
if (gt->HaveCxx20ModuleSources()) {
cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
constexpr size_t HASH_TRUNCATION = 12;
auto dirhash = hasher.HashString(
gt->GetLocalGenerator()->GetCurrentBinaryDirectory());
std::string safeName = gt->GetName();
cmSystemTools::ReplaceString(safeName, ":", "_");
auto targetIdent =
hasher.HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash()));
std::string targetName =
cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION));
cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
constexpr size_t HASH_TRUNCATION = 12;
auto dirhash =
hasher.HashString(gt->GetLocalGenerator()->GetCurrentBinaryDirectory());
std::string safeName = gt->GetName();
cmSystemTools::ReplaceString(safeName, ":", "_");
auto targetIdent =
hasher.HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash()));
std::string targetName =
cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION));
// Check the cache to see if this instance of the imported target has
// already been created.
auto cached = cache.CxxModuleTargets.find(targetName);
cmGeneratorTarget const* synthDep = nullptr;
if (cached == cache.CxxModuleTargets.end()) {
auto const* model = gt->Target;
auto* mf = gt->Makefile;
auto* lg = gt->GetLocalGenerator();
auto* tgt = mf->AddSynthesizedTarget(cmStateEnums::INTERFACE_LIBRARY,
targetName);
// Check the cache to see if this instance of the target has
// already been created.
auto cached = cache.CxxModuleTargets.find(targetName);
cmGeneratorTarget const* synthDep = nullptr;
if (cached == cache.CxxModuleTargets.end()) {
auto const* model = gt->Target;
auto* mf = gt->Makefile;
auto* lg = gt->GetLocalGenerator();
auto* tgt =
mf->AddSynthesizedTarget(cmStateEnums::INTERFACE_LIBRARY, targetName);
// Copy relevant information from the existing IMPORTED target.
// Copy relevant information from the existing target.
// Copy policies to the target.
tgt->CopyPolicyStatuses(model);
// Copy policies to the target.
tgt->CopyPolicyStatuses(model);
// Copy file sets.
{
auto fsNames = model->GetAllFileSetNames();
for (auto const& fsName : fsNames) {
auto const* fs = model->GetFileSet(fsName);
if (!fs) {
mf->IssueMessage(MessageType::INTERNAL_ERROR,
cmStrCat("Failed to find file set named '",
fsName, "' on target '", tgt->GetName(),
'\''));
continue;
// Copy file sets.
{
auto fsNames = model->GetAllFileSetNames();
for (auto const& fsName : fsNames) {
auto const* fs = model->GetFileSet(fsName);
if (!fs) {
mf->IssueMessage(MessageType::INTERNAL_ERROR,
cmStrCat("Failed to find file set named '",
fsName, "' on target '",
tgt->GetName(), '\''));
continue;
}
auto* newFs = tgt
->GetOrCreateFileSet(fs->GetName(), fs->GetType(),
fs->GetVisibility())
.first;
newFs->CopyEntries(fs);
}
auto* newFs = tgt
->GetOrCreateFileSet(fs->GetName(), fs->GetType(),
fs->GetVisibility())
.first;
newFs->CopyEntries(fs);
}
// Copy imported C++ module properties.
tgt->CopyImportedCxxModulesEntries(model);
// Copy other properties which may affect the C++ module BMI
// generation.
tgt->CopyImportedCxxModulesProperties(model);
tgt->AddLinkLibrary(*mf,
cmStrCat("$<COMPILE_ONLY:", model->GetName(), '>'),
GENERAL_LibraryType);
// Apply usage requirements to the target.
usage.ApplyToTarget(tgt);
// Create the generator target and attach it to the local generator.
auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg);
synthDep = gtp.get();
cache.CxxModuleTargets[targetName] = synthDep;
// See `localGen->ComputeTargetCompileFeatures()` call in
// `cmGlobalGenerator::Compute` for where non-synthetic targets resolve
// this.
for (auto const& innerConfig : allConfigs) {
gtp->ComputeCompileFeatures(innerConfig);
}
// See `cmGlobalGenerator::ApplyCXXStdTargets` in
// `cmGlobalGenerator::Compute` for non-synthetic target resolutions.
if (!gtp->ApplyCXXStdTargets()) {
return false;
}
gtp->DiscoverSyntheticTargets(cache, config);
lg->AddGeneratorTarget(std::move(gtp));
} else {
synthDep = cached->second;
}
// Copy C++ module properties.
tgt->CopyCxxModulesEntries(model);
// Copy other properties which may affect the C++ module BMI
// generation.
tgt->CopyCxxModulesProperties(model);
tgt->AddLinkLibrary(*mf,
cmStrCat("$<COMPILE_ONLY:", model->GetName(), '>'),
GENERAL_LibraryType);
// Apply usage requirements to the target.
usage.ApplyToTarget(tgt);
// Create the generator target and attach it to the local generator.
auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg);
synthDep = gtp.get();
cache.CxxModuleTargets[targetName] = synthDep;
// See `localGen->ComputeTargetCompileFeatures()` call in
// `cmGlobalGenerator::Compute` for where non-synthetic targets resolve
// this.
for (auto const& innerConfig : allConfigs) {
gtp->ComputeCompileFeatures(innerConfig);
}
// See `cmGlobalGenerator::ApplyCXXStdTargets` in
// `cmGlobalGenerator::Compute` for non-synthetic target resolutions.
if (!gtp->ApplyCXXStdTargets()) {
return false;
}
gtp->DiscoverSyntheticTargets(cache, config, bmiConsumer);
lg->AddGeneratorTarget(std::move(gtp));
} else {
synthDep = cached->second;
SyntheticDeps[gt].push_back(synthDep);
}
SyntheticDeps[gt].push_back(synthDep);
}
return true;
}
cmGeneratorTarget::SyntheticDepsMap const& cmGeneratorTarget::GetSyntheticDeps(
std::string const& config) const
{
return this->Configs[config].SyntheticDeps;
}
bool cmGeneratorTarget::HasPackageReferences() const
{
return this->IsInBuildSystem() &&
+2 -7
View File
@@ -1118,13 +1118,8 @@ public:
std::string GetImportedXcFrameworkPath(std::string const& config) const;
bool ApplyCXXStdTargets();
bool DiscoverSyntheticTargets(
cmSyntheticTargetCache& cache, std::string const& config,
cmGeneratorTarget const* bmiConsumer = nullptr);
using SyntheticDepsMap =
std::map<cmGeneratorTarget const*, std::vector<cmGeneratorTarget const*>>;
SyntheticDepsMap const& GetSyntheticDeps(std::string const& config) const;
bool DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
std::string const& config);
class CustomTransitiveProperty : public TransitiveProperty
{
+4 -47
View File
@@ -2587,8 +2587,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
std::vector<std::string> const& forward_modules_from_target_dirs,
std::string const& native_target_dir, std::string const& arg_lang,
std::string const& arg_modmapfmt, cmCxxModuleExportInfo const& export_info)
std::string const& arg_lang, std::string const& arg_modmapfmt,
cmCxxModuleExportInfo const& export_info)
{
// Setup path conversions.
{
@@ -2748,47 +2748,6 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
}
}
// If this is a synthetic target for a non-imported target, read PRIVATE
// module info from the native target
if (!native_target_dir.empty()) {
std::string const modules_info_path =
cmStrCat(native_target_dir, '/', arg_lang, "Modules.json");
Json::Value native_modules_info;
cmsys::ifstream modules_file(modules_info_path.c_str(),
std::ios::in | std::ios::binary);
if (!modules_file) {
cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to open ",
modules_info_path,
" for module information"));
return false;
}
Json::Reader reader;
if (!reader.parse(modules_file, native_modules_info, false)) {
cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
modules_info_path,
reader.getFormattedErrorMessages()));
return false;
}
if (native_modules_info.isObject()) {
Json::Value const& native_target_modules =
native_modules_info["modules"];
if (native_target_modules.isObject()) {
for (auto i = native_target_modules.begin();
i != native_target_modules.end(); ++i) {
Json::Value const& visible_module = *i;
if (visible_module.isObject()) {
auto is_private = visible_module["is-private"].asBool();
// Only add private modules since others are discovered by the
// synthetic target's own scan rules
if (is_private) {
target_modules[i.key().asString()] = visible_module;
}
}
}
}
}
}
cmGeneratedFileStream ddf(arg_dd);
ddf << "ninja_dyndep_version = 1.0\n";
@@ -3082,7 +3041,6 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
tdi_forward_modules_from_target_dir.asString());
}
}
std::string const native_target_dir = tdi["native-target-dir"].asString();
std::string const compilerId = tdi["compiler-id"].asString();
std::string const simulateId = tdi["compiler-simulate-id"].asString();
std::string const compilerFrontendVariant =
@@ -3106,9 +3064,8 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
# endif
return gg.WriteDyndepFile(dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld,
arg_dd, arg_ddis, module_dir, linked_target_dirs,
forward_modules_from_target_dirs,
native_target_dir, arg_lang, arg_modmapfmt,
*export_info)
forward_modules_from_target_dirs, arg_lang,
arg_modmapfmt, *export_info)
? 0
: 1;
}
+1 -2
View File
@@ -433,8 +433,7 @@ public:
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
std::vector<std::string> const& forward_modules_from_target_dirs,
std::string const& native_target_dir, std::string const& arg_lang,
std::string const& arg_modmapfmt,
std::string const& arg_lang, std::string const& arg_modmapfmt,
cmCxxModuleExportInfo const& export_info);
virtual std::string BuildAlias(std::string const& alias,
-33
View File
@@ -1232,23 +1232,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
this->WriteTargetDependInfo(language, config);
// Non-imported synthetic targets read module info from their native target
// Add as implicit dependency.
if (this->GeneratorTarget->IsSynthetic()) {
if (cmGeneratorTarget const* native_gt =
this->LocalGenerator->FindGeneratorTargetToUse(
this->GeneratorTarget->Target->GetTemplateName())) {
if (!native_gt->IsImported()) {
std::string native_dir = native_gt->GetSupportDirectory();
if (this->GetGlobalGenerator()->IsMultiConfig()) {
native_dir = cmStrCat(native_dir, '/', config);
}
build.ImplicitDeps.emplace_back(this->ConvertToNinjaPath(
cmStrCat(native_dir, '/', language, "Modules.json")));
}
}
}
auto const linked_directories =
this->GetLinkedTargetDirectories(language, config);
for (std::string const& l : linked_directories.Direct) {
@@ -2172,22 +2155,6 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
tdi_forward_modules_from_target_dirs.append(l);
}
// Record the native target support directory for non-imported synthetic
// targets
if (this->GeneratorTarget->IsSynthetic()) {
if (cmGeneratorTarget* nativeGT =
this->LocalGenerator->FindGeneratorTargetToUse(
this->GeneratorTarget->Target->GetTemplateName())) {
if (!nativeGT->IsImported()) {
std::string nativeDir = nativeGT->GetSupportDirectory();
if (this->GetGlobalGenerator()->IsMultiConfig()) {
nativeDir = cmStrCat(nativeDir, '/', config);
}
tdi["native-target-dir"] = nativeDir;
}
}
}
cmDyndepGeneratorCallbacks cb;
cb.ObjectFilePath = [this](cmSourceFile const* sf, std::string const& cnf) {
return this->GetObjectFilePath(sf, cnf);
+18 -33
View File
@@ -1721,52 +1721,37 @@ void cmTarget::CopyPolicyStatuses(cmTarget const* tgt)
assert(!this->IsNormal());
// Imported targets cannot be the target of a copy.
assert(!this->IsImported());
// Only imported or normal targets can be the source of a copy.
assert(tgt->IsImported() || tgt->IsNormal());
// Only imported targets can be the source of a copy.
assert(tgt->IsImported());
this->impl->PolicyMap = tgt->impl->PolicyMap;
this->impl->TemplateTarget = tgt;
}
void cmTarget::CopyCxxModulesEntries(cmTarget const* tgt)
void cmTarget::CopyImportedCxxModulesEntries(cmTarget const* tgt)
{
// Normal targets cannot be the target of a copy.
assert(!this->IsNormal());
// Imported targets cannot be the target of a copy.
assert(!this->IsImported());
// Only imported or normal targets can be the source of a copy.
assert(tgt->IsImported() || tgt->IsNormal());
// Only imported targets can be the source of a copy.
assert(tgt->IsImported());
this->impl->IncludeDirectories.Entries.clear();
this->impl->IncludeDirectories.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries));
this->impl->CompileDefinitions.Entries.clear();
this->impl->CompileDefinitions.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries));
this->impl->CompileFeatures.Entries.clear();
this->impl->CompileFeatures.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries));
this->impl->CompileOptions.Entries.clear();
this->impl->CompileOptions.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries));
this->impl->LinkLibraries.Entries.clear();
if (tgt->IsImported()) {
this->impl->IncludeDirectories.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries));
this->impl->CompileDefinitions.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries));
this->impl->CompileFeatures.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries));
this->impl->CompileOptions.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries));
this->impl->LinkLibraries.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesLinkLibraries.Entries));
} else {
this->impl->IncludeDirectories.CopyFromEntries(
cmMakeRange(tgt->impl->IncludeDirectories.Entries));
this->impl->CompileDefinitions.CopyFromEntries(
cmMakeRange(tgt->impl->CompileDefinitions.Entries));
this->impl->CompileFeatures.CopyFromEntries(
cmMakeRange(tgt->impl->CompileFeatures.Entries));
this->impl->CompileOptions.CopyFromEntries(
cmMakeRange(tgt->impl->CompileOptions.Entries));
this->impl->LinkLibraries.CopyFromEntries(
cmMakeRange(tgt->impl->LinkLibraries.Entries));
}
this->impl->LinkLibraries.CopyFromEntries(
cmMakeRange(tgt->impl->ImportedCxxModulesLinkLibraries.Entries));
// Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this
// target's `PRIVATE`.
@@ -1775,14 +1760,14 @@ void cmTarget::CopyCxxModulesEntries(cmTarget const* tgt)
tgt->impl->CxxModulesFileSets.InterfaceEntries.Entries;
}
void cmTarget::CopyCxxModulesProperties(cmTarget const* tgt)
void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt)
{
// Normal targets cannot be the target of a copy.
assert(!this->IsNormal());
// Imported targets cannot be the target of a copy.
assert(!this->IsImported());
// Only imported or normal targets can be the source of a copy.
assert(tgt->IsImported() || tgt->IsNormal());
// Only imported targets can be the source of a copy.
assert(tgt->IsImported());
// The list of properties that are relevant here include:
// - compilation-specific properties for any language or platform
+2 -2
View File
@@ -321,8 +321,8 @@ public:
cmBTStringRange GetLinkInterfaceDirectExcludeEntries() const;
void CopyPolicyStatuses(cmTarget const* tgt);
void CopyCxxModulesEntries(cmTarget const* tgt);
void CopyCxxModulesProperties(cmTarget const* tgt);
void CopyImportedCxxModulesEntries(cmTarget const* tgt);
void CopyImportedCxxModulesProperties(cmTarget const* tgt);
cmBTStringRange GetHeaderSetsEntries() const;
cmBTStringRange GetCxxModuleSetsEntries() const;
@@ -185,7 +185,7 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
# BMI generation
if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND
RunCMake_GENERATOR MATCHES "Ninja")
# FIXME(#27597): Restore per-importer BMI and enable this test.
# FIXME(#25539,#27600,#27597): Restore per-importer BMI and enable this test.
# run_cxx_module_test(mixed-bmi-compatibility)
endif()
@@ -1,27 +1,12 @@
file(GLOB synth_dirs
"${RunCMake_TEST_BINARY_DIR}/CMakeFiles/depchain_with_modules_json_file@synth_*.dir")
list(LENGTH synth_dirs synth_dirs_len)
if (NOT synth_dirs_len EQUAL 1)
list(APPEND RunCMake_TEST_FAILED
"Expected exactly one synthetic target for consuming 'depchain_with_modules_json_file' but found ${synth_dirs_len}: ${synth_dirs}")
endif ()
list(GET synth_dirs 0 synth_dir)
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/Debug/CXX.dd")
set(modules_json_path "${synth_dir}/Debug/CXXModules.json")
set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/Debug/CXXModules.json")
else ()
set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/CXX.dd")
set(modules_json_path "${synth_dir}/CXXModules.json")
set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/CXXModules.json")
endif ()
if ("${modules_json_path}" IS_NEWER_THAN "${RunCMake_TEST_BINARY_DIR}/${dep_modules_json_path}")
cmake_path(RELATIVE_PATH modules_json_path
BASE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
if ("${RunCMake_TEST_BINARY_DIR}/${modules_json_path}" IS_NEWER_THAN "${RunCMake_TEST_BINARY_DIR}/${dep_modules_json_path}")
list(APPEND RunCMake_TEST_FAILED
"Object '${dep_modules_json_path}' should have recompiled if '${modules_json_path}' changed.")
endif ()
@@ -1,17 +1,7 @@
file(GLOB synth_dirs
"${RunCMake_TEST_BINARY_DIR}/CMakeFiles/depchain_with_modules_json_file@synth_*.dir")
list(LENGTH synth_dirs synth_dirs_len)
if (NOT synth_dirs_len EQUAL 1)
return()
endif()
list(GET synth_dirs 0 synth_dir)
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(modules_json_path "${synth_dir}/Debug/CXXModules.json")
set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/Debug/CXXModules.json")
else ()
set(modules_json_path "${synth_dir}/CXXModules.json")
set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/CXXModules.json")
endif ()
file(TOUCH_NOCREATE "${modules_json_path}")
file(TOUCH_NOCREATE "${RunCMake_TEST_BINARY_DIR}/${modules_json_path}")