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_wasm = current_os == "emscripten" 319is_watchos = current_os == "watchos" 320is_win = current_os == "win" || current_os == "winuwp" 321 322is_apple = is_ios || is_mac || is_watchos 323is_posix = !is_win && !is_fuchsia 324 325# ============================================================================= 326# TARGET DEFAULTS 327# ============================================================================= 328# 329# Set up the default configuration for every build target of the given type. 330# The values configured here will be automatically set on the scope of the 331# corresponding target. Target definitions can add or remove to the settings 332# here as needed. 333# 334# WHAT GOES HERE? 335# 336# Other than the main compiler and linker configs, the only reason for a config 337# to be in this list is if some targets need to explicitly override that config 338# by removing it. This is how targets opt-out of flags. If you don't have that 339# requirement and just need to add a config everywhere, reference it as a 340# sub-config of an existing one, most commonly the main "compiler" one. 341 342# Holds all configs used for running the compiler. 343default_compiler_configs = [ 344 "//build/config:feature_flags", 345 "//build/config/compiler:afdo", 346 "//build/config/compiler:afdo_optimize_size", 347 "//build/config/compiler:cet_shadow_stack", 348 "//build/config/compiler:chromium_code", 349 "//build/config/compiler:compiler", 350 "//build/config/compiler:compiler_arm_fpu", 351 "//build/config/compiler:compiler_arm_thumb", 352 "//build/config/compiler:default_include_dirs", 353 "//build/config/compiler:default_init_stack_vars", 354 "//build/config/compiler:default_optimization", 355 "//build/config/compiler:default_stack_frames", 356 "//build/config/compiler:default_symbols", 357 "//build/config/compiler:disallow_unstable_features", 358 "//build/config/compiler:libcxx_hardening", 359 "//build/config/compiler:libcxx_module", 360 "//build/config/compiler:no_exceptions", 361 "//build/config/compiler:no_rtti", 362 "//build/config/compiler:no_unresolved_symbols", 363 "//build/config/compiler:runtime_library", 364 "//build/config/compiler:thin_archive", 365 "//build/config/compiler:thinlto_optimize_default", 366 "//build/config/compiler/pgo:default_pgo_flags", 367 "//build/config/coverage:default_coverage", 368 "//build/config/sanitizers:default_sanitizer_flags", 369] 370 371if (is_win) { 372 default_compiler_configs += [ 373 "//build/config/win:default_cfg_compiler", 374 "//build/config/win:default_crt", 375 "//build/config/win:lean_and_mean", 376 "//build/config/win:nominmax", 377 "//build/config/win:unicode", 378 "//build/config/win:winver", 379 ] 380} 381 382if (is_apple) { 383 default_compiler_configs += [ "//build/config/compiler:enable_arc" ] 384} 385 386if (is_posix) { 387 if (current_os != "aix") { 388 default_compiler_configs += 389 [ "//build/config/gcc:symbol_visibility_hidden" ] 390 } 391} 392 393if (is_fuchsia) { 394 default_compiler_configs += [ "//build/config/gcc:symbol_visibility_hidden" ] 395} 396 397if (is_android) { 398 default_compiler_configs += 399 [ "//build/config/android:default_orderfile_instrumentation" ] 400} 401 402if (is_clang && !is_nacl) { 403 default_compiler_configs += [ 404 "//build/config/clang:extra_warnings", 405 "//build/config/clang:find_bad_constructs", 406 "//build/config/clang:unsafe_buffers", 407 ] 408} 409 410# Debug/release-related defines. 411if (is_debug) { 412 default_compiler_configs += [ "//build/config:debug" ] 413} else { 414 default_compiler_configs += [ "//build/config:release" ] 415} 416 417# Static libraries and source sets use only the compiler ones. 418set_defaults("static_library") { 419 configs = default_compiler_configs 420} 421set_defaults("source_set") { 422 configs = default_compiler_configs 423} 424set_defaults("rust_library") { 425 configs = default_compiler_configs 426} 427 428# Compute the set of configs common to all linked targets (shared libraries, 429# loadable modules, executables) to avoid duplication below. 430if (is_win) { 431 # Many targets remove these configs, so they are not contained within 432 # //build/config:executable_config for easy removal. 433 _linker_configs = [ 434 "//build/config/win:default_incremental_linking", 435 436 # Default to console-mode apps. Most of our targets are tests and such 437 # that shouldn't use the windows subsystem. 438 "//build/config/win:console", 439 ] 440} else if (is_apple) { 441 _linker_configs = [ "//build/config/apple:strip_all" ] 442} else { 443 _linker_configs = [] 444} 445 446# Executable defaults. 447default_executable_configs = default_compiler_configs + [ 448 "//build/config/compiler:export_dynamic", 449 "//build/config:default_libs", 450 "//build/config:executable_config", 451 ] + _linker_configs 452 453if (is_win) { 454 # Turn on linker CFI for executables, and position it so it can be removed 455 # if needed. 456 default_executable_configs += [ "//build/config/win:cfi_linker" ] 457} 458if (is_fuchsia) { 459 # Sometimes executables are linked by rustc passing a command line to 460 # clang++. It includes "-pie" which is pointless on Fuchsia. Suppress the 461 # resulting (fatal) warning. Unfortunately there's no way to do this only 462 # for binaries linked by rustc; gn does not make the distinction. 463 default_executable_configs += 464 [ "//build/config/fuchsia:rustc_no_pie_warning" ] 465} 466 467set_defaults("executable") { 468 configs = default_executable_configs 469} 470 471# Shared library and loadable module defaults (also for components in component 472# mode). 473default_shared_library_configs = default_compiler_configs + [ 474 "//build/config:default_libs", 475 "//build/config:shared_library_config", 476 ] + _linker_configs 477if (is_win) { 478 # Turn on linker CFI for DLLs, and position it so it can be removed if needed. 479 default_shared_library_configs += [ "//build/config/win:cfi_linker" ] 480} 481 482if (is_android) { 483 # Strip native JNI exports from shared libraries by default. Binaries that 484 # want this can remove this config. 485 default_shared_library_configs += 486 [ "//build/config/android:hide_all_but_jni_onload" ] 487} 488if (is_fuchsia) { 489 # Sometimes shared libraries are linked by rustc passing a command line to 490 # clang++. It includes "-pie" which is pointless on Fuchsia. Suppress the 491 # resulting (fatal) warning. Unfortunately there's no way to do this only 492 # for binaries linked by rustc; gn does not make the distinction. 493 default_shared_library_configs += 494 [ "//build/config/fuchsia:rustc_no_pie_warning" ] 495} 496set_defaults("shared_library") { 497 configs = default_shared_library_configs 498} 499set_defaults("loadable_module") { 500 configs = default_shared_library_configs 501 502 # loadable_modules are generally used by other libs, not just via JNI. 503 if (is_android) { 504 configs -= [ "//build/config/android:hide_all_but_jni_onload" ] 505 } 506} 507 508default_rust_proc_macro_configs = 509 default_shared_library_configs + [ "//build/rust:proc_macro_extern" ] + 510 # Rust proc macros don't support (Thin)LTO, so always remove it. 511 [ 512 "//build/config/compiler:thinlto_optimize_default", 513 "//build/config/compiler:thinlto_optimize_max", 514 ] - 515 [ 516 "//build/config/compiler:thinlto_optimize_default", 517 "//build/config/compiler:thinlto_optimize_max", 518 ] 519 520set_defaults("rust_proc_macro") { 521 configs = default_rust_proc_macro_configs 522} 523 524# A helper for forwarding testonly and visibility. 525# Forwarding "*" does not include variables from outer scopes (to avoid copying 526# all globals into each template invocation), so it will not pick up 527# file-scoped or outer-template-scoped variables. Normally this behavior is 528# desired, but "visibility" and "testonly" are commonly defined in outer scopes. 529# Explicitly forwarding them in forward_variables_from() works around this 530# nuance. See //build/docs/writing_gn_templates.md#using-forward_variables_from 531TESTONLY_AND_VISIBILITY = [ 532 "testonly", 533 "visibility", 534] 535 536# Sets default dependencies for static_library and source_set targets. 537# 538# Variables 539# use_libcxx_modules: If true, libc++'s modules are added to deps. 540# This is true by default. 541foreach(_target_type, 542 [ 543 "source_set", 544 "static_library", 545 ]) { 546 template(_target_type) { 547 target(_target_type, target_name) { 548 forward_variables_from(invoker, 549 "*", 550 TESTONLY_AND_VISIBILITY + [ "use_libcxx_modules" ]) 551 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 552 if (!defined(inputs)) { 553 inputs = [] 554 } 555 if (!defined(deps)) { 556 deps = [] 557 } 558 559 if (is_clang && (!defined(invoker.use_libcxx_modules) || 560 invoker.use_libcxx_modules)) { 561 # This is necessary for Clang modules builds. 562 deps += [ 563 "//buildtools/third_party/libc++:std", 564 "//buildtools/third_party/libc++:std_config", 565 "//buildtools/third_party/libc++:std_core", 566 "//buildtools/third_party/libc++:std_ctype_h", 567 "//buildtools/third_party/libc++:std_errno_h", 568 "//buildtools/third_party/libc++:std_fenv_h", 569 "//buildtools/third_party/libc++:std_float_h", 570 "//buildtools/third_party/libc++:std_inttypes_h", 571 "//buildtools/third_party/libc++:std_math_h", 572 "//buildtools/third_party/libc++:std_private_mbstate_t", 573 "//buildtools/third_party/libc++:std_string_h", 574 "//buildtools/third_party/libc++:std_uchar_h", 575 "//buildtools/third_party/libc++:std_wctype_h", 576 ] 577 } 578 579 # Consumed by the unsafe-buffers plugin during compile. 580 # 581 # TODO(crbug.com/326584510): Reclient doesn't respect this variable, see 582 # rbe_bug_326584510_missing_inputs in //build/config/clang/clang.gni 583 _uses_cflags = false 584 if (defined(sources)) { 585 foreach(f, sources) { 586 if (string_replace(f + ".END", ".cc.END", "") != f + ".END" || 587 string_replace(f + ".END", ".c.END", "") != f + ".END" || 588 string_replace(f + ".END", ".mm.END", "") != f + ".END" || 589 string_replace(f + ".END", ".m.END", "") != f + ".END") { 590 _uses_cflags = true 591 } 592 } 593 } 594 if (_uses_cflags && clang_unsafe_buffers_paths != "") { 595 inputs += [ clang_unsafe_buffers_paths ] 596 } 597 } 598 } 599} 600 601# Sets default dependencies for executable and shared_library targets. 602# 603# Variables 604# no_default_deps: If true, no standard dependencies will be added. 605# Targets that set this usually also want to remove 606# "//build/config/compiler:runtime_library" from configs (to remove 607# its subconfig "//build/config/c++:runtime_library"). 608# use_libcxx_modules: If true, libc++'s modules are added to deps. 609# This is true by default. 610foreach(_target_type, 611 [ 612 "executable", 613 "loadable_module", 614 "shared_library", 615 ]) { 616 template(_target_type) { 617 # Alias "target_name" because it is clobbered by forward_variables_from(). 618 _target_name = target_name 619 target(_target_type, _target_name) { 620 forward_variables_from(invoker, 621 "*", 622 TESTONLY_AND_VISIBILITY + [ 623 "no_default_deps", 624 "use_libcxx_modules", 625 ]) 626 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 627 if (!defined(inputs)) { 628 inputs = [] 629 } 630 631 # Consumed by the unsafe-buffers plugin during compile. 632 # 633 # TODO(crbug.com/326584510): Reclient doesn't respect this variable, see 634 # rbe_bug_326584510_missing_inputs in //build/config/clang/clang.gni 635 _uses_cflags = false 636 if (defined(sources)) { 637 foreach(f, sources) { 638 if (string_replace(f + ".END", ".cc.END", "") != f + ".END" || 639 string_replace(f + ".END", ".c.END", "") != f + ".END" || 640 string_replace(f + ".END", ".mm.END", "") != f + ".END" || 641 string_replace(f + ".END", ".m.END", "") != f + ".END") { 642 _uses_cflags = true 643 } 644 } 645 } 646 if (_uses_cflags && clang_unsafe_buffers_paths != "") { 647 inputs += [ clang_unsafe_buffers_paths ] 648 } 649 650 if (!defined(deps)) { 651 deps = [] 652 } 653 if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) { 654 # This pulls in one of: 655 # //build/config:executable_deps 656 # //build/config:loadable_module_deps 657 # //build/config:shared_library_deps 658 # (This explicit list is so that grepping for these configs finds where 659 # they are used.) 660 deps += [ "//build/config:${_target_type}_deps" ] 661 } 662 663 if (is_clang && (!defined(invoker.use_libcxx_modules) || 664 invoker.use_libcxx_modules)) { 665 # These are necessary for Clang modules builds. 666 deps += [ 667 "//buildtools/third_party/libc++:_Builtin_limits", 668 "//buildtools/third_party/libc++:_Builtin_stdarg", 669 "//buildtools/third_party/libc++:_Builtin_stddef", 670 "//buildtools/third_party/libc++:std", 671 "//buildtools/third_party/libc++:std_config", 672 "//buildtools/third_party/libc++:std_core", 673 "//buildtools/third_party/libc++:std_ctype_h", 674 "//buildtools/third_party/libc++:std_errno_h", 675 "//buildtools/third_party/libc++:std_fenv_h", 676 "//buildtools/third_party/libc++:std_float_h", 677 "//buildtools/third_party/libc++:std_inttypes_h", 678 "//buildtools/third_party/libc++:std_math_h", 679 "//buildtools/third_party/libc++:std_private_mbstate_t", 680 "//buildtools/third_party/libc++:std_string_h", 681 "//buildtools/third_party/libc++:std_uchar_h", 682 "//buildtools/third_party/libc++:std_wctype_h", 683 ] 684 } 685 686 # On Android, write shared library output file to metadata. We will use 687 # this information to, for instance, collect all shared libraries that 688 # should be packaged into an APK. 689 if (!defined(invoker.metadata) && (is_android || is_robolectric) && 690 (_target_type == "shared_library" || 691 _target_type == "loadable_module")) { 692 _output_name = _target_name 693 if (defined(invoker.output_name)) { 694 _output_name = invoker.output_name 695 } 696 697 # Remove 'lib' prefix from output name if it exists. 698 _magic_prefix = "$0x01$0x01" 699 _output_name = string_replace("${_magic_prefix}${_output_name}", 700 "${_magic_prefix}lib", 701 _magic_prefix, 702 1) 703 _output_name = string_replace(_output_name, _magic_prefix, "", 1) 704 705 if (defined(output_extension)) { 706 _shlib_extension = ".$output_extension" 707 } else { 708 _shlib_extension = ".so" 709 } 710 711 metadata = { 712 shared_libraries = 713 [ "$root_out_dir/lib${_output_name}${_shlib_extension}" ] 714 } 715 } 716 } 717 } 718} 719 720# ============================================================================== 721# COMPONENT SETUP 722# ============================================================================== 723 724# Defines a component, which equates to a shared_library when 725# is_component_build == true and a static_library otherwise. 726# 727# Use static libraries for the static build rather than source sets because 728# many of of our test binaries link many large dependencies but often don't 729# use large portions of them. The static libraries are much more efficient to 730# link in this situation since only the necessary object files are linked. 731# 732# The invoker can override the type of the target in the non-component-build 733# case by setting static_component_type to either "source_set" or 734# "static_library". If unset, the default will be used. 735template("component") { 736 if (is_component_build) { 737 _component_mode = "shared_library" 738 739 # Generate a unique output_name for a shared library if not set by invoker. 740 if (!defined(invoker.output_name)) { 741 _output_name = get_label_info(":$target_name", "label_no_toolchain") 742 _output_name = 743 string_replace(_output_name, "$target_name:$target_name", target_name) 744 _output_name = string_replace(_output_name, "//", "") 745 _output_name = string_replace(_output_name, "/", "_") 746 _output_name = string_replace(_output_name, ":", "_") 747 } 748 } else if (defined(invoker.static_component_type)) { 749 assert(invoker.static_component_type == "static_library" || 750 invoker.static_component_type == "source_set") 751 _component_mode = invoker.static_component_type 752 } else if (!defined(invoker.sources) || invoker.sources == []) { 753 # When there are no sources defined, use a source set to avoid creating 754 # an empty static library (which generally don't work). 755 _component_mode = "source_set" 756 } else { 757 _component_mode = "static_library" 758 } 759 target(_component_mode, target_name) { 760 if (defined(_output_name)) { 761 output_name = _output_name 762 } 763 if (is_component_build && is_android) { 764 # By appending .cr, we prevent name collisions with libraries already 765 # loaded by the Android zygote. 766 output_extension = "cr.so" 767 } 768 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 769 forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) 770 } 771} 772 773# Component defaults 774# Set a variable since we also want to make this available 775# to mixed_component.gni 776if (is_component_build) { 777 default_component_configs = default_shared_library_configs 778 if (is_android) { 779 default_component_configs -= 780 [ "//build/config/android:hide_all_but_jni_onload" ] 781 } 782 if (is_win) { 783 # We don't want component dlls to statically load OS dlls that aren't 784 # loaded normally. 785 default_component_configs += [ "//build/config/win:delayloads" ] 786 } 787} else { 788 default_component_configs = default_compiler_configs 789} 790 791set_defaults("component") { 792 configs = default_component_configs 793} 794