blob: 74784fe6ac2cb13fc81264272fe4cb58940d3a84 [file] [log] [blame]
# Copyright 2016 The Fuchsia Authors
# Copyright (c) 2008-2015 Travis Geiselbrecht
#
# 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
LOCAL_MAKEFILE:=$(MAKEFILE_LIST)
# include settings for prebuilts that are auto-updated by checkout scripts
-include prebuilt/config.mk
# try to include a file in the local dir to let the user semi-permanently set options
-include local.mk
include make/macros.mk
# various command line and environment arguments
# default them to something so when they're referenced in the make instance they're not undefined
BUILDROOT ?= .
DEBUG ?= 2
ENABLE_BUILD_LISTFILES ?= false
ENABLE_BUILD_SYSROOT ?= false
ENABLE_BUILD_LISTFILES := $(call TOBOOL,$(ENABLE_BUILD_LISTFILES))
ENABLE_BUILD_SYSROOT := $(call TOBOOL,$(ENABLE_BUILD_SYSROOT))
ENABLE_NEW_FB := true
DISABLE_UTEST ?= false
ENABLE_ULIB_ONLY ?= false
USE_ASAN ?= false
USE_SANCOV ?= false
USE_LTO ?= false
USE_THINLTO ?= $(USE_LTO)
USE_CLANG ?= $(firstword $(filter true,$(call TOBOOL,$(USE_ASAN)) $(call TOBOOL,$(USE_LTO))) false)
USE_LLD ?= $(USE_CLANG)
ifeq ($(call TOBOOL,$(USE_LLD)),true)
USE_GOLD := false
else
USE_GOLD ?= true
endif
THINLTO_CACHE_DIR ?= $(BUILDDIR)/thinlto-cache
LKNAME ?= zircon
CLANG_TARGET_FUCHSIA ?= false
USE_LINKER_GC ?= true
ifeq ($(call TOBOOL,$(ENABLE_ULIB_ONLY)),true)
ENABLE_BUILD_SYSROOT := false
ifeq (,$(strip $(TOOLS)))
$(error ENABLE_ULIB_ONLY=true requires TOOLS=build-.../tools on command line)
endif
endif
# If no build directory suffix has been explicitly supplied by the environment,
# generate a default based on build options. Start with no suffix, then add
# "-clang" if we are building with clang, and "-release" if we are building with
# DEBUG=0
ifeq ($(origin BUILDDIR_SUFFIX),undefined)
BUILDDIR_SUFFIX :=
ifeq ($(call TOBOOL,$(USE_ASAN)),true)
BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-asan
else ifeq ($(call TOBOOL,$(USE_LTO)),true)
ifeq ($(call TOBOOL,$(USE_THINLTO)),true)
BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-thinlto
else
BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-lto
endif
else ifeq ($(call TOBOOL,$(USE_CLANG)),true)
BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-clang
endif
ifeq ($(call TOBOOL,$(DEBUG)),false)
BUILDDIR_SUFFIX := $(BUILDDIR_SUFFIX)-release
endif
endif # if BUILDDIR_SUFFIX is empty
# special rule for handling make spotless
ifeq ($(MAKECMDGOALS),spotless)
spotless:
rm -rf -- "$(BUILDROOT)"/build-*
else
# If one of our goals (from the commandline) happens to have a
# matching project/goal.mk, then we should re-invoke make with
# that project name specified...
project-name := $(firstword $(MAKECMDGOALS))
ifneq ($(project-name),)
ifneq ($(strip $(wildcard kernel/project/$(project-name).mk)),)
do-nothing := 1
$(MAKECMDGOALS) _all: make-make
make-make:
@PROJECT=$(project-name) $(MAKE) -rR -f $(LOCAL_MAKEFILE) $(filter-out $(project-name), $(MAKECMDGOALS))
.PHONY: make-make
endif
endif
# some additional rules to print some help
include make/help.mk
ifeq ($(do-nothing),)
ifeq ($(PROJECT),)
ifneq ($(DEFAULT_PROJECT),)
PROJECT := $(DEFAULT_PROJECT)
else
$(error No project specified. Use 'make list' for a list of projects or 'make help' for additional help)
endif
endif
BUILDDIR := $(BUILDROOT)/build-$(PROJECT)$(BUILDDIR_SUFFIX)
GENERATED_INCLUDES:=$(BUILDDIR)/gen/include
OUTLKBIN := $(BUILDDIR)/$(LKNAME).bin
OUTLKELF := $(BUILDDIR)/$(LKNAME).elf
GLOBAL_CONFIG_HEADER := $(BUILDDIR)/config-global.h
KERNEL_CONFIG_HEADER := $(BUILDDIR)/config-kernel.h
USER_CONFIG_HEADER := $(BUILDDIR)/config-user.h
HOST_CONFIG_HEADER := $(BUILDDIR)/config-host.h
GLOBAL_INCLUDES := system/public system/private $(GENERATED_INCLUDES)
GLOBAL_OPTFLAGS ?= $(ARCH_OPTFLAGS)
GLOBAL_DEBUGFLAGS ?= -g
# When embedding source file locations in debugging information, by default
# the compiler will record the absolute path of the current directory and
# make everything relative to that. Instead, we tell the compiler to map
# the current directory to $(DEBUG_BUILDROOT), which is the "relative"
# location of the zircon source tree (i.e. usually . in a standalone build).
DEBUG_BUILDROOT ?= $(BUILDROOT)
GLOBAL_COMPILEFLAGS := $(GLOBAL_DEBUGFLAGS)
GLOBAL_COMPILEFLAGS += -fdebug-prefix-map=$(shell pwd)=$(DEBUG_BUILDROOT)
GLOBAL_COMPILEFLAGS += -finline -include $(GLOBAL_CONFIG_HEADER)
GLOBAL_COMPILEFLAGS += -Wall -Wextra -Wno-multichar -Werror -Wno-error=deprecated-declarations
GLOBAL_COMPILEFLAGS += -Wno-unused-parameter -Wno-unused-function -Werror=unused-label -Werror=return-type
GLOBAL_COMPILEFLAGS += -fno-common
ifeq ($(call TOBOOL,$(USE_CLANG)),true)
GLOBAL_COMPILEFLAGS += -no-canonical-prefixes
GLOBAL_COMPILEFLAGS += -Wno-address-of-packed-member
GLOBAL_COMPILEFLAGS += -Wthread-safety
else
GLOBAL_COMPILEFLAGS += -Wno-nonnull-compare
endif
GLOBAL_CFLAGS := -std=c11 -Werror-implicit-function-declaration -Wstrict-prototypes -Wwrite-strings
GLOBAL_CPPFLAGS := -std=c++14 -fno-exceptions -fno-rtti -fno-threadsafe-statics -Wconversion -Wno-sign-conversion
#GLOBAL_CPPFLAGS += -Weffc++
GLOBAL_ASMFLAGS := -DASSEMBLY
GLOBAL_LDFLAGS := -nostdlib --build-id
# $(addprefix -L,$(LKINC)) XXX
GLOBAL_MODULE_LDFLAGS :=
# By default the sysroot is generated in "sysroot" under
# the build directory, but this is overrideable
ifeq ($(BUILDSYSROOT),)
BUILDSYSROOT := $(BUILDDIR)/sysroot
else
# be noisy if we are
$(info BUILDSYSROOT = $(BUILDSYSROOT))
endif
# Kernel compile flags
KERNEL_INCLUDES := $(BUILDDIR) kernel/include
KERNEL_COMPILEFLAGS := -ffreestanding -include $(KERNEL_CONFIG_HEADER)
KERNEL_COMPILEFLAGS += -Wformat=2 -Wvla
ifeq ($(call TOBOOL,$(USE_CLANG)),false)
KERNEL_COMPILEFLAGS += -Wformat-signedness
endif
KERNEL_CFLAGS := -Wmissing-prototypes
KERNEL_CPPFLAGS :=
KERNEL_ASMFLAGS :=
KERNEL_LDFLAGS :=
# Build flags for modules that want frame pointers.
# crashlogger, ngunwind, backtrace use this so that the simplisitic unwinder
# will work with them. These are recorded here so that modules don't need
# knowledge of the details. They just need to do:
# MODULE_COMPILEFLAGS += $(KEEP_FRAME_POINTER_COMPILEFLAGS)
KEEP_FRAME_POINTER_COMPILEFLAGS := -fno-omit-frame-pointer
# User space compile flags
USER_COMPILEFLAGS := -include $(USER_CONFIG_HEADER) -fPIC -D_ALL_SOURCE=1
USER_CFLAGS :=
USER_CPPFLAGS :=
USER_ASMFLAGS :=
# Additional flags for dynamic linking, both for dynamically-linked
# executables and for shared libraries.
USER_LDFLAGS := \
-z combreloc -z relro -z now -z text \
--hash-style=gnu --eh-frame-hdr
ifeq ($(call TOBOOL,$(USE_LLD)),true)
USER_LDFLAGS += -z rodynamic
RODSO_LDFLAGS :=
else
RODSO_LDFLAGS := -T scripts/rodso.ld
endif
# Turn on -fasynchronous-unwind-tables to get .eh_frame.
# This is necessary for unwinding through optimized code.
# The unwind information is part of the loaded binary. It's not that much space
# and it allows for unwinding of stripped binaries, pc -> source translation
# can be done offline with, e.g., scripts/symbolize.
USER_COMPILEFLAGS += -fasynchronous-unwind-tables
# We want .debug_frame for the kernel. ZX-62
# 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 - heh)!
# Assembler code has its own way of requesting .debug_frame vs .eh_frame with
# the .cfi_sections directive. Sigh.
KERNEL_COMPILEFLAGS += -fno-exceptions -fno-unwind-tables
ifeq ($(call TOBOOL,$(USE_CLANG)),true)
SAFESTACK := -fsanitize=safe-stack -fstack-protector-strong
NO_SAFESTACK := -fno-sanitize=safe-stack -fno-stack-protector
NO_SANITIZERS := -fno-sanitize=all -fno-stack-protector
else
SAFESTACK :=
NO_SAFESTACK :=
NO_SANITIZERS :=
endif
USER_COMPILEFLAGS += $(SAFESTACK)
USER_SCRT1_OBJ := $(BUILDDIR)/system/ulib/Scrt1.o
# Additional flags for building shared libraries (ld -shared).
USERLIB_SO_LDFLAGS := $(USER_LDFLAGS) -z defs
# This is the string embedded into dynamically-linked executables
# as PT_INTERP. The launchpad library looks this up via the
# "loader service", so it should be a simple name rather than an
# absolute pathname as is used for this on other systems.
USER_SHARED_INTERP := ld.so.1
# Programs built with ASan use the ASan-supporting dynamic linker.
ifeq ($(call TOBOOL,$(USE_ASAN)),true)
USER_SHARED_INTERP := asan/$(USER_SHARED_INTERP)
endif
# Additional flags for building dynamically-linked executables.
USERAPP_LDFLAGS := \
$(USER_LDFLAGS) -pie -dynamic-linker $(USER_SHARED_INTERP)
ifeq ($(call TOBOOL,$(USE_GOLD)),false)
# BFD ld stupidly insists on resolving dependency DSO's symbols when
# doing a -shared -z defs link. To do this it needs to find
# dependencies' dependencies, which requires -rpath-link. Gold does
# not have this misfeature. Since ulib/musl needs ulib/zircon and
# everything needs ulib/musl, this covers the actual needs in the
# build today without resorting to resolving inter-module dependencies
# to generate -rpath-link in a general fashion. Eventually we should
# always use gold or lld for all the user-mode links, and then we'll
# never need this.
USERAPP_LDFLAGS += -rpath-link $(BUILDDIR)/ulib/zircon
endif
# Architecture specific compile flags
ARCH_COMPILEFLAGS :=
ARCH_CFLAGS :=
ARCH_CPPFLAGS :=
ARCH_ASMFLAGS :=
# top level rule
all::
# master module object list
ALLOBJS_MODULE :=
# all module objects for the target (does not include hostapp)
ALL_TARGET_OBJS :=
# master object list (for dep generation)
ALLOBJS :=
# master source file list
ALLSRCS :=
# anything you add here will be deleted in make clean
GENERATED :=
# anything added to GLOBAL_DEFINES will be put into $(BUILDDIR)/config-global.h
GLOBAL_DEFINES :=
# anything added to KERNEL_DEFINES will be put into $(BUILDDIR)/config-kernel.h
KERNEL_DEFINES := LK=1 _KERNEL=1 ZIRCON_TOOLCHAIN=1
# anything added to USER_DEFINES will be put into $(BUILDDIR)/config-user.h
USER_DEFINES := ZIRCON_TOOLCHAIN=1
# anything added to HOST_DEFINES will be put into $(BUILDDIR)/config-host.h
HOST_DEFINES :=
# Anything added to GLOBAL_SRCDEPS will become a dependency of every source file in the system.
# Useful for header files that may be included by one or more source files.
GLOBAL_SRCDEPS := $(GLOBAL_CONFIG_HEADER)
# Anything added to TARGET_SRCDEPS will become a dependency of every target module file in the system.
# Useful for header files that may be included by one or more source files.
TARGET_MODDEPS :=
# these need to be filled out by the project/target/platform rules.mk files
TARGET :=
PLATFORM :=
ARCH :=
ALLMODULES :=
# this is the *true* allmodules, to check for duplicate modules
# (since submodules do not contribute to ALLMODULES)
DUPMODULES :=
# add any external module dependencies
MODULES := $(EXTERNAL_MODULES)
# any .mk specified here will be included before build.mk
EXTRA_BUILDRULES :=
# any rules you put here will also be built by the system before considered being complete
EXTRA_BUILDDEPS :=
# any rules you put here will be built if the kernel is also being built
EXTRA_KERNELDEPS :=
# any rules you put here will be depended on in clean builds
EXTRA_CLEANDEPS :=
# build ids
EXTRA_IDFILES :=
# any objects you put here get linked with the final image
EXTRA_OBJS :=
# userspace apps to build and include in initfs
ALLUSER_APPS :=
# userspace app modules
ALLUSER_MODULES :=
# userspace lib modules
ALLUSER_LIBS :=
# host apps to build
ALLHOST_APPS :=
# host libs to build
ALLHOST_LIBS :=
# EFI libs to build
ALLEFI_LIBS :=
# sysroot (exported libraries and headers)
SYSROOT_DEPS :=
# MDI source files used to generate the mdi.bin binary blob
MDI_SRCS :=
# MDI source files used to generate the mdi-defs.h header file
MDI_INCLUDES := system/public/zircon/mdi/zircon.mdi
# For now always enable frame pointers so kernel backtraces
# can work and define WITH_PANIC_BACKTRACE to enable them in panics
# ZX-623
KERNEL_DEFINES += WITH_PANIC_BACKTRACE=1 WITH_FRAME_POINTERS=1
KERNEL_COMPILEFLAGS += $(KEEP_FRAME_POINTER_COMPILEFLAGS)
# userspace boot file system generated by the build system
USER_BOOTDATA := $(BUILDDIR)/bootdata.bin
USER_FS := $(BUILDDIR)/user.fs
# additional bootdata items to be included to bootdata.bin
ADDITIONAL_BOOTDATA_ITEMS :=
# manifest of files to include in the user bootfs
USER_MANIFEST := $(BUILDDIR)/bootfs.manifest
USER_MANIFEST_LINES :=
# The contents of this are derived from BOOTFS_DEBUG_MODULES.
USER_MANIFEST_DEBUG_INPUTS :=
# if someone defines this, the build id will be pulled into lib/version
BUILDID ?=
# Tool locations.
TOOLS := $(BUILDDIR)/tools
MDIGEN := $(TOOLS)/mdigen
MKBOOTFS := $(TOOLS)/mkbootfs
SYSGEN := $(TOOLS)/sysgen
# set V=1 in the environment if you want to see the full command line of every command
ifeq ($(V),1)
NOECHO :=
else
NOECHO ?= @
endif
# used to force a rule to run every time
.PHONY: FORCE
FORCE:
# try to include the project file
-include kernel/project/$(PROJECT).mk
ifndef TARGET
$(error couldn't find project or project doesn't define target)
endif
include kernel/target/$(TARGET)/rules.mk
ifndef PLATFORM
$(error couldn't find target or target doesn't define platform)
endif
include kernel/platform/$(PLATFORM)/rules.mk
ifeq ($(call TOBOOL,$(QUIET)),false)
$(info PROJECT/PLATFORM/TARGET = $(PROJECT) / $(PLATFORM) / $(TARGET))
endif
include system/host/rules.mk
include kernel/arch/$(ARCH)/rules.mk
include kernel/top/rules.mk
include make/sysgen.mk
ifeq ($(call TOBOOL,$(USE_CLANG)),true)
GLOBAL_COMPILEFLAGS += --target=$(CLANG_ARCH)-fuchsia
endif
ifeq ($(call TOBOOL,$(USE_LTO)),true)
ifeq ($(call TOBOOL,$(USE_CLANG)),false)
$(error USE_LTO requires USE_CLANG)
endif
ifeq ($(call TOBOOL,$(USE_LLD)),false)
$(error USE_LTO requires USE_LLD)
endif
# LTO doesn't store -mcmodel=kernel information in the bitcode files as it
# does for many other codegen options so we have to set it explicitly. This
# can be removed when https://bugs.llvm.org/show_bug.cgi?id=33306 is fixed.
KERNEL_LDFLAGS += $(patsubst -mcmodel=%,-mllvm -code-model=%,\
$(filter -mcmodel=%,$(KERNEL_COMPILEFLAGS)))
ifeq ($(call TOBOOL,$(USE_THINLTO)),true)
GLOBAL_COMPILEFLAGS += -flto=thin
GLOBAL_LDFLAGS += --thinlto-jobs=8 --thinlto-cache-dir=$(THINLTO_CACHE_DIR)
else
GLOBAL_COMPILEFLAGS += -flto -fwhole-program-vtables
# Full LTO doesn't require any special ld flags.
endif
endif
ifeq ($(call TOBOOL,$(USE_SANCOV)),true)
ifeq ($(call TOBOOL,$(USE_ASAN)),false)
$(error USE_SANCOV requires USE_ASAN)
endif
endif
ifeq ($(call TOBOOL,$(USE_ASAN)),true)
ifeq ($(call TOBOOL,$(USE_CLANG)),false)
$(error USE_ASAN requires USE_CLANG)
endif
# Compile all of userland with ASan. ASan makes safe-stack superfluous
# and ASan reporting doesn't really grok safe-stack, so disable it.
# Individual modules can append $(NO_SANITIZERS) to counteract this.
USER_COMPILEFLAGS += -fsanitize=address -fno-sanitize=safe-stack
# Ask the Clang driver where the library with SONAME $1 is found at link time.
find-clang-solib = \
$(shell $(CLANG_TOOLCHAIN_PREFIX)clang $(GLOBAL_COMPILEFLAGS) \
-print-file-name=$1)
# Every userland executable and shared library compiled with ASan
# needs to link with $(ASAN_SOLIB). module-user{app,lib}.mk adds it
# to MODULE_EXTRA_OBJS so the linking target will depend on it.
ASAN_SONAME := libclang_rt.asan-$(CLANG_ARCH).so
ASAN_SOLIB := $(call find-clang-solib,$(ASAN_SONAME))
USER_MANIFEST_LINES += {core}lib/$(ASAN_SONAME)=$(ASAN_SOLIB)
# The ASan runtime DSO depends on more DSOs from the toolchain. We don't
# link against those, so we don't need any build-time dependencies on them.
# But we need them alongside the ASan runtime DSO in the bootfs.
ASAN_RUNTIME_SONAMES := libc++abi.so.1 libunwind.so.1
USER_MANIFEST_LINES += \
$(foreach soname,$(ASAN_RUNTIME_SONAMES),\
{core}lib/$(soname)=$(call find-clang-solib,$(soname)))
endif
ifeq ($(call TOBOOL,$(USE_SANCOV)),true)
# Compile all of userland with coverage.
USER_COMPILEFLAGS += -fsanitize-coverage=trace-pc-guard
NO_SANCOV := -fno-sanitize-coverage=trace-pc-guard
NO_SANITIZERS += $(NO_SANCOV)
else
NO_SANCOV :=
endif
# Save these for the first module.mk iteration to see.
SAVED_EXTRA_BUILDDEPS := $(EXTRA_BUILDDEPS)
SAVED_GENERATED := $(GENERATED)
SAVED_USER_MANIFEST_LINES := $(USER_MANIFEST_LINES)
# recursively include any modules in the MODULE variable, leaving a trail of included
# modules in the ALLMODULES list
include make/recurse.mk
ifeq ($(call TOBOOL,$(ENABLE_ULIB_ONLY)),false)
# rules for generating MDI header and binary
include make/mdi.mk
endif
ifneq ($(EXTRA_IDFILES),)
$(BUILDDIR)/ids.txt: $(EXTRA_IDFILES)
$(call BUILDECHO,generating $@)
@rm -f -- "$@.tmp"
@for f in $(EXTRA_IDFILES); do \
echo `cat $$f` `echo $$f | sed 's/\.id$$//g'` >> $@.tmp; \
done; \
mv $@.tmp $@
EXTRA_BUILDDEPS += $(BUILDDIR)/ids.txt
GENERATED += $(BUILDDIR)/ids.txt
GENERATED += $(EXTRA_IDFILES)
endif
# include some rules for generating sysroot/ and contents in the build dir
include make/sysroot.mk
# make the build depend on all of the user apps
all:: $(foreach app,$(ALLUSER_APPS),$(app) $(app).strip)
# and all host tools
all:: $(ALLHOST_APPS) $(ALLHOST_LIBS)
tools:: $(ALLHOST_APPS) $(ALLHOST_LIBS)
# meta rule for the kernel
.PHONY: kernel
kernel: $(OUTLKBIN) $(EXTRA_KERNELDEPS)
ifeq ($(ENABLE_BUILD_LISTFILES),true)
kernel: $(OUTLKELF).lst $(OUTLKELF).debug.lst $(OUTLKELF).sym $(OUTLKELF).sym.sorted $(OUTLKELF).size
endif
ifeq ($(call TOBOOL,$(ENABLE_ULIB_ONLY)),false)
# add the kernel to the build
all:: kernel
else
# No kernel, but we want the bootdata.bin containing the shared libraries.
all:: $(USER_BOOTDATA)
endif
# add some automatic configuration defines
KERNEL_DEFINES += \
PROJECT_$(PROJECT)=1 \
PROJECT=\"$(PROJECT)\" \
TARGET_$(TARGET)=1 \
TARGET=\"$(TARGET)\" \
PLATFORM_$(PLATFORM)=1 \
PLATFORM=\"$(PLATFORM)\" \
ARCH_$(ARCH)=1 \
ARCH=\"$(ARCH)\" \
# debug build?
# TODO(johngro) : Make LK and ZX debug levels independently controlable.
ifneq ($(DEBUG),)
GLOBAL_DEFINES += \
LK_DEBUGLEVEL=$(DEBUG) \
ZX_DEBUGLEVEL=$(DEBUG)
endif
# allow additional defines from outside the build system
ifneq ($(EXTERNAL_DEFINES),)
GLOBAL_DEFINES += $(EXTERNAL_DEFINES)
$(info EXTERNAL_DEFINES = $(EXTERNAL_DEFINES))
endif
# Modules are added earlier before the recurse stage, so just print the info here
ifneq ($(EXTERNAL_MODULES),)
$(info EXTERNAL_MODULES = $(EXTERNAL_MODULES))
endif
ifneq ($(EXTERNAL_KERNEL_DEFINES),)
KERNEL_DEFINES += $(EXTERNAL_KERNEL_DEFINES)
$(info EXTERNAL_KERNEL_DEFINES = $(EXTERNAL_KERNEL_DEFINES))
endif
# prefix all of the paths in GLOBAL_INCLUDES and KERNEL_INCLUDES with -I
GLOBAL_INCLUDES := $(addprefix -I,$(GLOBAL_INCLUDES))
KERNEL_INCLUDES := $(addprefix -I,$(KERNEL_INCLUDES))
# Path to the Goma compiler wrapper. Defaults to using no wrapper.
GOMACC ?=
# set up paths to various tools
ifeq ($(call TOBOOL,$(USE_CLANG)),true)
CC := $(GOMACC) $(CLANG_TOOLCHAIN_PREFIX)clang
AR := $(CLANG_TOOLCHAIN_PREFIX)llvm-ar
OBJDUMP := $(CLANG_TOOLCHAIN_PREFIX)llvm-objdump
READELF := $(CLANG_TOOLCHAIN_PREFIX)llvm-readelf
CPPFILT := $(CLANG_TOOLCHAIN_PREFIX)llvm-cxxfilt
SIZE := $(CLANG_TOOLCHAIN_PREFIX)llvm-size
NM := $(CLANG_TOOLCHAIN_PREFIX)llvm-nm
OBJCOPY := $(CLANG_TOOLCHAIN_PREFIX)llvm-objcopy
else
CC := $(GOMACC) $(TOOLCHAIN_PREFIX)gcc
AR := $(TOOLCHAIN_PREFIX)ar
OBJDUMP := $(TOOLCHAIN_PREFIX)objdump
READELF := $(TOOLCHAIN_PREFIX)readelf
CPPFILT := $(TOOLCHAIN_PREFIX)c++filt
SIZE := $(TOOLCHAIN_PREFIX)size
NM := $(TOOLCHAIN_PREFIX)nm
OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy
endif
LD := $(TOOLCHAIN_PREFIX)ld
ifeq ($(call TOBOOL,$(USE_LLD)),true)
LD := $(CLANG_TOOLCHAIN_PREFIX)ld.lld
endif
ifeq ($(call TOBOOL,$(USE_GOLD)),true)
USER_LD := $(LD).gold
else
USER_LD := $(LD)
endif
STRIP := $(TOOLCHAIN_PREFIX)strip
LIBGCC := $(shell $(CC) $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) -print-libgcc-file-name)
ifeq ($(LIBGCC),)
$(error cannot find runtime library, please set LIBGCC)
endif
# try to have the compiler output colorized error messages if available
export GCC_COLORS ?= 1
# setup bootloader toolchain
ifeq ($(call TOBOOL,$(USE_CLANG)),true)
EFI_AR := $(CLANG_TOOLCHAIN_PREFIX)llvm-ar
EFI_CC := $(CLANG_TOOLCHAIN_PREFIX)clang
EFI_CXX := $(CLANG_TOOLCHAIN_PREFIX)clang++
EFI_COMPILEFLAGS := --target=x86_64-windows-msvc
else
EFI_AR := $(TOOLCHAIN_PREFIX)ar
EFI_CC := $(TOOLCHAIN_PREFIX)gcc
EFI_CXX := $(TOOLCHAIN_PREFIX)g++
EFI_COMPILEFLAGS := -fPIE
endif
EFI_OPTFLAGS := -O2
EFI_COMPILEFLAGS += -fno-stack-protector -mno-red-zone
EFI_COMPILEFLAGS += -nostdinc
EFI_COMPILEFLAGS += -Wall
EFI_CFLAGS := -fshort-wchar -std=c99 -ffreestanding
# setup host toolchain
# default to prebuilt clang
FOUND_HOST_GCC ?= $(shell which $(HOST_TOOLCHAIN_PREFIX)gcc)
HOST_TOOLCHAIN_PREFIX ?= $(CLANG_TOOLCHAIN_PREFIX)
HOST_USE_CLANG ?= $(shell which $(HOST_TOOLCHAIN_PREFIX)clang)
ifneq ($(HOST_USE_CLANG),)
HOST_CC := $(GOMACC) $(HOST_TOOLCHAIN_PREFIX)clang
HOST_CXX := $(GOMACC) $(HOST_TOOLCHAIN_PREFIX)clang++
HOST_AR := $(HOST_TOOLCHAIN_PREFIX)llvm-ar
HOST_OBJDUMP := $(HOST_TOOLCHAIN_PREFIX)llvm-objdump
HOST_READELF := $(HOST_TOOLCHAIN_PREFIX)llvm-readelf
HOST_CPPFILT := $(HOST_TOOLCHAIN_PREFIX)llvm-cxxfilt
HOST_SIZE := $(HOST_TOOLCHAIN_PREFIX)llvm-size
HOST_NM := $(HOST_TOOLCHAIN_PREFIX)llvm-nm
HOST_LD := $(HOST_TOOLCHAIN_PREFIX)lld-link
else
ifeq ($(FOUND_HOST_GCC),)
$(error cannot find toolchain, please set HOST_TOOLCHAIN_PREFIX or add it to your path)
endif
HOST_CC := $(GOMACC) $(HOST_TOOLCHAIN_PREFIX)gcc
HOST_CXX := $(GOMACC) $(HOST_TOOLCHAIN_PREFIX)g++
HOST_AR := $(HOST_TOOLCHAIN_PREFIX)ar
HOST_OBJDUMP := $(HOST_TOOLCHAIN_PREFIX)objdump
HOST_READELF := $(HOST_TOOLCHAIN_PREFIX)readelf
HOST_CPPFILT := $(HOST_TOOLCHAIN_PREFIX)c++filt
HOST_SIZE := $(HOST_TOOLCHAIN_PREFIX)size
HOST_NM := $(HOST_TOOLCHAIN_PREFIX)nm
HOST_LD := $(HOST_TOOLCHAIN_PREFIX)ld
endif
HOST_OBJCOPY := $(HOST_TOOLCHAIN_PREFIX)objcopy
HOST_STRIP := $(HOST_TOOLCHAIN_PREFIX)strip
# Host compile flags
HOST_COMPILEFLAGS := -Wall -g -O2 -Isystem/public -Isystem/private -I$(GENERATED_INCLUDES)
HOST_CFLAGS := -std=c11
HOST_CPPFLAGS := -std=c++14 -fno-exceptions -fno-rtti
HOST_LDFLAGS :=
ifneq ($(HOST_USE_CLANG),)
# We need to use our provided libc++ and libc++abi (and their pthread
# dependency) rather than the host library. For host tools without
# C++, ignore the unused arguments.
HOST_CPPFLAGS += -stdlib=libc++
HOST_LDFLAGS += -stdlib=libc++ -static-libstdc++
# We don't need to link libc++abi.a on OS X.
ifneq ($(HOST_PLATFORM),darwin)
HOST_LDFLAGS += -Lprebuilt/downloads/clang+llvm-$(HOST_ARCH)-$(HOST_PLATFORM)/lib -Wl,-Bstatic -lc++abi -Wl,-Bdynamic -lpthread
endif
HOST_LDFLAGS += -Wno-unused-command-line-argument
endif
HOST_ASMFLAGS :=
ifneq ($(HOST_USE_CLANG),)
ifeq ($(HOST_PLATFORM),darwin)
HOST_SYSROOT ?= $(shell xcrun --show-sdk-path)
endif
endif
ifneq ($(HOST_SYSROOT),)
HOST_COMPILEFLAGS += --sysroot=$(HOST_SYSROOT)
endif
# the logic to compile and link stuff is in here
include make/build.mk
DEPS := $(ALLOBJS:%o=%d)
# put all of the build flags in various config.h files to force a rebuild if any change
GLOBAL_DEFINES += GLOBAL_INCLUDES=\"$(subst $(SPACE),_,$(GLOBAL_INCLUDES))\"
GLOBAL_DEFINES += GLOBAL_COMPILEFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_COMPILEFLAGS))\"
GLOBAL_DEFINES += GLOBAL_OPTFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_OPTFLAGS))\"
GLOBAL_DEFINES += GLOBAL_CFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_CFLAGS))\"
GLOBAL_DEFINES += GLOBAL_CPPFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_CPPFLAGS))\"
GLOBAL_DEFINES += GLOBAL_ASMFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_ASMFLAGS))\"
GLOBAL_DEFINES += GLOBAL_LDFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_LDFLAGS))\"
GLOBAL_DEFINES += ARCH_COMPILEFLAGS=\"$(subst $(SPACE),_,$(ARCH_COMPILEFLAGS))\"
GLOBAL_DEFINES += ARCH_CFLAGS=\"$(subst $(SPACE),_,$(ARCH_CFLAGS))\"
GLOBAL_DEFINES += ARCH_CPPFLAGS=\"$(subst $(SPACE),_,$(ARCH_CPPFLAGS))\"
GLOBAL_DEFINES += ARCH_ASMFLAGS=\"$(subst $(SPACE),_,$(ARCH_ASMFLAGS))\"
KERNEL_DEFINES += KERNEL_INCLUDES=\"$(subst $(SPACE),_,$(KERNEL_INCLUDES))\"
KERNEL_DEFINES += KERNEL_COMPILEFLAGS=\"$(subst $(SPACE),_,$(KERNEL_COMPILEFLAGS))\"
KERNEL_DEFINES += KERNEL_CFLAGS=\"$(subst $(SPACE),_,$(KERNEL_CFLAGS))\"
KERNEL_DEFINES += KERNEL_CPPFLAGS=\"$(subst $(SPACE),_,$(KERNEL_CPPFLAGS))\"
KERNEL_DEFINES += KERNEL_ASMFLAGS=\"$(subst $(SPACE),_,$(KERNEL_ASMFLAGS))\"
KERNEL_DEFINES += KERNEL_LDFLAGS=\"$(subst $(SPACE),_,$(KERNEL_LDFLAGS))\"
USER_DEFINES += USER_COMPILEFLAGS=\"$(subst $(SPACE),_,$(USER_COMPILEFLAGS))\"
USER_DEFINES += USER_CFLAGS=\"$(subst $(SPACE),_,$(USER_CFLAGS))\"
USER_DEFINES += USER_CPPFLAGS=\"$(subst $(SPACE),_,$(USER_CPPFLAGS))\"
USER_DEFINES += USER_ASMFLAGS=\"$(subst $(SPACE),_,$(USER_ASMFLAGS))\"
USER_DEFINES += USER_LDFLAGS=\"$(subst $(SPACE),_,$(USER_LDFLAGS))\"
HOST_DEFINES += HOST_COMPILEFLAGS=\"$(subst $(SPACE),_,$(HOST_COMPILEFLAGS))\"
HOST_DEFINES += HOST_CFLAGS=\"$(subst $(SPACE),_,$(HOST_CFLAGS))\"
HOST_DEFINES += HOST_CPPFLAGS=\"$(subst $(SPACE),_,$(HOST_CPPFLAGS))\"
HOST_DEFINES += HOST_ASMFLAGS=\"$(subst $(SPACE),_,$(HOST_ASMFLAGS))\"
HOST_DEFINES += HOST_LDFLAGS=\"$(subst $(SPACE),_,$(HOST_LDFLAGS))\"
#$(info LIBGCC = $(LIBGCC))
#$(info GLOBAL_COMPILEFLAGS = $(GLOBAL_COMPILEFLAGS))
#$(info GLOBAL_OPTFLAGS = $(GLOBAL_OPTFLAGS))
ifeq ($(call TOBOOL,$(ENABLE_ULIB_ONLY)),false)
# bootloader (x86-64 only for now)
# This needs to be after CC et al are set above.
ifeq ($(ARCH),x86)
include bootloader/build.mk
endif
endif
# make all object files depend on any targets in GLOBAL_SRCDEPS
$(ALLOBJS): $(GLOBAL_SRCDEPS)
# make all target object files depend on any targets in TARGET_MODDEPS
$(ALL_TARGET_OBJS): $(TARGET_MODDEPS)
# any extra top level build dependencies that someone may have declared
all:: $(EXTRA_BUILDDEPS)
clean: $(EXTRA_CLEANDEPS)
rm -f $(ALLOBJS)
rm -f $(DEPS)
rm -f $(GENERATED)
rm -f $(OUTLKBIN) $(OUTLKELF) $(OUTLKELF).lst $(OUTLKELF).debug.lst $(OUTLKELF).sym $(OUTLKELF).sym.sorted $(OUTLKELF).size $(OUTLKELF).hex $(OUTLKELF).dump $(OUTLKELF)-gdb.py
rm -f $(foreach app,$(ALLUSER_APPS),$(app) $(app).lst $(app).dump $(app).strip)
install: all
scp $(OUTLKBIN) 192.168.0.4:/tftproot
# generate a config-global.h file with all of the GLOBAL_DEFINES laid out in #define format
$(GLOBAL_CONFIG_HEADER): FORCE
@$(call MAKECONFIGHEADER,$@,GLOBAL_DEFINES,"#define __Fuchsia__ 1")
# generate a config-kernel.h file with all of the KERNEL_DEFINES laid out in #define format
$(KERNEL_CONFIG_HEADER): FORCE
@$(call MAKECONFIGHEADER,$@,KERNEL_DEFINES,"")
# generate a config-user.h file with all of the USER_DEFINES laid out in #define format
$(USER_CONFIG_HEADER): FORCE
@$(call MAKECONFIGHEADER,$@,USER_DEFINES,"")
$(HOST_CONFIG_HEADER): FORCE
@$(call MAKECONFIGHEADER,$@,HOST_DEFINES,"")
GENERATED += $(GLOBAL_CONFIG_HEADER) $(KERNEL_CONFIG_HEADER) $(USER_CONFIG_HEADER) $(HOST_CONFIG_HEADER)
# Empty rule for the .d files. The above rules will build .d files as a side
# effect. Only works on gcc 3.x and above, however.
%.d:
ifeq ($(filter $(MAKECMDGOALS), clean), )
-include $(DEPS)
endif
endif
endif # make spotless