blob: f69c66b431be79133b705061b194b4fd4bb71146 [file] [log] [blame]
# 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" ]
},
]
},
]