commit ce021f13c697ea50f184ce1aeef44bef4b6e9a0e
parent 4bd590c72d314bb417d5eca0553be1ee2fa6f094
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Mon, 11 May 2026 17:17:45 -0700
Move runtime make rules into rt makefile
Diffstat:
| M | Makefile | | | 95 | ++++++++++--------------------------------------------------------------------- |
| M | rt/Makefile | | | 423 | +++++++++++++++++++++++++++++++++++++++++++------------------------------------ |
2 files changed, 243 insertions(+), 275 deletions(-)
diff --git a/Makefile b/Makefile
@@ -19,7 +19,9 @@ LIB_CFLAGS = $(CFLAGS_COMMON) -ffreestanding -Iinclude -Isrc
DRIVER_CFLAGS = $(CFLAGS_COMMON) -Iinclude
LIB_SRCS = $(shell find src -name '*.c')
-LIB_OBJS = $(patsubst src/%.c,build/lib/%.o,$(LIB_SRCS))
+LIB_ASMS = $(shell find src -name '*.S')
+LIB_OBJS = $(patsubst src/%.c,build/lib/%.o,$(LIB_SRCS)) \
+ $(patsubst src/%.S,build/lib/%.o,$(LIB_ASMS))
LIB_DEPS = $(LIB_OBJS:.o=.d)
DRIVER_SRCS = $(wildcard driver/*.c)
@@ -29,95 +31,14 @@ DRIVER_DEPS = $(DRIVER_OBJS:.o=.d)
LIB_AR = build/libcfree.a
BIN = build/cfree
-.PHONY: all lib driver bin rt rt-aarch64-linux rt-x86_64-linux rt-riscv64-linux \
- hosted-macos hosted-linux hosted-linux-aarch64 hosted-linux-x64 hosted-linux-rv64 \
- format clean self self-stage2
+.PHONY: all lib bin format clean self self-stage2
-# Default: compile libcfree.a, the driver objects, and link the cfree
-# binary. The link step currently fails because most libcfree functions
-# are header-only declarations — that's expected and tracks how much of
-# the implementation is still TODO.
-all: lib driver bin
+all: lib bin
lib: $(LIB_AR)
-driver: $(DRIVER_OBJS)
-
bin: $(BIN)
-# rt/ is the cfree compiler-rt equivalent: __extenddftf2 etc. — the
-# soft-float / 128-bit-int helpers clang emits when targeting our
-# variants. Each variant produces rt/build/<variant>/libcfree_rt.a.
-# The aarch64-linux variant (LDBL128=1) is what static-musl tests need.
-rt-aarch64-linux: rt/build/aarch64-linux/libcfree_rt.a
-rt-x86_64-linux: rt/build/x86_64-linux/libcfree_rt.a
-rt-riscv64-linux: rt/build/riscv64-linux/libcfree_rt.a
-
-rt/build/aarch64-linux/libcfree_rt.a:
- $(MAKE) -C rt VARIANT=aarch64-linux OUT=build/aarch64-linux all
-
-rt/build/x86_64-linux/libcfree_rt.a:
- $(MAKE) -C rt VARIANT=x86_64-linux OUT=build/x86_64-linux all
-
-rt/build/riscv64-linux/libcfree_rt.a:
- $(MAKE) -C rt VARIANT=riscv64-linux OUT=build/riscv64-linux all
-
-# `rt` alias builds whichever variants are typically wanted on the host.
-rt: rt-aarch64-linux
-
-# libcfree_hosted: tiny per-OS shim that bridges the ABI-neutral names in
-# rt/include/libc/ to whatever the platform libc actually exports. macOS
-# variant is the only one wired today.
-#
-# Built by cfree itself. The shim reads libSystem-imported global
-# variables (__stdinp, __stdoutp, __stderrp), which require Mach-O
-# GOT_LOAD_PAGE21 / GOT_LO12_NC relocations so dyld can route the load
-# through a non-lazy pointer in __DATA,__got; the AArch64 backend picks
-# that sequence automatically for undefined externs on Mach-O targets
-# (see use_got_for_sym in src/arch/aarch64.c).
-HOSTED_MACOS_AR = build/libcfree_hosted_macos.a
-HOSTED_MACOS_SRC = rt/lib/cfree_hosted/macos.c
-HOSTED_MACOS_OBJ = build/cfree_hosted/macos.o
-
-hosted-macos: $(HOSTED_MACOS_AR)
-
-$(HOSTED_MACOS_OBJ): $(HOSTED_MACOS_SRC) $(BIN)
- @mkdir -p $(dir $@)
- $(BIN) cc -target aarch64-darwin -c $< -o $@
-
-$(HOSTED_MACOS_AR): $(HOSTED_MACOS_OBJ) $(BIN)
- @rm -f $@
- $(BIN) ar rcs $@ $(HOSTED_MACOS_OBJ)
-
-# libcfree_hosted_linux: per-arch ELF shim object. Built by cfree-cc for
-# the cross-target so test-libc can link host-libc test cases against it
-# without needing clang's resource dir or a separate compile pass.
-# stdin/stdout/stderr are extern data globals on Linux; cfree-cc doesn't
-# yet emit GOT-loads for extern data on ELF (only Mach-O), so callers
-# must static-link the resulting exes — the addresses resolve at link
-# time when libc.a is in the input set.
-HOSTED_LINUX_SRC = rt/lib/cfree_hosted/linux.c
-HOSTED_LINUX_AARCH64_OBJ = build/cfree_hosted/linux-aarch64.o
-HOSTED_LINUX_X64_OBJ = build/cfree_hosted/linux-x64.o
-HOSTED_LINUX_RV64_OBJ = build/cfree_hosted/linux-rv64.o
-
-hosted-linux: hosted-linux-aarch64 hosted-linux-x64 hosted-linux-rv64
-hosted-linux-aarch64: $(HOSTED_LINUX_AARCH64_OBJ)
-hosted-linux-x64: $(HOSTED_LINUX_X64_OBJ)
-hosted-linux-rv64: $(HOSTED_LINUX_RV64_OBJ)
-
-$(HOSTED_LINUX_AARCH64_OBJ): $(HOSTED_LINUX_SRC) $(BIN)
- @mkdir -p $(dir $@)
- $(BIN) cc -target aarch64-linux -fPIE -fpic -c $< -o $@
-
-$(HOSTED_LINUX_X64_OBJ): $(HOSTED_LINUX_SRC) $(BIN)
- @mkdir -p $(dir $@)
- $(BIN) cc -target x86_64-linux -fPIE -fpic -c $< -o $@
-
-$(HOSTED_LINUX_RV64_OBJ): $(HOSTED_LINUX_SRC) $(BIN)
- @mkdir -p $(dir $@)
- $(BIN) cc -target riscv64-linux -fPIE -fpic -c $< -o $@
-
# Replace the archive (`ar rcs` only adds/updates), so removing a .c file
# also removes its .o from the archive on the next build.
$(LIB_AR): $(LIB_OBJS)
@@ -132,10 +53,16 @@ build/lib/%.o: src/%.c
@mkdir -p $(dir $@)
$(CC) $(LIB_CFLAGS) $(DEPFLAGS) -c $< -o $@
+build/lib/%.o: src/%.S
+ @mkdir -p $(dir $@)
+ $(CC) $(LIB_CFLAGS) $(DEPFLAGS) -c $< -o $@
+
build/driver/%.o: driver/%.c
@mkdir -p $(dir $@)
$(CC) $(DRIVER_CFLAGS) $(DEPFLAGS) -c $< -o $@
+include rt/Makefile
+
# Self-host: build cfree with clang (stage 1), then rebuild libcfree.a +
# driver + bin from clean using stage-1 cfree as CC (stage 2). Stage 1 is
# preserved at build/cfree-stage1; build/cfree is replaced with stage 2.
diff --git a/rt/Makefile b/rt/Makefile
@@ -1,11 +1,12 @@
-CC = clang
-AR = llvm-ar
-OUT = build
+# Included by the repository-root Makefile. Paths are root-relative.
-COMMON_CFLAGS = -ffreestanding -fno-builtin -std=c11 -Wpedantic -Wall -Wextra -Werror
-LIB_INCS = -Ilib/include/common -Ilib/impl
+RT_AR ?= llvm-ar
-VARIANTS = \
+RT_BUILD_DIR = rt/build
+RT_COMMON_CFLAGS = -ffreestanding -fno-builtin -std=c11 -Wpedantic -Wall -Wextra -Werror
+RT_LIB_INCS = -Irt/lib/include/common -Irt/lib/impl
+
+RT_VARIANTS = \
x86_64-linux \
x86_64-apple-darwin \
aarch64-linux \
@@ -21,196 +22,236 @@ VARIANTS = \
arm-eabi-thumb2 \
arm-eabi-thumb1
-.PHONY: all-targets $(VARIANTS)
-all-targets: $(VARIANTS)
+RT_DEFAULT_VARIANTS = \
+ aarch64-linux \
+ x86_64-linux \
+ riscv64-linux \
+ aarch64-apple-darwin \
+ x86_64-apple-darwin
+
+.PHONY: rt rt-all-targets $(addprefix rt-,$(RT_VARIANTS)) \
+ hosted-macos hosted-linux hosted-linux-aarch64 hosted-linux-x64 hosted-linux-rv64 \
+ clean-rt
-$(VARIANTS):
- $(MAKE) VARIANT=$@ OUT=build/$@ all
+rt: $(addprefix rt-,$(RT_DEFAULT_VARIANTS))
+rt-all-targets: $(addprefix rt-,$(RT_VARIANTS))
# ---------- variant feature flags --------------------------------------------
-# Select a named variant with VARIANT=, or override individual flags directly.
+# TARGET - clang target triple
+# ABI - lp64 | ilp32 | llp64
+# INT128 - 0 | 1
+# CORO - x86_64 | x86_64_win | i386 | aarch64 |
+# arm32 | arm32_thumb1 | riscv32 | riscv64 | empty
+# LDBL128 - 1 enables binary128 long double support
+# SAVE_RESTORE - 1 enables RISC-V save-restore routines
+# AEABI - thumb2 | thumb1 | empty
+# ARCH_FLAGS - extra target-specific flags
+
+RT_x86_64-linux_TARGET = x86_64-linux-gnu
+RT_x86_64-linux_ABI = lp64
+RT_x86_64-linux_INT128 = 1
+RT_x86_64-linux_CORO = x86_64
+
+RT_x86_64-apple-darwin_TARGET = x86_64-apple-darwin
+RT_x86_64-apple-darwin_ABI = lp64
+RT_x86_64-apple-darwin_INT128 = 1
+RT_x86_64-apple-darwin_CORO = x86_64
+
+RT_aarch64-linux_TARGET = aarch64-linux-gnu
+RT_aarch64-linux_ABI = lp64
+RT_aarch64-linux_INT128 = 1
+RT_aarch64-linux_CORO = aarch64
+RT_aarch64-linux_LDBL128 = 1
+
+RT_aarch64-apple-darwin_TARGET = aarch64-apple-darwin
+RT_aarch64-apple-darwin_ABI = lp64
+RT_aarch64-apple-darwin_INT128 = 1
+RT_aarch64-apple-darwin_CORO = aarch64
+
+RT_riscv64-linux_TARGET = riscv64-linux-gnu
+RT_riscv64-linux_ABI = lp64
+RT_riscv64-linux_INT128 = 1
+RT_riscv64-linux_CORO = riscv64
+RT_riscv64-linux_LDBL128 = 1
+RT_riscv64-linux_ARCH_FLAGS = -mabi=lp64d -march=rv64imafd
+
+RT_riscv64-elf_TARGET = riscv64-unknown-elf
+RT_riscv64-elf_ABI = lp64
+RT_riscv64-elf_INT128 = 1
+RT_riscv64-elf_CORO = riscv64
+RT_riscv64-elf_ARCH_FLAGS = -mabi=lp64 -march=rv64imafd
+
+RT_riscv64-elf-save-restore_TARGET = riscv64-unknown-elf
+RT_riscv64-elf-save-restore_ABI = lp64
+RT_riscv64-elf-save-restore_INT128 = 1
+RT_riscv64-elf-save-restore_CORO = riscv64
+RT_riscv64-elf-save-restore_SAVE_RESTORE = 1
+RT_riscv64-elf-save-restore_ARCH_FLAGS = -mabi=lp64 -march=rv64imafd
+
+RT_x86_64-pc-windows_TARGET = x86_64-pc-windows-msvc
+RT_x86_64-pc-windows_ABI = llp64
+RT_x86_64-pc-windows_INT128 = 1
+RT_x86_64-pc-windows_CORO = x86_64_win
+
+RT_i386-linux_TARGET = i386-linux-gnu
+RT_i386-linux_ABI = ilp32
+RT_i386-linux_INT128 = 0
+RT_i386-linux_CORO = i386
+
+RT_wasm32_TARGET = wasm32-unknown-unknown
+RT_wasm32_ABI = ilp32
+RT_wasm32_INT128 = 0
+
+RT_riscv32-elf_TARGET = riscv32-unknown-elf
+RT_riscv32-elf_ABI = ilp32
+RT_riscv32-elf_INT128 = 0
+RT_riscv32-elf_CORO = riscv32
+RT_riscv32-elf_ARCH_FLAGS = -mabi=ilp32 -march=rv32imafd
+
+RT_riscv32-elf-save-restore_TARGET = riscv32-unknown-elf
+RT_riscv32-elf-save-restore_ABI = ilp32
+RT_riscv32-elf-save-restore_INT128 = 0
+RT_riscv32-elf-save-restore_CORO = riscv32
+RT_riscv32-elf-save-restore_SAVE_RESTORE = 1
+RT_riscv32-elf-save-restore_ARCH_FLAGS = -mabi=ilp32 -march=rv32imafd
+
+RT_arm-eabi-thumb2_TARGET = arm-none-eabi
+RT_arm-eabi-thumb2_ABI = ilp32
+RT_arm-eabi-thumb2_INT128 = 0
+RT_arm-eabi-thumb2_CORO = arm32
+RT_arm-eabi-thumb2_AEABI = thumb2
+
+RT_arm-eabi-thumb1_TARGET = arm-none-eabi
+RT_arm-eabi-thumb1_ABI = ilp32
+RT_arm-eabi-thumb1_INT128 = 0
+RT_arm-eabi-thumb1_CORO = arm32_thumb1
+RT_arm-eabi-thumb1_AEABI = thumb1
+
+# ---------- sources and flags derived from features --------------------------
+RT_BASE_SRCS = \
+ rt/lib/int/int.c \
+ rt/lib/fp/fp.c \
+ rt/lib/mem/mem.c \
+ rt/lib/atomic/atomic_freestanding.c \
+ rt/lib/cfree/ifunc_init.c
+
+RT_ABI_SRCS_lp64 = rt/lib/int64/int64.c
+RT_ABI_SRCS_llp64 = rt/lib/int64/int64.c
+RT_ABI_SRCS_ilp32 = rt/lib/int32/int32.c
+
+RT_ABI_INC_lp64 = -Irt/lib/include/lp64_le
+RT_ABI_INC_llp64 = -Irt/lib/include/llp64_le
+RT_ABI_INC_ilp32 = -Irt/lib/include/ilp32_le
+
+RT_CORO_SRCS_x86_64 = rt/lib/coro/x86_64.c rt/lib/coro/coro.c
+RT_CORO_SRCS_x86_64_win = rt/lib/coro/x86_64_win.c rt/lib/coro/coro.c
+RT_CORO_SRCS_i386 = rt/lib/coro/i386.c rt/lib/coro/coro.c
+RT_CORO_SRCS_aarch64 = rt/lib/coro/aarch64.c rt/lib/coro/coro.c
+RT_CORO_SRCS_arm32 = rt/lib/coro/arm32.c rt/lib/coro/coro.c
+RT_CORO_SRCS_arm32_thumb1 = rt/lib/coro/arm32_thumb1.c rt/lib/coro/coro.c
+RT_CORO_SRCS_riscv32 = rt/lib/coro/riscv32.c rt/lib/coro/coro.c
+RT_CORO_SRCS_riscv64 = rt/lib/coro/riscv64.c rt/lib/coro/coro.c
+
+RT_LDBL128_SRCS = rt/lib/fp_tf/fp_tf.c rt/lib/fp_ti/fp_ti.c
+RT_LDBL128_FLAGS = -Irt/lib/include/lp64_le_ldbl128 \
+ -include rt/lib/include/lp64_le_ldbl128/tf_supplement.h
+
+RT_SAVE_RESTORE_SRCS_lp64 = rt/lib/riscv/rv64.S
+RT_SAVE_RESTORE_SRCS_ilp32 = rt/lib/riscv/rv32.S
+RT_SAVE_RESTORE_FLAGS = -msave-restore
+
+RT_AEABI_SRCS_thumb2 = rt/lib/arm/aeabi_thumb2.S rt/lib/arm/aeabi.c
+RT_AEABI_SRCS_thumb1 = rt/lib/arm/aeabi_thumb1.S rt/lib/arm/aeabi.c
+RT_AEABI_FLAGS_thumb2 = -march=armv7-a -mthumb -mfloat-abi=soft
+RT_AEABI_FLAGS_thumb1 = -march=armv6-m -mthumb -mfloat-abi=soft
+
+define RT_VARIANT_template
+RT_SRCS_$(1) := \
+ $$(RT_BASE_SRCS) \
+ $$(RT_ABI_SRCS_$$(RT_$(1)_ABI)) \
+ $$(RT_CORO_SRCS_$$(RT_$(1)_CORO)) \
+ $$(if $$(RT_$(1)_LDBL128),$$(RT_LDBL128_SRCS)) \
+ $$(if $$(RT_$(1)_SAVE_RESTORE),$$(RT_SAVE_RESTORE_SRCS_$$(RT_$(1)_ABI))) \
+ $$(RT_AEABI_SRCS_$$(RT_$(1)_AEABI))
+RT_CFLAGS_$(1) := \
+ $$(RT_COMMON_CFLAGS) $$(RT_LIB_INCS) \
+ --target=$$(RT_$(1)_TARGET) \
+ -DHAS_INT128=$$(RT_$(1)_INT128) \
+ $$(RT_ABI_INC_$$(RT_$(1)_ABI)) \
+ $$(RT_$(1)_ARCH_FLAGS) \
+ $$(if $$(RT_$(1)_LDBL128),$$(RT_LDBL128_FLAGS)) \
+ $$(if $$(RT_$(1)_CORO),-Irt/include) \
+ $$(if $$(RT_$(1)_SAVE_RESTORE),$$(RT_SAVE_RESTORE_FLAGS)) \
+ $$(RT_AEABI_FLAGS_$$(RT_$(1)_AEABI))
+RT_OBJS_$(1) := $$(patsubst rt/lib/%,$$(RT_BUILD_DIR)/$(1)/%.o,$$(RT_SRCS_$(1)))
+
+rt-$(1): $$(RT_BUILD_DIR)/$(1)/libcfree_rt.a
+
+$$(RT_BUILD_DIR)/$(1)/libcfree_rt.a: $$(RT_OBJS_$(1))
+ @mkdir -p $$(dir $$@)
+ $$(RT_AR) rcs $$@ $$^
+
+$$(RT_BUILD_DIR)/$(1)/%.o: rt/lib/%
+ @mkdir -p $$(dir $$@)
+ $$(CC) $$(RT_CFLAGS_$(1)) -c $$< -o $$@
+endef
+
+$(foreach variant,$(RT_VARIANTS),$(eval $(call RT_VARIANT_template,$(variant))))
+
+# libcfree_hosted: tiny per-OS shim that bridges the ABI-neutral names in
+# rt/include/libc/ to whatever the platform libc actually exports. macOS
+# variant is the only one wired today.
#
-# TARGET — clang target triple (required)
-# ABI — lp64 | ilp32 | llp64
-# INT128 — 0 | 1
-# CORO — x86_64 | x86_64_win | i386 | aarch64 |
-# arm32 | arm32_thumb1 | riscv32 | riscv64 | (empty = none)
-# LDBL128 — 0 | 1 (long double = binary128; only aarch64-linux)
-# SAVE_RESTORE — 0 | 1 (RISC-V save-restore routines)
-# AEABI — thumb2 | thumb1 | (empty = none)
-# ARCH_FLAGS — extra target-specific flags (e.g. -mabi=lp64 -march=rv64imafd)
-
-VARIANT ?= aarch64-apple-darwin
-
-ifeq ($(VARIANT),x86_64-linux)
- TARGET = x86_64-linux-gnu
- ABI = lp64
- INT128 = 1
- CORO = x86_64
-endif
-ifeq ($(VARIANT),x86_64-apple-darwin)
- TARGET = x86_64-apple-darwin
- ABI = lp64
- INT128 = 1
- CORO = x86_64
-endif
-ifeq ($(VARIANT),aarch64-linux)
- TARGET = aarch64-linux-gnu
- ABI = lp64
- INT128 = 1
- CORO = aarch64
- LDBL128 = 1
-endif
-ifeq ($(VARIANT),aarch64-apple-darwin)
- TARGET = aarch64-apple-darwin
- ABI = lp64
- INT128 = 1
- CORO = aarch64
-endif
-ifeq ($(VARIANT),riscv64-linux)
- TARGET = riscv64-linux-gnu
- ABI = lp64
- INT128 = 1
- CORO = riscv64
- LDBL128 = 1
- ARCH_FLAGS = -mabi=lp64d -march=rv64imafd
-endif
-ifeq ($(VARIANT),riscv64-elf)
- TARGET = riscv64-unknown-elf
- ABI = lp64
- INT128 = 1
- CORO = riscv64
- ARCH_FLAGS = -mabi=lp64 -march=rv64imafd
-endif
-ifeq ($(VARIANT),riscv64-elf-save-restore)
- TARGET = riscv64-unknown-elf
- ABI = lp64
- INT128 = 1
- CORO = riscv64
- SAVE_RESTORE = 1
- ARCH_FLAGS = -mabi=lp64 -march=rv64imafd
-endif
-ifeq ($(VARIANT),x86_64-pc-windows)
- TARGET = x86_64-pc-windows-msvc
- ABI = llp64
- INT128 = 1
- CORO = x86_64_win
-endif
-ifeq ($(VARIANT),i386-linux)
- TARGET = i386-linux-gnu
- ABI = ilp32
- INT128 = 0
- CORO = i386
-endif
-ifeq ($(VARIANT),wasm32)
- TARGET = wasm32-unknown-unknown
- ABI = ilp32
- INT128 = 0
-endif
-ifeq ($(VARIANT),riscv32-elf)
- TARGET = riscv32-unknown-elf
- ABI = ilp32
- INT128 = 0
- CORO = riscv32
- ARCH_FLAGS = -mabi=ilp32 -march=rv32imafd
-endif
-ifeq ($(VARIANT),riscv32-elf-save-restore)
- TARGET = riscv32-unknown-elf
- ABI = ilp32
- INT128 = 0
- CORO = riscv32
- SAVE_RESTORE = 1
- ARCH_FLAGS = -mabi=ilp32 -march=rv32imafd
-endif
-ifeq ($(VARIANT),arm-eabi-thumb2)
- TARGET = arm-none-eabi
- ABI = ilp32
- INT128 = 0
- CORO = arm32
- AEABI = thumb2
-endif
-ifeq ($(VARIANT),arm-eabi-thumb1)
- TARGET = arm-none-eabi
- ABI = ilp32
- INT128 = 0
- CORO = arm32_thumb1
- AEABI = thumb1
-endif
-
-# defaults for unset flags
-ABI ?= lp64
-INT128 ?= 1
-CORO ?=
-LDBL128 ?= 0
-SAVE_RESTORE ?= 0
-AEABI ?=
-ARCH_FLAGS ?=
-
-# ---------- sources derived from features ------------------------------------
-SRCS = lib/int/int.c lib/fp/fp.c lib/mem/mem.c lib/atomic/atomic_freestanding.c \
- lib/cfree/ifunc_init.c
-
-ifeq ($(ABI),lp64)
- SRCS += lib/int64/int64.c
- ABI_INC = -Ilib/include/lp64_le
-endif
-ifeq ($(ABI),llp64)
- SRCS += lib/int64/int64.c
- ABI_INC = -Ilib/include/llp64_le
-endif
-ifeq ($(ABI),ilp32)
- SRCS += lib/int32/int32.c
- ABI_INC = -Ilib/include/ilp32_le
-endif
-
-ifeq ($(LDBL128),1)
- SRCS += lib/fp_tf/fp_tf.c lib/fp_ti/fp_ti.c
- LDBL128_FLAGS = -Ilib/include/lp64_le_ldbl128 \
- -include lib/include/lp64_le_ldbl128/tf_supplement.h
-endif
-
-ifneq ($(CORO),)
- SRCS += lib/coro/$(CORO).c lib/coro/coro.c
- CORO_INC = -Iinclude
-endif
-
-ifeq ($(SAVE_RESTORE),1)
- ifeq ($(ABI),lp64)
- SRCS += lib/riscv/rv64.S
- else
- SRCS += lib/riscv/rv32.S
- endif
- ARCH_FLAGS += -msave-restore
-endif
-
-ifeq ($(AEABI),thumb2)
- SRCS += lib/arm/aeabi_thumb2.S lib/arm/aeabi.c
- ARCH_FLAGS += -march=armv7-a -mthumb -mfloat-abi=soft
-endif
-ifeq ($(AEABI),thumb1)
- SRCS += lib/arm/aeabi_thumb1.S lib/arm/aeabi.c
- ARCH_FLAGS += -march=armv6-m -mthumb -mfloat-abi=soft
-endif
-
-# ---------- compiler flags from features -------------------------------------
-CFLAGS = $(COMMON_CFLAGS) $(LIB_INCS)
-CFLAGS += --target=$(TARGET) -DHAS_INT128=$(INT128)
-CFLAGS += $(ABI_INC) $(ARCH_FLAGS) $(LDBL128_FLAGS) $(CORO_INC)
-
-# ---------- rules -------------------------------------------------------------
-OBJS = $(patsubst lib/%,$(OUT)/%.o,$(SRCS))
-
-.PHONY: all clean
-
-all: $(OUT)/libcfree_rt.a
-
-$(OBJS): $(OUT)/%.o: lib/%
+# Built by cfree itself. The shim reads libSystem-imported global
+# variables (__stdinp, __stdoutp, __stderrp), which require Mach-O
+# GOT_LOAD_PAGE21 / GOT_LO12_NC relocations so dyld can route the load
+# through a non-lazy pointer in __DATA,__got; the AArch64 backend picks
+# that sequence automatically for undefined externs on Mach-O targets
+# (see use_got_for_sym in src/arch/aarch64.c).
+RT_HOSTED_MACOS_AR = build/libcfree_hosted_macos.a
+RT_HOSTED_MACOS_SRC = rt/lib/cfree_hosted/macos.c
+RT_HOSTED_MACOS_OBJ = build/cfree_hosted/macos.o
+
+hosted-macos: $(RT_HOSTED_MACOS_AR)
+
+$(RT_HOSTED_MACOS_OBJ): $(RT_HOSTED_MACOS_SRC) $(BIN)
@mkdir -p $(dir $@)
- $(CC) $(CFLAGS) -c $< -o $@
+ $(BIN) cc -target aarch64-darwin -c $< -o $@
+
+$(RT_HOSTED_MACOS_AR): $(RT_HOSTED_MACOS_OBJ) $(BIN)
+ @rm -f $@
+ $(BIN) ar rcs $@ $(RT_HOSTED_MACOS_OBJ)
+
+# libcfree_hosted_linux: per-arch ELF shim object. Built by cfree-cc for
+# the cross-target so test-libc can link host-libc test cases against it
+# without needing clang's resource dir or a separate compile pass.
+# stdin/stdout/stderr are extern data globals on Linux; cfree-cc doesn't
+# yet emit GOT-loads for extern data on ELF (only Mach-O), so callers
+# must static-link the resulting exes - the addresses resolve at link
+# time when libc.a is in the input set.
+RT_HOSTED_LINUX_SRC = rt/lib/cfree_hosted/linux.c
+RT_HOSTED_LINUX_AARCH64_OBJ = build/cfree_hosted/linux-aarch64.o
+RT_HOSTED_LINUX_X64_OBJ = build/cfree_hosted/linux-x64.o
+RT_HOSTED_LINUX_RV64_OBJ = build/cfree_hosted/linux-rv64.o
-$(OUT)/libcfree_rt.a: $(OBJS)
+hosted-linux: hosted-linux-aarch64 hosted-linux-x64 hosted-linux-rv64
+hosted-linux-aarch64: $(RT_HOSTED_LINUX_AARCH64_OBJ)
+hosted-linux-x64: $(RT_HOSTED_LINUX_X64_OBJ)
+hosted-linux-rv64: $(RT_HOSTED_LINUX_RV64_OBJ)
+
+$(RT_HOSTED_LINUX_AARCH64_OBJ): $(RT_HOSTED_LINUX_SRC) $(BIN)
@mkdir -p $(dir $@)
- $(AR) rcs $@ $^
+ $(BIN) cc -target aarch64-linux -fPIE -fpic -c $< -o $@
+
+$(RT_HOSTED_LINUX_X64_OBJ): $(RT_HOSTED_LINUX_SRC) $(BIN)
+ @mkdir -p $(dir $@)
+ $(BIN) cc -target x86_64-linux -fPIE -fpic -c $< -o $@
+
+$(RT_HOSTED_LINUX_RV64_OBJ): $(RT_HOSTED_LINUX_SRC) $(BIN)
+ @mkdir -p $(dir $@)
+ $(BIN) cc -target riscv64-linux -fPIE -fpic -c $< -o $@
+
+clean: clean-rt
-clean:
- rm -rf $(OUT)
+clean-rt:
+ rm -rf $(RT_BUILD_DIR)