1# Copyright 2016 The Fuchsia Authors 2# Copyright (c) 2008-2015 Travis Geiselbrecht 3# 4# Use of this source code is governed by a MIT-style 5# license that can be found in the LICENSE file or at 6# https://opensource.org/licenses/MIT 7 8LOCAL_MAKEFILE:=$(MAKEFILE_LIST) 9 10# include settings for prebuilts that are auto-updated by checkout scripts 11-include prebuilt/config.mk 12 13# try to include a file in the local dir to let the user semi-permanently set options 14-include local.mk 15include make/macros.mk 16 17# various command line and environment arguments 18# default them to something so when they're referenced in the make instance they're not undefined 19BUILDROOT ?= . 20DEBUG ?= 2 21DEBUG_HARD ?= false 22ENABLE_BUILD_LISTFILES ?= false 23ENABLE_BUILD_SYSROOT ?= false 24ENABLE_BUILD_LISTFILES := $(call TOBOOL,$(ENABLE_BUILD_LISTFILES)) 25ENABLE_BUILD_SYSROOT := $(call TOBOOL,$(ENABLE_BUILD_SYSROOT)) 26ENABLE_INSTALL_SAMPLES ?= false 27ENABLE_NEW_BOOTDATA := true 28ENABLE_LOCK_DEP ?= false 29ENABLE_LOCK_DEP_TESTS ?= $(ENABLE_LOCK_DEP) 30DISABLE_UTEST ?= false 31ENABLE_ULIB_ONLY ?= false 32USE_ASAN ?= false 33USE_SANCOV ?= false 34USE_PROFILE ?= false 35USE_LTO ?= false 36USE_THINLTO ?= $(USE_LTO) 37USE_CLANG ?= $(firstword $(filter true,$(call TOBOOL,$(USE_ASAN)) \ 38 $(call TOBOOL,$(USE_SANCOV)) \ 39 $(call TOBOOL,$(USE_PROFILE)) \ 40 $(call TOBOOL,$(USE_LTO))) \ 41 false) 42USE_LLD ?= $(USE_CLANG) 43ifeq ($(call TOBOOL,$(USE_LLD)),true) 44USE_GOLD := false 45else 46USE_GOLD ?= true 47endif 48THINLTO_CACHE_DIR ?= $(BUILDDIR)/thinlto-cache 49CLANG_TARGET_FUCHSIA ?= false 50USER_USE_LINKER_GC ?= true 51KERNEL_USE_LINKER_GC ?= true 52HOST_USE_ASAN ?= false 53 54ifeq ($(call TOBOOL,$(ENABLE_ULIB_ONLY)),true) 55ENABLE_BUILD_SYSROOT := false 56ifeq (,$(strip $(TOOLS))) 57$(error ENABLE_ULIB_ONLY=true requires TOOLS=build-.../tools on command line) 58endif 59endif 60 61# If no build directory suffix has been explicitly supplied by the environment, 62# generate a default based on build options. Start with no suffix, then add 63# "-clang" if we are building with clang, and "-release" if we are building with 64# DEBUG=0 65ifeq ($(origin BUILDDIR_SUFFIX),undefined) 66BUILDDIR_SUFFIX := 67 68ifeq ($(call TOBOOL,$(USE_ASAN)),true) 69BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-asan 70else ifeq ($(call TOBOOL,$(USE_PROFILE)),true) 71BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-profile 72else ifeq ($(call TOBOOL,$(USE_LTO)),true) 73ifeq ($(call TOBOOL,$(USE_THINLTO)),true) 74BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-thinlto 75else 76BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-lto 77endif 78else ifeq ($(call TOBOOL,$(USE_CLANG)),true) 79BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-clang 80endif 81 82ifeq ($(call TOBOOL,$(DEBUG)),false) 83BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-release 84endif 85 86endif # if BUILDDIR_SUFFIX is empty 87 88# special rule for handling make spotless 89ifeq ($(MAKECMDGOALS),spotless) 90spotless: 91 rm -rf -- "$(BUILDROOT)"/build-* 92else 93 94# If one of our goals (from the commandline) happens to have a 95# matching project/goal.mk, then we should re-invoke make with 96# that project name specified... 97 98project-name := $(firstword $(MAKECMDGOALS)) 99 100ifneq ($(project-name),) 101ifneq ($(strip $(wildcard kernel/project/$(project-name).mk \ 102 kernel/project/alias/$(project-name).mk)),) 103do-nothing := 1 104$(MAKECMDGOALS) _all: make-make 105make-make: 106 @PROJECT=$(project-name) $(MAKE) -rR -f $(LOCAL_MAKEFILE) $(filter-out $(project-name), $(MAKECMDGOALS)) 107 108.PHONY: make-make 109endif 110endif 111 112# some additional rules to print some help 113include make/help.mk 114 115ifeq ($(do-nothing),) 116 117ifeq ($(PROJECT),) 118 119ifneq ($(DEFAULT_PROJECT),) 120PROJECT := $(DEFAULT_PROJECT) 121else 122$(error No project specified. Use 'make list' for a list of projects or 'make help' for additional help) 123endif 124endif 125 126# DEBUG_HARD enables limited optimizations and full debug symbols for use with gdb/lldb 127ifeq ($(call TOBOOL,$(DEBUG_HARD)),true) 128GLOBAL_DEBUGFLAGS := -O0 -g3 129endif 130GLOBAL_DEBUGFLAGS ?= -O2 -g 131 132BUILDDIR := $(BUILDROOT)/build-$(PROJECT)$(BUILDDIR_SUFFIX) 133GENERATED_INCLUDES:=$(BUILDDIR)/gen/global/include 134ZIRCON_BOOTIMAGE := $(BUILDDIR)/zircon.zbi 135KERNEL_ZBI := $(BUILDDIR)/kernel.zbi 136KERNEL_ELF := $(BUILDDIR)/zircon.elf 137KERNEL_IMAGE := $(BUILDDIR)/kernel-image.elf 138GLOBAL_CONFIG_HEADER := $(BUILDDIR)/config-global.h 139KERNEL_CONFIG_HEADER := $(BUILDDIR)/config-kernel.h 140USER_CONFIG_HEADER := $(BUILDDIR)/config-user.h 141HOST_CONFIG_HEADER := $(BUILDDIR)/config-host.h 142GLOBAL_INCLUDES := system/public system/private $(GENERATED_INCLUDES) 143GLOBAL_OPTFLAGS ?= $(ARCH_OPTFLAGS) 144# When embedding source file locations in debugging information, by default 145# the compiler will record the absolute path of the current directory and 146# make everything relative to that. Instead, we tell the compiler to map 147# the current directory to $(DEBUG_BUILDROOT), which is the "relative" 148# location of the zircon source tree (i.e. usually . in a standalone build). 149DEBUG_BUILDROOT ?= $(BUILDROOT) 150GLOBAL_COMPILEFLAGS := $(GLOBAL_DEBUGFLAGS) 151GLOBAL_COMPILEFLAGS += -fdebug-prefix-map=$(shell pwd)=$(DEBUG_BUILDROOT) 152GLOBAL_COMPILEFLAGS += -finline -include $(GLOBAL_CONFIG_HEADER) 153GLOBAL_COMPILEFLAGS += -Wall -Wextra -Wno-multichar -Werror -Wno-error=deprecated-declarations 154GLOBAL_COMPILEFLAGS += -Wno-unused-parameter -Wno-unused-function -Werror=unused-label -Werror=return-type 155GLOBAL_COMPILEFLAGS += -fno-common 156# kernel/include/lib/counters.h and kernel.ld depend on -fdata-sections. 157GLOBAL_COMPILEFLAGS += -ffunction-sections -fdata-sections 158ifeq ($(call TOBOOL,$(USE_CLANG)),true) 159GLOBAL_COMPILEFLAGS += -nostdlibinc 160GLOBAL_COMPILEFLAGS += -no-canonical-prefixes 161GLOBAL_COMPILEFLAGS += -Wno-address-of-packed-member 162GLOBAL_COMPILEFLAGS += -Wthread-safety 163GLOBAL_COMPILEFLAGS += -Wimplicit-fallthrough 164else 165GLOBAL_COMPILEFLAGS += -Wno-nonnull-compare 166# TODO(mcgrathr): New warning in GCC 7 biting a lot of code; figure it out. 167GLOBAL_COMPILEFLAGS += -Wno-format-truncation 168endif 169GLOBAL_CFLAGS := -std=c11 -Werror-implicit-function-declaration -Wstrict-prototypes -Wwrite-strings 170GLOBAL_CPPFLAGS := -std=c++17 -fno-exceptions -fno-rtti -fno-threadsafe-statics -Wconversion -Wno-sign-conversion 171#GLOBAL_CPPFLAGS += -Weffc++ 172GLOBAL_ASMFLAGS := 173GLOBAL_LDFLAGS := -nostdlib --build-id -z noexecstack 174ifeq ($(call TOBOOL,$(USE_LLD)),true) 175GLOBAL_LDFLAGS += --pack-dyn-relocs=relr 176GLOBAL_LDFLAGS += -color-diagnostics 177endif 178# $(addprefix -L,$(LKINC)) XXX 179GLOBAL_MODULE_LDFLAGS := 180 181# By default the sysroot is generated in "sysroot" under 182# the build directory, but this is overrideable 183ifeq ($(BUILDSYSROOT),) 184BUILDSYSROOT := $(BUILDDIR)/sysroot 185else 186# be noisy if we are 187$(info BUILDSYSROOT = $(BUILDSYSROOT)) 188endif 189 190# Kernel compile flags 191KERNEL_INCLUDES := $(BUILDDIR) kernel/include 192KERNEL_COMPILEFLAGS := -ffreestanding -include $(KERNEL_CONFIG_HEADER) 193KERNEL_COMPILEFLAGS += -Wformat=2 -Wvla 194# GCC supports "-Wformat-signedness" but Clang currently does not. 195ifeq ($(call TOBOOL,$(USE_CLANG)),false) 196KERNEL_COMPILEFLAGS += -Wformat-signedness 197endif 198KERNEL_CFLAGS := -Wmissing-prototypes 199KERNEL_CPPFLAGS := 200KERNEL_ASMFLAGS := 201KERNEL_LDFLAGS := 202 203# Build flags for modules that want frame pointers. 204# ngunwind, backtrace use this so that the simplisitic unwinder will work with 205# them. These are recorded here so that modules don't need knowledge of the 206# details. They just need to do: 207# MODULE_COMPILEFLAGS += $(KEEP_FRAME_POINTER_COMPILEFLAGS) 208KEEP_FRAME_POINTER_COMPILEFLAGS := -fno-omit-frame-pointer 209 210# User space compile flags 211USER_COMPILEFLAGS := -include $(USER_CONFIG_HEADER) -fPIC -D_ALL_SOURCE=1 212USER_CFLAGS := 213USER_CPPFLAGS := 214USER_ASMFLAGS := 215 216# Additional flags for dynamic linking, both for dynamically-linked 217# executables and for shared libraries. 218USER_LDFLAGS := \ 219 -z combreloc -z relro -z now -z text \ 220 --hash-style=gnu --eh-frame-hdr 221 222ifeq ($(call TOBOOL,$(USE_LLD)),true) 223USER_LDFLAGS += -z rodynamic 224RODSO_LDFLAGS := 225else 226RODSO_LDFLAGS := -T scripts/rodso.ld 227endif 228 229# Use linker garbage collection if enabled. 230ifeq ($(call TOBOOL,$(KERNEL_USE_LINKER_GC)),true) 231KERNEL_LDFLAGS += --gc-sections 232endif 233ifeq ($(call TOBOOL,$(USER_USE_LINKER_GC)),true) 234USER_LDFLAGS += --gc-sections 235endif 236 237# Turn on -fasynchronous-unwind-tables to get .eh_frame. 238# This is necessary for unwinding through optimized code. 239# The unwind information is part of the loaded binary. It's not that much space 240# and it allows for unwinding of stripped binaries, pc -> source translation 241# can be done offline with, e.g., scripts/symbolize. 242USER_COMPILEFLAGS += -fasynchronous-unwind-tables 243 244# TODO(ZX-2361): Remove frame pointers when libunwind and our tooling agree on 245# unwind tables. Until then compile with frame pointers in debug builds to get 246# high-quality backtraces. 247ifeq ($(call TOBOOL,$(DEBUG)),true) 248USER_COMPILEFLAGS += $(KEEP_FRAME_POINTER_COMPILEFLAGS) 249endif 250 251# We want .debug_frame for the kernel. ZX-62 252# And we still want asynchronous unwind tables. Alas there's (currently) no way 253# to achieve this with our GCC. At the moment we compile with 254# -fno-omit-frame-pointer which is good because we link with -gc-sections which 255# means .eh_frame gets discarded so GCC-built kernels don't have any unwind 256# info (except for assembly - heh)! 257# Assembler code has its own way of requesting .debug_frame vs .eh_frame with 258# the .cfi_sections directive. Sigh. 259KERNEL_COMPILEFLAGS += -fno-exceptions -fno-unwind-tables 260 261ifeq ($(call TOBOOL,$(USE_CLANG)),true) 262NO_SAFESTACK := -fno-sanitize=safe-stack -fno-stack-protector 263NO_SANITIZERS := -fno-sanitize=all -fno-stack-protector 264else 265NO_SAFESTACK := 266NO_SANITIZERS := 267endif 268 269USER_SCRT1_OBJ := $(BUILDDIR)/system/ulib/Scrt1.o 270 271# Additional flags for building shared libraries (ld -shared). 272USERLIB_SO_LDFLAGS := $(USER_LDFLAGS) -z defs 273 274# This is the string embedded into dynamically-linked executables 275# as PT_INTERP. The launchpad library looks this up via the 276# "loader service", so it should be a simple name rather than an 277# absolute pathname as is used for this on other systems. 278USER_SHARED_INTERP := ld.so.1 279 280# Programs built with ASan use the ASan-supporting dynamic linker. 281ifeq ($(call TOBOOL,$(USE_ASAN)),true) 282USER_SHARED_INTERP := asan/$(USER_SHARED_INTERP) 283endif 284 285# Additional flags for building dynamically-linked executables. 286USERAPP_LDFLAGS := \ 287 $(USER_LDFLAGS) -pie -dynamic-linker $(USER_SHARED_INTERP) 288 289ifeq ($(call TOBOOL,$(USE_GOLD)),false) 290# BFD ld stupidly insists on resolving dependency DSO's symbols when 291# doing a -shared -z defs link. To do this it needs to find 292# dependencies' dependencies, which requires -rpath-link. Gold does 293# not have this misfeature. Since ulib/musl needs ulib/zircon and 294# everything needs ulib/musl, this covers the actual needs in the 295# build today without resorting to resolving inter-module dependencies 296# to generate -rpath-link in a general fashion. Eventually we should 297# always use gold or lld for all the user-mode links, and then we'll 298# never need this. 299USERAPP_LDFLAGS += -rpath-link $(BUILDDIR)/ulib/zircon 300endif 301 302# Architecture specific compile flags 303ARCH_COMPILEFLAGS := 304ARCH_CFLAGS := 305ARCH_CPPFLAGS := 306ARCH_ASMFLAGS := 307 308# top level rule 309all:: 310 311# master module object list 312ALLOBJS_MODULE := 313 314# all module objects for the target (does not include hostapp) 315ALL_TARGET_OBJS := 316 317# master object list (for dep generation) 318ALLOBJS := 319 320# master source file list 321ALLSRCS := 322 323# master list of packages for export 324ALLPKGS := 325 326# anything you add here will be deleted in make clean 327GENERATED := 328 329# anything added to GLOBAL_DEFINES will be put into $(BUILDDIR)/config-global.h 330GLOBAL_DEFINES := 331 332# anything added to KERNEL_DEFINES will be put into $(BUILDDIR)/config-kernel.h 333KERNEL_DEFINES := LK=1 _KERNEL=1 ZIRCON_TOOLCHAIN=1 334 335# anything added to USER_DEFINES will be put into $(BUILDDIR)/config-user.h 336USER_DEFINES := ZIRCON_TOOLCHAIN=1 337 338# anything added to HOST_DEFINES will be put into $(BUILDDIR)/config-host.h 339HOST_DEFINES := 340 341# Anything added to GLOBAL_SRCDEPS will become a dependency of every source file in the system. 342# Useful for header files that may be included by one or more source files. 343GLOBAL_SRCDEPS := $(GLOBAL_CONFIG_HEADER) 344 345# Anything added to TARGET_SRCDEPS will become a dependency of every target module file in the system. 346# Useful for header files that may be included by one or more source files. 347TARGET_MODDEPS := 348 349# these need to be filled out by the project/target/platform rules.mk files 350TARGET := 351PLATFORM := 352ARCH := 353ALLMODULES := 354 355# this is the *true* allmodules, to check for duplicate modules 356# (since submodules do not contribute to ALLMODULES) 357DUPMODULES := 358 359# add any external module dependencies 360MODULES := $(EXTERNAL_MODULES) 361 362# any .mk specified here will be included before build.mk 363EXTRA_BUILDRULES := 364 365# any rules you put here will also be built by the system before considered being complete 366EXTRA_BUILDDEPS := 367 368# any rules you put here will be built if the kernel is also being built 369EXTRA_KERNELDEPS := 370 371# any rules you put here will be depended on in clean builds 372EXTRA_CLEANDEPS := 373 374# build ids 375EXTRA_IDFILES := 376 377# All kernel modules contribute to this list. 378ALLMODULE_OBJS := 379 380# userspace apps to build and include in initfs 381ALLUSER_APPS := 382 383# userspace app modules 384ALLUSER_MODULES := 385 386# userspace lib modules 387ALLUSER_LIBS := 388 389# host apps to build 390ALLHOST_APPS := 391 392# host libs to build 393ALLHOST_LIBS := 394 395# EFI libs to build 396ALLEFI_LIBS := 397 398# sysroot (exported libraries and headers) 399SYSROOT_DEPS := 400 401# For now always enable frame pointers so kernel backtraces 402# can work and define WITH_PANIC_BACKTRACE to enable them in panics 403# ZX-623 404KERNEL_DEFINES += WITH_PANIC_BACKTRACE=1 WITH_FRAME_POINTERS=1 405KERNEL_COMPILEFLAGS += $(KEEP_FRAME_POINTER_COMPILEFLAGS) 406 407KERNEL_DEFINES += WITH_KERNEL_PCIE=1 408 409# Kernel lock dependency tracking. 410ifeq ($(call TOBOOL,$(ENABLE_LOCK_DEP)),true) 411KERNEL_DEFINES += WITH_LOCK_DEP=1 412KERNEL_DEFINES += LOCK_DEP_ENABLE_VALIDATION=1 413endif 414 415# Kernel lock dependency tracking tests. By default this is enabled when 416# tracking is enabled, but can also be eanbled independently to assess whether 417# the tests build and *fail correctly* when lockdep is disabled. 418ifeq ($(call TOBOOL,$(ENABLE_LOCK_DEP_TESTS)),true) 419KERNEL_DEFINES += WITH_LOCK_DEP_TESTS=1 420endif 421 422# additional bootdata items to be included to bootdata.bin 423ADDITIONAL_BOOTDATA_ITEMS := 424 425# manifest of files to include in the user bootfs 426USER_MANIFEST := $(BUILDDIR)/bootfs.manifest 427USER_MANIFEST_LINES := 428# The contents of this are derived from BOOTFS_DEBUG_MODULES. 429USER_MANIFEST_DEBUG_INPUTS := 430# Filter on manifest lines by {group} prefix. 431ifeq ($(call TOBOOL,$(ENABLE_INSTALL_SAMPLES)),true) 432USER_MANIFEST_GROUPS := 433else 434USER_MANIFEST_GROUPS := --groups=!sample,ddk-sample 435endif 436 437# Directory in the bootfs where MODULE_FIRMWARE files go. 438FIRMWARE_INSTALL_DIR := lib/firmware 439# Directory in the source tree where MODULE_FIRMWARE files are found. 440FIRMWARE_SRC_DIR := prebuilt/downloads/firmware 441# TODO(mcgrathr): Force an absolute path for this so that every rhs in the 442# manifest either starts with $(BUILDDIR) or is absolute. 443# //scripts/build-zircon.sh needs this. 444FIRMWARE_SRC_DIR := $(abspath $(FIRMWARE_SRC_DIR)) 445 446# if someone defines this, the build id will be pulled into lib/version 447BUILDID ?= 448 449# Tool locations. 450TOOLS := $(BUILDDIR)/tools 451FIDL := $(TOOLS)/fidlc 452ABIGEN := $(TOOLS)/abigen 453ZBI := $(TOOLS)/zbi 454 455# set V=1 in the environment if you want to see the full command line of every command 456ifeq ($(V),1) 457NOECHO := 458else 459NOECHO ?= @ 460endif 461 462# used to force a rule to run every time 463.PHONY: FORCE 464FORCE: 465 466# try to include the project file 467-include $(firstword $(wildcard kernel/project/$(PROJECT).mk \ 468 kernel/project/alias/$(PROJECT).mk)) 469ifndef TARGET 470$(error couldn't find project "$(PROJECT)" or project doesn't define target) 471endif 472include kernel/target/$(TARGET)/rules.mk 473ifndef PLATFORM 474$(error couldn't find target or target doesn't define platform) 475endif 476include kernel/platform/$(PLATFORM)/rules.mk 477 478ifeq ($(call TOBOOL,$(QUIET)),false) 479$(info PROJECT/PLATFORM/TARGET = $(PROJECT) / $(PLATFORM) / $(TARGET)) 480endif 481 482include system/host/rules.mk 483include kernel/arch/$(ARCH)/rules.mk 484include kernel/top/rules.mk 485include make/abigen.mk 486 487ifeq ($(call TOBOOL,$(USE_CLANG)),true) 488GLOBAL_COMPILEFLAGS += --target=$(CLANG_ARCH)-fuchsia 489endif 490 491ifeq ($(call TOBOOL,$(USE_LTO)),true) 492ifeq ($(call TOBOOL,$(USE_CLANG)),false) 493$(error USE_LTO requires USE_CLANG) 494endif 495ifeq ($(call TOBOOL,$(USE_LLD)),false) 496$(error USE_LTO requires USE_LLD) 497endif 498# LTO doesn't store -mcmodel=kernel information in the bitcode files as it 499# does for many other codegen options so we have to set it explicitly. This 500# can be removed when https://bugs.llvm.org/show_bug.cgi?id=33306 is fixed. 501KERNEL_LDFLAGS += $(patsubst -mcmodel=%,-mllvm -code-model=%,\ 502 $(filter -mcmodel=%,$(KERNEL_COMPILEFLAGS))) 503ifeq ($(call TOBOOL,$(USE_THINLTO)),true) 504GLOBAL_COMPILEFLAGS += -flto=thin 505GLOBAL_LDFLAGS += --thinlto-jobs=8 --thinlto-cache-dir=$(THINLTO_CACHE_DIR) 506else 507GLOBAL_COMPILEFLAGS += -flto -fwhole-program-vtables 508# Full LTO doesn't require any special ld flags. 509endif 510endif 511 512ifeq ($(call TOBOOL,$(USE_SANCOV)),true) 513ifeq ($(call TOBOOL,$(USE_ASAN)),false) 514$(error USE_SANCOV requires USE_ASAN) 515endif 516endif 517 518ifeq ($(call TOBOOL,$(USE_ASAN)),true) 519ifeq ($(call TOBOOL,$(USE_CLANG)),false) 520$(error USE_ASAN requires USE_CLANG) 521endif 522 523# Compile all of userland with ASan. ASan makes safe-stack superfluous 524# and ASan reporting doesn't really grok safe-stack, so disable it. 525# Individual modules can append $(NO_SANITIZERS) to counteract this. 526USER_COMPILEFLAGS += -fsanitize=address -fno-sanitize=safe-stack 527 528# The Clang toolchain includes a manifest for the shared libraries it provides. 529# The right-hand sides are relative to the directory containing the manifest. 530CLANG_MANIFEST := $(CLANG_TOOLCHAIN_PREFIX)../lib/$(CLANG_ARCH)-fuchsia.manifest 531CLANG_MANIFEST_LINES := \ 532 $(subst =,=$(CLANG_TOOLCHAIN_PREFIX)../lib/,$(shell cat $(CLANG_MANIFEST))) 533find-clang-solib = $(filter lib/$1=%,$(CLANG_MANIFEST_LINES)) 534# Every userland executable and shared library compiled with ASan 535# needs to link with $(ASAN_SOLIB). module-user{app,lib}.mk adds it 536# to MODULE_EXTRA_OBJS so the linking target will depend on it. 537ASAN_SONAME := libclang_rt.asan.so 538ASAN_SOLIB_MANIFEST := $(call find-clang-solib,$(ASAN_SONAME)) 539ASAN_SOLIB := $(word 2,$(subst =, ,$(ASAN_SOLIB_MANIFEST))) 540USER_MANIFEST_LINES += {core}$(ASAN_SOLIB_MANIFEST) 541 542# The ASan runtime DSO depends on more DSOs from the toolchain. We don't 543# link against those, so we don't need any build-time dependencies on them. 544# But we need them alongside the ASan runtime DSO in the bootfs. 545find-clang-asan-solib = $(or $(call find-clang-solib,asan/$1), \ 546 $(call find-clang-solib,$1)) 547ASAN_RUNTIME_SONAMES := libc++abi.so.1 libunwind.so.1 548ASAN_RUNTIME_MANIFEST := \ 549 $(foreach soname,$(ASAN_RUNTIME_SONAMES),\ 550 {core}$(call find-clang-asan-solib,$(soname))) 551USER_MANIFEST_LINES += $(ASAN_RUNTIME_MANIFEST) 552 553TOOLCHAIN_SOLIBS += \ 554 $(foreach entry,$(ASAN_SOLIB_MANIFEST) $(ASAN_RUNTIME_MANIFEST),\ 555 $(word 2,$(subst =, ,$(entry)))) 556endif 557 558ifeq ($(call TOBOOL,$(USE_SANCOV)),true) 559# Compile all of userland with coverage. 560USER_COMPILEFLAGS += -fsanitize-coverage=trace-pc-guard 561NO_SANCOV := -fno-sanitize-coverage=trace-pc-guard 562NO_SANITIZERS += $(NO_SANCOV) 563else 564NO_SANCOV := 565endif 566 567clang-print-file-name = $(shell $(CLANG_TOOLCHAIN_PREFIX)clang \ 568 $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) \ 569 -print-file-name=$1) 570 571# To use LibFuzzer, we need to provide it and its dependency to the linker 572# since we're not using Clang and its '-fsanitize=fuzzer' flag as a driver to 573# lld. Additionally, we need to make sure the shared objects are available on 574# the device. 575ifeq ($(call TOBOOL,$(USE_ASAN)),true) 576FUZZ_ALIB := $(call clang-print-file-name,libclang_rt.fuzzer.a) 577 578FUZZ_RUNTIME_SONAMES := libc++abi.so.1 579FUZZ_RUNTIME_SOLIBS := $(foreach soname,$(FUZZ_RUNTIME_SONAMES),\ 580 $(word 2,$(subst =, ,$(call find-clang-asan-solib,$(soname))))) 581 582FUZZ_EXTRA_OBJS := $(FUZZ_ALIB) $(FUZZ_RUNTIME_SOLIBS) 583else 584FUZZ_EXTRA_OBJS := 585endif 586 587ifeq ($(call TOBOOL,$(USE_PROFILE)),true) 588USER_COMPILEFLAGS += -fprofile-instr-generate -fcoverage-mapping 589NO_PROFILE := -fno-profile-instr-generate -fno-coverage-mapping 590NO_SANITIZERS += $(NO_PROFILE) 591PROFILE_LIB := $(call clang-print-file-name,libclang_rt.profile.a) 592else 593NO_PROFILE := 594PROFILE_LIB := 595endif 596 597# Save these for the first module.mk iteration to see. 598SAVED_EXTRA_BUILDDEPS := $(EXTRA_BUILDDEPS) 599SAVED_GENERATED := $(GENERATED) 600SAVED_USER_MANIFEST_LINES := $(USER_MANIFEST_LINES) 601 602# recursively include any modules in the MODULE variable, leaving a trail of included 603# modules in the ALLMODULES list 604include make/recurse.mk 605 606define link-toolchain-file-cmd 607$(call BUILDECHO,generating $@) 608$(NOECHO)ln -n -f -L $< $@ 2> /dev/null || cp -f $< $@ 609endef 610define toolchain-id-files 611$(foreach lib,$(TOOLCHAIN_SOLIBS), 612EXTRA_IDFILES += $$(BUILDDIR)/$(notdir $(lib)).id 613$$(BUILDDIR)/$(notdir $(lib)): $(lib); $$(link-toolchain-file-cmd) 614) 615endef 616$(eval $(toolchain-id-files)) 617 618ifneq ($(EXTRA_IDFILES),) 619$(BUILDDIR)/ids.txt: $(EXTRA_IDFILES) 620 $(call BUILDECHO,generating $@) 621 @rm -f -- "$@.tmp" 622 @for f in $(EXTRA_IDFILES); do \ 623 echo `cat $$f` `echo $$f | sed 's/\.id$$//g'` >> $@.tmp; \ 624 done; \ 625 mv $@.tmp $@ 626 627EXTRA_BUILDDEPS += $(BUILDDIR)/ids.txt 628GENERATED += $(BUILDDIR)/ids.txt 629GENERATED += $(EXTRA_IDFILES) 630endif 631 632# include some rules for generating sysroot/ and contents in the build dir 633include make/sysroot.mk 634 635# make the build depend on all of the user apps 636all:: $(foreach app,$(ALLUSER_APPS),$(app) $(app).strip) 637 638# and all host tools 639all:: $(ALLHOST_APPS) $(ALLHOST_LIBS) 640 641tools:: $(ALLHOST_APPS) $(ALLHOST_LIBS) 642 643# meta rule for the kernel 644.PHONY: kernel 645kernel: $(KERNEL_ZBI) $(EXTRA_KERNELDEPS) 646ifeq ($(ENABLE_BUILD_LISTFILES),true) 647kernel: $(KERNEL_ELF).lst $(KERNEL_ELF).sym $(KERNEL_ELF).sym.sorted $(KERNEL_ELF).size 648endif 649 650ifeq ($(call TOBOOL,$(ENABLE_ULIB_ONLY)),false) 651# add the kernel to the build 652all:: kernel 653else 654# No kernel, but we want the bootfs.manifest listing the installed libraries. 655all:: user-manifest 656endif 657 658# meta rule for building just packages 659.PHONY: packages 660packages: $(ALLPKGS) $(BUILDDIR)/export/manifest 661 662$(BUILDDIR)/export/manifest: FORCE 663 @$(call BUILDECHO,generating $@ ;)\ 664 $(MKDIR) ;\ 665 rm -f $@.tmp ;\ 666 (for p in $(sort $(notdir $(ALLPKGS))) ; do echo $$p ; done) > $@.tmp ;\ 667 $(call TESTANDREPLACEFILE,$@.tmp,$@) 668 669# build depends on all packages 670all:: packages 671 672# add some automatic configuration defines 673KERNEL_DEFINES += \ 674 PROJECT_$(PROJECT)=1 \ 675 PROJECT=\"$(PROJECT)\" \ 676 TARGET_$(TARGET)=1 \ 677 TARGET=\"$(TARGET)\" \ 678 PLATFORM_$(PLATFORM)=1 \ 679 PLATFORM=\"$(PLATFORM)\" \ 680 ARCH_$(ARCH)=1 \ 681 ARCH=\"$(ARCH)\" \ 682 683# debug build? 684# TODO(johngro) : Make LK and ZX debug levels independently controlable. 685ifneq ($(DEBUG),) 686GLOBAL_DEFINES += \ 687 LK_DEBUGLEVEL=$(DEBUG) \ 688 ZX_DEBUGLEVEL=$(DEBUG) 689endif 690 691# allow additional defines from outside the build system 692ifneq ($(EXTERNAL_DEFINES),) 693GLOBAL_DEFINES += $(EXTERNAL_DEFINES) 694$(info EXTERNAL_DEFINES = $(EXTERNAL_DEFINES)) 695endif 696 697# Modules are added earlier before the recurse stage, so just print the info here 698ifneq ($(EXTERNAL_MODULES),) 699$(info EXTERNAL_MODULES = $(EXTERNAL_MODULES)) 700endif 701 702ifneq ($(EXTERNAL_KERNEL_DEFINES),) 703KERNEL_DEFINES += $(EXTERNAL_KERNEL_DEFINES) 704$(info EXTERNAL_KERNEL_DEFINES = $(EXTERNAL_KERNEL_DEFINES)) 705endif 706 707# prefix all of the paths in GLOBAL_INCLUDES and KERNEL_INCLUDES with -I 708GLOBAL_INCLUDES := $(addprefix -I,$(GLOBAL_INCLUDES)) 709KERNEL_INCLUDES := $(addprefix -I,$(KERNEL_INCLUDES)) 710 711# Path to the Goma compiler wrapper. Defaults to using no wrapper. 712GOMACC ?= 713 714# set up paths to various tools 715ifeq ($(call TOBOOL,$(USE_CLANG)),true) 716CC := $(GOMACC) $(CLANG_TOOLCHAIN_PREFIX)clang 717AR := $(CLANG_TOOLCHAIN_PREFIX)llvm-ar 718OBJDUMP := $(CLANG_TOOLCHAIN_PREFIX)llvm-objdump 719READELF := $(CLANG_TOOLCHAIN_PREFIX)llvm-readelf 720CPPFILT := $(CLANG_TOOLCHAIN_PREFIX)llvm-cxxfilt 721SIZE := $(CLANG_TOOLCHAIN_PREFIX)llvm-size 722NM := $(CLANG_TOOLCHAIN_PREFIX)llvm-nm 723OBJCOPY := $(CLANG_TOOLCHAIN_PREFIX)llvm-objcopy 724STRIP := $(CLANG_TOOLCHAIN_PREFIX)llvm-objcopy --strip-sections 725else 726CC := $(GOMACC) $(TOOLCHAIN_PREFIX)gcc 727AR := $(TOOLCHAIN_PREFIX)ar 728OBJDUMP := $(TOOLCHAIN_PREFIX)objdump 729READELF := $(TOOLCHAIN_PREFIX)readelf 730CPPFILT := $(TOOLCHAIN_PREFIX)c++filt 731SIZE := $(TOOLCHAIN_PREFIX)size 732NM := $(TOOLCHAIN_PREFIX)nm 733OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy 734STRIP := $(TOOLCHAIN_PREFIX)objcopy --strip-all 735endif 736LD := $(TOOLCHAIN_PREFIX)ld 737ifeq ($(call TOBOOL,$(USE_LLD)),true) 738LD := $(CLANG_TOOLCHAIN_PREFIX)ld.lld 739endif 740ifeq ($(call TOBOOL,$(USE_GOLD)),true) 741USER_LD := $(LD).gold 742else 743USER_LD := $(LD) 744endif 745 746LIBGCC := $(shell $(CC) $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) -print-libgcc-file-name) 747ifeq ($(LIBGCC),) 748$(error cannot find runtime library, please set LIBGCC) 749endif 750 751# try to have the compiler output colorized error messages if available 752export GCC_COLORS ?= 1 753 754# setup bootloader toolchain 755ifeq ($(ARCH),x86) 756EFI_ARCH := x86_64 757else ifeq ($(ARCH),arm64) 758EFI_ARCH := aarch64 759endif 760 761ifeq ($(call TOBOOL,$(USE_CLANG)),true) 762EFI_AR := $(CLANG_TOOLCHAIN_PREFIX)llvm-ar 763EFI_CC := $(CLANG_TOOLCHAIN_PREFIX)clang 764EFI_CXX := $(CLANG_TOOLCHAIN_PREFIX)clang++ 765EFI_LD := $(CLANG_TOOLCHAIN_PREFIX)lld-link 766EFI_COMPILEFLAGS := --target=$(EFI_ARCH)-windows-msvc 767else 768EFI_AR := $(TOOLCHAIN_PREFIX)ar 769EFI_CC := $(TOOLCHAIN_PREFIX)gcc 770EFI_CXX := $(TOOLCHAIN_PREFIX)g++ 771EFI_LD := $(TOOLCHAIN_PREFIX)ld 772EFI_COMPILEFLAGS := -fPIE 773endif 774 775EFI_OPTFLAGS := -O2 776EFI_COMPILEFLAGS += -fno-stack-protector 777EFI_COMPILEFLAGS += -Wall 778EFI_CFLAGS := -fshort-wchar -std=c99 -ffreestanding 779ifeq ($(EFI_ARCH),x86_64) 780EFI_CFLAGS += -mno-red-zone 781endif 782 783 784# setup host toolchain 785# default to prebuilt clang 786FOUND_HOST_GCC ?= $(shell which $(HOST_TOOLCHAIN_PREFIX)gcc) 787HOST_TOOLCHAIN_PREFIX ?= $(CLANG_TOOLCHAIN_PREFIX) 788HOST_USE_CLANG ?= $(shell which $(HOST_TOOLCHAIN_PREFIX)clang) 789ifneq ($(HOST_USE_CLANG),) 790HOST_CC := $(GOMACC) $(HOST_TOOLCHAIN_PREFIX)clang 791HOST_CXX := $(GOMACC) $(HOST_TOOLCHAIN_PREFIX)clang++ 792HOST_AR := $(HOST_TOOLCHAIN_PREFIX)llvm-ar 793else 794ifeq ($(FOUND_HOST_GCC),) 795$(error cannot find toolchain, please set HOST_TOOLCHAIN_PREFIX or add it to your path) 796endif 797HOST_CC := $(GOMACC) $(HOST_TOOLCHAIN_PREFIX)gcc 798HOST_CXX := $(GOMACC) $(HOST_TOOLCHAIN_PREFIX)g++ 799HOST_AR := $(HOST_TOOLCHAIN_PREFIX)ar 800endif 801 802# Host compile flags 803HOST_COMPILEFLAGS := -g -O2 -Isystem/public -Isystem/private -I$(GENERATED_INCLUDES) 804HOST_COMPILEFLAGS += -Wall -Wextra 805HOST_COMPILEFLAGS += -Wno-unused-parameter -Wno-sign-compare 806HOST_CFLAGS := -std=c11 807HOST_CPPFLAGS := -std=c++17 -fno-exceptions -fno-rtti 808HOST_LDFLAGS := 809ifneq ($(HOST_USE_CLANG),) 810# We need to use our provided libc++ and libc++abi (and their pthread 811# dependency) rather than the host library. The only exception is the 812# case when we are cross-compiling the host tools in which case we use 813# the C++ library from the sysroot. 814# TODO(TC-78): This can be removed once the Clang 815# toolchain ships with a cross-compiled C++ runtime. 816ifeq ($(HOST_TARGET),) 817ifeq ($(HOST_PLATFORM),linux) 818ifeq ($(HOST_ARCH),x86_64) 819HOST_SYSROOT ?= $(SYSROOT_linux-amd64_PATH) 820else ifeq ($(HOST_ARCH),aarch64) 821HOST_SYSROOT ?= $(SYSROOT_linux-arm64_PATH) 822endif 823# TODO(TC-77): Using explicit sysroot currently overrides location of C++ 824# runtime so we need to explicitly add it here. 825HOST_LDFLAGS += -Lprebuilt/downloads/clang/lib 826# The implicitly linked static libc++.a depends on these. 827HOST_LDFLAGS += -ldl -lpthread 828endif 829endif 830HOST_LDFLAGS += -static-libstdc++ 831# For host tools without C++, ignore the unused arguments. 832HOST_LDFLAGS += -Wno-unused-command-line-argument 833endif 834HOST_ASMFLAGS := 835 836ifneq ($(HOST_TARGET),) 837HOST_COMPILEFLAGS += --target=$(HOST_TARGET) 838ifeq ($(HOST_TARGET),x86_64-linux-gnu) 839HOST_SYSROOT ?= $(SYSROOT_linux-amd64_PATH) 840else ifeq ($(HOST_TARGET),aarch64-linux-gnu) 841HOST_SYSROOT ?= $(SYSROOT_linux-arm64_PATH) 842endif 843endif 844 845ifneq ($(HOST_USE_CLANG),) 846ifeq ($(HOST_PLATFORM),darwin) 847HOST_SYSROOT ?= $(shell xcrun --show-sdk-path) 848endif 849endif 850 851ifneq ($(HOST_SYSROOT),) 852HOST_COMPILEFLAGS += --sysroot=$(HOST_SYSROOT) 853endif 854 855ifeq ($(call TOBOOL,$(HOST_USE_ASAN)),true) 856HOST_COMPILEFLAGS += -fsanitize=address 857export ASAN_SYMBOLIZER_PATH := $(HOST_TOOLCHAIN_PREFIX)llvm-symbolizer 858endif 859 860# the logic to compile and link stuff is in here 861include make/build.mk 862 863# top level target to just build the bootloader 864.PHONY: bootloader 865bootloader: 866 867# build a bootloader if needed 868include bootloader/build.mk 869 870DEPS := $(ALLOBJS:%o=%d) 871 872# put all of the build flags in various config.h files to force a rebuild if any change 873GLOBAL_DEFINES += GLOBAL_INCLUDES=\"$(subst $(SPACE),_,$(GLOBAL_INCLUDES))\" 874GLOBAL_DEFINES += GLOBAL_COMPILEFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_COMPILEFLAGS))\" 875GLOBAL_DEFINES += GLOBAL_OPTFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_OPTFLAGS))\" 876GLOBAL_DEFINES += GLOBAL_CFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_CFLAGS))\" 877GLOBAL_DEFINES += GLOBAL_CPPFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_CPPFLAGS))\" 878GLOBAL_DEFINES += GLOBAL_ASMFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_ASMFLAGS))\" 879GLOBAL_DEFINES += GLOBAL_LDFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_LDFLAGS))\" 880GLOBAL_DEFINES += ARCH_COMPILEFLAGS=\"$(subst $(SPACE),_,$(ARCH_COMPILEFLAGS))\" 881GLOBAL_DEFINES += ARCH_CFLAGS=\"$(subst $(SPACE),_,$(ARCH_CFLAGS))\" 882GLOBAL_DEFINES += ARCH_CPPFLAGS=\"$(subst $(SPACE),_,$(ARCH_CPPFLAGS))\" 883GLOBAL_DEFINES += ARCH_ASMFLAGS=\"$(subst $(SPACE),_,$(ARCH_ASMFLAGS))\" 884 885KERNEL_DEFINES += KERNEL_INCLUDES=\"$(subst $(SPACE),_,$(KERNEL_INCLUDES))\" 886KERNEL_DEFINES += KERNEL_COMPILEFLAGS=\"$(subst $(SPACE),_,$(KERNEL_COMPILEFLAGS))\" 887KERNEL_DEFINES += KERNEL_CFLAGS=\"$(subst $(SPACE),_,$(KERNEL_CFLAGS))\" 888KERNEL_DEFINES += KERNEL_CPPFLAGS=\"$(subst $(SPACE),_,$(KERNEL_CPPFLAGS))\" 889KERNEL_DEFINES += KERNEL_ASMFLAGS=\"$(subst $(SPACE),_,$(KERNEL_ASMFLAGS))\" 890KERNEL_DEFINES += KERNEL_LDFLAGS=\"$(subst $(SPACE),_,$(KERNEL_LDFLAGS))\" 891 892USER_DEFINES += USER_COMPILEFLAGS=\"$(subst $(SPACE),_,$(USER_COMPILEFLAGS))\" 893USER_DEFINES += USER_CFLAGS=\"$(subst $(SPACE),_,$(USER_CFLAGS))\" 894USER_DEFINES += USER_CPPFLAGS=\"$(subst $(SPACE),_,$(USER_CPPFLAGS))\" 895USER_DEFINES += USER_ASMFLAGS=\"$(subst $(SPACE),_,$(USER_ASMFLAGS))\" 896USER_DEFINES += USER_LDFLAGS=\"$(subst $(SPACE),_,$(USER_LDFLAGS))\" 897 898HOST_DEFINES += HOST_COMPILEFLAGS=\"$(subst $(SPACE),_,$(HOST_COMPILEFLAGS))\" 899HOST_DEFINES += HOST_CFLAGS=\"$(subst $(SPACE),_,$(HOST_CFLAGS))\" 900HOST_DEFINES += HOST_CPPFLAGS=\"$(subst $(SPACE),_,$(HOST_CPPFLAGS))\" 901HOST_DEFINES += HOST_ASMFLAGS=\"$(subst $(SPACE),_,$(HOST_ASMFLAGS))\" 902HOST_DEFINES += HOST_LDFLAGS=\"$(subst $(SPACE),_,$(HOST_LDFLAGS))\" 903 904#$(info LIBGCC = $(LIBGCC)) 905#$(info GLOBAL_COMPILEFLAGS = $(GLOBAL_COMPILEFLAGS)) 906#$(info GLOBAL_OPTFLAGS = $(GLOBAL_OPTFLAGS)) 907 908# make all object files depend on any targets in GLOBAL_SRCDEPS 909$(ALLOBJS): $(GLOBAL_SRCDEPS) 910 911# make all target object files depend on any targets in TARGET_MODDEPS 912$(ALL_TARGET_OBJS): $(TARGET_MODDEPS) 913 914# any extra top level build dependencies that someone may have declared 915all:: $(EXTRA_BUILDDEPS) 916 917clean: $(EXTRA_CLEANDEPS) 918 rm -f $(ALLOBJS) 919 rm -f $(DEPS) 920 rm -f $(GENERATED) 921 rm -f $(KERNEL_ZBI) $(KERNEL_IMAGE) $(KERNEL_ELF) $(KERNEL_ELF).lst $(KERNEL_ELF).debug.lst $(KERNEL_ELF).sym $(KERNEL_ELF).sym.sorted $(KERNEL_ELF).size $(KERNEL_ELF).hex $(KERNEL_ELF).dump $(KERNEL_ELF)-gdb.py 922 rm -f $(foreach app,$(ALLUSER_APPS),$(app) $(app).lst $(app).dump $(app).strip) 923 924install: all 925 scp $(KERNEL_ZBI) 192.168.0.4:/tftproot 926 927# generate a config-global.h file with all of the GLOBAL_DEFINES laid out in #define format 928$(GLOBAL_CONFIG_HEADER): FORCE 929 @$(call MAKECONFIGHEADER,$@,GLOBAL_DEFINES,"#define __Fuchsia__ 1") 930 931# generate a config-kernel.h file with all of the KERNEL_DEFINES laid out in #define format 932$(KERNEL_CONFIG_HEADER): FORCE 933 @$(call MAKECONFIGHEADER,$@,KERNEL_DEFINES,"") 934 935# generate a config-user.h file with all of the USER_DEFINES laid out in #define format 936$(USER_CONFIG_HEADER): FORCE 937 @$(call MAKECONFIGHEADER,$@,USER_DEFINES,"") 938 939$(HOST_CONFIG_HEADER): FORCE 940 @$(call MAKECONFIGHEADER,$@,HOST_DEFINES,"") 941 942GENERATED += $(GLOBAL_CONFIG_HEADER) $(KERNEL_CONFIG_HEADER) $(USER_CONFIG_HEADER) $(HOST_CONFIG_HEADER) 943 944# Empty rule for the .d files. The above rules will build .d files as a side 945# effect. Only works on gcc 3.x and above, however. 946%.d: 947 948ifeq ($(filter $(MAKECMDGOALS), clean), ) 949-include $(DEPS) 950endif 951 952endif 953 954endif # make spotless 955