diff options
Diffstat (limited to 'Source/cmLocalGenerator.h')
-rw-r--r-- | Source/cmLocalGenerator.h | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h new file mode 100644 index 0000000..f9839f6 --- /dev/null +++ b/Source/cmLocalGenerator.h @@ -0,0 +1,468 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmLocalGenerator_h +#define cmLocalGenerator_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include "cm_kwiml.h" +#include <iosfwd> +#include <map> +#include <set> +#include <string> +#include <unordered_map> +#include <vector> + +#include "cmListFileCache.h" +#include "cmMessageType.h" +#include "cmOutputConverter.h" +#include "cmPolicies.h" +#include "cmStateSnapshot.h" + +class cmComputeLinkInformation; +class cmCustomCommandGenerator; +class cmGeneratorTarget; +class cmGlobalGenerator; +class cmLinkLineComputer; +class cmMakefile; +class cmRulePlaceholderExpander; +class cmSourceFile; +class cmState; +class cmake; + +/** \class cmLocalGenerator + * \brief Create required build files for a directory. + * + * Subclasses of this abstract class generate makefiles, DSP, etc for various + * platforms. This class should never be constructed directly. A + * GlobalGenerator will create it and invoke the appropriate commands on it. + */ +class cmLocalGenerator : public cmOutputConverter +{ +public: + cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile); + virtual ~cmLocalGenerator(); + + /** + * Generate the makefile for this directory. + */ + virtual void Generate() {} + + virtual void ComputeHomeRelativeOutputPath() {} + + /** + * Calls TraceVSDependencies() on all targets of this generator. + */ + void TraceDependencies(); + + virtual void AddHelperCommands() {} + + /** + * Generate the install rules files in this directory. + */ + void GenerateInstallRules(); + + /** + * Generate the test files for tests. + */ + void GenerateTestFiles(); + + /** + * Generate a manifest of target files that will be built. + */ + void ComputeTargetManifest(); + + bool ComputeTargetCompileFeatures(); + + bool IsRootMakefile() const; + + ///! Get the makefile for this generator + cmMakefile* GetMakefile() { return this->Makefile; } + + ///! Get the makefile for this generator, const version + const cmMakefile* GetMakefile() const { return this->Makefile; } + + ///! Get the GlobalGenerator this is associated with + cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; } + const cmGlobalGenerator* GetGlobalGenerator() const + { + return this->GlobalGenerator; + } + + virtual cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const; + + std::string GetLinkLibsCMP0065(std::string const& linkLanguage, + cmGeneratorTarget& tgt) const; + + cmState* GetState() const; + cmStateSnapshot GetStateSnapshot() const; + + void AddArchitectureFlags(std::string& flags, + cmGeneratorTarget const* target, + const std::string& lang, + const std::string& config); + + void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target, + const std::string& lang, const std::string& config); + void AddLanguageFlagsForLinking(std::string& flags, + cmGeneratorTarget const* target, + const std::string& lang, + const std::string& config); + void AddCMP0018Flags(std::string& flags, cmGeneratorTarget const* target, + std::string const& lang, const std::string& config); + void AddVisibilityPresetFlags(std::string& flags, + cmGeneratorTarget const* target, + const std::string& lang); + void AddConfigVariableFlags(std::string& flags, const std::string& var, + const std::string& config); + void AddCompilerRequirementFlag(std::string& flags, + cmGeneratorTarget const* target, + const std::string& lang); + ///! Append flags to a string. + virtual void AppendFlags(std::string& flags, + const std::string& newFlags) const; + virtual void AppendFlags(std::string& flags, const char* newFlags) const; + virtual void AppendFlagEscape(std::string& flags, + const std::string& rawFlag) const; + void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target, + const std::string& config, + const std::string& lang); + void AppendPositionIndependentLinkerFlags(std::string& flags, + cmGeneratorTarget* target, + const std::string& config, + const std::string& lang); + ///! Get the include flags for the current makefile and language + std::string GetIncludeFlags(const std::vector<std::string>& includes, + cmGeneratorTarget* target, + const std::string& lang, + bool forceFullPaths = false, + bool forResponseFile = false, + const std::string& config = ""); + + const std::vector<cmGeneratorTarget*>& GetGeneratorTargets() const + { + return this->GeneratorTargets; + } + + void AddGeneratorTarget(cmGeneratorTarget* gt); + void AddImportedGeneratorTarget(cmGeneratorTarget* gt); + void AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt); + + cmGeneratorTarget* FindLocalNonAliasGeneratorTarget( + const std::string& name) const; + cmGeneratorTarget* FindGeneratorTargetToUse(const std::string& name) const; + + /** + * Process a list of include directories + */ + void AppendIncludeDirectories(std::vector<std::string>& includes, + const char* includes_list, + const cmSourceFile& sourceFile) const; + void AppendIncludeDirectories(std::vector<std::string>& includes, + std::string const& includes_list, + const cmSourceFile& sourceFile) const + { + this->AppendIncludeDirectories(includes, includes_list.c_str(), + sourceFile); + } + void AppendIncludeDirectories(std::vector<std::string>& includes, + const std::vector<std::string>& includes_vec, + const cmSourceFile& sourceFile) const; + + /** + * Encode a list of preprocessor definitions for the compiler + * command line. + */ + void AppendDefines(std::set<std::string>& defines, + std::string const& defines_list) const; + void AppendDefines(std::set<BT<std::string>>& defines, + std::string const& defines_list) const; + void AppendDefines(std::set<BT<std::string>>& defines, + const std::vector<BT<std::string>>& defines_vec) const; + + /** + * Encode a list of compile options for the compiler + * command line. + */ + void AppendCompileOptions(std::string& options, const char* options_list, + const char* regex = nullptr) const; + void AppendCompileOptions(std::string& options, + std::string const& options_list, + const char* regex = nullptr) const + { + this->AppendCompileOptions(options, options_list.c_str(), regex); + } + void AppendCompileOptions(std::string& options, + const std::vector<std::string>& options_vec, + const char* regex = nullptr) const; + + /** + * Join a set of defines into a definesString with a space separator. + */ + void JoinDefines(const std::set<std::string>& defines, + std::string& definesString, const std::string& lang); + + /** Lookup and append options associated with a particular feature. */ + void AppendFeatureOptions(std::string& flags, const std::string& lang, + const char* feature); + + const char* GetFeature(const std::string& feature, + const std::string& config); + + /** \brief Get absolute path to dependency \a name + * + * Translate a dependency as given in CMake code to the name to + * appear in a generated build file. + * - If \a name is a utility target, returns false. + * - If \a name is a CMake target, it will be transformed to the real output + * location of that target for the given configuration. + * - If \a name is the full path to a file, it will be returned. + * - Otherwise \a name is treated as a relative path with respect to + * the source directory of this generator. This should only be + * used for dependencies of custom commands. + */ + bool GetRealDependency(const std::string& name, const std::string& config, + std::string& dep); + + virtual std::string ConvertToIncludeReference( + std::string const& path, + cmOutputConverter::OutputFormat format = cmOutputConverter::SHELL, + bool forceFullPaths = false); + + /** Called from command-line hook to clear dependencies. */ + virtual void ClearDependencies(cmMakefile* /* mf */, bool /* verbose */) {} + + /** Called from command-line hook to update dependencies. */ + virtual bool UpdateDependencies(const std::string& /* tgtInfo */, + bool /*verbose*/, bool /*color*/) + { + return true; + } + + /** @brief Get the include directories for the current makefile and language + * and optional the compiler implicit include directories. + * + * @arg stripImplicitDirs Strip all directories found in + * CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES from the result. + * @arg appendAllImplicitDirs Append all directories found in + * CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES to the result. + */ + std::vector<BT<std::string>> GetIncludeDirectoriesImplicit( + cmGeneratorTarget const* target, std::string const& lang = "C", + std::string const& config = "", bool stripImplicitDirs = true, + bool appendAllImplicitDirs = false) const; + + /** @brief Get the include directories for the current makefile and language + * and optional the compiler implicit include directories. + * + * @arg dirs Directories are appended to this list + */ + void GetIncludeDirectoriesImplicit(std::vector<std::string>& dirs, + cmGeneratorTarget const* target, + const std::string& lang = "C", + const std::string& config = "", + bool stripImplicitDirs = true, + bool appendAllImplicitDirs = false) const; + + /** @brief Get the include directories for the current makefile and language. + * @arg dirs Include directories are appended to this list + */ + void GetIncludeDirectories(std::vector<std::string>& dirs, + cmGeneratorTarget const* target, + const std::string& lang = "C", + const std::string& config = "") const; + + /** @brief Get the include directories for the current makefile and language. + * @return The include directory list + */ + std::vector<BT<std::string>> GetIncludeDirectories( + cmGeneratorTarget const* target, std::string const& lang = "C", + std::string const& config = "") const; + + void AddCompileOptions(std::string& flags, cmGeneratorTarget* target, + const std::string& lang, const std::string& config); + + std::string GetProjectName() const; + + /** Compute the language used to compile the given source file. */ + std::string GetSourceFileLanguage(const cmSourceFile& source); + + // Fill the vector with the target names for the object files, + // preprocessed files and assembly files. + void GetIndividualFileTargets(std::vector<std::string>&) {} + + /** + * Get the relative path from the generator output directory to a + * per-target support directory. + */ + virtual std::string GetTargetDirectory( + cmGeneratorTarget const* target) const; + + /** + * Get the level of backwards compatibility requested by the project + * in this directory. This is the value of the CMake variable + * CMAKE_BACKWARDS_COMPATIBILITY whose format is + * "major.minor[.patch]". The returned integer is encoded as + * + * CMake_VERSION_ENCODE(major, minor, patch) + * + * and is monotonically increasing with the CMake version. + */ + KWIML_INT_uint64_t GetBackwardsCompatibility(); + + /** + * Test whether compatibility is set to a given version or lower. + */ + bool NeedBackwardsCompatibility_2_4(); + + cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id) const; + + cmake* GetCMakeInstance() const; + + std::string const& GetSourceDirectory() const; + std::string const& GetBinaryDirectory() const; + + std::string const& GetCurrentBinaryDirectory() const; + std::string const& GetCurrentSourceDirectory() const; + + /** + * Convert the given remote path to a relative path with respect to + * the given local path. Both paths must use forward slashes and not + * already be escaped or quoted. + * The conversion is skipped if the paths are not both in the source + * or both in the binary tree. + */ + std::string MaybeConvertToRelativePath(std::string const& local_path, + std::string const& remote_path) const; + + /** + * Generate a macOS application bundle Info.plist file. + */ + void GenerateAppleInfoPList(cmGeneratorTarget* target, + const std::string& targetName, + const char* fname); + + /** + * Generate a macOS framework Info.plist file. + */ + void GenerateFrameworkInfoPList(cmGeneratorTarget* target, + const std::string& targetName, + const char* fname); + /** Construct a comment for a custom command. */ + std::string ConstructComment(cmCustomCommandGenerator const& ccg, + const char* default_comment = ""); + // Compute object file names. + std::string GetObjectFileNameWithoutTarget( + const cmSourceFile& source, std::string const& dir_max, + bool* hasSourceExtension = nullptr, + char const* customOutputExtension = nullptr); + + /** Fill out the static linker flags for the given target. */ + void GetStaticLibraryFlags(std::string& flags, std::string const& config, + std::string const& linkLanguage, + cmGeneratorTarget* target); + + /** Fill out these strings for the given target. Libraries to link, + * flags, and linkflags. */ + void GetTargetFlags(cmLinkLineComputer* linkLineComputer, + const std::string& config, std::string& linkLibs, + std::string& flags, std::string& linkFlags, + std::string& frameworkPath, std::string& linkPath, + cmGeneratorTarget* target); + void GetTargetDefines(cmGeneratorTarget const* target, + std::string const& config, std::string const& lang, + std::set<std::string>& defines) const; + std::set<BT<std::string>> GetTargetDefines(cmGeneratorTarget const* target, + std::string const& config, + std::string const& lang) const; + void GetTargetCompileFlags(cmGeneratorTarget* target, + std::string const& config, + std::string const& lang, std::string& flags); + + std::string GetFrameworkFlags(std::string const& l, + std::string const& config, + cmGeneratorTarget* target); + virtual std::string GetTargetFortranFlags(cmGeneratorTarget const* target, + std::string const& config); + + virtual void ComputeObjectFilenames( + std::map<cmSourceFile const*, std::string>& mapping, + cmGeneratorTarget const* gt = nullptr); + + bool IsWindowsShell() const; + bool IsWatcomWMake() const; + bool IsMinGWMake() const; + bool IsNMake() const; + + void IssueMessage(MessageType t, std::string const& text) const; + + void CreateEvaluationFileOutputs(const std::string& config); + void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles); + + const char* GetRuleLauncher(cmGeneratorTarget* target, + const std::string& prop); + +protected: + ///! put all the libraries for a target on into the given stream + void OutputLinkLibraries(cmComputeLinkInformation* pcli, + cmLinkLineComputer* linkLineComputer, + std::string& linkLibraries, + std::string& frameworkPath, std::string& linkPath); + + // Handle old-style install rules stored in the targets. + void GenerateTargetInstallRules( + std::ostream& os, const std::string& config, + std::vector<std::string> const& configurationTypes); + + std::string& CreateSafeUniqueObjectFileName(const std::string& sin, + std::string const& dir_max); + + /** Check whether the native build system supports the given + definition. Issues a warning. */ + virtual bool CheckDefinition(std::string const& define) const; + + cmMakefile* Makefile; + cmStateSnapshot StateSnapshot; + cmListFileBacktrace DirectoryBacktrace; + cmGlobalGenerator* GlobalGenerator; + std::map<std::string, std::string> UniqueObjectNamesMap; + std::string::size_type ObjectPathMax; + std::set<std::string> ObjectMaxPathViolations; + + typedef std::unordered_map<std::string, cmGeneratorTarget*> + GeneratorTargetMap; + GeneratorTargetMap GeneratorTargetSearchIndex; + std::vector<cmGeneratorTarget*> GeneratorTargets; + + std::set<cmGeneratorTarget const*> WarnCMP0063; + GeneratorTargetMap ImportedGeneratorTargets; + std::vector<cmGeneratorTarget*> OwnedImportedGeneratorTargets; + std::map<std::string, std::string> AliasTargets; + + std::map<std::string, std::string> Compilers; + std::map<std::string, std::string> VariableMappings; + std::string CompilerSysroot; + std::string LinkerSysroot; + + bool EmitUniversalBinaryFlags; + + KWIML_INT_uint64_t BackwardsCompatibility; + bool BackwardsCompatibilityFinal; + +private: + void AddSharedFlags(std::string& flags, const std::string& lang, + bool shared); + bool GetShouldUseOldFlags(bool shared, const std::string& lang) const; + void AddPositionIndependentFlags(std::string& flags, std::string const& l, + int targetType); + + void ComputeObjectMaxPath(); +}; + +#if defined(CMAKE_BUILD_WITH_CMAKE) +bool cmLocalGeneratorCheckObjectName(std::string& objName, + std::string::size_type dir_len, + std::string::size_type max_total_len); +#endif + +#endif |