| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file LICENSE.rst or https://cmake.org/licensing for details. */ |
| #pragma once |
| |
| #include "cmConfigure.h" // IWYU pragma: keep |
| |
| #include <cstddef> |
| #include <string> |
| #include <type_traits> |
| #include <unordered_map> |
| #include <utility> |
| #include <vector> |
| |
| #include "cmAlgorithms.h" |
| #include "cmListFileCache.h" |
| #include "cmPropertyMap.h" |
| #include "cmValue.h" |
| |
| class cmMakefile; |
| class cmTarget; |
| class cmFileSet; |
| class cmSourceFile; |
| |
| namespace cm { |
| |
| enum class RuleScope |
| { |
| Local, |
| Global |
| }; |
| |
| template <typename E> |
| struct enum_hash |
| { |
| typename std::enable_if<std::is_enum<E>::value, std::size_t>::type |
| operator()(E const key) const |
| { |
| return static_cast<std::size_t>(key); |
| } |
| }; |
| } |
| |
| // |
| // cmRule: base class for various rule types |
| // |
| class cmRule |
| { |
| public: |
| using CustomCommand = std::vector<std::string>; |
| using CustomCommands = std::vector<CustomCommand>; |
| |
| virtual ~cmRule() = default; |
| |
| cmRule& operator=(cmRule const&) = delete; |
| |
| cmMakefile& GetMakefile() const { return *this->Makefile; } |
| |
| /** Get the name of the rule */ |
| std::string const& GetName() const { return this->Name; } |
| virtual std::string const& GetParentName() const; |
| |
| /** Get the command lines. */ |
| virtual CustomCommands const& GetCommands() const = 0; |
| /** Get the output files. */ |
| virtual std::vector<std::string> const& GetOutputs() const = 0; |
| |
| /** Get the extra files produced by the command. */ |
| virtual std::vector<std::string> const& GetByproducts() const = 0; |
| |
| /** Get the vector that holds the list of dependencies. */ |
| virtual std::vector<std::string> const& GetDepends() const = 0; |
| /** Get the file that holds the list of dependencies. */ |
| virtual std::string const& GetDepfile() const = 0; |
| |
| enum class ConfiguratorType |
| { |
| FileSet, |
| Source |
| }; |
| enum class ChainConfigurators |
| { |
| No, |
| Yes |
| }; |
| using ConfiguratorSet = |
| std::vector<std::pair<std::string const*, std::string const*>>; |
| void SetConfigurator(ConfiguratorType type, std::string configurator, |
| ChainConfigurators chain = ChainConfigurators::No); |
| ConfiguratorSet const& GetConfigurators(ConfiguratorType type) const; |
| |
| bool HasConfigurators(ConfiguratorType type) const; |
| |
| bool IsGloballyVisible() const |
| { |
| return this->Scope == cm::RuleScope::Global; |
| } |
| |
| cmFileSet* GetOutputFileSet(cmTarget* target, |
| cmFileSet const* fileSet) const; |
| |
| // Special properties |
| cmBTStringRange GetIncludeDirectories() const; |
| |
| cmBTStringRange GetCompileOptions() const; |
| |
| cmBTStringRange GetCompileDefinitions() const; |
| |
| //! Set/Get a property of this rule |
| void SetProperty(std::string const& prop, cmValue value); |
| void SetProperty(std::string const& prop, std::nullptr_t) |
| { |
| this->SetProperty(prop, cmValue{ nullptr }); |
| } |
| void RemoveProperty(std::string const& prop) |
| { |
| this->SetProperty(prop, cmValue{ nullptr }); |
| } |
| void SetProperty(std::string const& prop, std::string const& value) |
| { |
| this->SetProperty(prop, cmValue{ value }); |
| } |
| void AppendProperty(std::string const& prop, std::string const& value, |
| bool asString = false); |
| cmValue GetProperty(std::string const& prop) const; |
| |
| void CheckProperty(std::string const& prop, cmMakefile& context) const; |
| |
| bool InGeneration() const { return this->Generation; } |
| |
| struct Pattern |
| { |
| Pattern(std::string name, std::string value) |
| : Name(std::move(name)) |
| , Value(std::move(value)) |
| { |
| } |
| |
| std::string Name; |
| std::string Value; |
| }; |
| using PatternSet = std::vector<Pattern>; |
| bool Instantiate(cmTarget const* target, cmFileSet const* fileSet, |
| cmFileSet const* outputFileSet, PatternSet& patterns) const; |
| bool Instantiate(cmTarget const* target, cmFileSet const* fileSet, |
| cmFileSet const* outputFileSet, cmSourceFile* source, |
| PatternSet& patterns) const; |
| |
| protected: |
| cmRule(cmMakefile& makefile, std::string name, cm::RuleScope scope); |
| cmRule(cmRule const& parent, cmMakefile& makefile, std::string name, |
| cm::RuleScope scope); |
| |
| private: |
| // switch context cmRule usage |
| void SwitchMode() const { this->Generation = true; } |
| |
| cmMakefile* Makefile; |
| std::string Name; |
| cm::RuleScope Scope = cm::RuleScope::Local; |
| std::unordered_map<ConfiguratorType, std::string, |
| cm::enum_hash<ConfiguratorType>> |
| Configurators; |
| std::unordered_map<ConfiguratorType, ConfiguratorSet, |
| cm::enum_hash<ConfiguratorType>> |
| ConfiguratorsChain; |
| cmPropertyMap Properties; |
| std::vector<BT<std::string>> IncludeDirectories; |
| std::vector<BT<std::string>> CompileOptions; |
| std::vector<BT<std::string>> CompileDefinitions; |
| // cmRule properties should not be changed during generation phase |
| // Use mutable field to track current phase independently of state of object |
| // (const or not) |
| mutable bool Generation = false; |
| }; |
| |
| // |
| // cmCustomRule: define a template used to generate custom commands |
| // |
| class cmCustomRule : public cmRule |
| { |
| public: |
| cmCustomRule(cmMakefile& makefile, std::string name, CustomCommands commands, |
| std::vector<std::string> outputs, |
| cm::RuleScope scope = cm::RuleScope::Local); |
| |
| cmCustomRule& operator=(cmCustomRule const&) = delete; |
| |
| /** Get the command lines. */ |
| CustomCommands const& GetCommands() const override; |
| /** Get the output files. */ |
| std::vector<std::string> const& GetOutputs() const override; |
| |
| /** Set/Get the extra files produced by the command. */ |
| void SetByproducts(std::vector<std::string> byproducts); |
| std::vector<std::string> const& GetByproducts() const override; |
| |
| /** Set/Get the vector that holds the list of dependencies. */ |
| void SetDepends(std::vector<std::string> depends); |
| std::vector<std::string> const& GetDepends() const override; |
| /** Set/Get the file that holds the list of dependencies. */ |
| void SetDepfile(std::string depfile); |
| std::string const& GetDepfile() const override; |
| |
| private: |
| CustomCommands Commands; |
| std::vector<std::string> Outputs; |
| std::vector<std::string> Byproducts; |
| std::vector<std::string> Depends; |
| std::string Depfile; |
| }; |
| |
| // |
| // cmSpecializedRule: rule embedding another rule and enabling properties |
| // customization. |
| // |
| class cmSpecializedRule : public cmRule |
| { |
| public: |
| cmSpecializedRule(cmMakefile& makefile, std::string name, |
| cmRule const& parent, |
| cm::RuleScope scope = cm::RuleScope::Local); |
| |
| cmSpecializedRule& operator=(cmSpecializedRule const&) = delete; |
| |
| std::string const& GetParentName() const override; |
| |
| /** Get the command lines. */ |
| CustomCommands const& GetCommands() const override; |
| /** Get the output files. */ |
| std::vector<std::string> const& GetOutputs() const override; |
| |
| /** Get the extra files produced by the command. */ |
| std::vector<std::string> const& GetByproducts() const override; |
| |
| /** Get the vector that holds the list of dependencies. */ |
| std::vector<std::string> const& GetDepends() const override; |
| /** Get the file that holds the list of dependencies. */ |
| std::string const& GetDepfile() const override; |
| |
| private: |
| cmRule const& ParentRule; |
| }; |