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 = 174 is_debug && current_os != "ios" && current_os != "watchos" 175} 176 177assert(!(is_debug && is_official_build), "Can't do official debug builds") 178assert(!(current_os == "ios" && is_component_build), 179 "Can't use component build on iOS") 180assert(!(current_os == "watchos" && is_component_build), 181 "Can't use component build on watchOS") 182 183declare_args() { 184 # Unsafe buffers. Location of file used by plugins to track portions of 185 # the codebase which have been made manifestly safe. 186 clang_unsafe_buffers_paths = "" 187} 188 189# ============================================================================== 190# TOOLCHAIN SETUP 191# ============================================================================== 192# 193# Here we set the default toolchain, as well as the variable host_toolchain 194# which will identify the toolchain corresponding to the local system when 195# doing cross-compiles. When not cross-compiling, this will be the same as the 196# default toolchain. 197# 198# We do this before anything else to make sure we complain about any 199# unsupported os/cpu combinations as early as possible. 200 201if (host_toolchain == "") { 202 # This should only happen in the top-level context. 203 # In a specific toolchain context, the toolchain_args() 204 # block should have propagated a value down. 205 # TODO(dpranke): Add some sort of assert here that verifies that 206 # no toolchain omitted host_toolchain from its toolchain_args(). 207 208 if (host_os == "linux") { 209 if (target_os != "linux") { 210 host_toolchain = "//build/toolchain/linux:clang_$host_cpu" 211 } else if (is_clang) { 212 host_toolchain = "//build/toolchain/linux:clang_$host_cpu" 213 } else { 214 host_toolchain = "//build/toolchain/linux:$host_cpu" 215 } 216 } else if (host_os == "mac") { 217 host_toolchain = "//build/toolchain/mac:clang_$host_cpu" 218 } else if (host_os == "win") { 219 # On Windows always use the target CPU for host builds for x86/x64. On the 220 # configurations we support this will always work and it saves build steps. 221 # Windows ARM64 targets require an x64 host for cross build. 222 if (target_cpu == "x86" || target_cpu == "x64") { 223 if (is_clang) { 224 host_toolchain = "//build/toolchain/win:win_clang_$target_cpu" 225 } else { 226 host_toolchain = "//build/toolchain/win:$target_cpu" 227 } 228 } else if (is_clang) { 229 host_toolchain = "//build/toolchain/win:win_clang_$host_cpu" 230 } else { 231 host_toolchain = "//build/toolchain/win:$host_cpu" 232 } 233 } else if (host_os == "aix") { 234 host_toolchain = "//build/toolchain/aix:$host_cpu" 235 } else if (host_os == "zos") { 236 host_toolchain = "//build/toolchain/zos:$host_cpu" 237 } else { 238 assert(false, "Unsupported host_os: $host_os") 239 } 240} 241 242_default_toolchain = "" 243 244if (target_os == "android") { 245 # Targeting android on Mac is best-effort and not guaranteed to work. 246 assert(host_os == "linux", "Android builds are only supported on Linux.") 247 _default_toolchain = "//build/toolchain/android:android_clang_$target_cpu" 248} else if (target_os == "chromeos" || target_os == "linux") { 249 # See comments in build/toolchain/cros/BUILD.gn about board compiles. 250 if (is_clang) { 251 _default_toolchain = "//build/toolchain/linux:clang_$target_cpu" 252 } else { 253 _default_toolchain = "//build/toolchain/linux:$target_cpu" 254 } 255} else if (target_os == "fuchsia") { 256 _default_toolchain = "//build/toolchain/fuchsia:$target_cpu" 257} else if (target_os == "ios") { 258 _default_toolchain = "//build/toolchain/ios:ios_clang_$target_cpu" 259} else if (target_os == "mac") { 260 assert(host_os == "mac" || host_os == "linux", 261 "Mac cross-compiles are unsupported.") 262 _default_toolchain = "//build/toolchain/mac:clang_$target_cpu" 263} else if (target_os == "win") { 264 # On Windows, we use the same toolchain for host and target by default. 265 # Beware, win cross builds have some caveats, see docs/win_cross.md 266 if (is_clang) { 267 _default_toolchain = "//build/toolchain/win:win_clang_$target_cpu" 268 } else { 269 _default_toolchain = "//build/toolchain/win:$target_cpu" 270 } 271} else if (target_os == "winuwp") { 272 # Only target WinUWP on for a Windows store application and only 273 # x86, x64 and arm are supported target CPUs. 274 assert(target_cpu == "x86" || target_cpu == "x64" || target_cpu == "arm" || 275 target_cpu == "arm64") 276 _default_toolchain = "//build/toolchain/win:uwp_$target_cpu" 277} else if (target_os == "aix") { 278 _default_toolchain = "//build/toolchain/aix:$target_cpu" 279} else if (target_os == "zos") { 280 _default_toolchain = "//build/toolchain/zos:$target_cpu" 281} else { 282 assert(false, "Unsupported target_os: $target_os") 283} 284 285# If a custom toolchain has been set in the args, set it as default. Otherwise, 286# set the default toolchain for the platform (if any). 287if (custom_toolchain != "") { 288 set_default_toolchain(custom_toolchain) 289} else if (_default_toolchain != "") { 290 set_default_toolchain(_default_toolchain) 291} 292 293# ============================================================================= 294# OS DEFINITIONS 295# ============================================================================= 296# 297# We set these various is_FOO booleans for convenience in writing OS-based 298# conditions. 299# 300# - is_android, is_chromeos, is_ios, and is_win should be obvious. 301# - is_mac is set only for desktop Mac. It is not set on iOS. 302# - is_posix is true for mac and any Unix-like system (basically everything 303# except Fuchsia and Windows). 304# - is_linux is true for desktop Linux, but not for ChromeOS nor Android (which 305# is generally too different despite being based on the Linux kernel). 306# 307# Do not add more is_* variants here for random lesser-used Unix systems like 308# aix or one of the BSDs. If you need to check these, just check the 309# current_os value directly. 310 311is_android = current_os == "android" 312is_chromeos = current_os == "chromeos" 313is_fuchsia = current_os == "fuchsia" 314is_ios = current_os == "ios" 315is_linux = current_os == "linux" 316is_mac = current_os == "mac" 317is_nacl = current_os == "nacl" 318is_watchos = current_os == "watchos" 319is_win = current_os == "win" || current_os == "winuwp" 320 321is_apple = is_ios || is_mac || is_watchos 322is_posix = !is_win && !is_fuchsia 323 324# ============================================================================= 325# TARGET DEFAULTS 326# ============================================================================= 327# 328# Set up the default configuration for every build target of the given type. 329# The values configured here will be automatically set on the scope of the 330# corresponding target. Target definitions can add or remove to the settings 331# here as needed. 332# 333# WHAT GOES HERE? 334# 335# Other than the main compiler and linker configs, the only reason for a config 336# to be in this list is if some targets need to explicitly override that config 337# by removing it. This is how targets opt-out of flags. If you don't have that 338# requirement and just need to add a config everywhere, reference it as a 339# sub-config of an existing one, most commonly the main "compiler" one. 340 341# Holds all configs used for running the compiler. 342default_compiler_configs = [ 343 "//build/config:feature_flags", 344 "//build/config/compiler:afdo", 345 "//build/config/compiler:afdo_optimize_size", 346 "//build/config/compiler:cet_shadow_stack", 347 "//build/config/compiler:chromium_code", 348 "//build/config/compiler:compiler", 349 "//build/config/compiler:compiler_arm_fpu", 350 "//build/config/compiler:compiler_arm_thumb", 351 "//build/config/compiler:default_include_dirs", 352 "//build/config/compiler:default_init_stack_vars", 353 "//build/config/compiler:default_optimization", 354 "//build/config/compiler:default_stack_frames", 355 "//build/config/compiler:default_symbols", 356 "//build/config/compiler:disallow_unstable_features", 357 "//build/config/compiler:libcxx_hardening", 358 "//build/config/compiler:libcxx_module", 359 "//build/config/compiler:no_exceptions", 360 "//build/config/compiler:no_rtti", 361 "//build/config/compiler:no_unresolved_symbols", 362 "//build/config/compiler:runtime_library", 363 "//build/config/compiler:thin_archive", 364 "//build/config/compiler:thinlto_optimize_default", 365 "//build/config/compiler/pgo:default_pgo_flags", 366 "//build/config/coverage:default_coverage", 367 "//build/config/sanitizers:default_sanitizer_flags", 368] 369 370if (is_win) { 371 default_compiler_configs += [ 372 "//build/config/win:default_cfg_compiler", 373 "//build/config/win:default_crt", 374 "//build/config/win:lean_and_mean", 375 "//build/config/win:nominmax", 376 "//build/config/win:unicode", 377 "//build/config/win:winver", 378 ] 379} 380 381if (is_apple) { 382 default_compiler_configs += [ "//build/config/compiler:enable_arc" ] 383} 384 385if (is_posix) { 386 if (current_os != "aix") { 387 default_compiler_configs += 388 [ "//build/config/gcc:symbol_visibility_hidden" ] 389 } 390} 391 392if (is_fuchsia) { 393 default_compiler_configs += [ "//build/config/gcc:symbol_visibility_hidden" ] 394} 395 396if (is_android) { 397 default_compiler_configs += 398 [ "//build/config/android:default_orderfile_instrumentation" ] 399} 400 401if (is_clang && !is_nacl) { 402 default_compiler_configs += [ 403 "//build/config/clang:extra_warnings", 404 "//build/config/clang:find_bad_constructs", 405 "//build/config/clang:unsafe_buffers", 406 ] 407} 408 409# Debug/release-related defines. 410if (is_debug) { 411 default_compiler_configs += [ "//build/config:debug" ] 412} else { 413 default_compiler_configs += [ "//build/config:release" ] 414} 415 416# Static libraries and source sets use only the compiler ones. 417set_defaults("static_library") { 418 configs = default_compiler_configs 419} 420set_defaults("source_set") { 421 configs = default_compiler_configs 422} 423set_defaults("rust_library") { 424 configs = default_compiler_configs 425} 426 427# Compute the set of configs common to all linked targets (shared libraries, 428# loadable modules, executables) to avoid duplication below. 429if (is_win) { 430 # Many targets remove these configs, so they are not contained within 431 # //build/config:executable_config for easy removal. 432 _linker_configs = [ 433 "//build/config/win:default_incremental_linking", 434 435 # Default to console-mode apps. Most of our targets are tests and such 436 # that shouldn't use the windows subsystem. 437 "//build/config/win:console", 438 ] 439} else if (is_apple) { 440 _linker_configs = [ "//build/config/apple:strip_all" ] 441} else { 442 _linker_configs = [] 443} 444 445# Executable defaults. 446default_executable_configs = default_compiler_configs + [ 447 "//build/config/compiler:export_dynamic", 448 "//build/config:default_libs", 449 "//build/config:executable_config", 450 ] + _linker_configs 451 452if (is_win) { 453 # Turn on linker CFI for executables, and position it so it can be removed 454 # if needed. 455 default_executable_configs += [ "//build/config/win:cfi_linker" ] 456} 457if (is_fuchsia) { 458 # Sometimes executables are linked by rustc passing a command line to 459 # clang++. It includes "-pie" which is pointless on Fuchsia. Suppress the 460 # resulting (fatal) warning. Unfortunately there's no way to do this only 461 # for binaries linked by rustc; gn does not make the distinction. 462 default_executable_configs += 463 [ "//build/config/fuchsia:rustc_no_pie_warning" ] 464} 465 466set_defaults("executable") { 467 configs = default_executable_configs 468} 469 470# Shared library and loadable module defaults (also for components in component 471# mode). 472default_shared_library_configs = default_compiler_configs + [ 473 "//build/config:default_libs", 474 "//build/config:shared_library_config", 475 ] + _linker_configs 476if (is_win) { 477 # Turn on linker CFI for DLLs, and position it so it can be removed if needed. 478 default_shared_library_configs += [ "//build/config/win:cfi_linker" ] 479} 480 481if (is_android) { 482 # Strip native JNI exports from shared libraries by default. Binaries that 483 # want this can remove this config. 484 default_shared_library_configs += 485 [ "//build/config/android:hide_all_but_jni_onload" ] 486} 487if (is_fuchsia) { 488 # Sometimes shared libraries are linked by rustc passing a command line to 489 # clang++. It includes "-pie" which is pointless on Fuchsia. Suppress the 490 # resulting (fatal) warning. Unfortunately there's no way to do this only 491 # for binaries linked by rustc; gn does not make the distinction. 492 default_shared_library_configs += 493 [ "//build/config/fuchsia:rustc_no_pie_warning" ] 494} 495set_defaults("shared_library") { 496 configs = default_shared_library_configs 497} 498set_defaults("loadable_module") { 499 configs = default_shared_library_configs 500 501 # loadable_modules are generally used by other libs, not just via JNI. 502 if (is_android) { 503 configs -= [ "//build/config/android:hide_all_but_jni_onload" ] 504 } 505} 506 507default_rust_proc_macro_configs = 508 default_shared_library_configs + [ "//build/rust:proc_macro_extern" ] + 509 # Rust proc macros don't support (Thin)LTO, so always remove it. 510 [ 511 "//build/config/compiler:thinlto_optimize_default", 512 "//build/config/compiler:thinlto_optimize_max", 513 ] - 514 [ 515 "//build/config/compiler:thinlto_optimize_default", 516 "//build/config/compiler:thinlto_optimize_max", 517 ] 518 519set_defaults("rust_proc_macro") { 520 configs = default_rust_proc_macro_configs 521} 522 523# A helper for forwarding testonly and visibility. 524# Forwarding "*" does not include variables from outer scopes (to avoid copying 525# all globals into each template invocation), so it will not pick up 526# file-scoped or outer-template-scoped variables. Normally this behavior is 527# desired, but "visibility" and "testonly" are commonly defined in outer scopes. 528# Explicitly forwarding them in forward_variables_from() works around this 529# nuance. See //build/docs/writing_gn_templates.md#using-forward_variables_from 530TESTONLY_AND_VISIBILITY = [ 531 "testonly", 532 "visibility", 533] 534 535# Sets default dependencies for static_library and source_set targets. 536foreach(_target_type, 537 [ 538 "source_set", 539 "static_library", 540 ]) { 541 template(_target_type) { 542 target(_target_type, target_name) { 543 forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) 544 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 545 if (!defined(inputs)) { 546 inputs = [] 547 } 548 549 # Consumed by the unsafe-buffers plugin during compile. 550 # 551 # TODO(crbug.com/326584510): Reclient doesn't respect this variable, see 552 # rbe_bug_326584510_missing_inputs in //build/config/rbe.gni. 553 _uses_cflags = false 554 if (defined(sources)) { 555 foreach(f, sources) { 556 if (string_replace(f + ".END", ".cc.END", "") != f + ".END" || 557 string_replace(f + ".END", ".c.END", "") != f + ".END" || 558 string_replace(f + ".END", ".mm.END", "") != f + ".END" || 559 string_replace(f + ".END", ".m.END", "") != f + ".END") { 560 _uses_cflags = true 561 } 562 } 563 } 564 if (_uses_cflags && clang_unsafe_buffers_paths != "") { 565 inputs += [ clang_unsafe_buffers_paths ] 566 } 567 } 568 } 569} 570 571# Sets default dependencies for executable and shared_library targets. 572# 573# Variables 574# no_default_deps: If true, no standard dependencies will be added. 575# Targets that set this usually also want to remove 576# "//build/config/compiler:runtime_library" from configs (to remove 577# its subconfig "//build/config/c++:runtime_library"). 578foreach(_target_type, 579 [ 580 "executable", 581 "loadable_module", 582 "shared_library", 583 ]) { 584 template(_target_type) { 585 # Alias "target_name" because it is clobbered by forward_variables_from(). 586 _target_name = target_name 587 target(_target_type, _target_name) { 588 forward_variables_from(invoker, 589 "*", 590 TESTONLY_AND_VISIBILITY + [ "no_default_deps" ]) 591 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 592 if (!defined(inputs)) { 593 inputs = [] 594 } 595 596 # Consumed by the unsafe-buffers plugin during compile. 597 # 598 # TODO(crbug.com/326584510): Reclient doesn't respect this variable, see 599 # rbe_bug_326584510_missing_inputs in //build/config/rbe.gni. 600 _uses_cflags = false 601 if (defined(sources)) { 602 foreach(f, sources) { 603 if (string_replace(f + ".END", ".cc.END", "") != f + ".END" || 604 string_replace(f + ".END", ".c.END", "") != f + ".END" || 605 string_replace(f + ".END", ".mm.END", "") != f + ".END" || 606 string_replace(f + ".END", ".m.END", "") != f + ".END") { 607 _uses_cflags = true 608 } 609 } 610 } 611 if (_uses_cflags && clang_unsafe_buffers_paths != "") { 612 inputs += [ clang_unsafe_buffers_paths ] 613 } 614 615 if (!defined(deps)) { 616 deps = [] 617 } 618 if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) { 619 # This pulls in one of: 620 # //build/config:executable_deps 621 # //build/config:loadable_module_deps 622 # //build/config:shared_library_deps 623 # (This explicit list is so that grepping for these configs finds where 624 # they are used.) 625 deps += [ "//build/config:${_target_type}_deps" ] 626 } 627 628 # On Android, write shared library output file to metadata. We will use 629 # this information to, for instance, collect all shared libraries that 630 # should be packaged into an APK. 631 if (!defined(invoker.metadata) && (is_android || is_robolectric) && 632 (_target_type == "shared_library" || 633 _target_type == "loadable_module")) { 634 _output_name = _target_name 635 if (defined(invoker.output_name)) { 636 _output_name = invoker.output_name 637 } 638 639 # Remove 'lib' prefix from output name if it exists. 640 _magic_prefix = "$0x01$0x01" 641 _output_name = string_replace("${_magic_prefix}${_output_name}", 642 "${_magic_prefix}lib", 643 _magic_prefix, 644 1) 645 _output_name = string_replace(_output_name, _magic_prefix, "", 1) 646 647 if (defined(output_extension)) { 648 _shlib_extension = ".$output_extension" 649 } else { 650 _shlib_extension = ".so" 651 } 652 653 metadata = { 654 shared_libraries = 655 [ "$root_out_dir/lib${_output_name}${_shlib_extension}" ] 656 } 657 } 658 } 659 } 660} 661 662# ============================================================================== 663# COMPONENT SETUP 664# ============================================================================== 665 666# Defines a component, which equates to a shared_library when 667# is_component_build == true and a static_library otherwise. 668# 669# Use static libraries for the static build rather than source sets because 670# many of of our test binaries link many large dependencies but often don't 671# use large portions of them. The static libraries are much more efficient to 672# link in this situation since only the necessary object files are linked. 673# 674# The invoker can override the type of the target in the non-component-build 675# case by setting static_component_type to either "source_set" or 676# "static_library". If unset, the default will be used. 677template("component") { 678 if (is_component_build) { 679 _component_mode = "shared_library" 680 681 # Generate a unique output_name for a shared library if not set by invoker. 682 if (!defined(invoker.output_name)) { 683 _output_name = get_label_info(":$target_name", "label_no_toolchain") 684 _output_name = 685 string_replace(_output_name, "$target_name:$target_name", target_name) 686 _output_name = string_replace(_output_name, "//", "") 687 _output_name = string_replace(_output_name, "/", "_") 688 _output_name = string_replace(_output_name, ":", "_") 689 } 690 } else if (defined(invoker.static_component_type)) { 691 assert(invoker.static_component_type == "static_library" || 692 invoker.static_component_type == "source_set") 693 _component_mode = invoker.static_component_type 694 } else if (!defined(invoker.sources) || invoker.sources == []) { 695 # When there are no sources defined, use a source set to avoid creating 696 # an empty static library (which generally don't work). 697 _component_mode = "source_set" 698 } else { 699 _component_mode = "static_library" 700 } 701 target(_component_mode, target_name) { 702 if (defined(_output_name)) { 703 output_name = _output_name 704 } 705 if (is_component_build && is_android) { 706 # By appending .cr, we prevent name collisions with libraries already 707 # loaded by the Android zygote. 708 output_extension = "cr.so" 709 } 710 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 711 forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) 712 } 713} 714 715# Component defaults 716# Set a variable since we also want to make this available 717# to mixed_component.gni 718if (is_component_build) { 719 default_component_configs = default_shared_library_configs 720 if (is_android) { 721 default_component_configs -= 722 [ "//build/config/android:hide_all_but_jni_onload" ] 723 } 724 if (is_win) { 725 # We don't want component dlls to statically load OS dlls that aren't 726 # loaded normally. 727 default_component_configs += [ "//build/config/win:delayloads" ] 728 } 729} else { 730 default_component_configs = default_compiler_configs 731} 732 733set_defaults("component") { 734 configs = default_component_configs 735} 736 737# ============================================================================= 738# ACTION OVERRIDE 739# ============================================================================= 740# 741# We override gn action() to support remote execution using rewrapper. The 742# invoker should set allow_remote to true if remote execution is desired. 743# 744# As remote execution requires inputs to be made more explicit than is normally 745# expected with gn, you may find that setting allow_remote to true will result 746# in many missing file errors. In most cases, this should be resolved by 747# explicitly declaring these inputs/sources. 748# 749# However, it may be impractical to determine these inputs in gn. For such 750# cases, the invoker can specify a custom input processor, which are currently 751# defined and implemented in //build/util/action_remote.py. The appropriate 752# value should be set using the custom_processor arg. 753 754# Variables needed by rbe.gni aren't available at the top of this file. 755import("//build/toolchain/rbe.gni") 756import("//build/toolchain/siso.gni") 757 758# TODO(b/253987456): Add action_foreach support. 759# TODO(379584977): remove this. no need this for siso native. 760foreach(_target_type, [ "action" ]) { 761 template(_target_type) { 762 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 763 action("${target_name}") { 764 forward_variables_from(invoker, 765 [ 766 "args", 767 "assert_no_deps", 768 "check_includes", 769 "configs", 770 "data_deps", 771 "data", 772 "depfile", 773 "deps", 774 "metadata", 775 "outputs", 776 "pool", 777 "script", 778 "public_configs", 779 "public_deps", 780 "response_file_contents", 781 "sources", 782 "write_runtime_deps", 783 ]) 784 allow_remote = false 785 if (defined(invoker.allow_remote)) { 786 allow_remote = invoker.allow_remote 787 } 788 789 # If remote execution is desired, only run remotely when use_remoteexec 790 # is enabled, and the environment is not nacl. 791 # Siso doesn't use action_remote.py wrapper because it sends requests to 792 # Reproxy directly without actions_remote.py/rewrapper. 793 # TODO(b/259381924): Investigate enabling in nacl config. 794 if (allow_remote && use_reclient && !is_nacl && !use_siso) { 795 pool = "//build/toolchain:remote_action_pool($default_toolchain)" 796 script = "//build/util/action_remote.py" 797 inputs = [ invoker.script ] 798 799 re_inputs = [ rebase_path(invoker.script, rbe_exec_root) ] 800 if (defined(invoker.inputs)) { 801 foreach(input, invoker.inputs) { 802 re_inputs += [ rebase_path(input, rbe_exec_root) ] 803 inputs += [ input ] 804 } 805 } 806 if (defined(invoker.sources)) { 807 foreach(source, invoker.sources) { 808 re_inputs += [ rebase_path(source, rbe_exec_root) ] 809 } 810 } 811 812 re_outputs = [] 813 if (defined(invoker.outputs)) { 814 foreach(output, invoker.outputs) { 815 re_outputs += [ rebase_path(output, rbe_exec_root) ] 816 } 817 } 818 819 # Write input/output lists to files as these can grow extremely large. 820 re_inputs_file = "$target_gen_dir/${target_name}__remote_inputs.rsp" 821 write_file(re_inputs_file, re_inputs) 822 inputs += [ re_inputs_file ] 823 re_outputs_file = "$target_gen_dir/${target_name}__remote_outputs.rsp" 824 write_file(re_outputs_file, re_outputs) 825 826 rewrapper_cfg = "$reclient_py_cfg_file" 827 if (defined(invoker.remote_worker)) { 828 remote_worker = invoker.remote_worker 829 assert(remote_worker == "large", 830 "remote_worker = " + remote_worker + " is not supported") 831 rewrapper_cfg = "$reclient_py_large_cfg_file" 832 } 833 834 args = [] 835 args += [ "$reclient_bin_dir/rewrapper" ] 836 if (defined(invoker.custom_processor)) { 837 args += [ "--custom_processor=" + invoker.custom_processor ] 838 } 839 840 args += [ 841 "--cfg=" + rewrapper_cfg, 842 "--exec_root=$rbe_exec_root", 843 "--input_list_paths=" + rebase_path(re_inputs_file, root_build_dir), 844 "--output_list_paths=" + rebase_path(re_outputs_file, root_build_dir), 845 "python3", 846 rebase_path(invoker.script, root_build_dir), 847 ] 848 849 if (defined(invoker.args)) { 850 args += invoker.args 851 } 852 } else { 853 forward_variables_from(invoker, [ "inputs" ]) 854 not_needed(invoker, 855 [ 856 "custom_processor", 857 "remote_worker", 858 ]) 859 } 860 } 861 } 862} 863