env.mk (7404B)
1 # mk/env.mk 2 # =========================================================================== 3 # Host environment detection and driver/env source selection. 4 # 5 # This file is the *only* place in the build system that branches on the 6 # host OS or arch. It produces the variables below; the rest of the build 7 # consumes them directly without re-deriving anything from `uname`. 8 # 9 # Contract: 10 # 11 # Detection: 12 # HOST_UNAME raw `uname -s` (Darwin / Linux / FreeBSD / 13 # MINGW64_NT-* / MSYS_NT-* / CYGWIN_NT-*) 14 # HOST_ARCH_RAW raw `uname -m` 15 # HOST_OS normalized OS tag: darwin | linux | freebsd 16 # | windows. Unknown is a hard error. 17 # HOST_ARCH normalized arch tag: x86_64 | aarch64 | rv64. 18 # Unknown is a hard error. 19 # 20 # Host SDK (Darwin only; empty elsewhere so `$(HOST_SYSROOT_CFLAGS)` is 21 # still safe to splice into any command line): 22 # HOST_SDK_PATH the resolved -isysroot path, or empty 23 # HOST_SYSROOT_CFLAGS `-isysroot <path>` or empty 24 # HOST_SYSROOT_LDFLAGS `-isysroot <path>` or empty 25 # 26 # driver/env wiring: 27 # DRIVER_ENV_OS_CFLAGS feature-test macros required by the per-OS env 28 # TU before any libc header is included 29 # (-D_XOPEN_SOURCE, -D_GNU_SOURCE, -D_WIN32_WINNT, 30 # ...) 31 # DRIVER_ENV_SRCS exact set of driver/env/*.c files to compile 32 # into the host binary. One file per OS, one 33 # per arch (icache), and on POSIX one per 34 # (arch, OS) for ucontext marshalling. Removing 35 # OS/arch ifdefs from the impl is the explicit 36 # point of this layout. 37 # 38 # Link surface: 39 # HOST_LDLIBS extra libraries the host link needs because of 40 # env choices (-lpsapi on Windows for 41 # EnumProcessModules). The main Makefile splices 42 # this onto the binary's link line. 43 # 44 # Not produced here: HOST_OPTFLAGS / HOST_MODE_*FLAGS. Those are 45 # build-mode (debug vs release) concerns, not env concerns; they live in 46 # the main Makefile. 47 48 HOST_UNAME := $(shell uname -s) 49 HOST_ARCH_RAW := $(shell uname -m) 50 51 # ---- HOST_OS --------------------------------------------------------------- 52 53 ifeq ($(HOST_UNAME),Darwin) 54 HOST_OS := darwin 55 else ifeq ($(HOST_UNAME),Linux) 56 HOST_OS := linux 57 else ifeq ($(HOST_UNAME),FreeBSD) 58 HOST_OS := freebsd 59 else ifneq ($(filter MINGW% MSYS% CYGWIN%,$(HOST_UNAME)),) 60 HOST_OS := windows 61 else 62 $(error env.mk: unsupported HOST_UNAME=$(HOST_UNAME); see driver/env/windows.c for the Windows port skeleton) 63 endif 64 65 # ---- HOST_ARCH ------------------------------------------------------------- 66 67 ifneq ($(filter $(HOST_ARCH_RAW),x86_64 amd64),) 68 HOST_ARCH := x86_64 69 else ifneq ($(filter $(HOST_ARCH_RAW),aarch64 arm64),) 70 HOST_ARCH := aarch64 71 else ifneq ($(filter $(HOST_ARCH_RAW),riscv64),) 72 HOST_ARCH := rv64 73 else 74 $(error env.mk: unsupported HOST_ARCH_RAW=$(HOST_ARCH_RAW)) 75 endif 76 77 # ---- host SDK (Darwin only) ----------------------------------------------- 78 # -isysroot is a Darwin-only flag and xcrun lives there too. On Linux / 79 # FreeBSD / Windows we leave the vars empty so the host link/compile lines 80 # stay well-formed when they splice $(HOST_SYSROOT_*FLAGS). 81 82 HOST_SDK_PATH := 83 HOST_SYSROOT_CFLAGS := 84 HOST_SYSROOT_LDFLAGS := 85 ifeq ($(HOST_OS),darwin) 86 HOST_SDK_PATH := $(shell xcrun --show-sdk-path 2>/dev/null) 87 ifneq ($(HOST_SDK_PATH),) 88 HOST_SYSROOT_CFLAGS := -isysroot $(HOST_SDK_PATH) 89 HOST_SYSROOT_LDFLAGS := -isysroot $(HOST_SDK_PATH) 90 endif 91 endif 92 93 # ---- user-level sysroot cache dir ----------------------------------------- 94 # Mirrors the XDG convention used by the per-OS provisioner scripts. 95 # Override by setting XDG_CACHE_HOME or KIT_CACHE_DIR in the environment. 96 XDG_CACHE_HOME ?= $(HOME)/.cache 97 KIT_CACHE_DIR ?= $(XDG_CACHE_HOME)/kit 98 KIT_SYSROOTS_DIR ?= $(KIT_CACHE_DIR)/sysroots 99 100 # ---- per-OS env wiring ----------------------------------------------------- 101 102 DRIVER_ENV_OS_CFLAGS := 103 DRIVER_ENV_HINT_SRC := 104 HOST_LDLIBS := 105 HOST_ENV_LDFLAGS := 106 107 ifeq ($(HOST_OS),darwin) 108 DRIVER_ENV_OS_CFLAGS := -D_XOPEN_SOURCE=600 -D_DARWIN_C_SOURCE=1 109 DRIVER_ENV_OS_SRC := driver/env/macos.c 110 else ifeq ($(HOST_OS),linux) 111 DRIVER_ENV_OS_CFLAGS := -D_GNU_SOURCE=1 112 DRIVER_ENV_OS_SRC := driver/env/linux.c 113 ifeq ($(HOST_ARCH),x86_64) 114 DRIVER_ENV_HINT_SRC := driver/env/linux_exec_hint_x86_64.c 115 else 116 DRIVER_ENV_HINT_SRC := driver/env/linux_exec_hint_default.c 117 endif 118 else ifeq ($(HOST_OS),freebsd) 119 DRIVER_ENV_OS_SRC := driver/env/freebsd.c 120 HOST_LDLIBS += -lpthread 121 # Export all globals so libc.so can resolve symbols like `environ` from the exe 122 HOST_ENV_LDFLAGS += -rdynamic 123 else ifeq ($(HOST_OS),windows) 124 # windows.c subsumes posix.c / posix_dbg.c and folds in its own 125 # CONTEXT-based register marshalling -- there's no POSIX overlap worth 126 # sharing. EnumProcessModules pulls in -lpsapi. 127 DRIVER_ENV_OS_CFLAGS := -D_WIN32_WINNT=0x0601 128 DRIVER_ENV_OS_SRC := driver/env/windows.c 129 HOST_LDLIBS += -lpsapi 130 endif 131 132 # ---- per-arch icache flush TU --------------------------------------------- 133 134 ifeq ($(HOST_ARCH),x86_64) 135 DRIVER_ENV_ICACHE_SRC := driver/env/icache_x86.c 136 else ifeq ($(HOST_ARCH),aarch64) 137 DRIVER_ENV_ICACHE_SRC := driver/env/icache_arm.c 138 else ifeq ($(HOST_ARCH),rv64) 139 DRIVER_ENV_ICACHE_SRC := driver/env/icache_riscv.c 140 endif 141 142 # ---- per-(arch, OS) ucontext marshalling (POSIX only) --------------------- 143 144 DRIVER_ENV_UCTX_SRC := 145 ifeq ($(HOST_OS),darwin) 146 ifeq ($(HOST_ARCH),aarch64) 147 DRIVER_ENV_UCTX_SRC := driver/env/uctx_aarch64_macos.c 148 else ifeq ($(HOST_ARCH),x86_64) 149 DRIVER_ENV_UCTX_SRC := driver/env/uctx_x86_64_macos.c 150 endif 151 else ifeq ($(HOST_OS),linux) 152 ifeq ($(HOST_ARCH),aarch64) 153 DRIVER_ENV_UCTX_SRC := driver/env/uctx_aarch64_linux.c 154 else ifeq ($(HOST_ARCH),x86_64) 155 DRIVER_ENV_UCTX_SRC := driver/env/uctx_x86_64_linux.c 156 else ifeq ($(HOST_ARCH),rv64) 157 DRIVER_ENV_UCTX_SRC := driver/env/uctx_rv64_linux.c 158 endif 159 else ifeq ($(HOST_OS),freebsd) 160 ifeq ($(HOST_ARCH),aarch64) 161 DRIVER_ENV_UCTX_SRC := driver/env/uctx_aarch64_freebsd.c 162 else ifeq ($(HOST_ARCH),x86_64) 163 DRIVER_ENV_UCTX_SRC := driver/env/uctx_x86_64_freebsd.c 164 else ifeq ($(HOST_ARCH),rv64) 165 DRIVER_ENV_UCTX_SRC := driver/env/uctx_rv64_freebsd.c 166 endif 167 endif 168 169 ifneq ($(HOST_OS),windows) 170 ifeq ($(DRIVER_ENV_UCTX_SRC),) 171 $(error env.mk: no ucontext marshalling for HOST_OS=$(HOST_OS) HOST_ARCH=$(HOST_ARCH)) 172 endif 173 endif 174 175 # ---- DRIVER_ENV_SRCS ------------------------------------------------------- 176 # common.c is the libc-pure floor shared by every host (heap/diag/printf/ 177 # string helpers; no syscalls). POSIX hosts layer on the shared POSIX 178 # scaffolding (file I/O, mkdir, sigint, exec_dual registry, signals, 179 # pthread TLS) plus the per-OS file and the per-(arch, OS) uctx TU. 180 # Windows has no POSIX overlap; windows.c is the entire host surface. 181 182 ifeq ($(HOST_OS),windows) 183 DRIVER_ENV_SRCS := \ 184 driver/env/common.c \ 185 $(DRIVER_ENV_OS_SRC) \ 186 $(DRIVER_ENV_ICACHE_SRC) 187 else 188 DRIVER_ENV_SRCS := \ 189 driver/env/common.c \ 190 driver/env/posix.c \ 191 driver/env/posix_dbg.c \ 192 $(DRIVER_ENV_OS_SRC) \ 193 $(DRIVER_ENV_HINT_SRC) \ 194 $(DRIVER_ENV_ICACHE_SRC) \ 195 $(DRIVER_ENV_UCTX_SRC) 196 endif