From 9c0491a3e41a0232ae10d53c0e12921bf1be4880 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 25 Mar 2024 07:30:04 -0400 Subject: [PATCH] cmDyndepCollation: write out scanned source information too This is required to fill in the `requires` field for sources using modules that do not provide them. --- Source/cmDyndepCollation.cxx | 126 ++++++++++++------ .../NinjaDependInfoBMIInstall-private.json | 3 +- .../NinjaDependInfoBMIInstall-public.json | 3 +- .../expect/NinjaDependInfoExport-private.json | 3 +- .../expect/NinjaDependInfoExport-public.json | 3 +- ...ependInfoExportFilesystemSafe-private.json | 3 +- ...DependInfoExportFilesystemSafe-public.json | 3 +- .../NinjaDependInfoFileSet-private.json | 20 ++- .../expect/NinjaDependInfoFileSet-public.json | 20 ++- 9 files changed, 137 insertions(+), 47 deletions(-) diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx index bfe3a75eab..cbb0e34a1c 100644 --- a/Source/cmDyndepCollation.cxx +++ b/Source/cmDyndepCollation.cxx @@ -39,13 +39,55 @@ namespace { -Json::Value CollationInformationCxxModules( - cmGeneratorTarget const* gt, std::string const& config, - cmDyndepGeneratorCallbacks const& cb) +struct TdiSourceInfo { + Json::Value Sources; + Json::Value CxxModules; +}; + +TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt, + std::string const& config, + cmDyndepGeneratorCallbacks const& cb) +{ + TdiSourceInfo info; cmTarget const* tgt = gt->Target; auto all_file_sets = tgt->GetAllFileSetNames(); - Json::Value tdi_cxx_module_info = Json::objectValue; + Json::Value& tdi_sources = info.Sources = Json::objectValue; + Json::Value& tdi_cxx_module_info = info.CxxModules = Json::objectValue; + + enum class CompileType + { + ObjectAndBmi, + BmiOnly, + }; + std::map> sf_map; + { + auto fill_sf_map = [gt, tgt, &sf_map](cmSourceFile const* sf, + CompileType type) { + auto full_path = sf->GetFullPath(); + if (full_path.empty()) { + gt->Makefile->IssueMessage( + MessageType::INTERNAL_ERROR, + cmStrCat("Target \"", tgt->GetName(), + "\" has a full path-less source file.")); + return; + } + sf_map[full_path] = std::make_pair(sf, type); + }; + + std::vector objectSources; + gt->GetObjectSources(objectSources, config); + for (auto const* sf : objectSources) { + fill_sf_map(sf, CompileType::ObjectAndBmi); + } + + std::vector cxxModuleSources; + gt->GetCxxModuleSources(cxxModuleSources, config); + for (auto const* sf : cxxModuleSources) { + fill_sf_map(sf, CompileType::BmiOnly); + } + } + for (auto const& file_set_name : all_file_sets) { auto const* file_set = tgt->GetFileSet(file_set_name); if (!file_set) { @@ -73,39 +115,6 @@ Json::Value CollationInformationCxxModules( gt->LocalGenerator, config, gt); } - enum class CompileType - { - ObjectAndBmi, - BmiOnly, - }; - std::map> sf_map; - { - auto fill_sf_map = [gt, tgt, &sf_map](cmSourceFile const* sf, - CompileType type) { - auto full_path = sf->GetFullPath(); - if (full_path.empty()) { - gt->Makefile->IssueMessage( - MessageType::INTERNAL_ERROR, - cmStrCat("Target \"", tgt->GetName(), - "\" has a full path-less source file.")); - return; - } - sf_map[full_path] = std::make_pair(sf, type); - }; - - std::vector objectSources; - gt->GetObjectSources(objectSources, config); - for (auto const* sf : objectSources) { - fill_sf_map(sf, CompileType::ObjectAndBmi); - } - - std::vector cxxModuleSources; - gt->GetCxxModuleSources(cxxModuleSources, config); - for (auto const* sf : cxxModuleSources) { - fill_sf_map(sf, CompileType::BmiOnly); - } - } - Json::Value fs_dest = Json::nullValue; for (auto const& ig : gt->Makefile->GetInstallGenerators()) { if (auto const* fsg = @@ -134,6 +143,8 @@ Json::Value CollationInformationCxxModules( auto const* sf = lookup->second.first; CompileType const ct = lookup->second.second; + sf_map.erase(lookup); + if (!sf) { gt->Makefile->IssueMessage( MessageType::INTERNAL_ERROR, @@ -160,7 +171,26 @@ Json::Value CollationInformationCxxModules( } } - return tdi_cxx_module_info; + for (auto const& sf_entry : sf_map) { + CompileType const ct = sf_entry.second.second; + if (ct == CompileType::BmiOnly) { + continue; + } + + auto const* sf = sf_entry.second.first; + if (!gt->NeedDyndepForSource(sf->GetLanguage(), config, sf)) { + continue; + } + + auto full_file = cmSystemTools::CollapseFullPath(sf->GetFullPath()); + auto obj_path = cb.ObjectFilePath(sf, config); + Json::Value& tdi_source_info = tdi_sources[obj_path] = Json::objectValue; + + tdi_source_info["source"] = full_file; + tdi_source_info["language"] = sf->GetLanguage(); + } + + return info; } Json::Value CollationInformationBmiInstallation(cmGeneratorTarget const* gt, @@ -289,12 +319,20 @@ void cmDyndepCollation::AddCollationInformation( Json::Value& tdi, cmGeneratorTarget const* gt, std::string const& config, cmDyndepGeneratorCallbacks const& cb) { - tdi["cxx-modules"] = CollationInformationCxxModules(gt, config, cb); + auto sourcesInfo = CollationInformationSources(gt, config, cb); + tdi["sources"] = sourcesInfo.Sources; + tdi["cxx-modules"] = sourcesInfo.CxxModules; tdi["bmi-installation"] = CollationInformationBmiInstallation(gt, config); tdi["exports"] = CollationInformationExports(gt); tdi["config"] = config; } +struct SourceInfo +{ + std::string SourcePath; + std::string Language; +}; + struct CxxModuleFileSet { std::string Name; @@ -330,6 +368,7 @@ struct CxxModuleExport struct cmCxxModuleExportInfo { + std::map ObjectToSource; std::map ObjectToFileSet; cm::optional BmiInstallation; std::vector Exports; @@ -405,6 +444,15 @@ cmDyndepCollation::ParseExportInfo(Json::Value const& tdi) } } } + Json::Value const& tdi_sources = tdi["sources"]; + if (tdi_sources.isObject()) { + for (auto i = tdi_sources.begin(); i != tdi_sources.end(); ++i) { + SourceInfo& si = export_info->ObjectToSource[i.key().asString()]; + auto const& tdi_source = *i; + si.SourcePath = tdi_source["source"].asString(); + si.Language = tdi_source["language"].asString(); + } + } return export_info; } diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json index 78f7928670..4bb2455c01 100644 --- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json +++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json @@ -47,5 +47,6 @@ "language": "CXX", "forward-modules-from-target-dirs": [], "linked-target-dirs": [], - "module-dir": "/CMakeFiles/ninja-bmi-install-private.dir" + "module-dir": "/CMakeFiles/ninja-bmi-install-private.dir", + "sources": {} } diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json index 6c23354188..364bce203c 100644 --- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json +++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json @@ -47,5 +47,6 @@ "language": "CXX", "forward-modules-from-target-dirs": [], "linked-target-dirs": [], - "module-dir": "/CMakeFiles/ninja-bmi-install-public.dir" + "module-dir": "/CMakeFiles/ninja-bmi-install-public.dir", + "sources": {} } diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json index 71b2b66e81..45cd8abab6 100644 --- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json +++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json @@ -79,5 +79,6 @@ "language": "CXX", "forward-modules-from-target-dirs": [], "linked-target-dirs": [], - "module-dir": "/CMakeFiles/ninja-exports-private.dir" + "module-dir": "/CMakeFiles/ninja-exports-private.dir", + "sources": {} } diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json index a9cde991ad..43a4e4fbe1 100644 --- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json +++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json @@ -79,5 +79,6 @@ "language": "CXX", "forward-modules-from-target-dirs": [], "linked-target-dirs": [], - "module-dir": "/CMakeFiles/ninja-exports-public.dir" + "module-dir": "/CMakeFiles/ninja-exports-public.dir", + "sources": {} } diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExportFilesystemSafe-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExportFilesystemSafe-private.json index 7905c535f1..03e2018f84 100644 --- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExportFilesystemSafe-private.json +++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExportFilesystemSafe-private.json @@ -79,5 +79,6 @@ "language": "CXX", "forward-modules-from-target-dirs": [], "linked-target-dirs": [], - "module-dir": "/CMakeFiles/ninja-exports-private.dir" + "module-dir": "/CMakeFiles/ninja-exports-private.dir", + "sources": {} } diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExportFilesystemSafe-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExportFilesystemSafe-public.json index 1734590a94..4128252469 100644 --- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExportFilesystemSafe-public.json +++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExportFilesystemSafe-public.json @@ -79,5 +79,6 @@ "language": "CXX", "forward-modules-from-target-dirs": [], "linked-target-dirs": [], - "module-dir": "/CMakeFiles/ninja-exports-public.dir" + "module-dir": "/CMakeFiles/ninja-exports-public.dir", + "sources": {} } diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json index ed61e0e276..f4e19f4cc1 100644 --- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json +++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json @@ -42,5 +42,23 @@ "language": "CXX", "forward-modules-from-target-dirs": [], "linked-target-dirs": [], - "module-dir": "/CMakeFiles/ninja-file-sets-private.dir" + "module-dir": "/CMakeFiles/ninja-file-sets-private.dir", + "sources": { + "CMakeFiles/ninja-file-sets-private.dir/sources/module-impl.cxx" : { + "language" : "CXX", + "source" : "/sources/module-impl.cxx" + }, + "CMakeFiles/ninja-file-sets-private.dir/sources/module-internal-part-impl.cxx" : { + "language" : "CXX", + "source" : "/sources/module-internal-part-impl.cxx" + }, + "CMakeFiles/ninja-file-sets-private.dir/sources/module-part-impl.cxx" : { + "language" : "CXX", + "source" : "/sources/module-part-impl.cxx" + }, + "CMakeFiles/ninja-file-sets-private.dir/sources/module-use.cxx" : { + "language" : "CXX", + "source" : "/sources/module-use.cxx" + } + } } diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json index 171935f267..9604ba212e 100644 --- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json +++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json @@ -42,5 +42,23 @@ "language": "CXX", "forward-modules-from-target-dirs": [], "linked-target-dirs": [], - "module-dir": "/CMakeFiles/ninja-file-sets-public.dir" + "module-dir": "/CMakeFiles/ninja-file-sets-public.dir", + "sources": { + "CMakeFiles/ninja-file-sets-public.dir/sources/module-impl.cxx" : { + "language" : "CXX", + "source" : "/sources/module-impl.cxx" + }, + "CMakeFiles/ninja-file-sets-public.dir/sources/module-internal-part-impl.cxx" : { + "language" : "CXX", + "source" : "/sources/module-internal-part-impl.cxx" + }, + "CMakeFiles/ninja-file-sets-public.dir/sources/module-part-impl.cxx" : { + "language" : "CXX", + "source" : "/sources/module-part-impl.cxx" + }, + "CMakeFiles/ninja-file-sets-public.dir/sources/module-use.cxx" : { + "language" : "CXX", + "source" : "/sources/module-use.cxx" + } + } }