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/config/nacl/config.gni") | 5 import("//build/config/nacl/config.gni") |
6 import("//build/config/sanitizers/sanitizers.gni") | 6 import("//build/config/sanitizers/sanitizers.gni") |
7 import("//build/toolchain/cc_wrapper.gni") | 7 import("//build/toolchain/cc_wrapper.gni") |
8 import("//build/toolchain/goma.gni") | 8 import("//build/toolchain/goma.gni") |
9 import("//build/toolchain/toolchain.gni") | 9 import("//build/toolchain/toolchain.gni") |
10 | 10 |
11 # "concurrent_links" is a toolchain variable. By computing it here rather than | 11 # "concurrent_links" is a toolchain variable. By computing it here rather than |
12 # inside the toolchain, the exec_script will only get run once rather than | 12 # inside the toolchain, the exec_script will only get run once rather than |
13 # each time the toolchain template is invoked. | 13 # each time the toolchain template is invoked. |
14 if (allow_posix_link_time_opt || is_cfi) { | 14 if (allow_posix_link_time_opt || is_cfi) { |
15 concurrent_links_ = | 15 concurrent_links_ = |
16 exec_script("get_concurrent_links.py", [ "--lto" ], "value") | 16 exec_script("get_concurrent_links.py", [ "--lto" ], "value") |
17 } else { | 17 } else { |
18 concurrent_links_ = exec_script("get_concurrent_links.py", [], "value") | 18 concurrent_links_ = exec_script("get_concurrent_links.py", [], "value") |
19 } | 19 } |
20 | 20 |
21 # This template defines a toolchain for something that works like gcc | 21 # This template defines a toolchain for something that works like gcc |
22 # (including clang). | 22 # (including clang). |
23 # | 23 # |
24 # It requires the following variables specifying the executables to run: | 24 # It requires the following variables specifying the executables to run: |
| 25 # - ar |
25 # - cc | 26 # - cc |
26 # - cxx | 27 # - cxx |
27 # - ar | |
28 # - ld | 28 # - ld |
29 # and the following which is used in the toolchain_args | 29 # and the following which is used in the toolchain_args |
30 # - toolchain_cpu (What "current_cpu" should be set to when invoking a | 30 # - toolchain_cpu (What "current_cpu" should be set to when invoking a |
31 # build using this toolchain.) | 31 # build using this toolchain.) |
32 # - toolchain_os (What "current_os" should be set to when invoking a | 32 # - toolchain_os (What "current_os" should be set to when invoking a |
33 # build using this toolchain.) | 33 # build using this toolchain.) |
34 # | 34 # |
35 # Optional parameters that control the tools: | 35 # Optional parameters that control the tools: |
36 # | 36 # |
| 37 # - extra_cflags |
| 38 # Extra flags to be appended when compiling C files (but not C++ files). |
| 39 # - extra_cppflags |
| 40 # Extra flags to be appended when compiling both C and C++ files. "CPP" |
| 41 # stands for "C PreProcessor" in this context, although it can be |
| 42 # used for non-preprocessor flags as well. Not to be confused with |
| 43 # "CXX" (which follows). |
| 44 # - extra_cxxflags |
| 45 # Extra flags to be appended when compiling C++ files (but not C files). |
| 46 # - extra_ldflags |
| 47 # Extra flags to be appended when linking |
| 48 # |
37 # - libs_section_prefix | 49 # - libs_section_prefix |
38 # - libs_section_postfix | 50 # - libs_section_postfix |
39 # The contents of these strings, if specified, will be placed around | 51 # The contents of these strings, if specified, will be placed around |
40 # the libs section of the linker line. It allows one to inject libraries | 52 # the libs section of the linker line. It allows one to inject libraries |
41 # at the beginning and end for all targets in a toolchain. | 53 # at the beginning and end for all targets in a toolchain. |
42 # - solink_libs_section_prefix | 54 # - solink_libs_section_prefix |
43 # - solink_libs_section_postfix | 55 # - solink_libs_section_postfix |
44 # Same as libs_section_{pre,post}fix except used for solink instead of link
. | 56 # Same as libs_section_{pre,post}fix except used for solink instead of link
. |
45 # - link_outputs | 57 # - link_outputs |
46 # The content of this array, if specified, will be added to the list of | 58 # The content of this array, if specified, will be added to the list of |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 # useful to opt-out of cc_wrapper in a particular toolchain by setting | 99 # useful to opt-out of cc_wrapper in a particular toolchain by setting |
88 # cc_wrapper = "" in it. | 100 # cc_wrapper = "" in it. |
89 # - use_goma | 101 # - use_goma |
90 # Override the global use_goma setting, useful to opt-out of goma in a | 102 # Override the global use_goma setting, useful to opt-out of goma in a |
91 # particular toolchain by setting use_gome = false in it. | 103 # particular toolchain by setting use_gome = false in it. |
92 # - use_gold | 104 # - use_gold |
93 # Override the global use_gold setting, useful if the particular | 105 # Override the global use_gold setting, useful if the particular |
94 # toolchain has a custom link step that is not actually using Gold. | 106 # toolchain has a custom link step that is not actually using Gold. |
95 template("gcc_toolchain") { | 107 template("gcc_toolchain") { |
96 toolchain(target_name) { | 108 toolchain(target_name) { |
| 109 assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") |
97 assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") | 110 assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") |
98 assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") | 111 assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") |
99 assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") | |
100 assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") | 112 assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") |
101 assert(defined(invoker.toolchain_cpu), | 113 assert(defined(invoker.toolchain_cpu), |
102 "gcc_toolchain() must specify a \"toolchain_cpu\"") | 114 "gcc_toolchain() must specify a \"toolchain_cpu\"") |
103 assert(defined(invoker.toolchain_os), | 115 assert(defined(invoker.toolchain_os), |
104 "gcc_toolchain() must specify a \"toolchain_os\"") | 116 "gcc_toolchain() must specify a \"toolchain_os\"") |
105 | 117 |
106 concurrent_links = concurrent_links_ | 118 concurrent_links = concurrent_links_ |
107 | 119 |
108 if (defined(invoker.cc_wrapper)) { | 120 if (defined(invoker.cc_wrapper)) { |
109 cc_wrapper = invoker.cc_wrapper | 121 cc_wrapper = invoker.cc_wrapper |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } else { | 185 } else { |
174 solink_libs_section_prefix = "" | 186 solink_libs_section_prefix = "" |
175 } | 187 } |
176 | 188 |
177 if (defined(invoker.solink_libs_section_postfix)) { | 189 if (defined(invoker.solink_libs_section_postfix)) { |
178 solink_libs_section_postfix = invoker.solink_libs_section_postfix | 190 solink_libs_section_postfix = invoker.solink_libs_section_postfix |
179 } else { | 191 } else { |
180 solink_libs_section_postfix = "" | 192 solink_libs_section_postfix = "" |
181 } | 193 } |
182 | 194 |
| 195 if (defined(invoker.extra_cflags) && invoker.extra_cflags != "") { |
| 196 extra_cflags = " " + invoker.extra_cflags |
| 197 } else { |
| 198 extra_cflags = "" |
| 199 } |
| 200 |
| 201 if (defined(invoker.extra_cppflags) && invoker.extra_cppflags != "") { |
| 202 extra_cppflags = " " + invoker.extra_cppflags |
| 203 } else { |
| 204 extra_cppflags = "" |
| 205 } |
| 206 |
| 207 if (defined(invoker.extra_cxxflags) && invoker.extra_cxxflags != "") { |
| 208 extra_cxxflags = " " + invoker.extra_cxxflags |
| 209 } else { |
| 210 extra_cxxflags = "" |
| 211 } |
| 212 |
| 213 if (defined(invoker.extra_ldflags) && invoker.extra_ldflags != "") { |
| 214 extra_ldflags = " " + invoker.extra_ldflags |
| 215 } else { |
| 216 extra_ldflags = "" |
| 217 } |
| 218 |
183 # These library switches can apply to all tools below. | 219 # These library switches can apply to all tools below. |
184 lib_switch = "-l" | 220 lib_switch = "-l" |
185 lib_dir_switch = "-L" | 221 lib_dir_switch = "-L" |
186 | 222 |
187 # Object files go in this directory. | 223 # Object files go in this directory. |
188 object_subdir = "{{target_out_dir}}/{{label_name}}" | 224 object_subdir = "{{target_out_dir}}/{{label_name}}" |
189 | 225 |
190 tool("cc") { | 226 tool("cc") { |
191 depfile = "{{output}}.d" | 227 depfile = "{{output}}.d" |
192 command = "$cc -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_di
rs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" | 228 command = "$cc -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_di
rs}} {{cflags}} {{cflags_c}}${extra_cppflags}${extra_cflags} -c {{source}} -o {{
output}}" |
193 depsformat = "gcc" | 229 depsformat = "gcc" |
194 description = "CC {{output}}" | 230 description = "CC {{output}}" |
195 outputs = [ | 231 outputs = [ |
196 "$object_subdir/{{source_name_part}}.o", | 232 "$object_subdir/{{source_name_part}}.o", |
197 ] | 233 ] |
198 } | 234 } |
199 | 235 |
200 tool("cxx") { | 236 tool("cxx") { |
201 depfile = "{{output}}.d" | 237 depfile = "{{output}}.d" |
202 command = "$cxx -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_d
irs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}" | 238 command = "$cxx -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_d
irs}} {{cflags}} {{cflags_cc}}${extra_cppflags}${extra_cxxflags} -c {{source}} -
o {{output}}" |
203 depsformat = "gcc" | 239 depsformat = "gcc" |
204 description = "CXX {{output}}" | 240 description = "CXX {{output}}" |
205 outputs = [ | 241 outputs = [ |
206 "$object_subdir/{{source_name_part}}.o", | 242 "$object_subdir/{{source_name_part}}.o", |
207 ] | 243 ] |
208 } | 244 } |
209 | 245 |
210 tool("asm") { | 246 tool("asm") { |
211 # For GCC we can just use the C compiler to compile assembly. | 247 # For GCC we can just use the C compiler to compile assembly. |
212 depfile = "{{output}}.d" | 248 depfile = "{{output}}.d" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 } else { | 286 } else { |
251 unstripped_sofile = sofile | 287 unstripped_sofile = sofile |
252 } | 288 } |
253 | 289 |
254 # These variables are not built into GN but are helpers that | 290 # These variables are not built into GN but are helpers that |
255 # implement (1) linking to produce a .so, (2) extracting the symbols | 291 # implement (1) linking to produce a .so, (2) extracting the symbols |
256 # from that file (3) if the extracted list differs from the existing | 292 # from that file (3) if the extracted list differs from the existing |
257 # .TOC file, overwrite it, otherwise, don't change it. | 293 # .TOC file, overwrite it, otherwise, don't change it. |
258 tocfile = sofile + ".TOC" | 294 tocfile = sofile + ".TOC" |
259 | 295 |
260 link_command = "$ld -shared {{ldflags}} -o \"$unstripped_sofile\" -Wl,-son
ame=\"$soname\" @\"$rspfile\"" | 296 link_command = "$ld -shared {{ldflags}}${extra_ldflags} -o \"$unstripped_s
ofile\" -Wl,-soname=\"$soname\" @\"$rspfile\"" |
261 | 297 |
262 assert(defined(readelf), "to solink you must have a readelf") | 298 assert(defined(readelf), "to solink you must have a readelf") |
263 assert(defined(nm), "to solink you must have an nm") | 299 assert(defined(nm), "to solink you must have an nm") |
264 strip_switch = "" | 300 strip_switch = "" |
265 if (defined(invoker.strip)) { | 301 if (defined(invoker.strip)) { |
266 strip_switch = "--strip=${invoker.strip}" | 302 strip_switch = "--strip=${invoker.strip}" |
267 } | 303 } |
268 | 304 |
269 # This needs a Python script to avoid using a complex shell command | 305 # This needs a Python script to avoid using a complex shell command |
270 # requiring sh control structures, pipelines, and POSIX utilities. | 306 # requiring sh control structures, pipelines, and POSIX utilities. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". | 346 soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". |
311 sofile = "{{output_dir}}/$soname" | 347 sofile = "{{output_dir}}/$soname" |
312 rspfile = sofile + ".rsp" | 348 rspfile = sofile + ".rsp" |
313 | 349 |
314 if (defined(invoker.strip)) { | 350 if (defined(invoker.strip)) { |
315 unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname" | 351 unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname" |
316 } else { | 352 } else { |
317 unstripped_sofile = sofile | 353 unstripped_sofile = sofile |
318 } | 354 } |
319 | 355 |
320 command = "$ld -shared {{ldflags}} -o \"$unstripped_sofile\" -Wl,-soname=\
"$soname\" @\"$rspfile\"" | 356 command = "$ld -shared {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile
\" -Wl,-soname=\"$soname\" @\"$rspfile\"" |
321 | 357 |
322 if (defined(invoker.strip)) { | 358 if (defined(invoker.strip)) { |
323 strip_command = "${invoker.strip} --strip-unneeded -o \"$sofile\" \"$uns
tripped_sofile\"" | 359 strip_command = "${invoker.strip} --strip-unneeded -o \"$sofile\" \"$uns
tripped_sofile\"" |
324 command += " && " + strip_command | 360 command += " && " + strip_command |
325 } | 361 } |
326 rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whol
e-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" | 362 rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whol
e-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" |
327 | 363 |
328 description = "SOLINK_MODULE $sofile" | 364 description = "SOLINK_MODULE $sofile" |
329 | 365 |
330 # Use this for {{output_extension}} expansions unless a target manually | 366 # Use this for {{output_extension}} expansions unless a target manually |
(...skipping 30 matching lines...) Expand all Loading... |
361 # overrides it (in which case {{output_extension}} will be what the target | 397 # overrides it (in which case {{output_extension}} will be what the target |
362 # specifies). | 398 # specifies). |
363 default_output_extension = default_executable_extension | 399 default_output_extension = default_executable_extension |
364 | 400 |
365 default_output_dir = "{{root_out_dir}}" | 401 default_output_dir = "{{root_out_dir}}" |
366 | 402 |
367 if (defined(invoker.strip)) { | 403 if (defined(invoker.strip)) { |
368 unstripped_outfile = "{{root_out_dir}}/exe.unstripped/$exename" | 404 unstripped_outfile = "{{root_out_dir}}/exe.unstripped/$exename" |
369 } | 405 } |
370 | 406 |
371 command = "$ld {{ldflags}} -o \"$unstripped_outfile\" -Wl,--start-group @\
"$rspfile\" {{solibs}} -Wl,--end-group $libs_section_prefix {{libs}} $libs_secti
on_postfix" | 407 command = "$ld {{ldflags}}${extra_ldflags} -o \"$unstripped_outfile\" -Wl,
--start-group @\"$rspfile\" {{solibs}} -Wl,--end-group $libs_section_prefix {{li
bs}} $libs_section_postfix" |
372 if (defined(invoker.strip)) { | 408 if (defined(invoker.strip)) { |
373 link_wrapper = | 409 link_wrapper = |
374 rebase_path("//build/toolchain/gcc_link_wrapper.py", root_build_dir) | 410 rebase_path("//build/toolchain/gcc_link_wrapper.py", root_build_dir) |
375 command = "$python_path \"$link_wrapper\" --strip=\"${invoker.strip}\" -
-unstripped-file=\"$unstripped_outfile\" --output=\"$outfile\" -- $command" | 411 command = "$python_path \"$link_wrapper\" --strip=\"${invoker.strip}\" -
-unstripped-file=\"$unstripped_outfile\" --output=\"$outfile\" -- $command" |
376 } | 412 } |
377 description = "LINK $outfile" | 413 description = "LINK $outfile" |
378 rspfile_content = "{{inputs}}" | 414 rspfile_content = "{{inputs}}" |
379 outputs = [ | 415 outputs = [ |
380 outfile, | 416 outfile, |
381 ] | 417 ] |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 } | 457 } |
422 if (defined(invoker.symbol_level)) { | 458 if (defined(invoker.symbol_level)) { |
423 symbol_level = invoker.symbol_level | 459 symbol_level = invoker.symbol_level |
424 } | 460 } |
425 if (defined(invoker.use_allocator)) { | 461 if (defined(invoker.use_allocator)) { |
426 use_allocator = invoker.use_allocator | 462 use_allocator = invoker.use_allocator |
427 } | 463 } |
428 if (defined(invoker.use_gold)) { | 464 if (defined(invoker.use_gold)) { |
429 use_gold = invoker.use_gold | 465 use_gold = invoker.use_gold |
430 } | 466 } |
| 467 if (defined(invoker.use_sysroot)) { |
| 468 use_sysroot = invoker.use_sysroot |
| 469 } |
431 | 470 |
432 if (defined(invoker.clear_sanitizers) && invoker.clear_sanitizers) { | 471 if (defined(invoker.clear_sanitizers) && invoker.clear_sanitizers) { |
433 is_asan = false | 472 is_asan = false |
434 is_cfi = false | 473 is_cfi = false |
435 is_lsan = false | 474 is_lsan = false |
436 is_msan = false | 475 is_msan = false |
437 is_syzyasan = false | 476 is_syzyasan = false |
438 is_tsan = false | 477 is_tsan = false |
439 is_ubsan = false | 478 is_ubsan = false |
440 is_ubsan_vptr = false | 479 is_ubsan_vptr = false |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 | 516 |
478 forward_variables_from(invoker, | 517 forward_variables_from(invoker, |
479 [ | 518 [ |
480 "toolchain_cpu", | 519 "toolchain_cpu", |
481 "toolchain_os", | 520 "toolchain_os", |
482 "use_gold", | 521 "use_gold", |
483 "strip", | 522 "strip", |
484 ]) | 523 ]) |
485 } | 524 } |
486 } | 525 } |
OLD | NEW |