blob: c276a5701f6b2c1180a0be8a49a110a04bedaa11 [file] [log] [blame]
# Copyright 2016 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("//build/config/clang/clang.gni")
import("//build/config/compiler.gni")
import("//build/rust/config.gni")
import("//build/toolchain/ccache.gni")
import("//build/toolchain/goma.gni")
declare_args() {
# Clang crash reports directory path. Use empty path to disable altogether.
crash_diagnostics_dir = "$root_build_dir/clang-crashreports"
if (is_fuchsia) {
# Controls whether the compiler emits full stack frames for function calls.
# This reduces performance but increases the ability to generate good
# stack traces, especially when we have bugs around unwind table generation.
# It applies only for Fuchsia targets (see below where it is unset).
#
# TODO(ZX-2361): Theoretically unwind tables should be good enough so we can
# remove this option when the issues are addressed.
enable_frame_pointers = is_debug
}
}
# No frame pointers for host compiles.
if (!is_fuchsia) {
enable_frame_pointers = false
}
config("rust_edition_2018") {
rustflags = [ "--edition=2018" ]
}
config("rust_edition_2015") {
rustflags = [ "--edition=2015" ]
}
config("rust_opt_level_z") {
rustflags = [ "-Copt-level=z" ]
}
config("rust_no_features") {
rustflags = [ "-Zallow-features=" ]
}
config("netstack3_only_specialization_feature") {
rustflags = [ "-Zallow-features=specialization" ]
}
config("rust_2018_idioms") {
rustflags = [ "-Wrust-2018-idioms" ]
}
config("rust_target") {
rustflags = [
"--target",
rust_target,
"--cap-lints=$rust_cap_lints",
]
}
config("rust_panic_abort") {
rustflags = [
"-Cpanic=abort",
"-Cforce-unwind-tables=yes",
"-Zpanic_abort_tests",
]
}
config("language") {
cflags_c = [ "-std=c11" ]
cflags_cc = [ "-std=c++17" ]
if (current_os == "mac") {
# macOS needs this to not complain about C++17isms that older macOS
# system libc++ doesn't support. But we use our own toolchain's static
# libc++ anyway.
cflags_cc += [ "-faligned-allocation" ]
# libc++ headers mark some symbols as unavailable on macOS by default
# because the system libc++ doesn't support them. But we use our own
# toolchain's static libc++ anyway.
defines = [ "_LIBCPP_DISABLE_AVAILABILITY" ]
}
}
config("compiler") {
asmflags = []
cflags = [ "-fcolor-diagnostics" ]
cflags_c = []
cflags_cc = [ "-fvisibility-inlines-hidden" ]
cflags_objc = []
cflags_objcc = [ "-fvisibility-inlines-hidden" ]
ldflags = []
defines = []
configs = [
":toolchain_version_stamp",
":rust_panic_cfg",
]
if (current_os == "fuchsia") {
configs += [ "//build/config/fuchsia:compiler" ]
} else {
cflags_cc += [ "-stdlib=libc++" ]
if (current_os == "linux") {
configs += [ "//build/config/linux:compiler" ]
} else if (current_os == "mac") {
configs += [ "//build/config/mac:compiler" ]
}
}
# Linker on macOS does not support `color-diagnostics`
if (current_os != "mac") {
ldflags += [ "-Wl,--color-diagnostics" ]
}
if (crash_diagnostics_dir != "") {
cflags += [ "-fcrash-diagnostics-dir=" +
rebase_path(crash_diagnostics_dir, root_build_dir) ]
}
asmflags += cflags
asmflags += cflags_c
}
# We want to force a recompile and relink of the world whenever our toolchain
# changes since artifacts from an older version of the toolchain may or may not
# be compatible with newer ones.
#
# To achieve this, we insert an unused flag in the compile line.
config("toolchain_version_stamp") {
if (clang_prefix == default_clang_prefix) {
clang_version = read_file(
"//prebuilt/third_party/clang/${host_platform}/.versions/clang.cipd_version",
"json")
defines = [ "TOOLCHAIN_VERSION=${clang_version.instance_id}" ]
}
if (rustc_prefix == default_rustc_prefix) {
rustc_version = read_file(
"//prebuilt/third_party/rust/${host_platform}/.versions/rust.cipd_version",
"json")
rustflags = [ "--cfg=__rust_toolchain=\"${rustc_version.instance_id}\"" ]
}
}
config("relative_paths") {
# Make builds independent of absolute file path. The file names
# embedded in debugging information will be expressed as relative to
# the build directory, e.g. "../.." for an "out/subdir" under //.
#
# This is consistent with the file names in __FILE__ expansions
# (e.g. in assertion messages), which the compiler doesn't provide a
# way to remap. That way source file names in logging and
# symbolization can all be treated the same way. This won't go well
# if $root_build_dir is not a subdirectory of //, but there isn't
# a better option to keep all source file name references uniformly
# relative to a single root. Stripping out per-user or per-config
# path information additionally allows caching compilers (like Goma)
# to reuse compilation results amongst users/configs.
#
# Given a build directory of of the form
# "/xxx/yyy/fuchsia/out/my-config-name", we want to normalize as
# follows:
#
# /xxx/yyy/fuchsia/out/my-config-name → .
# /xxx/yyy/fuchsia/out/my-config-name.zircon → ../my-config-name.zircon
# /xxx/yyy/fuchsia/out → ..
# /xxx/yyy/fuchsia/src → ../src
#
# GCC and Clang only perform naïve prefix matching, so we need to
# match replace multiple prefixes
# ("/xxx/yyy/fuchsia/out/my-config-name", "/xxx/yyy/fuchsia/out",
# "/xxx/yyy/fuchsia") to avoid excess path information leaking into
# the debug symbols.
if (use_goma) {
# TODO(TC-585): `-fdebug-prefix-map` is also used by Goma to canonicalize
# build commands, allowing it to reuse compilation results for users running
# out of different working directories. However, it only supports a single
# "-fdebug-prefix-map" prefix. Attempting to provide more than one causes
# canonicalization to fail, meaning that builds running out of different
# directories won't share cache results. For now, we just provide a single
# debug-prefix-map, even though more would be ideal.
# Map "/some/dir/fuchsia" to "../..".
cflags = [ "-fdebug-prefix-map=" + rebase_path("//") + "=" +
rebase_path("//", root_build_dir) ]
} else {
cflags = [
# Map "/some/dir/fuchsia/out/my-build.my-arch" to ".".
"-fdebug-prefix-map=" + rebase_path(root_build_dir) + "=.",
# Map "/some/dir/fuchsia/out" to "..".
"-fdebug-prefix-map=" + rebase_path("$root_build_dir/..") + "=..",
# Map "/some/dir/fuchsia" to "../..".
"-fdebug-prefix-map=" + rebase_path("//.") + "=" +
rebase_path("//.", root_build_dir),
]
}
rustflags = [
"--remap-path-prefix",
rebase_path("//") + "=" + rebase_path("//", root_build_dir),
]
cflags += [
# This makes sure that include directories in the toolchain are
# represented as relative to the build directory (because that's how
# we invoke the compiler), rather than absolute. This can affect
# __FILE__ expansions (e.g. assertions in system headers). We
# normally run a compiler that's someplace within the source tree
# (//prebuilt/...), so its absolute installation path will have a
# prefix matching absolute_path and hence be mapped to relative_path
# in the debugging information, so this should actually be
# superfluous for purposes of the debugging information.
"-no-canonical-prefixes",
]
asmflags = cflags
ldflags = cflags
}
config("debug") {
# TODO(phosek): remove this config when nothing refers on it.
}
config("release") {
defines = [ "NDEBUG=1" ]
}
config("exceptions") {
cflags_cc = [ "-fexceptions" ]
cflags_objcc = cflags_cc
ldflags = cflags_cc
}
config("no_exceptions") {
cflags_cc = [ "-fno-exceptions" ]
cflags_objcc = cflags_cc
ldflags = cflags_cc
}
config("rtti") {
cflags_cc = [ "-frtti" ]
cflags_objcc = cflags_cc
ldflags = cflags_cc
}
config("no_rtti") {
cflags_cc = [ "-fno-rtti" ]
cflags_objcc = cflags_cc
ldflags = cflags_cc
}
config("default_include_dirs") {
include_dirs = [
"//",
root_gen_dir,
]
}
config("linker_gc") {
cflags = [
"-fdata-sections",
"-ffunction-sections",
]
ldflags = cflags
if (current_os == "mac") {
ldflags += [ "-Wl,-dead_strip" ]
} else {
ldflags += [ "-Wl,--gc-sections" ]
}
}
config("linker_string_merging") {
if (current_os == "win") {
ldflags = [ "-Wl,/opt:lldtailmerge" ]
} else if (current_os != "mac") {
ldflags = [ "-Wl,-O2" ]
}
}
# Each optimize_$optimize config below corresponds to a single setting that's
# controlled by the optimize argument. The default_optimize level is set to
# optimize_$optimize for convenience, but individual targets can override their
# optimization level by remove default_optimize and manually applying one of
# the configs below.
#
# The linker_gc_$optimize configs are an exact parallel. default_linker_gc
# is separate from default_optimize so it can be removed separately.
# NOTE: Keep in sync with //zircon/public/gn/config/BUILD.gn
config("optimize_none") {
cflags = [ "-O0" ]
ldflags = cflags
rustflags = [ "-Copt-level=0" ]
}
config("optimize_debug") {
if (false) {
# TODO(phosek): consider different settings to improve performance.
# -Og is what the compiler documents as "optimize the debugging
# experience", but zxdb team has reported Clang's -Og is problematic.
# This should have a bug# for a detailed bug about -Og and/or Rust-O1
# making debugging difficult in known specific reproducible ways.
cflags = [ "-Og" ]
ldflags = cflags
rustflags = [ "-Copt-level=1" ]
} else {
configs = [ ":optimize_none" ]
}
}
config("optimize_default") {
cflags = [ "-O2" ]
ldflags = cflags
rustflags = [ "-Copt-level=2" ]
}
config("optimize_size") {
cflags = [ "-Oz" ]
ldflags = cflags
rustflags = [ "-Copt-level=z" ]
configs = [ ":linker_string_merging" ]
}
config("optimize_speed") {
cflags = [ "-O3" ]
ldflags = cflags
# TODO(phosek): this should be the same as for C/C++.
rustflags = [ "-Copt-level=z" ]
configs = [ ":linker_string_merging" ]
}
config("optimize_sanitizer") {
# TODO(51509): Probably should use a different default.
configs = [ ":optimize_none" ]
}
config("optimize_profile") {
# TODO(51509): Perhaps use a different default.
configs = [ ":optimize_none" ]
}
config("default_optimize") {
configs = [ ":optimize_${optimize}" ]
}
config("linker_gc_none") {
# No linker GC when wholly unoptimized.
}
# Linker GC is a good default for most cases.
config("linker_gc_debug") {
configs = [ ":linker_gc" ]
}
config("linker_gc_default") {
configs = [ ":linker_gc" ]
}
config("linker_gc_size") {
configs = [ ":linker_gc" ]
}
config("linker_gc_speed") {
configs = [ ":linker_gc" ]
}
config("linker_gc_sanitizer") {
# TODO(51487): Enable when known rust/asan interaction bug is fixed.
}
config("linker_gc_profile") {
# TODO(51509): See if we can enable linker GC for profile.
}
config("default_linker_gc") {
configs = [ ":linker_gc_$optimize" ]
}
config("minimal_symbols") {
cflags = [ "-gline-tables-only" ]
asmflags = cflags
ldflags = cflags
rustflags = [ "-Cdebuginfo=1" ]
}
config("symbols") {
cflags = [ "-g3" ]
asmflags = cflags
ldflags = cflags
rustflags = [ "-Cdebuginfo=2" ]
}
config("no_symbols") {
cflags = [ "-g0" ]
asmflags = cflags
ldflags = cflags
rustflags = [ "-Cdebuginfo=0" ]
}
# Default symbols.
config("default_symbols") {
if (symbol_level == 0) {
configs = [ ":no_symbols" ]
} else if (symbol_level == 1) {
configs = [ ":minimal_symbols" ]
} else if (symbol_level == 2) {
configs = [ ":symbols" ]
} else {
assert(symbol_level >= 0 && symbol_level <= 2)
}
}
config("default_frame_pointers") {
if (enable_frame_pointers) {
configs = [ ":frame_pointers" ]
} else {
configs = [ ":no_frame_pointers" ]
}
}
config("frame_pointers") {
cflags = [ "-fno-omit-frame-pointer" ]
ldflags = cflags
rustflags = [ "-Cforce-frame-pointers" ]
}
config("no_frame_pointers") {
cflags = [ "-fomit-frame-pointer" ]
ldflags = cflags
# rustc automatically does this for release builds, and there's no way to
# force it for non-release.
}
config("default_warnings") {
cflags = [
"-Wall",
"-Wextra",
"-Wnewline-eof",
"-Wno-unused-parameter",
"-Wno-unknown-warning-option",
# TODO(35965): Temporarily disable C99 designator warnings introduced in
# https://reviews.llvm.org/D59754. After the new Clang toolchain lands
# and we do some cleanup, this will be re-enabled.
"-Wno-unknown-warning-option",
"-Wno-c99-designator",
# TODO(37215): Temporarily disable this warning until we roll toolchain.
# Then we can re-enable it and cleanup instances it appears.
"-Wno-int-in-bool-context",
# TODO(37765): Keep this flag here while it is enabled in ZN to keep the
# flags unified.
"-Wno-address-of-packed-member",
# TODO(43681): Temporarily disable this warning until we roll toolchain,
# then come back and fix the instances this appears after rolling.
"-Wno-range-loop-analysis",
# TODO(49143): Temporarily disable this warning until we disable it
# individually for affected third_party libraries.
"-Wno-deprecated-declarations",
]
cflags_cc = [
# TODO(38640): Keep this flag here while it is enabled in ZN to keep the
# flags unified.
"-Wno-deprecated-copy",
# TODO(45689): Temporarily disable this warning until we roll toolchain,
# then come back and fix the instances this appears after rolling.
"-Wno-non-c-typedef-for-linkage",
]
}
config("Wno-reorder-init-list") {
cflags = [ "-Wno-reorder-init-list" ]
}
config("Wno-unused-function") {
cflags = [ "-Wno-unused-function" ]
}
config("symbol_visibility_hidden") {
# Disable libc++ visibility annotations to make sure that the compiler option
# has effect on symbols defined in libc++ headers. Note that we don't want to
# disable these annotations altogether to ensure that our toolchain is usable
# outside of our build since not every user uses hidden visibility by default.
defines = [ "_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS" ]
cflags = [ "-fvisibility=hidden" ]
}
config("symbol_no_undefined") {
if (current_os == "mac") {
ldflags = [ "-Wl,-undefined,error" ]
} else {
ldflags = [ "-Wl,--no-undefined" ]
}
}
config("shared_library_config") {
configs = []
cflags = []
if (current_os == "fuchsia") {
configs += [ "//build/config/fuchsia:shared_library_config" ]
} else if (current_os == "linux") {
cflags += [ "-fPIC" ]
} else if (current_os == "mac") {
configs += [ "//build/config/mac:mac_dynamic_flags" ]
}
}
config("executable_config") {
configs = []
if (current_os == "fuchsia") {
configs += [ "//build/config/fuchsia:executable_config" ]
} else if (current_os == "mac") {
configs += [
"//build/config/mac:mac_dynamic_flags",
"//build/config/mac:mac_executable_flags",
]
}
}
config("default_libs") {
configs = []
if (current_os == "mac") {
configs += [ "//build/config/mac:default_libs" ]
}
}
config("no-shadow-call-stack") {
if (current_cpu == "arm64") {
cflags = [ "-fsanitize=no-shadow-call-stack" ]
}
}
# Defines a Rust cfg flag with the value of the rust_panic build arg.
# Useful for changing behavior of code based on panic behavior.
config("rust_panic_cfg") {
rustflags = [ "--cfg=rust_panic=\"${rust_panic}\"" ]
}
config("werror") {
if (!use_ccache) {
cflags = [
"-Werror",
# Declarations marked as deprecated should cause build failures, rather
# they should emit warnings to notify developers about the use of
# deprecated interfaces.
"-Wno-error=deprecated-declarations",
# Do not add additional -Wno-error to this config.
]
}
rustflags = [ "-Dwarnings" ]
}
config("temporarily_disable_ubsan_do_not_use") {
cflags = [ "-fno-sanitize=undefined" ]
}
config("no_stack_protector") {
cflags = [ "-fno-stack-protector" ]
}
config("no_sanitizers") {
cflags = [
"-fno-sanitize=all",
"-fsanitize-coverage=0",
]
configs = [ ":no_stack_protector" ]
}