| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//zircon/public/gn/prebuilt.gni") |
| import("//zircon/public/gn/toolchain/clang.gni") |
| |
| # All the $current_cpu values that `current_os == "fuchsia"` supports. |
| standard_fuchsia_cpus = [ |
| "arm64", |
| "x64", |
| ] |
| |
| # All the {cpu, os} combinations supported as build or SDK hosts. The |
| # build will define toolchains for all of these. Successful |
| # cross-compilation may require that a sysroot be installed and configured. |
| standard_build_hosts = [ |
| { |
| cpu = "arm64" |
| os = "linux" |
| }, |
| { |
| cpu = "x64" |
| os = "linux" |
| }, |
| ] |
| |
| # Default value for $sysroot build argument. |
| standard_sysroot = [] |
| foreach(host, standard_build_hosts) { |
| standard_sysroot += [ |
| { |
| cpu = host.cpu |
| os = host.os |
| sysroot = "$prebuilt_dir/third_party/sysroot/linux" |
| }, |
| ] |
| } |
| |
| declare_args() { |
| # Path to Mac SDK. |
| mac_sdk_path = "" |
| } |
| |
| # Cross-compiling to Mac isn't possible because of the Mach-O linker. |
| if (host_os == "mac") { |
| standard_build_hosts += [ |
| { |
| cpu = host_cpu |
| os = "mac" |
| }, |
| ] |
| if (mac_sdk_path == "") { |
| mac_sdk_path = exec_script("/usr/bin/xcrun", |
| [ |
| "--sdk", |
| "macosx", |
| "--show-sdk-path", |
| ], |
| "trim string") |
| } |
| if (mac_sdk_path != "") { |
| standard_sysroot += [ |
| { |
| cpu = host_cpu |
| os = "mac" |
| sysroot = mac_sdk_path |
| }, |
| ] |
| } |
| } |
| |
| # Universal configs that apply to all code in the build. |
| standard_configs = [ |
| "//build/config/zircon:compiler", |
| "//build/config/zircon:language", |
| "//build/config/zircon:machine", |
| "//build/config/zircon:relative_paths", |
| "//build/config/zircon:assert_level", |
| "//build/config/zircon:default_optimize", |
| "//build/config/zircon:default_debuginfo", |
| "//build/config/zircon:default_warnings", |
| "//build/config/zircon:default_icf", |
| "//build/config/zircon:default_include_dirs", |
| "//build/config/zircon:default_frame_pointers", |
| "//build/config/zircon:default_linker_gc", |
| "//build/config/zircon:default_template_backtrace_limit", |
| "//build/config/zircon:no_exceptions", |
| "//build/config/zircon:no_rtti", |
| "//build/config/zircon:thread_safety_annotations", |
| "//build/config/zircon:warn-implicit-fallthrough", |
| "//build/config/zircon:visibility_hidden", |
| "//build/config/zircon:auto_var_init", |
| "//build/config/zircon:werror", |
| |
| { |
| # Additional configs apply only to code built into shared libraries. |
| # This means everything in a ${toolchain.shlib} toolchain, not just code |
| # directly in the `sources` of a shared_library() or library() target. |
| shlib = true |
| add = [ |
| "//build/config/zircon:shared_library_config", |
| "//build/config/zircon:no_undefined_symbols", |
| ] |
| }, |
| ] |
| |
| # Additional configs apply to code built for Fuchsia but not to host code. |
| standard_fuchsia_configs = [] |
| |
| # See environment(). These are the environments that are |
| # vanilla bases to make derived environments from. |
| standard_environments = [ |
| { |
| name = "host" |
| targets = standard_build_hosts |
| globals = { |
| is_host = true |
| } |
| |
| # Ensure that host binaries have __zx_panic. |
| implicit_deps = [ "//zircon/system/ulib/zx-panic-libc" ] |
| strip = true |
| }, |
| { |
| name = "user" |
| targets = [] |
| foreach(cpu, standard_fuchsia_cpus) { |
| targets += [ |
| { |
| cpu = cpu |
| }, |
| ] |
| } |
| configs = standard_fuchsia_configs |
| configs += [ |
| "//build/config/zircon:user", |
| { |
| shlib = false |
| add = [ "//build/config/zircon:user_executable" ] |
| }, |
| { |
| # All drivers use hidden visibility and the static standard C++ library. |
| types = [ |
| "driver", |
| "test_driver", |
| ] |
| add = [ "//build/config/zircon:static-libc++" ] |
| }, |
| ] |
| implicit_deps = [ |
| "//zircon/system/ulib/c", |
| { |
| types = [ |
| "executable", |
| "host_tool", |
| "test", |
| ] |
| add = [ |
| "//zircon/system/ulib/c:crt1", |
| "//build/config/zircon:maybe_scudo_default_options", |
| ] |
| }, |
| ] |
| shlib = true |
| strip = "--strip-sections" |
| }, |
| ] |
| |
| # These `standard*variants` lists have the same structure as $variants (see |
| # //zircon/public/gn/toolchain/environment.gni) but it just supply definitions |
| # of variants with standard names. The $variants list can refer to |
| # variants defined here by name, but these are not otherwise involved in |
| # variant selection. |
| standard_variants = [] |
| |
| # These are the baseline variants. $default_variants refers only to things |
| # defined here. |
| standard_base_variants = [ |
| { |
| variant = { |
| name = "clang" |
| } |
| }, |
| { |
| variant = { |
| name = "gcc" |
| tags = [ "gcc" ] |
| globals = { |
| is_gcc = true |
| } |
| } |
| }, |
| ] |
| standard_variants += standard_base_variants |
| |
| if (clang_tool_dir == "") { |
| _llvm_symbolizer_path = "llvm-symbolizer" |
| } else { |
| _llvm_symbolizer_path = |
| rebase_path("$clang_tool_dir/llvm-symbolizer", root_build_dir) |
| } |
| |
| # These are variants that use "sanitizer" instrumentation. |
| # They are interesting for e.g. fuzzer environments. |
| standard_sanitizer_variants = [ |
| { |
| variant = { |
| name = "asan" |
| configs = [ |
| # ASan wants frame pointers because it captures stack traces |
| # on allocations and such, not just on errors. |
| { |
| # First add and then remove both in case either is already there. |
| add = [ |
| "//build/config/zircon:frame_pointers", |
| "//build/config/zircon:default_frame_pointers", |
| ] |
| remove = add |
| }, |
| |
| # Now add frame_pointers back, only one and no default_frame_pointers. |
| "//build/config/zircon:frame_pointers", |
| "//zircon/public/gn/config/instrumentation:asan", |
| ] |
| toolchain_vars = { |
| # This is the key for toolchain_runtime_deps() to find the right |
| # shared library dependencies for the instrumentation. Note that |
| # the asan runtime includes ubsan but not vice versa, so this set |
| # must be used in preference to ubsan when both are enabled. |
| runtime_deps_cflags = [ "-fsanitize=address" ] |
| |
| # This is picked up by the runtime for host_tool_action() runs. |
| host_run_env = [ |
| "/usr/bin/env", |
| "ASAN_SYMBOLIZER_PATH=$_llvm_symbolizer_path", |
| ] |
| } |
| implicit_deps = [ |
| { |
| types = [ |
| "executable", |
| "host_tool", |
| "test", |
| ] |
| add = [ |
| "//zircon/public/gn/config/instrumentation:asan_default_options", |
| ] |
| }, |
| ] |
| tags = [ |
| "asan", |
| "instrumentation-runtime", |
| "instrumented", |
| "lsan", |
| "replaces-allocator", |
| "useronly", |
| ] |
| } |
| }, |
| { |
| variant = { |
| name = "ubsan" |
| configs = [ |
| { |
| add = [ "//zircon/public/gn/config/instrumentation:ubsan" ] |
| |
| # The vptr instrumentation requires RTTI. If -fno-rtti is passed |
| # then this checking is implicitly disabled. However, another |
| # translation unit built without -fno-rtti will have the checking |
| # enabled. The -fno-rtti vtables are not compatible with the |
| # checking at runtime, so a vtable from a -fno-rtti TU used by code |
| # from a -frtti TU gets false positive failures. Since the vtables |
| # are emitted in multiple TUs in COMDAT and one implementation chosen |
| # randomly at link time, there's no way to be sure the checking code |
| # requiring RTTI uses its own RTTI-enabled vtables rather than other |
| # non-RTTI vtables. So just let RTTI be enabled everywhere, and then |
| # get the vptr checking everywhere too. |
| remove = [ "//zircon/public/gn/config:no_rtti" ] |
| }, |
| ] |
| toolchain_vars = { |
| # This is the key for toolchain_runtime_deps() to find the right |
| # shared library dependencies for the instrumentation. Note that |
| # the asan runtime includes ubsan but not vice versa, so this set |
| # should be ignored and the asan set used instead. |
| runtime_deps_cflags = [ "-fsanitize=undefined" ] |
| |
| # This is picked up by the runtime for host_tool_action() runs. |
| # Note this is replaced with asan's setting as mentioned above. |
| host_run_env = [ |
| "/usr/bin/env", |
| "UBSAN_SYMBOLIZER_PATH=$_llvm_symbolizer_path", |
| ] |
| } |
| implicit_deps = [ |
| { |
| types = [ |
| "executable", |
| "host_tool", |
| "test", |
| ] |
| add = [ |
| "//zircon/public/gn/config/instrumentation:ubsan_default_options", |
| ] |
| |
| # The asan runtime trumps the standalone ubsan runtime and the |
| # `__ubsan_default_options()` would go unused. |
| unless_configs = [ "//zircon/public/gn/config/instrumentation:asan" ] |
| }, |
| ] |
| tags = [ |
| "instrumentation-runtime", |
| "instrumented", |
| "useronly", |
| ] |
| } |
| }, |
| { |
| variant = { |
| name = "asan-ubsan" |
| bases = [ |
| # Note ubsan comes first so that asan's runtime_deps_cflags setting |
| # can override it. Later bases append to configs and |
| # implicit_deps, but each toolchain_vars field just replaces any |
| # value set by the earlier base. |
| "ubsan", |
| "asan", |
| ] |
| } |
| }, |
| ] |
| standard_variants += standard_sanitizer_variants |
| |
| # These are additional standard variants that are not likely to |
| # be interesting for special-purpose environments like fuzzers. |
| standard_variants += [ |
| { |
| # TODO(fxbug.dev/30033): This is identical to "asan" except for having "kernel" |
| # and not "useronly" in tags. When kernel ASan is ready for prime |
| # time, this will be removed and the "useronly" tag dropped from "asan" |
| # so that a simple "asan" selector will enable it for kernel too. For |
| # now, it's easier to let a simple "kasan" selector enable kernel ASan |
| # and not user ASan, and "asan" vice versa. |
| variant = { |
| name = "kasan" |
| configs = [ |
| # ASan wants frame pointers because it captures stack traces |
| # on allocations and such, not just on errors. |
| { |
| # First add and then remove both in case either is already there. |
| add = [ |
| "//build/config/zircon:frame_pointers", |
| "//build/config/zircon:default_frame_pointers", |
| ] |
| remove = add |
| }, |
| |
| # Now add frame_pointers back, only one and no default_frame_pointers. |
| "//build/config/zircon:frame_pointers", |
| |
| # kasan disables safestack for all files built with instrumentation, so |
| # we need to ensure that files built without instrumentation have a |
| # consistent no_safestack setting. |
| "//build/config/zircon:no_safestack", |
| |
| "//zircon/public/gn/config/instrumentation:asan", |
| ] |
| toolchain_vars = { |
| # This is the key for toolchain_runtime_deps() to find the right |
| # shared library dependencies for the instrumentation. Note that |
| # the asan runtime includes ubsan but not vice versa, so this set |
| # must be used in preference to ubsan when both are enabled. |
| runtime_deps_cflags = [ "-fsanitize=address" ] |
| } |
| implicit_deps = [ |
| { |
| types = [ |
| "executable", |
| "host_tool", |
| "test", |
| ] |
| add = [ |
| "//zircon/public/gn/config/instrumentation:asan_default_options", |
| ] |
| }, |
| ] |
| tags = [ |
| "instrumentation-runtime", |
| "instrumented", |
| "kernel", |
| ] |
| } |
| }, |
| |
| # TODO(fxbug.dev/30033): see above |
| { |
| variant = { |
| name = "kasan-sancov" |
| bases = [ |
| "kasan", |
| "sancov", |
| ] |
| } |
| }, |
| { |
| variant = { |
| name = "lto" |
| configs = [ "//zircon/public/gn/config/lto" ] |
| tags = [ "lto" ] |
| } |
| }, |
| { |
| variant = { |
| name = "thinlto" |
| configs = [ "//zircon/public/gn/config/lto:thinlto" ] |
| tags = [ "lto" ] |
| } |
| }, |
| { |
| variant = { |
| name = "profile" |
| configs = [ "//zircon/public/gn/config/instrumentation:profile" ] |
| implicit_deps = |
| [ "//zircon/public/gn/config/instrumentation:profile_deps" ] |
| tags = [ |
| "instrumented", |
| |
| # TODO(fxbug.dev/27321): The instrumentation metadata sections are not put |
| # into section groups properly under -ffunction-sections. This |
| # means that links (like the x86 kernel's) that rely for their |
| # correctness on --gc-sections pruning dead code with dangling |
| # references won't work. |
| "breaks-gc-sections", |
| ] |
| } |
| }, |
| { |
| variant = { |
| name = "sancov" |
| configs = [ "//zircon/public/gn/config/instrumentation:sancov" ] |
| |
| # The "sancov" tag is important: see //zircon/system/ulib/c/sanitizers. |
| tags = [ |
| "instrumentation-runtime", |
| "instrumented", |
| "sancov", |
| ] |
| |
| # When no other sanitizer is enabled, clang links in the ubsan |
| # runtime to provide the sancov runtime. |
| toolchain_vars = { |
| runtime_deps_cflags = [ "-fsanitize=undefined" ] |
| } |
| } |
| }, |
| { |
| variant = { |
| name = "ubsan-sancov" |
| bases = [ |
| "ubsan", |
| "sancov", |
| ] |
| } |
| }, |
| { |
| variant = { |
| name = "ubsan-sancov-full" |
| bases = [ |
| "ubsan", |
| "sancov", |
| ] |
| configs = [ "//zircon/public/gn/config/instrumentation:sancov-full" ] |
| |
| # The kernel provides runtime for sancov but not for sancov-full. |
| tags = [ "useronly" ] |
| } |
| }, |
| ] |
| |
| # This list is appended to the $variants list for the build. It provides |
| # default selectors that match if nothing else does. The first catch-all |
| # selector must be compatible with all environments used in |
| # environment_redirect(), |
| default_variants = [ |
| # Use Clang as default for both host and the target. |
| "clang", |
| ] |
| |
| # default_variants only refers to variants in standard_base_variants. |
| foreach(default, default_variants) { |
| if (default == "$default") { |
| _default = default |
| } else { |
| _default = default.variant |
| } |
| assert(_default == "$_default") |
| foreach(selector, standard_base_variants) { |
| _variant = { |
| # Clear from last iteration. |
| } |
| _variant = selector.variant |
| if (_default == _variant.name) { |
| _default = true |
| } |
| } |
| assert(_default == true) |
| } |
| |
| # Define shorthand selectors that can be used in $variants, which see. |
| # This is a list of scopes. Each scope defines one shorthand. |
| # |
| # name |
| # Required: The name that matches a string element of $variants (or the |
| # part of an element before the slash). |
| # Type: string |
| # |
| # selectors |
| # Required: The expansion, a list of selectors. An element of $variants |
| # that matches $name is removed and the $selectors list is spliced into the |
| # list in its place. An element that matches "$name/something" is instead |
| # replaced by this $selectors list with `output_name = "something"` added |
| # to each element. |
| # Type: See $variants. |
| # |
| variant_shorthands = [ |
| { |
| name = "host_gcc" |
| selectors = [ |
| { |
| variant = "gcc" |
| host = true |
| }, |
| ] |
| }, |
| { |
| name = "host_asan" |
| selectors = [ |
| { |
| variant = "asan" |
| host = true |
| }, |
| ] |
| }, |
| { |
| name = "host_asan-ubsan" |
| selectors = [ |
| { |
| variant = "asan-ubsan" |
| host = true |
| }, |
| ] |
| }, |
| { |
| name = "host_profile" |
| selectors = [ |
| { |
| variant = "profile" |
| host = true |
| }, |
| ] |
| }, |
| { |
| name = "asan_drivers" |
| selectors = [ |
| { |
| variant = "asan" |
| target_type = [ "driver" ] |
| }, |
| ] |
| }, |
| ] |