219f135635aee87eebb1cc7ea68b72b11931bbbf
[platform/framework/web/crosswalk.git] / src / tools / gn / substitution_writer.h
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_