| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TOOLS_GN_SUBSTITUTION_WRITER_H_ |
| #define TOOLS_GN_SUBSTITUTION_WRITER_H_ |
| |
| #include <iosfwd> |
| #include <string> |
| #include <vector> |
| |
| #include "gn/substitution_type.h" |
| |
| struct EscapeOptions; |
| class OutputFile; |
| class Settings; |
| class SourceDir; |
| class SourceFile; |
| class SubstitutionList; |
| class SubstitutionPattern; |
| class Target; |
| class Tool; |
| |
| // Help text for script source expansion. |
| extern const char kSourceExpansion_Help[]; |
| |
| // This class handles writing or applying substitution patterns to strings. |
| // |
| // There are several different uses: |
| // |
| // - Source substitutions: These are used to compute action_foreach |
| // outputs and arguments. Functions are provided to expand these in terms |
| // of both OutputFiles (for writing Ninja files) as well as SourceFiles |
| // (for computing lists used by code). |
| // |
| // - Target substitutions: These are specific to the target+tool combination |
| // and are shared between the compiler and linker ones. It includes things |
| // like the target_gen_dir. |
| // |
| // - Compiler substitutions: These are used to compute compiler outputs. |
| // It includes all source substitutions (since they depend on the various |
| // parts of the source file) as well as the target substitutions. |
| // |
| // - Linker substitutions: These are used to compute linker outputs. It |
| // includes the target substitutions. |
| // |
| // The compiler and linker specific substitutions do NOT include the various |
| // cflags, ldflags, libraries, etc. These are written by the ninja target |
| // writer since they depend on traversing the dependency tree. |
| // |
| // The methods which take a target as an argument can accept null target |
| // pointer if there is no target context, in which case the substitutions |
| // requiring target context will not work. |
| class SubstitutionWriter { |
| public: |
| enum OutputStyle { |
| OUTPUT_ABSOLUTE, // Dirs will be absolute "//foo/bar". |
| OUTPUT_RELATIVE, // Dirs will be relative to a given directory. |
| }; |
| |
| // Writes the pattern to the given stream with no special handling, and with |
| // Ninja variables replacing the patterns. |
| static void WriteWithNinjaVariables(const SubstitutionPattern& pattern, |
| const EscapeOptions& escape_options, |
| std::ostream& out); |
| |
| // NOP substitutions --------------------------------------------------------- |
| |
| // Converts the given SubstitutionList to OutputFiles assuming there are |
| // no substitutions (it will assert if there are). This is used for cases |
| // like actions where the outputs are explicit, but the list is stored as |
| // a SubstitutionList. |
| static void GetListAsSourceFiles(const SubstitutionList& list, |
| std::vector<SourceFile>* output); |
| static void GetListAsOutputFiles(const Settings* settings, |
| const SubstitutionList& list, |
| std::vector<OutputFile>* output); |
| |
| // Source substitutions ----------------------------------------------------- |
| |
| // Applies the substitution pattern to a source file, returning the result |
| // as either a string, a SourceFile or an OutputFile. If the result is |
| // expected to be a SourceFile or an OutputFile, this will CHECK if the |
| // result isn't in the correct directory. The caller should validate this |
| // first (see for example IsFileInOuputDir). |
| // |
| // The target can be null (see class comment above). |
| static SourceFile ApplyPatternToSource(const Target* target, |
| const Settings* settings, |
| const SubstitutionPattern& pattern, |
| const SourceFile& source); |
| static std::string ApplyPatternToSourceAsString( |
| const Target* target, |
| const Settings* settings, |
| const SubstitutionPattern& pattern, |
| const SourceFile& source); |
| static OutputFile ApplyPatternToSourceAsOutputFile( |
| const Target* target, |
| const Settings* settings, |
| const SubstitutionPattern& pattern, |
| const SourceFile& source); |
| |
| // Applies the substitution list to a source, APPENDING the result to the |
| // given output vector. It works this way so one can call multiple times to |
| // apply to multiple files and create a list. The result can either be |
| // SourceFiles or OutputFiles. |
| // |
| // The target can be null (see class comment above). |
| static void ApplyListToSource(const Target* target, |
| const Settings* settings, |
| const SubstitutionList& list, |
| const SourceFile& source, |
| std::vector<SourceFile>* output); |
| static void ApplyListToSourceAsString(const Target* target, |
| const Settings* settings, |
| const SubstitutionList& list, |
| const SourceFile& source, |
| std::vector<std::string>* output); |
| static void ApplyListToSourceAsOutputFile(const Target* target, |
| const Settings* settings, |
| const SubstitutionList& list, |
| const SourceFile& source, |
| std::vector<OutputFile>* output); |
| |
| // Like ApplyListToSource but applies the list to all sources and replaces |
| // rather than appends the output (this produces the complete output). |
| // |
| // The target can be null (see class comment above). |
| static void ApplyListToSources(const Target* target, |
| const Settings* settings, |
| const SubstitutionList& list, |
| const std::vector<SourceFile>& sources, |
| std::vector<SourceFile>* output); |
| static void ApplyListToSourcesAsString(const Target* target, |
| const Settings* settings, |
| const SubstitutionList& list, |
| const std::vector<SourceFile>& sources, |
| std::vector<std::string>* output); |
| static void ApplyListToSourcesAsOutputFile( |
| const Target* target, |
| const Settings* settings, |
| const SubstitutionList& list, |
| const std::vector<SourceFile>& sources, |
| std::vector<OutputFile>* output); |
| |
| // Given a list of source replacement types used, writes the Ninja variable |
| // definitions for the given source file to use for those replacements. The |
| // variables will be indented two spaces. Since this is for writing to |
| // Ninja files, paths will be relative to the build dir, and no definition |
| // for {{source}} will be written since that maps to Ninja's implicit $in |
| // variable. |
| // |
| // The target can be null (see class comment above). |
| static void WriteNinjaVariablesForSource( |
| const Target* target, |
| const Settings* settings, |
| const SourceFile& source, |
| const std::vector<const Substitution*>& types, |
| const EscapeOptions& escape_options, |
| std::ostream& out); |
| |
| // Extracts the given type of substitution related to a source file from the |
| // given source file. If output_style is OUTPUT_RELATIVE, relative_to |
| // indicates the directory that the relative directories should be relative |
| // to, otherwise it is ignored. |
| // |
| // The target can be null (see class comment above). |
| static std::string GetSourceSubstitution(const Target* target, |
| const Settings* settings, |
| const SourceFile& source, |
| const Substitution* type, |
| OutputStyle output_style, |
| const SourceDir& relative_to); |
| |
| // Target substitutions ------------------------------------------------------ |
| // |
| // Handles the target substitutions that apply to both compiler and linker |
| // tools. |
| static OutputFile ApplyPatternToTargetAsOutputFile( |
| const Target* target, |
| const Tool* tool, |
| const SubstitutionPattern& pattern); |
| static void ApplyListToTargetAsOutputFile(const Target* target, |
| const Tool* tool, |
| const SubstitutionList& list, |
| std::vector<OutputFile>* output); |
| |
| // This function is slightly different than the other substitution getters |
| // since it can handle failure (since it is designed to be used by the |
| // compiler and linker ones which will fall through if it's not a common tool |
| // one). |
| static bool GetTargetSubstitution(const Target* target, |
| const Substitution* type, |
| std::string* result); |
| static std::string GetTargetSubstitution(const Target* target, |
| const Substitution* type); |
| |
| // Compiler substitutions ---------------------------------------------------- |
| // |
| // A compiler substitution allows both source and tool substitutions. These |
| // are used to compute output names for compiler tools. |
| |
| static OutputFile ApplyPatternToCompilerAsOutputFile( |
| const Target* target, |
| const SourceFile& source, |
| const SubstitutionPattern& pattern); |
| static void ApplyListToCompilerAsOutputFile(const Target* target, |
| const SourceFile& source, |
| const SubstitutionList& list, |
| std::vector<OutputFile>* output); |
| |
| // Like GetSourceSubstitution but for strings based on the target or |
| // toolchain. This type of result will always be relative to the build |
| // directory. |
| static std::string GetCompilerSubstitution(const Target* target, |
| const SourceFile& source, |
| const Substitution* type); |
| |
| // Linker substitutions ------------------------------------------------------ |
| |
| static OutputFile ApplyPatternToLinkerAsOutputFile( |
| const Target* target, |
| const Tool* tool, |
| const SubstitutionPattern& pattern); |
| static void ApplyListToLinkerAsOutputFile(const Target* target, |
| const Tool* tool, |
| const SubstitutionList& list, |
| std::vector<OutputFile>* output); |
| |
| // Like GetSourceSubstitution but for strings based on the target or |
| // toolchain. This type of result will always be relative to the build |
| // directory. |
| static std::string GetLinkerSubstitution(const Target* target, |
| const Tool* tool, |
| const Substitution* type); |
| }; |
| |
| #endif // TOOLS_GN_SUBSTITUTION_WRITER_H_ |