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