| # Copyright 2019 The Fuchsia Authors | 
 | # | 
 | # Use of this source code is governed by a MIT-style | 
 | # license that can be found in the LICENSE file or at | 
 | # https://opensource.org/licenses/MIT | 
 |  | 
 | # TODO(fxbug.dev/54160): Keep this in sync with BUILD.zircon.gn | 
 | import("//build/config/zircon/standard.gni") | 
 | import("//build/toolchain/zircon/zircon_toolchain_suite.gni") | 
 | import("//build/unification/global_variables.gni") | 
 | import("//zircon/kernel/params.gni") | 
 |  | 
 | # Define an empty kernel-specific toolchain suite for now. | 
 | # This is needed for the benefit of vdso-code-header but | 
 | # it not actually used to build anything yet due to redirections. | 
 | if (current_toolchain == default_toolchain) { | 
 |   # In the default toolchain, just define the kernel toolchains. | 
 |   foreach(cpu, standard_fuchsia_cpus) { | 
 |     zircon_toolchain_suite("kernel_$cpu") { | 
 |       cpu = cpu | 
 |       os = "fuchsia" | 
 |       environment = "kernel" | 
 |  | 
 |       toolchain_variant_args = { | 
 |         # IMPORTANT: This definition currently lacks the appropriate | 
 |         # `remove_common_configs` and `configs` to really build anything | 
 |         # for the Zircon kernel per se. This will be addressed in the | 
 |         # near future. | 
 |         tags = [ | 
 |           "kernel", | 
 |           "standalone", | 
 |         ] | 
 |       } | 
 |  | 
 |       # NOTE: kernel artifacts currently do not build under fuzzer | 
 |       # variants. This was also true with the Zircon build, but | 
 |       # the Fuchsia build never invoked it with corresponding | 
 |       # variant selectors. Using an exclude_variant_tag is | 
 |       # enough to fix the issue. | 
 |       exclude_variant_tags = [ "fuzzer" ] | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | if (is_kernel) { | 
 |   config("headers") { | 
 |     include_dirs = [ | 
 |       "include", | 
 |       "lib/libc/include", | 
 |     ] | 
 |     configs = [ "lib/libc:limits-dummy" ] | 
 |   } | 
 |  | 
 |   # For any standalone static binary. | 
 |   config("standalone") { | 
 |     ldflags = [ | 
 |       "-nostdlib", | 
 |       "-static", | 
 |     ] | 
 |  | 
 |     cflags = [ | 
 |       "-ffreestanding", | 
 |       "-include", | 
 |       rebase_path("include/hidden.h", root_build_dir), | 
 |  | 
 |       # We want `.debug_frame` for the kernel (fxbug.dev/30023).  And we still want | 
 |       # asynchronous unwind tables.  Alas there's (currently) no way to | 
 |       # achieve this with our GCC.  At the moment we compile with | 
 |       # `-fno-omit-frame-pointer`, which is good because we link with | 
 |       # `--gc-sections`, which means `.eh_frame` gets discarded so GCC-built | 
 |       # kernels don't have any unwind info (except for assembly)!  Assembler | 
 |       # code has its own way of requesting `.debug_frame` vs `.eh_frame` with | 
 |       # the `.cfi_sections` directive. | 
 |       "-fno-unwind-tables", | 
 |     ] | 
 |  | 
 |     cflags_cc = [ | 
 |       # Underlying kernel heap only has default alignment of 8 bytes, so pass | 
 |       # this to the compiler as the default new alignment. | 
 |       "-faligned-new=8", | 
 |     ] | 
 |  | 
 |     if (current_cpu == "x64") { | 
 |       # This only matters in an environment where interrupt handlers might | 
 |       # push trap frames in the same privilege level, like the kernel. | 
 |       # e.g. Multiboot probably doesn't actually need it, but it doesn't hurt. | 
 |       cflags += [ "-mno-red-zone" ] | 
 |     } else if (current_cpu == "arm64") { | 
 |       # This matters if vector registers are not available, e.g. in the kernel | 
 |       # since the they hold unsaved user state, or in the physmem environment | 
 |       # because they might not be enabled in hardware yet. | 
 |       if (!is_gcc) { | 
 |         cflags += [ "-mgeneral-regs-only" ] | 
 |       } else { | 
 |         # TODO(mcgrathr): To work around a GCC bug we have to sneak | 
 |         # -mgeneral-regs-only in through an arcane mechanism.  See | 
 |         # //zircon/kernel/lib/arch/arm64/include/lib/arch/intrin.h for details. | 
 |         cflags += [ | 
 |           "-include", | 
 |           rebase_path("arch/arm64/general-regs-only.h", root_build_dir), | 
 |         ] | 
 |       } | 
 |     } | 
 |  | 
 |     if (is_gcc && current_os == "fuchsia") { | 
 |       cflags += [ "-fpie" ] | 
 |     } | 
 |  | 
 |     if (!is_gcc && current_os == "fuchsia") { | 
 |       # In the Fuchsia-target toolchains there's no way to prevent the | 
 |       # compiler driver from passing -pie, so negate it.  BFD ld doesn't | 
 |       # have --no-pie, but arm64-elf-gcc doesn't pass -pie either. | 
 |       ldflags += [ "-Wl,--no-pie" ] | 
 |     } | 
 |  | 
 |     if (!is_gcc) { | 
 |       # Disable the implicit addition of toolchain-provided libraries to | 
 |       # the link by the compiler driver.  No toolchain-provided library is | 
 |       # compatible with the kernel's internal ABI. | 
 |       # | 
 |       # TODO(fxbug.dev/27356): Clang doesn't have a single straightforward switch to | 
 |       # disable all such libraries, though it certainly should.  It | 
 |       # provides separate switches to disable the profiling/coverage | 
 |       # runtime and to disable all the flavors of runtime implied by | 
 |       # -fsanitize=... switches (including any such defaults).  It will | 
 |       # still provide other incompatible libraries to the link, but they | 
 |       # won't have any effect since they don't define any symbols the link | 
 |       # needs.  However, this is a fragile situation that could easily | 
 |       # break. | 
 |       ldflags += [ | 
 |         "-noprofilelib", | 
 |         "-fno-sanitize-link-runtime", | 
 |       ] | 
 |     } | 
 |  | 
 |     configs = [ "$zx_build_config:no_exceptions" ] | 
 |   } | 
 |  | 
 |   config("warnings") { | 
 |     cflags = [ | 
 |       "-Wformat=2", | 
 |       "-Wvla", | 
 |     ] | 
 |  | 
 |     # GCC supports `-Wformat-signedness` but Clang currently does not. | 
 |     if (is_gcc) { | 
 |       cflags += [ "-Wformat-signedness" ] | 
 |     } | 
 |  | 
 |     cflags_c = [ "-Wmissing-prototypes" ] | 
 |   } | 
 | } else {  # is_kernel | 
 |   group("tests") { | 
 |     testonly = true | 
 |     deps = [ | 
 |       "dev/coresight/tests($host_toolchain)", | 
 |       "lib/acpi_lite:tests", | 
 |       "lib/devicetree/tests", | 
 |       "lib/heap/cmpctmalloc/tests($host_toolchain)", | 
 |     ] | 
 |   } | 
 | } |