flags.mk (3599B)
1 # mk/flags.mk 2 # =========================================================================== 3 # Compiler/linker flag derivation and the .build-config stamp. 4 # 5 # Consumes HOST_OS and HOST_SYSROOT_{C,LD}FLAGS from mk/env.mk and the 6 # RELEASE switch from the top-level Makefile; produces the *_CFLAGS / 7 # *_LDFLAGS the compile rules splice in. Nothing here branches on the host 8 # beyond the Darwin dead-strip choice. 9 10 ifeq ($(RELEASE),1) 11 HOST_OPTFLAGS ?= -O2 12 HOST_MODE_CPPFLAGS = -DNDEBUG 13 HOST_MODE_CFLAGS = -ffunction-sections -fdata-sections 14 ifeq ($(HOST_OS),darwin) 15 HOST_MODE_LDFLAGS = -Wl,-dead_strip -Wl,-S 16 else 17 HOST_MODE_LDFLAGS = -Wl,--gc-sections -Wl,-S 18 endif 19 else 20 HOST_OPTFLAGS ?= -O0 21 HOST_MODE_CPPFLAGS = 22 HOST_MODE_CFLAGS = -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls \ 23 -fsanitize=address,undefined \ 24 -fno-sanitize-recover=address,undefined \ 25 -fsanitize-address-use-after-scope 26 HOST_MODE_LDFLAGS = -fsanitize=address,undefined 27 ASAN_OPTIONS ?= halt_on_error=1:abort_on_error=1 28 UBSAN_OPTIONS ?= halt_on_error=1:print_stacktrace=1 29 export ASAN_OPTIONS UBSAN_OPTIONS 30 endif 31 32 # HOST_SYSROOT_{C,LD}FLAGS come from env.mk: a `-isysroot <path>` pair on 33 # Darwin, empty elsewhere. Stage/bootstrap recipes can clear these when 34 # kit itself is the compiler. 35 36 CFLAGS_COMMON = $(HOST_OPTFLAGS) $(HOST_MODE_CPPFLAGS) $(HOST_MODE_CFLAGS) \ 37 -std=c11 -Wpedantic -Wall -Wextra -Werror 38 HOST_CFLAGS = $(CFLAGS_COMMON) $(HOST_SYSROOT_CFLAGS) 39 HOST_LDFLAGS = $(HOST_SYSROOT_LDFLAGS) $(HOST_MODE_LDFLAGS) $(HOST_ENV_LDFLAGS) 40 41 DEPFLAGS = -MMD -MP 42 43 BUILD_CONFIG = $(BUILD_DIR)/.build-config 44 45 .PHONY: FORCE 46 FORCE: 47 48 $(BUILD_CONFIG): FORCE 49 @mkdir -p $(dir $@) 50 @{ \ 51 printf '%s\n' 'RELEASE=$(RELEASE)'; \ 52 printf '%s\n' 'HOST_OPTFLAGS=$(HOST_OPTFLAGS)'; \ 53 printf '%s\n' 'HOST_MODE_CPPFLAGS=$(HOST_MODE_CPPFLAGS)'; \ 54 printf '%s\n' 'HOST_MODE_CFLAGS=$(HOST_MODE_CFLAGS)'; \ 55 printf '%s\n' 'HOST_MODE_LDFLAGS=$(HOST_MODE_LDFLAGS)'; \ 56 } > $@.tmp 57 @if ! cmp -s $@.tmp $@; then mv $@.tmp $@; else rm -f $@.tmp; fi 58 59 # Freestanding objects must not see host SDK/libc headers. Homebrew clang can 60 # also inject a configured sysroot before command-line flags; use 61 # --no-default-config when the selected compiler supports it, but omit it for 62 # bootstrap stages where $(CC) is kit cc. 63 FREESTANDING_CONFIG_CFLAGS = $(shell $(CC) --no-default-config -x c -E /dev/null >/dev/null 2>&1 && printf '%s' --no-default-config) 64 FREESTANDING_CFLAGS = $(CFLAGS_COMMON) $(FREESTANDING_CONFIG_CFLAGS) -ffreestanding -nostdinc -Irt/include 65 66 # libkit: written in C11 freestanding; sees both src/ (internal) and 67 # include/ (its own public surface). 68 LIB_VISIBILITY_CFLAGS = -fvisibility=hidden 69 LIB_CFLAGS = $(FREESTANDING_CFLAGS) $(LIB_VISIBILITY_CFLAGS) -Iinclude -Isrc -Ivendor 70 71 # Driver: mostly freestanding CLI binary. Sees only the public include/ tree — 72 # that's what makes the driver the first consumer of libkit. -Ilang lets `cc` 73 # reach the C frontend's public header ("c/c.h") for the JIT REPL; it 74 # deliberately does NOT get -Isrc, so internal headers ("core/...", "link/...") 75 # are unreachable from the driver. 76 # 77 # driver/env/ holds all hosted OS/libc adapter code and is compiled with 78 # DRIVER_ENV_CFLAGS. The per-OS feature-test macros and the exact source 79 # list (DRIVER_ENV_OS_CFLAGS / DRIVER_ENV_SRCS) come from mk/env.mk. 80 DRIVER_CFLAGS = $(FREESTANDING_CFLAGS) -Iinclude -Ilang -Idriver -Idriver/lib 81 DRIVER_ENV_CFLAGS = $(HOST_CFLAGS) -Iinclude -Ilang -Idriver -Idriver/lib 82 TEST_HOST_CFLAGS = $(HOST_CFLAGS) -Iinclude -Ilang