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.
5 #ifndef TOOLS_GN_SUBSTITUTION_WRITER_H_
6 #define TOOLS_GN_SUBSTITUTION_WRITER_H_
11 #include "base/basictypes.h"
12 #include "tools/gn/substitution_type.h"
19 class SubstitutionList
;
20 class SubstitutionPattern
;
24 // Help text for script source expansion.
25 extern const char kSourceExpansion_Help
[];
27 // This class handles writing or applying substitution patterns to strings.
29 // There are several different uses:
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).
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.
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.
44 // - Linker substitutions: These are used to compute linker outputs. It
45 // includes the target substitutions.
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
{
53 OUTPUT_ABSOLUTE
, // Dirs will be absolute "//foo/bar".
54 OUTPUT_RELATIVE
, // Dirs will be relative to a given directory.
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
,
64 // NOP substitutions ---------------------------------------------------------
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
);
78 // Source substitutions -----------------------------------------------------
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
);
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
);
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
);
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
142 static void WriteNinjaVariablesForSource(
143 const Settings
* settings
,
144 const SourceFile
& source
,
145 const std::vector
<SubstitutionType
>& types
,
146 const EscapeOptions
& escape_options
,
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
);
160 // Target substitutions ------------------------------------------------------
162 // Handles the target substitutions that apply to both compiler and linker
164 static OutputFile
ApplyPatternToTargetAsOutputFile(
165 const Target
* target
,
167 const SubstitutionPattern
& pattern
);
168 static void ApplyListToTargetAsOutputFile(
169 const Target
* target
,
171 const SubstitutionList
& list
,
172 std::vector
<OutputFile
>* output
);
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
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
);
186 // Compiler substitutions ----------------------------------------------------
188 // A compiler substitution allows both source and tool substitutions. These
189 // are used to compute output names for compiler tools.
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
);
201 // Like GetSourceSubstitution but for strings based on the target or
202 // toolchain. This type of result will always be relative to the build
204 static std::string
GetCompilerSubstitution(
205 const Target
* target
,
206 const SourceFile
& source
,
207 SubstitutionType type
);
209 // Linker substitutions ------------------------------------------------------
211 static OutputFile
ApplyPatternToLinkerAsOutputFile(
212 const Target
* target
,
214 const SubstitutionPattern
& pattern
);
215 static void ApplyListToLinkerAsOutputFile(
216 const Target
* target
,
218 const SubstitutionList
& list
,
219 std::vector
<OutputFile
>* output
);
221 // Like GetSourceSubstitution but for strings based on the target or
222 // toolchain. This type of result will always be relative to the build
224 static std::string
GetLinkerSubstitution(
225 const Target
* target
,
227 SubstitutionType type
);
230 #endif // TOOLS_GN_SUBSTITUTION_WRITER_H_