blob: 60a71c30c709049b9a1e6d9094763cdd6ce877b4 [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/fuchsia/zircon_legacy_vars.gni")
import("//build/rust/config.gni")
import("//build/toolchain/ccache.gni")
assert(current_os == "fuchsia")
declare_args() {
# Build ID algorithm to use for Fuchsia-target code. This does not apply
# to host or guest code. The value is the argument to the linker's
# `--build-id=...` switch. If left empty (the default), the linker's
# default format is used.
build_id_format = ""
}
# Deprecated.
# TODO(44795): Remove once none of the petals depend on this.
config("werror") {
configs = [ "//build/config:werror" ]
}
config("icf") {
# This changes C/C++ semantics and might be incompatible with third-party
# code that relies on function pointers comparison.
ldflags = [ "-Wl,--icf=all" ]
}
# ccache, at least in some configurations, caches preprocessed content. This
# means that by the time the compiler sees it, macros are unrolled. A number
# of gcc and clang diagnostics are conditioned on whether the source is part
# of a macro or not. This is because a "reasonable" looking macro invocation
# may end up doing something silly internally. This can mean self assignment
# and tautological comparisons, since macros are not typed. Macros also tend
# to over-parenthesize, and so on. This particular list of options was found
# via trial and error, and might be the best way of keeping the build quiet.
config("ccache") {
cflags = [
"-Wno-error",
"-Qunused-arguments",
"-Wno-parentheses-equality",
"-Wno-self-assign",
"-Wno-tautological-compare",
"-Wno-unused-command-line-argument",
]
asmflags = cflags
}
config("compiler") {
cflags = []
cflags_c = []
cflags_cc = []
ldflags = [
"-Wl,--pack-dyn-relocs=relr",
# TODO(41982): drop this when it becomes the default in Clang.
"-Wl,-z,now",
]
configs = [
":compiler_sysroot",
":compiler_target",
":compiler_cpu",
]
if (use_ccache) {
configs += [ ":ccache" ]
}
asmflags = cflags + cflags_c
rustflags = [
"-L",
sysroot + "/lib",
"-Clinker=" + rebase_path("$clang_prefix/lld", "", root_build_dir),
"-Clink-arg=--sysroot=" + sysroot,
"-Clink-arg=-L" + sysroot + "/lib",
"-Clink-arg=-L" + clang_resource_dir + "/" + rust_target + "/lib",
"-Clink-arg=--pack-dyn-relocs=relr",
"-Clink-arg=-dynamic-linker=ld.so.1",
"-Clink-arg=--icf=all",
]
lib_dirs = [
# These libraries are required by Rust's libstd.
"$root_build_dir/gen/zircon/public/lib/fdio",
"$root_build_dir/gen/zircon/public/lib/trace-engine",
"$root_build_dir/gen/zircon/public/lib/syslog",
]
if (build_id_format != "") {
ldflags += [ "-Wl,--build-id=$build_id_format" ]
}
}
config("compiler_sysroot") {
# Rather than using --sysroot and populating a sysroot per se, use
# specific compiler switches to find the C library and its headers from
# the Zircon build and source tree directly.
sysroot_include_dirs = []
foreach(entry, zircon_legacy_sysroot) {
if (defined(entry.include_dirs)) {
sysroot_include_dirs += entry.include_dirs
} else if (defined(entry.libc)) {
sysroot_libc = entry.libc
} else if (defined(entry.crt1)) {
sysroot_crt1 = entry.crt1
} else if (defined(entry.vdso)) {
sysroot_vdso = entry.vdso
}
}
# Point the preprocessor at the include directories. Use -idirafter
# so they come in the same place in the search order as the --sysroot
# include directory would: after the compiler-supplied headers,
# allowing those to override and wrap libc headers via #include_next.
cflags = []
foreach(dir, sysroot_include_dirs) {
cflags += [
"-idirafter",
rebase_path(dir, root_build_dir, zircon_root_build_dir),
]
}
asmflags = cflags
# Point the linker at a little directory we populate below. Plain -L
# switches (via lib_dirs) would be sufficient for the implicit -lc and -lm
# from the compiler driver. But Scrt1.o is found only in the sysroot.
ldflags = [ "--sysroot=" + rebase_path(target_gen_dir, root_build_dir) ]
# Use input linker scripts found in the dummy sysroot to redirect to the
# actual Zircon binaries. Because of this indirection (and the linker's
# lack of depfile support), the build system doesn't know about these
# dependencies. So list them as inputs of everything to force re-links
# when they change. This forces recompiles too since this config()
# applies to all compilation targets and not just linking ones, but this
# code only changes when touching core Zircon library sources.
libc = rebase_path(sysroot_libc, "", zircon_root_build_dir)
crt1 = rebase_path(sysroot_crt1, "", zircon_root_build_dir)
vdso = rebase_path(sysroot_vdso, "", zircon_root_build_dir)
inputs = [
libc,
crt1,
vdso,
]
write_file("$target_gen_dir/lib/Scrt1.o", [ "INPUT(${crt1})" ])
write_file("$target_gen_dir/lib/libc.so", [ "INPUT(${libc})" ])
write_file("$target_gen_dir/lib/libdl.so", [ "/* dummy */" ])
write_file("$target_gen_dir/lib/libm.so", [ "/* dummy */" ])
write_file("$target_gen_dir/lib/libpthread.so", [ "/* dummy */" ])
write_file("$target_gen_dir/lib/libzircon.so", [ "INPUT(${vdso})" ])
}
config("compiler_target") {
cflags = [ "--target=$clang_target" ]
asmflags = cflags
ldflags = cflags
}
config("compiler_cpu") {
cflags = []
if (current_cpu == "x64") {
cflags += [
"-march=x86-64",
"-mcx16",
]
}
ldflags = cflags
asmflags = cflags
if (current_cpu == "arm64") {
ldflags += [ "-Wl,--fix-cortex-a53-843419" ]
}
}
config("shared_library_config") {
cflags = [ "-fPIC" ]
}
config("fdio_config") {
# TODO(pylaligand): find a better way to let executables link in fdio.
# Ideally their dependencies should be set up in such a way that it would get
# inherited from them.
foreach(target, zircon_legacy_targets) {
if (target.target_name == "fdio") {
libs = rebase_path(target.libs, "", zircon_root_build_dir)
}
}
# TODO(mcgrathr): //build/go/go_build.gni depends on this because it
# uses -L... -lfdio rather than passing the file directly.
assert(libs == [ libs[0] ], "fdio libs has multiple elements?")
link_file = libs[0]
if (get_path_info(link_file, "file") != "libfdio.so") {
link_file = rebase_path(link_file)
write_file("$target_gen_dir/libfdio.so", [ "INPUT($link_file)" ])
libs[0] = "$target_gen_dir/libfdio.so"
}
}
config("executable_config") {
}
config("thread_safety_annotations") {
cflags = [ "-Wthread-safety" ]
defines = [ "_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS" ]
}
config("auto_var_init") {
# Automatically initialize variables with a pattern.
cflags = [ "-ftrivial-auto-var-init=pattern" ]
}
config("enable_zircon_asserts") {
defines = [ "ZX_ASSERT_LEVEL=2" ]
}
declare_args() {
zircon_asserts = is_debug
}
config("zircon_asserts") {
if (zircon_asserts) {
configs = [ ":enable_zircon_asserts" ]
}
}
config("no_cpp_standard_library") {
ldflags = [ "-nostdlib++" ]
}
config("static_cpp_standard_library") {
ldflags = [ "-static-libstdc++" ]
}
# Configure a larger (2MB) stack size for Rust binaries.
#
# Currently, threads created by Rust's libstd have a hardcoded default stack
# size of 2MB on Fuchsia. This can create overflows when moving code to the
# main thread, whose default stack size is 256kB. To remove this wrinkle, the
# default stack size is changed to 2MB for Rust binaries.
config("large_rust_stack") {
rustflags = [ "-Clink-args=-zstack-size=0x200000" ]
}
# Enable additional integer-math sanitizers
config("integer-paranoia") {
cflags = [
"-fsanitize=integer-divide-by-zero,signed-integer-overflow",
"-fsanitize-undefined-trap-on-error",
]
}