Home | History | Annotate | Download | only in gn
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef TOOLS_GN_SUBSTITUTION_WRITER_H_
      6 #define TOOLS_GN_SUBSTITUTION_WRITER_H_
      7 
      8 #include <iosfwd>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "tools/gn/substitution_type.h"
     13 
     14 struct EscapeOptions;
     15 class OutputFile;
     16 class Settings;
     17 class SourceDir;
     18 class SourceFile;
     19 class SubstitutionList;
     20 class SubstitutionPattern;
     21 class Target;
     22 class Tool;
     23 
     24 // Help text for script source expansion.
     25 extern const char kSourceExpansion_Help[];
     26 
     27 // This class handles writing or applying substitution patterns to strings.
     28 //
     29 // There are several different uses:
     30 //
     31 //  - Source substitutions: These are used to compute action_foreach
     32 //    outputs and arguments. Functions are provided to expand these in terms
     33 //    of both OutputFiles (for writing Ninja files) as well as SourceFiles
     34 //    (for computing lists used by code).
     35 //
     36 //  - Target substitutions: These are specific to the target+tool combination
     37 //    and are shared between the compiler and linker ones. It includes things
     38 //    like the target_gen_dir.
     39 //
     40 //  - Compiler substitutions: These are used to compute compiler outputs.
     41 //    It includes all source substitutions (since they depend on the various
     42 //    parts of the source file) as well as the target substitutions.
     43 //
     44 //  - Linker substitutions: These are used to compute linker outputs. It
     45 //    includes the target substitutions.
     46 //
     47 // The compiler and linker specific substitutions do NOT include the various
     48 // cflags, ldflags, libraries, etc. These are written by the ninja target
     49 // writer since they depend on traversing the dependency tree.
     50 class SubstitutionWriter {
     51  public:
     52   enum OutputStyle {
     53     OUTPUT_ABSOLUTE,  // Dirs will be absolute "//foo/bar".
     54     OUTPUT_RELATIVE,  // Dirs will be relative to a given directory.
     55   };
     56 
     57   // Writes the pattern to the given stream with no special handling, and with
     58   // Ninja variables replacing the patterns.
     59   static void WriteWithNinjaVariables(
     60       const SubstitutionPattern& pattern,
     61       const EscapeOptions& escape_options,
     62       std::ostream& out);
     63 
     64   // NOP substitutions ---------------------------------------------------------
     65 
     66   // Converts the given SubstitutionList to OutputFiles assuming there are
     67   // no substitutions (it will assert if there are). This is used for cases
     68   // like actions where the outputs are explicit, but the list is stored as
     69   // a SubstitutionList.
     70   static void GetListAsSourceFiles(
     71       const SubstitutionList& list,
     72       std::vector<SourceFile>* output);
     73   static void GetListAsOutputFiles(
     74       const Settings* settings,
     75       const SubstitutionList& list,
     76       std::vector<OutputFile>* output);
     77 
     78   // Source substitutions -----------------------------------------------------
     79 
     80   // Applies the substitution pattern to a source file, returning the result
     81   // as either a string, a SourceFile or an OutputFile. If the result is
     82   // expected to be a SourceFile or an OutputFile, this will CHECK if the
     83   // result isn't in the correct directory. The caller should validate this
     84   // first (see for example IsFileInOuputDir).
     85   static SourceFile ApplyPatternToSource(
     86       const Settings* settings,
     87       const SubstitutionPattern& pattern,
     88       const SourceFile& source);
     89   static std::string ApplyPatternToSourceAsString(
     90       const Settings* settings,
     91       const SubstitutionPattern& pattern,
     92       const SourceFile& source);
     93   static OutputFile ApplyPatternToSourceAsOutputFile(
     94       const Settings* settings,
     95       const SubstitutionPattern& pattern,
     96       const SourceFile& source);
     97 
     98   // Applies the substitution list to a source, APPENDING the result to the
     99   // given output vector. It works this way so one can call multiple times to
    100   // apply to multiple files and create a list. The result can either be
    101   // SourceFiles or OutputFiles.
    102   static void ApplyListToSource(
    103       const Settings* settings,
    104       const SubstitutionList& list,
    105       const SourceFile& source,
    106       std::vector<SourceFile>* output);
    107   static void ApplyListToSourceAsString(
    108       const Settings* settings,
    109       const SubstitutionList& list,
    110       const SourceFile& source,
    111       std::vector<std::string>* output);
    112   static void ApplyListToSourceAsOutputFile(
    113       const Settings* settings,
    114       const SubstitutionList& list,
    115       const SourceFile& source,
    116       std::vector<OutputFile>* output);
    117 
    118   // Like ApplyListToSource but applies the list to all sources and replaces
    119   // rather than appesnds the output (this produces the complete output).
    120   static void ApplyListToSources(
    121       const Settings* settings,
    122       const SubstitutionList& list,
    123       const std::vector<SourceFile>& sources,
    124       std::vector<SourceFile>* output);
    125   static void ApplyListToSourcesAsString(
    126       const Settings* settings,
    127       const SubstitutionList& list,
    128       const std::vector<SourceFile>& sources,
    129       std::vector<std::string>* output);
    130   static void ApplyListToSourcesAsOutputFile(
    131       const Settings* settings,
    132       const SubstitutionList& list,
    133       const std::vector<SourceFile>& sources,
    134       std::vector<OutputFile>* output);
    135 
    136   // Given a list of source replacement types used, writes the Ninja variable
    137   // definitions for the given source file to use for those replacements. The
    138   // variables will be indented two spaces. Since this is for writing to
    139   // Ninja files, paths will be relative to the build dir, and no definition
    140   // for {{source}} will be written since that maps to Ninja's implicit $in
    141   // variable.
    142   static void WriteNinjaVariablesForSource(
    143       const Settings* settings,
    144       const SourceFile& source,
    145       const std::vector<SubstitutionType>& types,
    146       const EscapeOptions& escape_options,
    147       std::ostream& out);
    148 
    149   // Extracts the given type of substitution related to a source file from the
    150   // given source file. If output_style is OUTPUT_RELATIVE, relative_to
    151   // indicates the directory that the relative directories should be relative
    152   // to, otherwise it is ignored.
    153   static std::string GetSourceSubstitution(
    154       const Settings* settings,
    155       const SourceFile& source,
    156       SubstitutionType type,
    157       OutputStyle output_style,
    158       const SourceDir& relative_to);
    159 
    160   // Target substitutions ------------------------------------------------------
    161   //
    162   // Handles the target substitutions that apply to both compiler and linker
    163   // tools.
    164   static OutputFile ApplyPatternToTargetAsOutputFile(
    165       const Target* target,
    166       const Tool* tool,
    167       const SubstitutionPattern& pattern);
    168   static void ApplyListToTargetAsOutputFile(
    169       const Target* target,
    170       const Tool* tool,
    171       const SubstitutionList& list,
    172       std::vector<OutputFile>* output);
    173 
    174   // This function is slightly different than the other substitution getters
    175   // since it can handle failure (since it is designed to be used by the
    176   // compiler and linker ones which will fall through if it's not a common tool
    177   // one).
    178   static bool GetTargetSubstitution(
    179       const Target* target,
    180       SubstitutionType type,
    181       std::string* result);
    182   static std::string GetTargetSubstitution(
    183       const Target* target,
    184       SubstitutionType type);
    185 
    186   // Compiler substitutions ----------------------------------------------------
    187   //
    188   // A compiler substitution allows both source and tool substitutions. These
    189   // are used to compute output names for compiler tools.
    190 
    191   static OutputFile ApplyPatternToCompilerAsOutputFile(
    192       const Target* target,
    193       const SourceFile& source,
    194       const SubstitutionPattern& pattern);
    195   static void ApplyListToCompilerAsOutputFile(
    196       const Target* target,
    197       const SourceFile& source,
    198       const SubstitutionList& list,
    199       std::vector<OutputFile>* output);
    200 
    201   // Like GetSourceSubstitution but for strings based on the target or
    202   // toolchain. This type of result will always be relative to the build
    203   // directory.
    204   static std::string GetCompilerSubstitution(
    205       const Target* target,
    206       const SourceFile& source,
    207       SubstitutionType type);
    208 
    209   // Linker substitutions ------------------------------------------------------
    210 
    211   static OutputFile ApplyPatternToLinkerAsOutputFile(
    212       const Target* target,
    213       const Tool* tool,
    214       const SubstitutionPattern& pattern);
    215   static void ApplyListToLinkerAsOutputFile(
    216       const Target* target,
    217       const Tool* tool,
    218       const SubstitutionList& list,
    219       std::vector<OutputFile>* output);
    220 
    221   // Like GetSourceSubstitution but for strings based on the target or
    222   // toolchain. This type of result will always be relative to the build
    223   // directory.
    224   static std::string GetLinkerSubstitution(
    225       const Target* target,
    226       const Tool* tool,
    227       SubstitutionType type);
    228 };
    229 
    230 #endif  // TOOLS_GN_SUBSTITUTION_WRITER_H_
    231