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