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