env.mk (6973B)
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 # ---- per-OS env wiring ----------------------------------------------------- 94 95 DRIVER_ENV_OS_CFLAGS := 96 DRIVER_ENV_HINT_SRC := 97 HOST_LDLIBS := 98 HOST_ENV_LDFLAGS := 99 100 ifeq ($(HOST_OS),darwin) 101 DRIVER_ENV_OS_CFLAGS := -D_XOPEN_SOURCE=600 -D_DARWIN_C_SOURCE=1 102 DRIVER_ENV_OS_SRC := driver/env/macos.c 103 else ifeq ($(HOST_OS),linux) 104 DRIVER_ENV_OS_CFLAGS := -D_GNU_SOURCE=1 105 DRIVER_ENV_OS_SRC := driver/env/linux.c 106 ifeq ($(HOST_ARCH),x86_64) 107 DRIVER_ENV_HINT_SRC := driver/env/linux_exec_hint_x86_64.c 108 else 109 DRIVER_ENV_HINT_SRC := driver/env/linux_exec_hint_default.c 110 endif 111 else ifeq ($(HOST_OS),freebsd) 112 DRIVER_ENV_OS_SRC := driver/env/freebsd.c 113 HOST_LDLIBS += -lpthread 114 # Export all globals so libc.so can resolve symbols like `environ` from the exe 115 HOST_ENV_LDFLAGS += -rdynamic 116 else ifeq ($(HOST_OS),windows) 117 # windows.c subsumes posix.c / posix_dbg.c and folds in its own 118 # CONTEXT-based register marshalling -- there's no POSIX overlap worth 119 # sharing. EnumProcessModules pulls in -lpsapi. 120 DRIVER_ENV_OS_CFLAGS := -D_WIN32_WINNT=0x0601 121 DRIVER_ENV_OS_SRC := driver/env/windows.c 122 HOST_LDLIBS += -lpsapi 123 endif 124 125 # ---- per-arch icache flush TU --------------------------------------------- 126 127 ifeq ($(HOST_ARCH),x86_64) 128 DRIVER_ENV_ICACHE_SRC := driver/env/icache_x86.c 129 else ifeq ($(HOST_ARCH),aarch64) 130 DRIVER_ENV_ICACHE_SRC := driver/env/icache_arm.c 131 else ifeq ($(HOST_ARCH),rv64) 132 DRIVER_ENV_ICACHE_SRC := driver/env/icache_riscv.c 133 endif 134 135 # ---- per-(arch, OS) ucontext marshalling (POSIX only) --------------------- 136 137 DRIVER_ENV_UCTX_SRC := 138 ifeq ($(HOST_OS),darwin) 139 ifeq ($(HOST_ARCH),aarch64) 140 DRIVER_ENV_UCTX_SRC := driver/env/uctx_aarch64_macos.c 141 endif 142 else ifeq ($(HOST_OS),linux) 143 ifeq ($(HOST_ARCH),aarch64) 144 DRIVER_ENV_UCTX_SRC := driver/env/uctx_aarch64_linux.c 145 else ifeq ($(HOST_ARCH),x86_64) 146 DRIVER_ENV_UCTX_SRC := driver/env/uctx_x86_64_linux.c 147 else ifeq ($(HOST_ARCH),rv64) 148 DRIVER_ENV_UCTX_SRC := driver/env/uctx_rv64_linux.c 149 endif 150 else ifeq ($(HOST_OS),freebsd) 151 ifeq ($(HOST_ARCH),aarch64) 152 DRIVER_ENV_UCTX_SRC := driver/env/uctx_aarch64_freebsd.c 153 else ifeq ($(HOST_ARCH),x86_64) 154 DRIVER_ENV_UCTX_SRC := driver/env/uctx_x86_64_freebsd.c 155 else ifeq ($(HOST_ARCH),rv64) 156 DRIVER_ENV_UCTX_SRC := driver/env/uctx_rv64_freebsd.c 157 endif 158 endif 159 160 ifneq ($(HOST_OS),windows) 161 ifeq ($(DRIVER_ENV_UCTX_SRC),) 162 $(error env.mk: no ucontext marshalling for HOST_OS=$(HOST_OS) HOST_ARCH=$(HOST_ARCH)) 163 endif 164 endif 165 166 # ---- DRIVER_ENV_SRCS ------------------------------------------------------- 167 # common.c is the libc-pure floor shared by every host (heap/diag/printf/ 168 # string helpers; no syscalls). POSIX hosts layer on the shared POSIX 169 # scaffolding (file I/O, mkdir, sigint, exec_dual registry, signals, 170 # pthread TLS) plus the per-OS file and the per-(arch, OS) uctx TU. 171 # Windows has no POSIX overlap; windows.c is the entire host surface. 172 173 ifeq ($(HOST_OS),windows) 174 DRIVER_ENV_SRCS := \ 175 driver/env/common.c \ 176 $(DRIVER_ENV_OS_SRC) \ 177 $(DRIVER_ENV_ICACHE_SRC) 178 else 179 DRIVER_ENV_SRCS := \ 180 driver/env/common.c \ 181 driver/env/posix.c \ 182 driver/env/posix_dbg.c \ 183 $(DRIVER_ENV_OS_SRC) \ 184 $(DRIVER_ENV_HINT_SRC) \ 185 $(DRIVER_ENV_ICACHE_SRC) \ 186 $(DRIVER_ENV_UCTX_SRC) 187 endif