/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #pragma once #include "cmConfigure.h" // IWYU pragma: keep #include #include #include #include #include #include #include #include "cmGeneratorExpression.h" class cmExportSet; class cmGeneratorTarget; class cmLocalGenerator; #define STRINGIFY_HELPER(X) #X #define STRINGIFY(X) STRINGIFY_HELPER(X) #define DEVEL_CMAKE_VERSION(major, minor) \ (CMake_VERSION_ENCODE(major, minor, 0) > \ CMake_VERSION_ENCODE(CMake_VERSION_MAJOR, CMake_VERSION_MINOR, 0) \ ? STRINGIFY(CMake_VERSION_MAJOR) "." STRINGIFY( \ CMake_VERSION_MINOR) "." STRINGIFY(CMake_VERSION_PATCH) \ : #major "." #minor ".0") /** \class cmExportFileGenerator * \brief Generate files exporting targets from a build or install tree. * * cmExportFileGenerator is the interface class for generating export files. */ class cmExportFileGenerator { public: cmExportFileGenerator(); virtual ~cmExportFileGenerator() = default; /** Set the full path to the export file to generate. */ void SetExportFile(char const* mainFile); std::string const& GetMainExportFileName() const; /** Set the namespace in which to place exported target names. */ void SetNamespace(std::string const& ns) { this->Namespace = ns; } std::string GetNamespace() const { return this->Namespace; } /** Add a configuration to be exported. */ void AddConfiguration(std::string const& config); /** Create and actually generate the export file. Returns whether there was an error. */ bool GenerateImportFile(); protected: using ImportPropertyMap = std::map; // Collect properties with detailed information about targets beyond // their location on disk. void SetImportDetailProperties(std::string const& config, std::string const& suffix, cmGeneratorTarget const* target, ImportPropertyMap& properties); enum class ImportLinkPropertyTargetNames { Yes, No, }; template void SetImportLinkProperty(std::string const& suffix, cmGeneratorTarget const* target, std::string const& propName, std::vector const& entries, ImportPropertyMap& properties, ImportLinkPropertyTargetNames targetNames); /** Generate the export file to the given output stream. Returns whether there was an error. */ virtual bool GenerateImportFile(std::ostream& os) = 0; /** Each subclass knows how to generate its kind of export file. */ virtual bool GenerateMainFile(std::ostream& os) = 0; /** Generate per-configuration target information to the given output stream. */ virtual void GenerateImportConfig(std::ostream& os, std::string const& config); /** Each subclass knows where the target files are located. */ virtual void GenerateImportTargetsConfig(std::ostream& os, std::string const& config, std::string const& suffix) = 0; /** Record a target referenced by an exported target. */ virtual bool NoteLinkedTarget(cmGeneratorTarget const* target, std::string const& linkedName, cmGeneratorTarget const* linkedTarget); /** Each subclass knows how to deal with a target that is missing from an * export set. */ virtual void HandleMissingTarget(std::string& link_libs, cmGeneratorTarget const* depender, cmGeneratorTarget* dependee) = 0; /** Complain when a duplicate target is encountered. */ virtual void ComplainAboutDuplicateTarget( std::string const& targetName) const = 0; virtual cm::string_view GetImportPrefixWithSlash() const = 0; void AddImportPrefix(std::string& exportDirs) const; void PopulateInterfaceProperty(std::string const& propName, cmGeneratorTarget const* target, ImportPropertyMap& properties) const; void PopulateInterfaceProperty(std::string const& propName, cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext, ImportPropertyMap& properties); bool PopulateInterfaceLinkLibrariesProperty( cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext, ImportPropertyMap& properties); bool PopulateInterfaceProperties( cmGeneratorTarget const* target, std::string const& includesDestinationDirs, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties); virtual void ReportError(std::string const& errorMessage) const = 0; using ExportInfo = std::pair, std::string>; /** Find the set of export files and the unique namespace (if any) for a * target. */ virtual ExportInfo FindExportInfo(cmGeneratorTarget const* target) const = 0; enum FreeTargetsReplace { ReplaceFreeTargets, NoReplaceFreeTargets }; void ResolveTargetsInGeneratorExpressions( std::string& input, cmGeneratorTarget const* target, FreeTargetsReplace replace = NoReplaceFreeTargets); virtual cmExportSet* GetExportSet() const { return nullptr; } virtual void ReplaceInstallPrefix(std::string& input) const; virtual std::string InstallNameDir(cmGeneratorTarget const* target, std::string const& config) = 0; /** Get the temporary location of the config-agnostic C++ module file. */ virtual std::string GetCxxModuleFile(std::string const& name) const = 0; virtual std::string GetCxxModulesDirectory() const = 0; virtual void GenerateCxxModuleConfigInformation(std::string const&, std::ostream& os) const = 0; bool AddTargetNamespace(std::string& input, cmGeneratorTarget const* target, cmLocalGenerator const* lg); // The namespace in which the exports are placed in the generated file. std::string Namespace; // The set of configurations to export. std::vector Configurations; // The file to generate. std::string MainImportFile; std::string FileDir; std::string FileBase; std::string FileExt; bool AppendMode = false; // The set of targets included in the export. std::set ExportedTargets; std::vector MissingTargets; std::set ExternalTargets; private: void PopulateInterfaceProperty(std::string const& propName, std::string const& outputName, cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext, ImportPropertyMap& properties); void PopulateCompatibleInterfaceProperties( cmGeneratorTarget const* target, ImportPropertyMap& properties) const; void PopulateCustomTransitiveInterfaceProperties( cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties); bool PopulateCxxModuleExportProperties( cmGeneratorTarget const* gte, ImportPropertyMap& properties, cmGeneratorExpression::PreprocessContext ctx, std::string const& includesDestinationDirs, std::string& errorMessage); bool PopulateExportProperties(cmGeneratorTarget const* gte, ImportPropertyMap& properties, std::string& errorMessage) const; void ResolveTargetsInGeneratorExpression(std::string& input, cmGeneratorTarget const* target, cmLocalGenerator const* lg); }; extern template void cmExportFileGenerator::SetImportLinkProperty( std::string const&, cmGeneratorTarget const*, std::string const&, std::vector const&, ImportPropertyMap& properties, ImportLinkPropertyTargetNames); extern template void cmExportFileGenerator::SetImportLinkProperty( std::string const&, cmGeneratorTarget const*, std::string const&, std::vector const&, ImportPropertyMap& properties, ImportLinkPropertyTargetNames);