| # 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/fuchsia/zircon.gni") |
| import("//build/toolchain/ccache.gni") |
| |
| assert(current_os == "fuchsia") |
| |
| 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. |
| ] |
| } |
| } |
| |
| 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 = [ "-std=c11" ] |
| cflags_cc = [ "-std=c++17" ] |
| ldflags = [ |
| "-Wl,--threads", |
| "-Wl,--pack-dyn-relocs=relr", |
| ] |
| configs = [ |
| ":compiler_sysroot", |
| ":compiler_target", |
| ":compiler_cpu", |
| ":toolchain_version_stamp", |
| ] |
| if (use_ccache) { |
| configs += [ ":ccache" ] |
| } |
| asmflags = cflags + cflags_c |
| } |
| |
| config("toolchain_version_stamp") { |
| # 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 a synthetic define into the compile line. |
| cipd_version = read_file( |
| "//buildtools/${host_platform}/clang/.versions/clang.cipd_version", |
| "json") |
| defines = [ "TOOLCHAIN_VERSION=${cipd_version.instance_id}" ] |
| } |
| |
| 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_cc = [ "-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_DEBUGLEVEL=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++" ] |
| } |