OLD | NEW |
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import("//build/toolchain/toolchain.gni") | 5 import("//build/toolchain/toolchain.gni") |
6 | 6 |
7 # This value will be inherited in the toolchain below. | 7 # This value will be inherited in the toolchain below. |
8 concurrent_links = exec_script("get_concurrent_links.py", [], "value") | 8 concurrent_links = exec_script("get_concurrent_links.py", [], "value") |
9 | 9 |
10 # This template defines a toolchain for something that works like gcc | 10 # This template defines a toolchain for something that works like gcc |
(...skipping 12 matching lines...) Expand all Loading... |
23 # | 23 # |
24 # Optional parameters: | 24 # Optional parameters: |
25 # - libs_section_prefix | 25 # - libs_section_prefix |
26 # - libs_section_postfix | 26 # - libs_section_postfix |
27 # The contents of these strings, if specified, will be placed around | 27 # The contents of these strings, if specified, will be placed around |
28 # the libs section of the linker line. It allows one to inject libraries | 28 # the libs section of the linker line. It allows one to inject libraries |
29 # at the beginning and end for all targets in a toolchain. | 29 # at the beginning and end for all targets in a toolchain. |
30 # - solink_libs_section_prefix | 30 # - solink_libs_section_prefix |
31 # - solink_libs_section_postfix | 31 # - solink_libs_section_postfix |
32 # Same as libs_section_{pre,post}fix except used for solink instead of link
. | 32 # Same as libs_section_{pre,post}fix except used for solink instead of link
. |
33 # - post_solink | 33 # - link_outputs |
34 # The content of this string, if specified, will be appended to the solink | 34 # The content of this array, if specified, will be added to the list of |
35 # command. | 35 # outputs from the link command. This can be useful in conjunction with |
| 36 # the post_link parameter. |
| 37 # - post_link |
| 38 # The content of this string, if specified, will be run as a separate |
| 39 # command following the the link command. |
36 # - deps | 40 # - deps |
37 # Just forwarded to the toolchain definition. | 41 # Just forwarded to the toolchain definition. |
| 42 # - executable_extension |
| 43 # If this string is specified it will be used for the file extension |
| 44 # for an executable, rather than using no extension; targets will |
| 45 # still be able to override the extension using the output_extension |
| 46 # variable. |
38 # - is_clang | 47 # - is_clang |
39 # Whether to use clang instead of gcc. | 48 # Whether to use clang instead of gcc. |
| 49 # - is_component_build |
| 50 # Whether to forcibly enable or disable component builds for this |
| 51 # toolchain; if not specified, the toolchain will inherit the |
| 52 # default setting. |
| 53 # - rebuild_define |
| 54 # The contents of this string, if specified, will be passed as a #define |
| 55 # to the toolchain. It can be used to force recompiles whenever a |
| 56 # toolchain is updated. |
| 57 # - shlib_extension |
| 58 # If this string is specified it will be used for the file extension |
| 59 # for a shared library, rather than default value specified in |
| 60 # toolchain.gni |
40 # - strip | 61 # - strip |
41 # Location of the strip executable. When specified, strip will be run on | 62 # Location of the strip executable. When specified, strip will be run on |
42 # all shared libraries and executables as they are built. The pre-stripped | 63 # all shared libraries and executables as they are built. The pre-stripped |
43 # artifacts will be put in lib.stripped/ and exe.stripped/. | 64 # artifacts will be put in lib.stripped/ and exe.stripped/. |
44 template("gcc_toolchain") { | 65 template("gcc_toolchain") { |
45 toolchain(target_name) { | 66 toolchain(target_name) { |
46 assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") | 67 assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") |
47 assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") | 68 assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") |
48 assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") | 69 assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") |
49 assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") | 70 assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") |
50 assert(defined(invoker.toolchain_cpu), | 71 assert(defined(invoker.toolchain_cpu), |
51 "gcc_toolchain() must specify a \"toolchain_cpu\"") | 72 "gcc_toolchain() must specify a \"toolchain_cpu\"") |
52 assert(defined(invoker.toolchain_os), | 73 assert(defined(invoker.toolchain_os), |
53 "gcc_toolchain() must specify a \"toolchain_os\"") | 74 "gcc_toolchain() must specify a \"toolchain_os\"") |
54 | 75 |
| 76 # This define changes when the toolchain changes, forcing a rebuild. |
| 77 # Nothing should ever use this define. |
| 78 if (defined(invoker.rebuild_define)) { |
| 79 rebuild_string = "-D" + invoker.rebuild_define + " " |
| 80 } else { |
| 81 rebuild_string = "" |
| 82 } |
| 83 |
55 # We can't do string interpolation ($ in strings) on things with dots in | 84 # We can't do string interpolation ($ in strings) on things with dots in |
56 # them. To allow us to use $cc below, for example, we create copies of | 85 # them. To allow us to use $cc below, for example, we create copies of |
57 # these values in our scope. | 86 # these values in our scope. |
58 cc = invoker.cc | 87 cc = invoker.cc |
59 cxx = invoker.cxx | 88 cxx = invoker.cxx |
60 ar = invoker.ar | 89 ar = invoker.ar |
61 ld = invoker.ld | 90 ld = invoker.ld |
62 if (defined(invoker.readelf)) { | 91 if (defined(invoker.readelf)) { |
63 readelf = invoker.readelf | 92 readelf = invoker.readelf |
64 } else { | 93 } else { |
65 readelf = "readelf" | 94 readelf = "readelf" |
66 } | 95 } |
67 if (defined(invoker.nm)) { | 96 if (defined(invoker.nm)) { |
68 nm = invoker.nm | 97 nm = invoker.nm |
69 } else { | 98 } else { |
70 nm = "nm" | 99 nm = "nm" |
71 } | 100 } |
72 | 101 |
| 102 if (defined(invoker.shlib_extension)) { |
| 103 default_shlib_extension = invoker.shlib_extension |
| 104 } else { |
| 105 default_shlib_extension = shlib_extension |
| 106 } |
| 107 |
| 108 if (defined(invoker.executable_extension)) { |
| 109 default_executable_extension = invoker.executable_extension |
| 110 } else { |
| 111 default_executable_extension = "" |
| 112 } |
| 113 |
73 # Bring these into our scope for string interpolation with default values. | 114 # Bring these into our scope for string interpolation with default values. |
74 if (defined(invoker.libs_section_prefix)) { | 115 if (defined(invoker.libs_section_prefix)) { |
75 libs_section_prefix = invoker.libs_section_prefix | 116 libs_section_prefix = invoker.libs_section_prefix |
76 } else { | 117 } else { |
77 libs_section_prefix = "" | 118 libs_section_prefix = "" |
78 } | 119 } |
79 | 120 |
80 if (defined(invoker.libs_section_postfix)) { | 121 if (defined(invoker.libs_section_postfix)) { |
81 libs_section_postfix = invoker.libs_section_postfix | 122 libs_section_postfix = invoker.libs_section_postfix |
82 } else { | 123 } else { |
(...skipping 11 matching lines...) Expand all Loading... |
94 } else { | 135 } else { |
95 solink_libs_section_postfix = "" | 136 solink_libs_section_postfix = "" |
96 } | 137 } |
97 | 138 |
98 # These library switches can apply to all tools below. | 139 # These library switches can apply to all tools below. |
99 lib_switch = "-l" | 140 lib_switch = "-l" |
100 lib_dir_switch = "-L" | 141 lib_dir_switch = "-L" |
101 | 142 |
102 tool("cc") { | 143 tool("cc") { |
103 depfile = "{{output}}.d" | 144 depfile = "{{output}}.d" |
104 command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {
{cflags_c}} -c {{source}} -o {{output}}" | 145 command = "$cc -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_di
rs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" |
105 depsformat = "gcc" | 146 depsformat = "gcc" |
106 description = "CC {{output}}" | 147 description = "CC {{output}}" |
107 outputs = [ | 148 outputs = [ |
108 "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o", | 149 "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o", |
109 ] | 150 ] |
110 } | 151 } |
111 | 152 |
112 tool("cxx") { | 153 tool("cxx") { |
113 depfile = "{{output}}.d" | 154 depfile = "{{output}}.d" |
114 command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}}
{{cflags_cc}} -c {{source}} -o {{output}}" | 155 command = "$cxx -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_d
irs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}" |
115 depsformat = "gcc" | 156 depsformat = "gcc" |
116 description = "CXX {{output}}" | 157 description = "CXX {{output}}" |
117 outputs = [ | 158 outputs = [ |
118 "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o", | 159 "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o", |
119 ] | 160 ] |
120 } | 161 } |
121 | 162 |
122 tool("asm") { | 163 tool("asm") { |
123 # For GCC we can just use the C compiler to compile assembly. | 164 # For GCC we can just use the C compiler to compile assembly. |
124 depfile = "{{output}}.d" | 165 depfile = "{{output}}.d" |
125 command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {
{cflags_c}} -c {{source}} -o {{output}}" | 166 command = "$cc -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_di
rs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" |
126 depsformat = "gcc" | 167 depsformat = "gcc" |
127 description = "ASM {{output}}" | 168 description = "ASM {{output}}" |
128 outputs = [ | 169 outputs = [ |
129 "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o", | 170 "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o", |
130 ] | 171 ] |
131 } | 172 } |
132 | 173 |
133 tool("alink") { | 174 tool("alink") { |
134 rspfile = "{{output}}.rsp" | 175 rspfile = "{{output}}.rsp" |
135 command = "rm -f {{output}} && $ar rcs {{output}} @$rspfile" | 176 command = "rm -f {{output}} && $ar rcs {{output}} @$rspfile" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 "${invoker.strip} --strip-unneeded -o $sofile $unstripped_sofile" | 215 "${invoker.strip} --strip-unneeded -o $sofile $unstripped_sofile" |
175 command += " && " + strip_command | 216 command += " && " + strip_command |
176 } | 217 } |
177 rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whol
e-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" | 218 rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whol
e-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" |
178 | 219 |
179 description = "SOLINK $sofile" | 220 description = "SOLINK $sofile" |
180 | 221 |
181 # Use this for {{output_extension}} expansions unless a target manually | 222 # Use this for {{output_extension}} expansions unless a target manually |
182 # overrides it (in which case {{output_extension}} will be what the target | 223 # overrides it (in which case {{output_extension}} will be what the target |
183 # specifies). | 224 # specifies). |
184 default_output_extension = shlib_extension | 225 default_output_extension = default_shlib_extension |
185 if (defined(invoker.default_output_extension)) { | |
186 default_output_extension = invoker.default_output_extension | |
187 } | |
188 | 226 |
189 output_prefix = "lib" | 227 output_prefix = "lib" |
190 | 228 |
191 # Since the above commands only updates the .TOC file when it changes, ask | 229 # Since the above commands only updates the .TOC file when it changes, ask |
192 # Ninja to check if the timestamp actually changed to know if downstream | 230 # Ninja to check if the timestamp actually changed to know if downstream |
193 # dependencies should be recompiled. | 231 # dependencies should be recompiled. |
194 restat = true | 232 restat = true |
195 | 233 |
196 # Tell GN about the output files. It will link to the sofile but use the | 234 # Tell GN about the output files. It will link to the sofile but use the |
197 # tocfile for dependency management. | 235 # tocfile for dependency management. |
198 outputs = [ | 236 outputs = [ |
199 sofile, | 237 sofile, |
200 tocfile, | 238 tocfile, |
201 ] | 239 ] |
202 if (sofile != unstripped_sofile) { | 240 if (sofile != unstripped_sofile) { |
203 outputs += [ unstripped_sofile ] | 241 outputs += [ unstripped_sofile ] |
204 } | 242 } |
205 link_output = sofile | 243 link_output = sofile |
206 depend_output = tocfile | 244 depend_output = tocfile |
207 } | 245 } |
208 | 246 |
209 tool("link") { | 247 tool("link") { |
210 exename = "{{target_output_name}}{{output_extension}}" | 248 exename = "{{target_output_name}}{{output_extension}}" |
211 outfile = "{{root_out_dir}}/$exename" | 249 outfile = "{{root_out_dir}}/$exename" |
212 rspfile = "$outfile.rsp" | 250 rspfile = "$outfile.rsp" |
213 unstripped_outfile = outfile | 251 unstripped_outfile = outfile |
| 252 |
| 253 # Use this for {{output_extension}} expansions unless a target manually |
| 254 # overrides it (in which case {{output_extension}} will be what the target |
| 255 # specifies). |
| 256 default_output_extension = default_executable_extension |
| 257 |
214 if (defined(invoker.strip)) { | 258 if (defined(invoker.strip)) { |
215 unstripped_outfile = "{{root_out_dir}}/exe.unstripped/$exename" | 259 unstripped_outfile = "{{root_out_dir}}/exe.unstripped/$exename" |
216 } | 260 } |
217 | 261 |
218 command = "$ld {{ldflags}} -o $unstripped_outfile -Wl,--start-group @$rspf
ile {{solibs}} -Wl,--end-group $libs_section_prefix {{libs}} $libs_section_postf
ix" | 262 command = "$ld {{ldflags}} -o $unstripped_outfile -Wl,--start-group @$rspf
ile {{solibs}} -Wl,--end-group $libs_section_prefix {{libs}} $libs_section_postf
ix" |
219 if (defined(invoker.strip)) { | 263 if (defined(invoker.strip)) { |
220 strip_command = | 264 strip_command = |
221 "${invoker.strip} --strip-unneeded -o $outfile $unstripped_outfile" | 265 "${invoker.strip} --strip-unneeded -o $outfile $unstripped_outfile" |
222 command += " && " + strip_command | 266 command += " && " + strip_command |
223 } | 267 } |
| 268 if (defined(invoker.postlink)) { |
| 269 command += " && " + invoker.postlink |
| 270 } |
224 description = "LINK $outfile" | 271 description = "LINK $outfile" |
225 rspfile_content = "{{inputs}}" | 272 rspfile_content = "{{inputs}}" |
226 outputs = [ | 273 outputs = [ |
227 outfile, | 274 outfile, |
228 ] | 275 ] |
229 if (outfile != unstripped_outfile) { | 276 if (outfile != unstripped_outfile) { |
230 outputs += [ unstripped_outfile ] | 277 outputs += [ unstripped_outfile ] |
231 } | 278 } |
| 279 if (defined(invoker.link_outputs)) { |
| 280 outputs += invoker.link_outputs |
| 281 } |
232 } | 282 } |
233 | 283 |
234 tool("stamp") { | 284 tool("stamp") { |
235 command = "touch {{output}}" | 285 command = "touch {{output}}" |
236 description = "STAMP {{output}}" | 286 description = "STAMP {{output}}" |
237 } | 287 } |
238 | 288 |
239 tool("copy") { | 289 tool("copy") { |
240 command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} &
& cp -af {{source}} {{output}})" | 290 command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} &
& cp -af {{source}} {{output}})" |
241 description = "COPY {{source}} {{output}}" | 291 description = "COPY {{source}} {{output}}" |
242 } | 292 } |
243 | 293 |
244 # When invoking this toolchain not as the default one, these args will be | 294 # When invoking this toolchain not as the default one, these args will be |
245 # passed to the build. They are ignored when this is the default toolchain. | 295 # passed to the build. They are ignored when this is the default toolchain. |
246 toolchain_args() { | 296 toolchain_args() { |
247 current_cpu = invoker.toolchain_cpu | 297 current_cpu = invoker.toolchain_cpu |
248 current_os = invoker.toolchain_os | 298 current_os = invoker.toolchain_os |
249 | 299 |
250 # These values need to be passed through unchanged. | 300 # These values need to be passed through unchanged. |
251 target_os = target_os | 301 target_os = target_os |
252 target_cpu = target_cpu | 302 target_cpu = target_cpu |
253 | 303 |
254 if (defined(invoker.is_clang)) { | 304 if (defined(invoker.is_clang)) { |
255 is_clang = invoker.is_clang | 305 is_clang = invoker.is_clang |
256 } | 306 } |
| 307 if (defined(invoker.is_component_build)) { |
| 308 is_component_build = invoker.is_component_build |
| 309 } |
257 } | 310 } |
258 | 311 |
259 if (defined(invoker.deps)) { | 312 if (defined(invoker.deps)) { |
260 deps = invoker.deps | 313 deps = invoker.deps |
261 } | 314 } |
262 } | 315 } |
263 } | 316 } |
OLD | NEW |