From c68b587abe610e0d35782aa1475231bfe1508684 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 24 Mar 2026 10:28:10 -0400 Subject: [PATCH] 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 --- Source/cmCommonTargetGenerator.cxx | 109 +++-------- Source/cmDyndepCollation.cxx | 5 - Source/cmGeneratorTarget.cxx | 185 ++++++++---------- Source/cmGeneratorTarget.h | 9 +- Source/cmGlobalNinjaGenerator.cxx | 51 +---- Source/cmGlobalNinjaGenerator.h | 3 +- Source/cmNinjaTargetGenerator.cxx | 33 ---- Source/cmTarget.cxx | 51 ++--- Source/cmTarget.h | 4 +- .../CXXModulesCompile/RunCMakeTest.cmake | 2 +- ...epchain-mods-json-file-rebuild-check.cmake | 21 +- .../depchain-mods-json-file/pre-rebuild.cmake | 16 +- 12 files changed, 145 insertions(+), 344 deletions(-) diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 6db67678ca..baa1198c71 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -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 pending; - std::set 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); diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx index 312272226e..2a179256ee 100644 --- a/Source/cmDyndepCollation.cxx +++ b/Source/cmDyndepCollation.cxx @@ -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(); diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 98049236af..e1cb914171 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -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 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("$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(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("$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(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() && diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 8c56a9b66f..a32ecbac5b 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -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>; - SyntheticDepsMap const& GetSyntheticDeps(std::string const& config) const; + bool DiscoverSyntheticTargets(cmSyntheticTargetCache& cache, + std::string const& config); class CustomTransitiveProperty : public TransitiveProperty { diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index f603fe2233..b14564174d 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -2587,8 +2587,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( std::string const& module_dir, std::vector const& linked_target_dirs, std::vector 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::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::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; } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 059dea87d3..152c45cd52 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -433,8 +433,7 @@ public: std::string const& module_dir, std::vector const& linked_target_dirs, std::vector 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, diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index f4b43f456e..20f6265b6e 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -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); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index fe713a24e6..296adf5462 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -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 diff --git a/Source/cmTarget.h b/Source/cmTarget.h index ad3a9c05e5..b275e47329 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -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; diff --git a/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake index eb9b5a549c..cd248390bd 100644 --- a/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake +++ b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake @@ -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() diff --git a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake index 4568873174..94e833ad1e 100644 --- a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake +++ b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake @@ -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 () diff --git a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake index 2b2ce92640..9c3f2ff97b 100644 --- a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake +++ b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake @@ -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}")