1# Copyright 2013 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5# ============================================================================= 6# WHAT IS THIS FILE? 7# ============================================================================= 8# 9# This is the main GN build configuration. This file is loaded after the 10# build args (args.gn) for the build directory and after the toplevel ".gn" 11# file (which points to this file as the build configuration). 12# 13# This file will be executed and the resulting context will be used to execute 14# every other file in the build. So variables declared here (that don't start 15# with an underscore) will be implicitly global. 16 17# ============================================================================= 18# PLATFORM SELECTION 19# ============================================================================= 20# 21# There are two main things to set: "os" and "cpu". The "toolchain" is the name 22# of the GN thing that encodes combinations of these things. 23# 24# Users typically only set the variables "target_os" and "target_cpu" in "gn 25# args", the rest are set up by our build and internal to GN. 26# 27# There are three different types of each of these things: The "host" 28# represents the computer doing the compile and never changes. The "target" 29# represents the main thing we're trying to build. The "current" represents 30# which configuration is currently being defined, which can be either the 31# host, the target, or something completely different (like nacl). GN will 32# run the same build file multiple times for the different required 33# configuration in the same build. 34# 35# This gives the following variables: 36# - host_os, host_cpu, host_toolchain 37# - target_os, target_cpu, default_toolchain 38# - current_os, current_cpu, current_toolchain. 39# 40# Note the default_toolchain isn't symmetrical (you would expect 41# target_toolchain). This is because the "default" toolchain is a GN built-in 42# concept, and "target" is something our build sets up that's symmetrical with 43# its GYP counterpart. Potentially the built-in default_toolchain variable 44# could be renamed in the future. 45# 46# When writing build files, to do something only for the host: 47# if (current_toolchain == host_toolchain) { ... 48 49if (target_os == "") { 50 target_os = host_os 51} 52 53if (target_cpu == "") { 54 if (target_os == "android") { 55 # If we're building for Android, we should assume that we want to 56 # build for ARM by default, not the host_cpu (which is likely x64). 57 # This allows us to not have to specify both target_os and target_cpu 58 # on the command line. 59 target_cpu = "arm" 60 } else { 61 target_cpu = host_cpu 62 } 63} 64 65if (current_cpu == "") { 66 current_cpu = target_cpu 67} 68if (current_os == "") { 69 current_os = target_os 70} 71 72# ============================================================================= 73# BUILD FLAGS 74# ============================================================================= 75# 76# This block lists input arguments to the build, along with their default 77# values. 78# 79# If a value is specified on the command line, it will overwrite the defaults 80# given in a declare_args block, otherwise the default will be used. 81# 82# YOU SHOULD ALMOST NEVER NEED TO ADD FLAGS TO THIS FILE. GN allows any file in 83# the build to declare build flags. If you need a flag for a single component, 84# you can just declare it in the corresponding BUILD.gn file. 85# 86# - If your feature is a single target, say //components/foo, you can put 87# a declare_args() block in //components/foo/BUILD.gn and use it there. 88# Nobody else in the build needs to see the flag. 89# 90# - Defines based on build variables should be implemented via the generated 91# build flag header system. See //build/buildflag_header.gni. You can put 92# the buildflag_header target in the same file as the build flag itself. You 93# should almost never set "defines" directly. 94# 95# - If your flag toggles a target on and off or toggles between different 96# versions of similar things, write a "group" target that forwards to the 97# right target (or no target) depending on the value of the build flag. This 98# group can be in the same BUILD.gn file as the build flag, and targets can 99# depend unconditionally on the group rather than duplicating flag checks 100# across many targets. 101# 102# - If a semi-random set of build files REALLY needs to know about a define and 103# the above pattern for isolating the build logic in a forwarding group 104# doesn't work, you can put the argument in a .gni file. This should be put 105# in the lowest level of the build that knows about this feature (which should 106# almost always be outside of the //build directory!). 107# 108# Other flag advice: 109# 110# - Use boolean values when possible. If you need a default value that expands 111# to some complex thing in the default case (like the location of the 112# compiler which would be computed by a script), use a default value of -1 or 113# the empty string. Outside of the declare_args block, conditionally expand 114# the default value as necessary. 115# 116# - Use a name like "use_foo" or "is_foo" (whatever is more appropriate for 117# your feature) rather than just "foo". 118# 119# - Write good comments directly above the declaration with no blank line. 120# These comments will appear as documentation in "gn args --list". 121# 122# - Don't call exec_script inside declare_args. This will execute the script 123# even if the value is overridden, which is wasteful. See first bullet. 124 125declare_args() { 126 # Set to enable the official build level of optimization. This has nothing 127 # to do with branding, but enables an additional level of optimization above 128 # release (!is_debug). This might be better expressed as a tri-state 129 # (debug, release, official) but for historical reasons there are two 130 # separate flags. 131 # 132 # IMPORTANT NOTE: (!is_debug) is *not* sufficient to get satisfying 133 # performance. In particular, DCHECK()s are still enabled for release builds, 134 # which can halve overall performance, and do increase memory usage. Always 135 # set "is_official_build" to true for any build intended to ship to end-users. 136 is_official_build = false 137 138 # Set to true when compiling with the Clang compiler. 139 is_clang = current_os != "linux" || 140 (current_cpu != "s390x" && current_cpu != "s390" && 141 current_cpu != "ppc64" && current_cpu != "ppc" && 142 current_cpu != "mips" && current_cpu != "mips64" && 143 current_cpu != "riscv64") 144 145 # Allows the path to a custom target toolchain to be injected as a single 146 # argument, and set as the default toolchain. 147 custom_toolchain = "" 148 149 # This should not normally be set as a build argument. It's here so that 150 # every toolchain can pass through the "global" value via toolchain_args(). 151 host_toolchain = "" 152 153 # Do not set this directly. 154 # It should be set only by //build/toolchains/android:robolectric_x64. 155 # True when compiling native code for use with robolectric_binary(). 156 is_robolectric = false 157 158 # DON'T ADD MORE FLAGS HERE. Read the comment above. 159} 160 161declare_args() { 162 # Debug build. Enabling official builds automatically sets is_debug to false. 163 is_debug = !is_official_build 164} 165 166declare_args() { 167 # Component build. Setting to true compiles targets declared as "components" 168 # as shared libraries loaded dynamically. This speeds up development time. 169 # When false, components will be linked statically. 170 # 171 # For more information see 172 # https://chromium.googlesource.com/chromium/src/+/main/docs/component_build.md 173 is_component_build = is_debug && current_os != "ios" 174} 175 176assert(!(is_debug && is_official_build), "Can't do official debug builds") 177assert(!(current_os == "ios" && is_component_build), 178 "Can't use component build on iOS") 179 180declare_args() { 181 # Unsafe buffers. Location of file used by plugins to track portions of 182 # the codebase which have been made manifestly safe. 183 clang_unsafe_buffers_paths = "" 184} 185 186# ============================================================================== 187# TOOLCHAIN SETUP 188# ============================================================================== 189# 190# Here we set the default toolchain, as well as the variable host_toolchain 191# which will identify the toolchain corresponding to the local system when 192# doing cross-compiles. When not cross-compiling, this will be the same as the 193# default toolchain. 194# 195# We do this before anything else to make sure we complain about any 196# unsupported os/cpu combinations as early as possible. 197 198if (host_toolchain == "") { 199 # This should only happen in the top-level context. 200 # In a specific toolchain context, the toolchain_args() 201 # block should have propagated a value down. 202 # TODO(dpranke): Add some sort of assert here that verifies that 203 # no toolchain omitted host_toolchain from its toolchain_args(). 204 205 if (host_os == "linux") { 206 if (target_os != "linux") { 207 host_toolchain = "//build/toolchain/linux:clang_$host_cpu" 208 } else if (is_clang) { 209 host_toolchain = "//build/toolchain/linux:clang_$host_cpu" 210 } else { 211 host_toolchain = "//build/toolchain/linux:$host_cpu" 212 } 213 } else if (host_os == "mac") { 214 host_toolchain = "//build/toolchain/mac:clang_$host_cpu" 215 } else if (host_os == "win") { 216 # On Windows always use the target CPU for host builds for x86/x64. On the 217 # configurations we support this will always work and it saves build steps. 218 # Windows ARM64 targets require an x64 host for cross build. 219 if (target_cpu == "x86" || target_cpu == "x64") { 220 if (is_clang) { 221 host_toolchain = "//build/toolchain/win:win_clang_$target_cpu" 222 } else { 223 host_toolchain = "//build/toolchain/win:$target_cpu" 224 } 225 } else if (is_clang) { 226 host_toolchain = "//build/toolchain/win:win_clang_$host_cpu" 227 } else { 228 host_toolchain = "//build/toolchain/win:$host_cpu" 229 } 230 } else if (host_os == "aix") { 231 host_toolchain = "//build/toolchain/aix:$host_cpu" 232 } else if (host_os == "zos") { 233 host_toolchain = "//build/toolchain/zos:$host_cpu" 234 } else { 235 assert(false, "Unsupported host_os: $host_os") 236 } 237} 238 239_default_toolchain = "" 240 241if (target_os == "android") { 242 assert(host_os == "linux", "Android builds are only supported on Linux.") 243 _default_toolchain = "//build/toolchain/android:android_clang_$target_cpu" 244} else if (target_os == "chromeos" || target_os == "linux") { 245 # See comments in build/toolchain/cros/BUILD.gn about board compiles. 246 if (is_clang) { 247 _default_toolchain = "//build/toolchain/linux:clang_$target_cpu" 248 } else { 249 _default_toolchain = "//build/toolchain/linux:$target_cpu" 250 } 251} else if (target_os == "fuchsia") { 252 _default_toolchain = "//build/toolchain/fuchsia:$target_cpu" 253} else if (target_os == "ios") { 254 _default_toolchain = "//build/toolchain/ios:ios_clang_$target_cpu" 255} else if (target_os == "mac") { 256 assert(host_os == "mac" || host_os == "linux", 257 "Mac cross-compiles are unsupported.") 258 _default_toolchain = "//build/toolchain/mac:clang_$target_cpu" 259} else if (target_os == "win") { 260 # On Windows, we use the same toolchain for host and target by default. 261 # Beware, win cross builds have some caveats, see docs/win_cross.md 262 if (is_clang) { 263 _default_toolchain = "//build/toolchain/win:win_clang_$target_cpu" 264 } else { 265 _default_toolchain = "//build/toolchain/win:$target_cpu" 266 } 267} else if (target_os == "winuwp") { 268 # Only target WinUWP on for a Windows store application and only 269 # x86, x64 and arm are supported target CPUs. 270 assert(target_cpu == "x86" || target_cpu == "x64" || target_cpu == "arm" || 271 target_cpu == "arm64") 272 _default_toolchain = "//build/toolchain/win:uwp_$target_cpu" 273} else if (target_os == "aix") { 274 _default_toolchain = "//build/toolchain/aix:$target_cpu" 275} else if (target_os == "zos") { 276 _default_toolchain = "//build/toolchain/zos:$target_cpu" 277} else { 278 assert(false, "Unsupported target_os: $target_os") 279} 280 281# If a custom toolchain has been set in the args, set it as default. Otherwise, 282# set the default toolchain for the platform (if any). 283if (custom_toolchain != "") { 284 set_default_toolchain(custom_toolchain) 285} else if (_default_toolchain != "") { 286 set_default_toolchain(_default_toolchain) 287} 288 289# ============================================================================= 290# OS DEFINITIONS 291# ============================================================================= 292# 293# We set these various is_FOO booleans for convenience in writing OS-based 294# conditions. 295# 296# - is_android, is_chromeos, is_ios, and is_win should be obvious. 297# - is_mac is set only for desktop Mac. It is not set on iOS. 298# - is_posix is true for mac and any Unix-like system (basically everything 299# except Fuchsia and Windows). 300# - is_linux is true for desktop Linux, but not for ChromeOS nor Android (which 301# is generally too different despite being based on the Linux kernel). 302# 303# Do not add more is_* variants here for random lesser-used Unix systems like 304# aix or one of the BSDs. If you need to check these, just check the 305# current_os value directly. 306 307is_android = current_os == "android" 308is_chromeos = current_os == "chromeos" 309is_fuchsia = current_os == "fuchsia" 310is_ios = current_os == "ios" 311is_linux = current_os == "linux" 312is_mac = current_os == "mac" 313is_nacl = current_os == "nacl" 314is_win = current_os == "win" || current_os == "winuwp" 315 316is_apple = is_ios || is_mac 317is_posix = !is_win && !is_fuchsia 318 319# ============================================================================= 320# TARGET DEFAULTS 321# ============================================================================= 322# 323# Set up the default configuration for every build target of the given type. 324# The values configured here will be automatically set on the scope of the 325# corresponding target. Target definitions can add or remove to the settings 326# here as needed. 327# 328# WHAT GOES HERE? 329# 330# Other than the main compiler and linker configs, the only reason for a config 331# to be in this list is if some targets need to explicitly override that config 332# by removing it. This is how targets opt-out of flags. If you don't have that 333# requirement and just need to add a config everywhere, reference it as a 334# sub-config of an existing one, most commonly the main "compiler" one. 335 336# Holds all configs used for running the compiler. 337default_compiler_configs = [ 338 "//build/config:feature_flags", 339 "//build/config/compiler:afdo", 340 "//build/config/compiler:afdo_optimize_size", 341 "//build/config/compiler:cet_shadow_stack", 342 "//build/config/compiler:chromium_code", 343 "//build/config/compiler:compiler", 344 "//build/config/compiler:compiler_arm_fpu", 345 "//build/config/compiler:compiler_arm_thumb", 346 "//build/config/compiler:default_include_dirs", 347 "//build/config/compiler:default_init_stack_vars", 348 "//build/config/compiler:default_optimization", 349 "//build/config/compiler:default_stack_frames", 350 "//build/config/compiler:default_symbols", 351 "//build/config/compiler:no_exceptions", 352 "//build/config/compiler:no_rtti", 353 "//build/config/compiler:no_unresolved_symbols", 354 "//build/config/compiler:runtime_library", 355 "//build/config/compiler:thin_archive", 356 "//build/config/compiler:thinlto_optimize_default", 357 "//build/config/compiler/pgo:default_pgo_flags", 358 "//build/config/coverage:default_coverage", 359 "//build/config/sanitizers:default_sanitizer_flags", 360] 361 362if (is_win) { 363 default_compiler_configs += [ 364 "//build/config/win:default_cfg_compiler", 365 "//build/config/win:default_crt", 366 "//build/config/win:lean_and_mean", 367 "//build/config/win:nominmax", 368 "//build/config/win:unicode", 369 "//build/config/win:winver", 370 ] 371} 372 373if (is_apple) { 374 default_compiler_configs += [ "//build/config/compiler:enable_arc" ] 375} 376 377if (is_posix) { 378 if (current_os != "aix") { 379 default_compiler_configs += 380 [ "//build/config/gcc:symbol_visibility_hidden" ] 381 } 382} 383 384if (is_fuchsia) { 385 default_compiler_configs += [ "//build/config/gcc:symbol_visibility_hidden" ] 386} 387 388if (is_android) { 389 default_compiler_configs += 390 [ "//build/config/android:default_orderfile_instrumentation" ] 391} 392 393if (is_clang && !is_nacl) { 394 default_compiler_configs += [ 395 "//build/config/clang:extra_warnings", 396 "//build/config/clang:find_bad_constructs", 397 "//build/config/clang:unsafe_buffers", 398 ] 399} 400 401# Debug/release-related defines. 402if (is_debug) { 403 default_compiler_configs += [ "//build/config:debug" ] 404} else { 405 default_compiler_configs += [ "//build/config:release" ] 406} 407 408# Static libraries and source sets use only the compiler ones. 409set_defaults("static_library") { 410 configs = default_compiler_configs 411} 412set_defaults("source_set") { 413 configs = default_compiler_configs 414} 415set_defaults("rust_library") { 416 configs = default_compiler_configs 417} 418 419# Compute the set of configs common to all linked targets (shared libraries, 420# loadable modules, executables) to avoid duplication below. 421if (is_win) { 422 # Many targets remove these configs, so they are not contained within 423 # //build/config:executable_config for easy removal. 424 _linker_configs = [ 425 "//build/config/win:default_incremental_linking", 426 427 # Default to console-mode apps. Most of our targets are tests and such 428 # that shouldn't use the windows subsystem. 429 "//build/config/win:console", 430 ] 431} else if (is_apple) { 432 _linker_configs = [ "//build/config/apple:strip_all" ] 433} else { 434 _linker_configs = [] 435} 436 437# Executable defaults. 438default_executable_configs = default_compiler_configs + [ 439 "//build/config/compiler:export_dynamic", 440 "//build/config:default_libs", 441 "//build/config:executable_config", 442 ] + _linker_configs 443 444if (is_win) { 445 # Turn on linker CFI for executables, and position it so it can be removed 446 # if needed. 447 default_executable_configs += [ "//build/config/win:cfi_linker" ] 448} 449if (is_fuchsia) { 450 # Sometimes executables are linked by rustc passing a command line to 451 # clang++. It includes "-pie" which is pointless on Fuchsia. Suppress the 452 # resulting (fatal) warning. Unfortunately there's no way to do this only 453 # for binaries linked by rustc; gn does not make the distinction. 454 default_executable_configs += 455 [ "//build/config/fuchsia:rustc_no_pie_warning" ] 456} 457 458set_defaults("executable") { 459 configs = default_executable_configs 460} 461 462# Shared library and loadable module defaults (also for components in component 463# mode). 464default_shared_library_configs = default_compiler_configs + [ 465 "//build/config:default_libs", 466 "//build/config:shared_library_config", 467 ] + _linker_configs 468if (is_win) { 469 # Turn on linker CFI for DLLs, and position it so it can be removed if needed. 470 default_shared_library_configs += [ "//build/config/win:cfi_linker" ] 471} 472 473if (is_android) { 474 # Strip native JNI exports from shared libraries by default. Binaries that 475 # want this can remove this config. 476 default_shared_library_configs += 477 [ "//build/config/android:hide_all_but_jni_onload" ] 478} 479if (is_fuchsia) { 480 # Sometimes shared libraries are linked by rustc passing a command line to 481 # clang++. It includes "-pie" which is pointless on Fuchsia. Suppress the 482 # resulting (fatal) warning. Unfortunately there's no way to do this only 483 # for binaries linked by rustc; gn does not make the distinction. 484 default_shared_library_configs += 485 [ "//build/config/fuchsia:rustc_no_pie_warning" ] 486} 487set_defaults("shared_library") { 488 configs = default_shared_library_configs 489} 490set_defaults("loadable_module") { 491 configs = default_shared_library_configs 492 493 # loadable_modules are generally used by other libs, not just via JNI. 494 if (is_android) { 495 configs -= [ "//build/config/android:hide_all_but_jni_onload" ] 496 } 497} 498 499default_rust_proc_macro_configs = 500 default_shared_library_configs + [ "//build/rust:proc_macro_extern" ] + 501 # Rust proc macros don't support (Thin)LTO, so always remove it. 502 [ 503 "//build/config/compiler:thinlto_optimize_default", 504 "//build/config/compiler:thinlto_optimize_max", 505 ] - 506 [ 507 "//build/config/compiler:thinlto_optimize_default", 508 "//build/config/compiler:thinlto_optimize_max", 509 ] 510 511set_defaults("rust_proc_macro") { 512 configs = default_rust_proc_macro_configs 513} 514 515# A helper for forwarding testonly and visibility. 516# Forwarding "*" does not include variables from outer scopes (to avoid copying 517# all globals into each template invocation), so it will not pick up 518# file-scoped or outer-template-scoped variables. Normally this behavior is 519# desired, but "visibility" and "testonly" are commonly defined in outer scopes. 520# Explicitly forwarding them in forward_variables_from() works around this 521# nuance. See //build/docs/writing_gn_templates.md#using-forward_variables_from 522TESTONLY_AND_VISIBILITY = [ 523 "testonly", 524 "visibility", 525] 526 527# Sets default dependencies for static_library and source_set targets. 528foreach(_target_type, 529 [ 530 "source_set", 531 "static_library", 532 ]) { 533 template(_target_type) { 534 target(_target_type, target_name) { 535 forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) 536 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 537 if (!defined(inputs)) { 538 inputs = [] 539 } 540 541 # Consumed by the unsafe-buffers plugin during compile. 542 # 543 # TODO(crbug.com/326584510): Reclient doesn't respect this variable, see 544 # rbe_bug_326584510_missing_inputs in //build/config/rbe.gni. 545 _uses_cflags = false 546 if (defined(sources)) { 547 foreach(f, sources) { 548 if (string_replace(f + ".END", ".cc.END", "") != f + ".END" || 549 string_replace(f + ".END", ".c.END", "") != f + ".END" || 550 string_replace(f + ".END", ".mm.END", "") != f + ".END" || 551 string_replace(f + ".END", ".m.END", "") != f + ".END") { 552 _uses_cflags = true 553 } 554 } 555 } 556 if (_uses_cflags && clang_unsafe_buffers_paths != "") { 557 inputs += [ clang_unsafe_buffers_paths ] 558 } 559 } 560 } 561} 562 563# Sets default dependencies for executable and shared_library targets. 564# 565# Variables 566# no_default_deps: If true, no standard dependencies will be added. 567# Targets that set this usually also want to remove 568# "//build/config/compiler:runtime_library" from configs (to remove 569# its subconfig "//build/config/c++:runtime_library"). 570foreach(_target_type, 571 [ 572 "executable", 573 "loadable_module", 574 "shared_library", 575 ]) { 576 template(_target_type) { 577 # Alias "target_name" because it is clobbered by forward_variables_from(). 578 _target_name = target_name 579 target(_target_type, _target_name) { 580 forward_variables_from(invoker, 581 "*", 582 TESTONLY_AND_VISIBILITY + [ "no_default_deps" ]) 583 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 584 if (!defined(inputs)) { 585 inputs = [] 586 } 587 588 # Consumed by the unsafe-buffers plugin during compile. 589 # 590 # TODO(crbug.com/326584510): Reclient doesn't respect this variable, see 591 # rbe_bug_326584510_missing_inputs in //build/config/rbe.gni. 592 _uses_cflags = false 593 if (defined(sources)) { 594 foreach(f, sources) { 595 if (string_replace(f + ".END", ".cc.END", "") != f + ".END" || 596 string_replace(f + ".END", ".c.END", "") != f + ".END" || 597 string_replace(f + ".END", ".mm.END", "") != f + ".END" || 598 string_replace(f + ".END", ".m.END", "") != f + ".END") { 599 _uses_cflags = true 600 } 601 } 602 } 603 if (_uses_cflags && clang_unsafe_buffers_paths != "") { 604 inputs += [ clang_unsafe_buffers_paths ] 605 } 606 607 if (!defined(deps)) { 608 deps = [] 609 } 610 if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) { 611 # This pulls in one of: 612 # //build/config:executable_deps 613 # //build/config:loadable_module_deps 614 # //build/config:shared_library_deps 615 # (This explicit list is so that grepping for these configs finds where 616 # they are used.) 617 deps += [ "//build/config:${_target_type}_deps" ] 618 } 619 620 # On Android, write shared library output file to metadata. We will use 621 # this information to, for instance, collect all shared libraries that 622 # should be packaged into an APK. 623 if (!defined(invoker.metadata) && (is_android || is_robolectric) && 624 (_target_type == "shared_library" || 625 _target_type == "loadable_module")) { 626 _output_name = _target_name 627 if (defined(invoker.output_name)) { 628 _output_name = invoker.output_name 629 } 630 631 # Remove 'lib' prefix from output name if it exists. 632 _magic_prefix = "$0x01$0x01" 633 _output_name = string_replace("${_magic_prefix}${_output_name}", 634 "${_magic_prefix}lib", 635 _magic_prefix, 636 1) 637 _output_name = string_replace(_output_name, _magic_prefix, "", 1) 638 639 if (defined(output_extension)) { 640 _shlib_extension = ".$output_extension" 641 } else { 642 _shlib_extension = ".so" 643 } 644 645 metadata = { 646 shared_libraries = 647 [ "$root_out_dir/lib${_output_name}${_shlib_extension}" ] 648 } 649 } 650 } 651 } 652} 653 654# ============================================================================== 655# COMPONENT SETUP 656# ============================================================================== 657 658# Defines a component, which equates to a shared_library when 659# is_component_build == true and a static_library otherwise. 660# 661# Use static libraries for the static build rather than source sets because 662# many of of our test binaries link many large dependencies but often don't 663# use large portions of them. The static libraries are much more efficient to 664# link in this situation since only the necessary object files are linked. 665# 666# The invoker can override the type of the target in the non-component-build 667# case by setting static_component_type to either "source_set" or 668# "static_library". If unset, the default will be used. 669template("component") { 670 if (is_component_build) { 671 _component_mode = "shared_library" 672 673 # Generate a unique output_name for a shared library if not set by invoker. 674 if (!defined(invoker.output_name)) { 675 _output_name = get_label_info(":$target_name", "label_no_toolchain") 676 _output_name = 677 string_replace(_output_name, "$target_name:$target_name", target_name) 678 _output_name = string_replace(_output_name, "//", "") 679 _output_name = string_replace(_output_name, "/", "_") 680 _output_name = string_replace(_output_name, ":", "_") 681 } 682 } else if (defined(invoker.static_component_type)) { 683 assert(invoker.static_component_type == "static_library" || 684 invoker.static_component_type == "source_set") 685 _component_mode = invoker.static_component_type 686 } else if (!defined(invoker.sources) || invoker.sources == []) { 687 # When there are no sources defined, use a source set to avoid creating 688 # an empty static library (which generally don't work). 689 _component_mode = "source_set" 690 } else { 691 _component_mode = "static_library" 692 } 693 target(_component_mode, target_name) { 694 if (defined(_output_name)) { 695 output_name = _output_name 696 } 697 if (is_component_build && is_android) { 698 # By appending .cr, we prevent name collisions with libraries already 699 # loaded by the Android zygote. 700 output_extension = "cr.so" 701 } 702 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 703 forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) 704 } 705} 706 707# Component defaults 708# Set a variable since we also want to make this available 709# to mixed_component.gni 710if (is_component_build) { 711 default_component_configs = default_shared_library_configs 712 if (is_android) { 713 default_component_configs -= 714 [ "//build/config/android:hide_all_but_jni_onload" ] 715 } 716} else { 717 default_component_configs = default_compiler_configs 718} 719 720set_defaults("component") { 721 configs = default_component_configs 722} 723 724# ============================================================================= 725# ACTION OVERRIDE 726# ============================================================================= 727# 728# We override gn action() to support remote execution using rewrapper. The 729# invoker should set allow_remote to true if remote execution is desired. 730# 731# As remote execution requires inputs to be made more explicit than is normally 732# expected with gn, you may find that setting allow_remote to true will result 733# in many missing file errors. In most cases, this should be resolved by 734# explicitly declaring these inputs/sources. 735# 736# However, it may be impractical to determine these inputs in gn. For such 737# cases, the invoker can specify a custom input processor, which are currently 738# defined and implemented in //build/util/action_remote.py. The appropriate 739# value should be set using the custom_processor arg. 740 741# Variables needed by rbe.gni aren't available at the top of this file. 742import("//build/toolchain/rbe.gni") 743import("//build/toolchain/siso.gni") 744 745# TODO(b/253987456): Add action_foreach support. 746foreach(_target_type, [ "action" ]) { 747 template(_target_type) { 748 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 749 action("${target_name}") { 750 forward_variables_from(invoker, 751 [ 752 "args", 753 "assert_no_deps", 754 "check_includes", 755 "configs", 756 "data_deps", 757 "data", 758 "depfile", 759 "deps", 760 "metadata", 761 "outputs", 762 "pool", 763 "script", 764 "public_configs", 765 "public_deps", 766 "response_file_contents", 767 "sources", 768 "write_runtime_deps", 769 ]) 770 allow_remote = false 771 if (defined(invoker.allow_remote)) { 772 allow_remote = invoker.allow_remote 773 } 774 775 # If remote execution is desired, only run remotely when use_remoteexec 776 # is enabled, and the environment is not nacl. 777 # Siso doesn't use action_remote.py wrapper because it sends requests to 778 # Reproxy directly without actions_remote.py/rewrapper. 779 # TODO(b/259381924): Investigate enabling in nacl config. 780 if (allow_remote && use_remoteexec && !is_nacl && !use_siso) { 781 pool = "//build/toolchain:remote_action_pool($default_toolchain)" 782 script = "//build/util/action_remote.py" 783 inputs = [ invoker.script ] 784 785 re_inputs = [ rebase_path(invoker.script, rbe_exec_root) ] 786 if (defined(invoker.inputs)) { 787 foreach(input, invoker.inputs) { 788 re_inputs += [ rebase_path(input, rbe_exec_root) ] 789 inputs += [ input ] 790 } 791 } 792 if (defined(invoker.sources)) { 793 foreach(source, invoker.sources) { 794 re_inputs += [ rebase_path(source, rbe_exec_root) ] 795 } 796 } 797 798 re_outputs = [] 799 if (defined(invoker.outputs)) { 800 foreach(output, invoker.outputs) { 801 re_outputs += [ rebase_path(output, rbe_exec_root) ] 802 } 803 } 804 805 # Write input/output lists to files as these can grow extremely large. 806 re_inputs_file = "$target_gen_dir/${target_name}__remote_inputs.rsp" 807 write_file(re_inputs_file, re_inputs) 808 inputs += [ re_inputs_file ] 809 re_outputs_file = "$target_gen_dir/${target_name}__remote_outputs.rsp" 810 write_file(re_outputs_file, re_outputs) 811 812 rewrapper_cfg = "$rbe_py_cfg_file" 813 if (defined(invoker.remote_worker)) { 814 remote_worker = invoker.remote_worker 815 assert(remote_worker == "large", 816 "remote_worker = " + remote_worker + " is not supported") 817 rewrapper_cfg = "$rbe_py_large_cfg_file" 818 } 819 820 args = [] 821 args += [ "$rbe_bin_dir/rewrapper" ] 822 if (defined(invoker.custom_processor)) { 823 args += [ "--custom_processor=" + invoker.custom_processor ] 824 } 825 826 args += [ 827 "--cfg=" + rewrapper_cfg, 828 "--exec_root=$rbe_exec_root", 829 "--input_list_paths=" + rebase_path(re_inputs_file, root_build_dir), 830 "--output_list_paths=" + rebase_path(re_outputs_file, root_build_dir), 831 "python3", 832 rebase_path(invoker.script, root_build_dir), 833 ] 834 835 if (defined(invoker.args)) { 836 args += invoker.args 837 } 838 } else { 839 forward_variables_from(invoker, [ "inputs" ]) 840 not_needed(invoker, 841 [ 842 "custom_processor", 843 "remote_worker", 844 ]) 845 } 846 } 847 } 848} 849