| // 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_ |