1# Copyright (c) 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5# =============================================================================
6# WHAT IS THIS FILE?
7# =============================================================================
8#
9# This is the master 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  is_official_build = false
132
133  # Whether we're a traditional desktop unix.
134  is_desktop_linux = current_os == "linux" || current_os == "freebsd"
135
136  # Set to true when compiling with the Clang compiler.
137  is_clang = current_os != "linux" || current_os == "freebsd" ||
138             (current_cpu != "s390x" && current_cpu != "s390" &&
139              current_cpu != "ppc64" && current_cpu != "ppc" &&
140              current_cpu != "mips" && current_cpu != "mips64")
141
142  # Allows the path to a custom target toolchain to be injected as a single
143  # argument, and set as the default toolchain.
144  custom_toolchain = ""
145
146  # This should not normally be set as a build argument.  It's here so that
147  # every toolchain can pass through the "global" value via toolchain_args().
148  host_toolchain = ""
149
150  # DON'T ADD MORE FLAGS HERE. Read the comment above.
151}
152
153declare_args() {
154  # Debug build. Enabling official builds automatically sets is_debug to false.
155  is_debug = !is_official_build
156}
157
158declare_args() {
159  # Component build. Setting to true compiles targets declared as "components"
160  # as shared libraries loaded dynamically. This speeds up development time.
161  # When false, components will be linked statically.
162  #
163  # For more information see
164  # https://chromium.googlesource.com/chromium/src/+/master/docs/component_build.md
165  is_component_build = is_debug && current_os != "ios"
166}
167
168declare_args() {
169  # Shared library build
170  is_shared = is_component_build
171}
172
173assert(!(is_debug && is_official_build), "Can't do official debug builds")
174
175# ==============================================================================
176# TOOLCHAIN SETUP
177# ==============================================================================
178#
179# Here we set the default toolchain, as well as the variable host_toolchain
180# which will identify the toolchain corresponding to the local system when
181# doing cross-compiles. When not cross-compiling, this will be the same as the
182# default toolchain.
183#
184# We do this before anything else to make sure we complain about any
185# unsupported os/cpu combinations as early as possible.
186
187if (host_toolchain == "") {
188  # This should only happen in the top-level context.
189  # In a specific toolchain context, the toolchain_args()
190  # block should have propagated a value down.
191  # TODO(dpranke): Add some sort of assert here that verifies that
192  # no toolchain omitted host_toolchain from its toolchain_args().
193
194  if (host_os == "linux" || host_os == "freebsd") {
195    if (target_os != "linux" && target_os != "freebsd") {
196      host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
197    } else if (is_clang) {
198      host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
199    } else {
200      host_toolchain = "//build/toolchain/linux:$host_cpu"
201    }
202  } else if (host_os == "mac") {
203    host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
204  } else if (host_os == "win") {
205    # On Windows always use the target CPU for host builds for x86/x64. On the
206    # configurations we support this will always work and it saves build steps.
207    # Windows ARM64 targets require an x64 host for cross build.
208    if (target_cpu == "x86" || target_cpu == "x64") {
209      if (is_clang) {
210        host_toolchain = "//build/toolchain/win:win_clang_$target_cpu"
211      } else {
212        host_toolchain = "//build/toolchain/win:$target_cpu"
213      }
214    } else if (is_clang) {
215      host_toolchain = "//build/toolchain/win:win_clang_$host_cpu"
216    } else {
217      host_toolchain = "//build/toolchain/win:$host_cpu"
218    }
219  } else if (host_os == "aix") {
220    host_toolchain = "//build/toolchain/aix:$host_cpu"
221  } else {
222    assert(false, "Unsupported host_os: $host_os")
223  }
224}
225
226_default_toolchain = ""
227
228if (target_os == "android") {
229  assert(host_os == "linux" || host_os == "mac",
230         "Android builds are only supported on Linux and Mac hosts.")
231  _default_toolchain = "//build/toolchain/android:android_clang_$target_cpu"
232} else if (target_os == "chromeos" || target_os == "linux" || target_os == "freebsd") {
233  # See comments in build/toolchain/cros/BUILD.gn about board compiles.
234  if (is_clang) {
235    _default_toolchain = "//build/toolchain/linux:clang_$target_cpu"
236  } else {
237    _default_toolchain = "//build/toolchain/linux:$target_cpu"
238  }
239} else if (target_os == "fuchsia") {
240  _default_toolchain = "//build/toolchain/fuchsia:$target_cpu"
241} else if (target_os == "ios") {
242  _default_toolchain = "//build/toolchain/mac:ios_clang_$target_cpu"
243} else if (target_os == "mac") {
244  assert(host_os == "mac", "Mac cross-compiles are unsupported.")
245  _default_toolchain = host_toolchain
246} else if (target_os == "win") {
247  # On Windows, we use the same toolchain for host and target by default.
248  # Beware, win cross builds have some caveats, see docs/win_cross.md
249  if (is_clang) {
250    _default_toolchain = "//build/toolchain/win:win_clang_$target_cpu"
251  } else {
252    _default_toolchain = "//build/toolchain/win:$target_cpu"
253  }
254} else if (target_os == "winuwp") {
255  # Only target WinUWP on for a Windows store application and only
256  # x86, x64 and arm are supported target CPUs.
257  assert(target_cpu == "x86" || target_cpu == "x64" || target_cpu == "arm" ||
258         target_cpu == "arm64")
259  _default_toolchain = "//build/toolchain/win:uwp_$target_cpu"
260} else if (target_os == "aix") {
261  _default_toolchain = "//build/toolchain/aix:$target_cpu"
262} else {
263  assert(false, "Unsupported target_os: $target_os")
264}
265
266# If a custom toolchain has been set in the args, set it as default. Otherwise,
267# set the default toolchain for the platform (if any).
268if (custom_toolchain != "") {
269  set_default_toolchain(custom_toolchain)
270} else if (_default_toolchain != "") {
271  set_default_toolchain(_default_toolchain)
272}
273
274# =============================================================================
275# OS DEFINITIONS
276# =============================================================================
277#
278# We set these various is_FOO booleans for convenience in writing OS-based
279# conditions.
280#
281# - is_android, is_chromeos, is_ios, and is_win should be obvious.
282# - is_mac is set only for desktop Mac. It is not set on iOS.
283# - is_posix is true for mac and any Unix-like system (basically everything
284#   except Fuchsia and Windows).
285# - is_linux is true for desktop Linux and ChromeOS, but not Android (which is
286#   generally too different despite being based on the Linux kernel).
287#
288# Do not add more is_* variants here for random lesser-used Unix systems like
289# aix or one of the BSDs. If you need to check these, just check the
290# current_os value directly.
291
292is_android = current_os == "android"
293is_chromeos = current_os == "chromeos"
294is_fuchsia = current_os == "fuchsia"
295is_ios = current_os == "ios"
296is_linux = current_os == "chromeos" || current_os == "linux" || current_os == "freebsd"
297is_mac = current_os == "mac"
298is_nacl = current_os == "nacl"
299is_win = current_os == "win" || current_os == "winuwp"
300is_bsd = current_os == "freebsd"
301
302is_posix = !is_win && !is_fuchsia
303
304# =============================================================================
305# SOURCES FILTERS
306# =============================================================================
307#
308# These patterns filter out platform-specific files when assigning to the
309# sources variable. The magic variable |sources_assignment_filter| is applied
310# to each assignment or appending to the sources variable and matches are
311# automatically removed.
312#
313# Note that the patterns are NOT regular expressions. Only "*" and "\b" (path
314# boundary = end of string or slash) are supported, and the entire string
315# must match the pattern (so you need "*.cc" to match all .cc files, for
316# example).
317
318# DO NOT ADD MORE PATTERNS TO THIS LIST, see set_sources_assignment_filter call
319# below.
320sources_assignment_filter = []
321
322if (!is_win) {
323  sources_assignment_filter += [
324    "*_win.cc",
325    "*_win.h",
326    "*_win_unittest.cc",
327    "*\bwin/*",
328    "*.def",
329    "*.rc",
330  ]
331}
332if (!is_mac) {
333  sources_assignment_filter += [
334    "*_mac.h",
335    "*_mac.cc",
336    "*_mac.mm",
337    "*_mac_unittest.h",
338    "*_mac_unittest.cc",
339    "*_mac_unittest.mm",
340    "*\bmac/*",
341    "*_cocoa.h",
342    "*_cocoa.cc",
343    "*_cocoa.mm",
344    "*_cocoa_unittest.h",
345    "*_cocoa_unittest.cc",
346    "*_cocoa_unittest.mm",
347    "*\bcocoa/*",
348  ]
349}
350if (!is_ios) {
351  sources_assignment_filter += [
352    "*_ios.h",
353    "*_ios.cc",
354    "*_ios.mm",
355    "*_ios_unittest.h",
356    "*_ios_unittest.cc",
357    "*_ios_unittest.mm",
358    "*\bios/*",
359  ]
360}
361if (!is_mac && !is_ios) {
362  sources_assignment_filter += [ "*.mm" ]
363}
364if (!is_linux) {
365  sources_assignment_filter += [
366    "*_linux.h",
367    "*_linux.cc",
368    "*_linux_unittest.h",
369    "*_linux_unittest.cc",
370    "*\blinux/*",
371  ]
372}
373if (!is_android) {
374  sources_assignment_filter += [
375    "*_android.h",
376    "*_android.cc",
377    "*_android_unittest.h",
378    "*_android_unittest.cc",
379    "*\bandroid/*",
380  ]
381}
382if (!is_chromeos) {
383  sources_assignment_filter += [
384    "*_chromeos.h",
385    "*_chromeos.cc",
386    "*_chromeos_unittest.h",
387    "*_chromeos_unittest.cc",
388    "*\bchromeos/*",
389  ]
390}
391
392# DO NOT ADD MORE PATTERNS TO THIS LIST, see set_sources_assignment_filter call
393# below.
394
395# Actually save this list.
396#
397# These patterns are executed for every file in the source tree of every run.
398# Therefore, adding more patterns slows down the build for everybody. We should
399# only add automatic patterns for configurations affecting hundreds of files
400# across many projects in the tree.
401#
402# Therefore, we only add rules to this list corresponding to platforms on the
403# Chromium waterfall.  This is not for non-officially-supported platforms
404# (FreeBSD, etc.) toolkits, (X11, GTK, etc.), or features. For these cases,
405# write a conditional in the target to remove the file(s) from the list when
406# your platform/toolkit/feature doesn't apply.
407set_sources_assignment_filter(sources_assignment_filter)
408
409# =============================================================================
410# TARGET DEFAULTS
411# =============================================================================
412#
413# Set up the default configuration for every build target of the given type.
414# The values configured here will be automatically set on the scope of the
415# corresponding target. Target definitions can add or remove to the settings
416# here as needed.
417#
418# WHAT GOES HERE?
419#
420# Other than the main compiler and linker configs, the only reason for a config
421# to be in this list is if some targets need to explicitly override that config
422# by removing it. This is how targets opt-out of flags. If you don't have that
423# requirement and just need to add a config everywhere, reference it as a
424# sub-config of an existing one, most commonly the main "compiler" one.
425
426# Holds all configs used for running the compiler.
427default_compiler_configs = [
428  "//build/config:feature_flags",
429  "//build/config/compiler:afdo",
430  "//build/config/compiler:afdo_optimize_size",
431  "//build/config/compiler:compiler",
432  "//build/config/compiler:compiler_arm_fpu",
433  "//build/config/compiler:compiler_arm_thumb",
434  "//build/config/compiler:chromium_code",
435  "//build/config/compiler:default_include_dirs",
436  "//build/config/compiler:default_optimization",
437  "//build/config/compiler:default_stack_frames",
438  "//build/config/compiler:default_symbols",
439  "//build/config/compiler:export_dynamic",
440  "//build/config/compiler:no_exceptions",
441  "//build/config/compiler:no_rtti",
442  "//build/config/compiler:runtime_library",
443  "//build/config/compiler:thin_archive",
444  "//build/config/compiler:default_init_stack_vars",
445  "//build/config/compiler/pgo:default_pgo_flags",
446  "//build/config/coverage:default_coverage",
447  "//build/config/sanitizers:default_sanitizer_flags",
448]
449
450if (is_win) {
451  default_compiler_configs += [
452    "//build/config/win:default_crt",
453    "//build/config/win:lean_and_mean",
454    "//build/config/win:nominmax",
455    "//build/config/win:unicode",
456    "//build/config/win:winver",
457  ]
458}
459
460if (is_posix) {
461  if (current_os != "aix") {
462    default_compiler_configs +=
463        [ "//build/config/gcc:symbol_visibility_hidden" ]
464  }
465}
466
467if (is_fuchsia) {
468  default_compiler_configs += [ "//build/config/gcc:symbol_visibility_hidden" ]
469}
470
471if (is_android) {
472  default_compiler_configs +=
473      [ "//build/config/android:default_orderfile_instrumentation" ]
474}
475
476if (is_win) {
477  default_compiler_configs +=
478      [ "//build/config/win:default_cygprofile_instrumentation" ]
479}
480
481if (is_clang && !is_nacl) {
482  default_compiler_configs += [
483    "//build/config/clang:find_bad_constructs",
484    "//build/config/clang:extra_warnings",
485  ]
486}
487
488# Debug/release-related defines.
489if (is_debug) {
490  default_compiler_configs += [ "//build/config:debug" ]
491} else {
492  default_compiler_configs += [ "//build/config:release" ]
493}
494
495# Static libraries and source sets use only the compiler ones.
496set_defaults("static_library") {
497  configs = default_compiler_configs
498}
499set_defaults("source_set") {
500  configs = default_compiler_configs
501}
502
503# Compute the set of configs common to all linked targets (shared libraries,
504# loadable modules, executables) to avoid duplication below.
505if (is_win) {
506  # Many targets remove these configs, so they are not contained within
507  # //build/config:executable_config for easy removal.
508  _linker_configs = [
509    "//build/config/win:default_incremental_linking",
510
511    # Default to console-mode apps. Most of our targets are tests and such
512    # that shouldn't use the windows subsystem.
513    "//build/config/win:console",
514  ]
515} else if (is_mac) {
516  _linker_configs = [ "//build/config/mac:strip_all" ]
517} else {
518  _linker_configs = []
519}
520
521# Executable defaults.
522default_executable_configs = default_compiler_configs + [
523                               "//build/config:default_libs",
524                               "//build/config:executable_config",
525                             ] + _linker_configs
526
527if (is_win) {
528  # Currently only turn on linker CFI for executables, and position it so it can
529  # be removed when needed.
530  default_executable_configs += [ "//build/config/win:cfi_linker" ]
531}
532
533set_defaults("executable") {
534  configs = default_executable_configs
535}
536
537# Shared library and loadable module defaults (also for components in component
538# mode).
539default_shared_library_configs = default_compiler_configs + [
540                                   "//build/config:default_libs",
541                                   "//build/config:shared_library_config",
542                                 ] + _linker_configs
543if (is_android) {
544  # Strip native JNI exports from shared libraries by default. Binaries that
545  # want this can remove this config.
546  default_shared_library_configs +=
547      [ "//build/config/android:hide_all_but_jni_onload" ]
548}
549set_defaults("shared_library") {
550  configs = default_shared_library_configs
551}
552set_defaults("loadable_module") {
553  configs = default_shared_library_configs
554
555  # loadable_modules are generally used by other libs, not just via JNI.
556  if (is_android) {
557    configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
558  }
559}
560
561# Sets default dependencies for executable and shared_library targets.
562#
563# Variables
564#   no_default_deps: If true, no standard dependencies will be added.
565#       Targets that set this usually also want to remove
566#       "//build/config/compiler:runtime_library" from configs (to remove
567#       its subconfig "//build/config/c++:runtime_library").
568foreach(_target_type,
569        [
570          "executable",
571          "loadable_module",
572          "shared_library",
573        ]) {
574  template(_target_type) {
575    _target_name = target_name
576    target(_target_type, _target_name) {
577      forward_variables_from(invoker, "*", [ "no_default_deps" ])
578      if (!defined(deps)) {
579        deps = []
580      }
581      if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) {
582        # This pulls in one of:
583        # //build/config:executable_deps
584        # //build/config:loadable_module_deps
585        # //build/config:shared_library_deps
586        # (This explicit list is so that grepping for these configs finds where
587        # they are used.)
588        deps += [ "//build/config:${_target_type}_deps" ]
589      }
590
591      # On Android, write shared library output file to metadata. We will use
592      # this information to, for instance, collect all shared libraries that
593      # should be packaged into an APK.
594      if (!defined(invoker.metadata) && is_android && (_target_type ==
595                                                       "shared_library" ||
596                                                       _target_type ==
597                                                       "loadable_module")) {
598        _output_name = _target_name
599        if (defined(invoker.output_name)) {
600          _output_name = invoker.output_name
601        }
602
603        # Remove 'lib' prefix from output name if it exists.
604        _magic_prefix = "$0x01$0x01"
605        _output_name = string_replace("${_magic_prefix}${_output_name}",
606                                      "${_magic_prefix}lib",
607                                      _magic_prefix,
608                                      1)
609        _output_name = string_replace(_output_name, _magic_prefix, "", 1)
610
611        if (defined(output_extension)) {
612          _shlib_extension = ".$output_extension"
613        } else if (is_component_build && _target_type != "loadable_module") {
614          _shlib_extension = ".cr.so"
615        } else {
616          _shlib_extension = ".so"
617        }
618
619        metadata = {
620          shared_libraries =
621              [ "$root_out_dir/lib${_output_name}${_shlib_extension}" ]
622        }
623      }
624    }
625  }
626}
627
628# ==============================================================================
629# COMPONENT SETUP
630# ==============================================================================
631
632# Defines a component, which equates to a shared_library when
633# is_component_build == true and a static_library otherwise.
634#
635# Use static libraries for the static build rather than source sets because
636# many of of our test binaries link many large dependencies but often don't
637# use large portions of them. The static libraries are much more efficient to
638# link in this situation since only the necessary object files are linked.
639#
640# The invoker can override the type of the target in the non-component-build
641# case by setting static_component_type to either "source_set" or
642# "static_library". If unset, the default will be used.
643template("component") {
644  if (is_component_build) {
645    _component_mode = "shared_library"
646  } else if (defined(invoker.static_component_type)) {
647    assert(invoker.static_component_type == "static_library" ||
648           invoker.static_component_type == "source_set")
649    _component_mode = invoker.static_component_type
650  } else if (!defined(invoker.sources)) {
651    # When there are no sources defined, use a source set to avoid creating
652    # an empty static library (which generally don't work).
653    _component_mode = "source_set"
654  } else {
655    _component_mode = "static_library"
656  }
657  target(_component_mode, target_name) {
658    # Explicitly forward visibility, implicitly forward everything else.
659    # Forwarding "*" doesn't recurse into nested scopes (to avoid copying all
660    # globals into each template invocation), so won't pick up file-scoped
661    # variables. Normally this isn't too bad, but visibility is commonly
662    # defined at the file scope. Explicitly forwarding visibility and then
663    # excluding it from the "*" set works around this problem.
664    # See http://crbug.com/594610
665    forward_variables_from(invoker, [ "visibility" ])
666    forward_variables_from(invoker, "*", [ "visibility" ])
667  }
668}
669
670# Component defaults
671set_defaults("component") {
672  if (is_component_build) {
673    configs = default_shared_library_configs
674    if (is_android) {
675      configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
676    }
677  } else {
678    configs = default_compiler_configs
679  }
680}
681