mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
243 lines
7.1 KiB
C++
243 lines
7.1 KiB
C++
/* 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;
|
|
};
|