From 48faa19c194364ab33a2a95ddc6a9f003e9d2e06 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sun, 1 Oct 2023 10:23:00 -0400 Subject: cmBuildDatabase: support writing template files --- Source/cmBuildDatabase.cxx | 86 ++++++++++++++++++++++++++++++++++++++++++++++ Source/cmBuildDatabase.h | 4 +++ 2 files changed, 90 insertions(+) diff --git a/Source/cmBuildDatabase.cxx b/Source/cmBuildDatabase.cxx index b2d714f..fafcee1 100644 --- a/Source/cmBuildDatabase.cxx +++ b/Source/cmBuildDatabase.cxx @@ -3,6 +3,7 @@ #include "cmBuildDatabase.h" #include +#include #include #include @@ -15,10 +16,23 @@ #include "cmsys/FStream.hxx" +#include "cmComputeLinkInformation.h" +#include "cmFileSet.h" #include "cmGeneratedFileStream.h" +#include "cmGeneratorTarget.h" +#include "cmGlobalGenerator.h" +#include "cmListFileCache.h" +#include "cmLocalGenerator.h" +#include "cmSourceFile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +namespace { + +std::string PlaceholderName = "<__CMAKE_UNKNOWN>"; + +} + cmBuildDatabase::cmBuildDatabase() = default; cmBuildDatabase::cmBuildDatabase(cmBuildDatabase const&) = default; cmBuildDatabase::~cmBuildDatabase() = default; @@ -374,6 +388,78 @@ cmBuildDatabase cmBuildDatabase::Merge( return db; } +cmBuildDatabase cmBuildDatabase::ForTarget(cmGeneratorTarget* gt, + std::string const& config) +{ + cmBuildDatabase db; + + Set set; + set.Name = cmStrCat(gt->GetName(), '@', config); + set.FamilyName = gt->GetFamilyName(); + if (auto* cli = gt->GetLinkInformation(config)) { + std::set emitted; + std::vector targets; + for (auto const& item : cli->GetItems()) { + auto const* linkee = item.Target; + if (linkee && linkee->HaveCxx20ModuleSources() && + !linkee->IsImported() && emitted.insert(linkee).second) { + set.VisibleSets.push_back(cmStrCat(linkee->GetName(), '@', config)); + } + } + } + + for (auto const& sfbt : gt->GetSourceFiles(config)) { + auto const* sf = sfbt.Value; + + bool isCXXModule = false; + bool isPrivate = true; + if (sf->GetLanguage() != "CXX"_s) { + auto const* fs = gt->GetFileSetForSource(config, sf); + if (fs && fs->GetType() == "CXX_MODULES"_s) { + isCXXModule = true; + isPrivate = !cmFileSetVisibilityIsForInterface(fs->GetVisibility()); + } + } + + TranslationUnit tu; + + // FIXME: Makefiles will want this to be the current working directory. + tu.WorkDirectory = gt->GetLocalGenerator()->GetBinaryDirectory(); + tu.Source = sf->GetFullPath(); + if (!gt->IsSynthetic()) { + auto* gg = gt->GetGlobalGenerator(); + std::string const objectDir = gg->ConvertToOutputPath( + cmStrCat(gt->GetSupportDirectory(), gg->GetConfigDirectory(config))); + std::string const objectFileName = gt->GetObjectName(sf); + tu.Object = cmStrCat(objectDir, '/', objectFileName); + } + if (isCXXModule) { + tu.Provides[PlaceholderName] = PlaceholderName; + } + + cmGeneratorTarget::ClassifiedFlags classifiedFlags = + gt->GetClassifiedFlagsForSource(sf, config); + for (auto const& classifiedFlag : classifiedFlags) { + if (classifiedFlag.Classification == + cmGeneratorTarget::FlagClassification::BaselineFlag) { + tu.BaselineArguments.push_back(classifiedFlag.Flag); + tu.LocalArguments.push_back(classifiedFlag.Flag); + } else if (classifiedFlag.Classification == + cmGeneratorTarget::FlagClassification::PrivateFlag) { + tu.LocalArguments.push_back(classifiedFlag.Flag); + } + tu.Arguments.push_back(classifiedFlag.Flag); + } + tu.Private = isPrivate; + + set.TranslationUnits.emplace_back(std::move(tu)); + } + + db.Sets.emplace_back(std::move(set)); + + return db; +} + int cmcmd_cmake_module_compile_db( std::vector::const_iterator argBeg, std::vector::const_iterator argEnd) diff --git a/Source/cmBuildDatabase.h b/Source/cmBuildDatabase.h index 0b87562..8ed35ec 100644 --- a/Source/cmBuildDatabase.h +++ b/Source/cmBuildDatabase.h @@ -11,6 +11,8 @@ #include +class cmGeneratorTarget; + class cmBuildDatabase { public: @@ -43,6 +45,8 @@ public: static std::unique_ptr Load(std::string const& path); static cmBuildDatabase Merge(std::vector const& components); + static cmBuildDatabase ForTarget(cmGeneratorTarget* gt, + std::string const& config); private: std::vector Sets; -- cgit v0.12