commit 3faa02c28b1de79212bfe7cc50b0525c22040002
parent ab675f5697a19ecc6d59233c1acfb096b0656588
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 20 May 2026 20:49:53 -0700
Place runtime cache under build rt
Diffstat:
11 files changed, 55 insertions(+), 19 deletions(-)
diff --git a/doc/RT_CFREERT_CHECKLIST.md b/doc/RT_CFREERT_CHECKLIST.md
@@ -12,7 +12,7 @@ and the freestanding runtime headers without requiring a system SDK.
```sh
make bin
-rm -rf rt/build/aarch64-apple-darwin
+rm -rf build/rt/aarch64-apple-darwin
env CC="$PWD/build/cfree cc" \
RT_AS="$PWD/build/cfree as" \
RT_AR="$PWD/build/cfree ar" \
@@ -40,7 +40,7 @@ As of the latest probe, cfree builds or assembles:
- [x] `rt/lib/coro/aarch64_macho.s`
That is 9 / 9 compile or assemble steps green for this variant, and
-`cfree ar` produces `rt/build/aarch64-apple-darwin/libcfree_rt.a`.
+`cfree ar` produces `build/rt/aarch64-apple-darwin/libcfree_rt.a`.
## Completed
diff --git a/driver/runtime.c b/driver/runtime.c
@@ -112,6 +112,42 @@ static char* rt_join(DriverEnv* env, const char* a, const char* b,
return p;
}
+static int rt_basename_is(const char* path, const char* name) {
+ const char* base;
+ const char* end;
+ size_t n;
+ size_t len;
+ if (!path || !name) return 0;
+ end = path + driver_strlen(path);
+ while (end > path && end[-1] == '/') --end;
+ base = end;
+ while (base > path && base[-1] != '/') --base;
+ n = (size_t)(end - base);
+ len = driver_strlen(name);
+ if (n != len) return 0;
+ while (len) {
+ if (*base++ != *name++) return 0;
+ --len;
+ }
+ return 1;
+}
+
+static char* rt_build_cache_root(DriverEnv* env, const char* support_root,
+ int runtime_root_is_support,
+ size_t* out_size) {
+ char* parent;
+ char* cache_root;
+ size_t parent_size = 0;
+ if (runtime_root_is_support && rt_basename_is(support_root, "rt")) {
+ parent = rt_join(env, support_root, "..", &parent_size);
+ if (!parent) return NULL;
+ cache_root = rt_join(env, parent, "build/rt", out_size);
+ driver_free(env, parent, parent_size);
+ return cache_root;
+ }
+ return rt_join(env, support_root, "build/rt", out_size);
+}
+
static void rt_free_str(DriverEnv* env, char** p, size_t* n) {
if (*p) driver_free(env, *p, *n);
*p = NULL;
@@ -156,7 +192,7 @@ static int rt_try_support_root(DriverEnv* env, const char* root,
int ok = 1;
if (rt_has_layout(root)) {
- cache_root = rt_join(env, root, "build", &cache_root_size);
+ cache_root = rt_build_cache_root(env, root, 1, &cache_root_size);
if (!cache_root) return 1;
ok = rt_set_layout(env, out, root, root, cache_root);
driver_free(env, cache_root, cache_root_size);
@@ -164,7 +200,7 @@ static int rt_try_support_root(DriverEnv* env, const char* root,
}
rt_root = rt_join(env, root, "rt", &rt_root_size);
- cache_root = rt_join(env, root, "cache", &cache_root_size);
+ cache_root = rt_build_cache_root(env, root, 0, &cache_root_size);
if (!rt_root || !cache_root) ok = 0;
if (ok && rt_has_layout(rt_root))
ok = rt_set_layout(env, out, root, rt_root, cache_root) == 0;
diff --git a/rt/Makefile b/rt/Makefile
@@ -5,7 +5,7 @@ RT_AR ?= $(BIN) ar
RT_AS ?= $(BIN) as
RT_AS_COMPILE_FLAGS ?=
-RT_BUILD_DIR = rt/build
+RT_BUILD_DIR = build/rt
RT_COMMON_CFLAGS = -Werror
RT_LIB_INCS = -Irt/lib/include/common -Irt/lib/impl
diff --git a/test/driver/run.sh b/test/driver/run.sh
@@ -228,7 +228,7 @@ SRC
if "$CFREE" cc --support-dir "$work/rt-support" -target aarch64-linux \
-e _start "$work/rt-div.c" -o "$work/rt-div" \
> "$work/rt-div.out" 2> "$work/rt-div.err" &&
- [ -f "$work/rt-support/cache/aarch64-linux/libcfree_rt.a" ]; then
+ [ -f "$work/rt-support/build/rt/aarch64-linux/libcfree_rt.a" ]; then
printf 'PASS %s\n' "cc-auto-builds-and-links-libcfree-rt"
pass=$((pass + 1))
else
diff --git a/test/libc/glibc/run.sh b/test/libc/glibc/run.sh
@@ -38,7 +38,7 @@ CASES_DIR="$ROOT/test/libc/cases"
BUILD_DIR="$ROOT/build/glibc"
SYSROOT="$ROOT/build/glibc-sysroot"
CFREE="$ROOT/build/cfree"
-CFREE_RT="$ROOT/rt/build/aarch64-linux/libcfree_rt.a"
+CFREE_RT="$ROOT/build/rt/aarch64-linux/libcfree_rt.a"
if [ ! -d "$SYSROOT" ]; then
echo "glibc sysroot missing — run test/libc/glibc/extract.sh first" >&2
diff --git a/test/libc/musl/Containerfile b/test/libc/musl/Containerfile
@@ -16,7 +16,7 @@ FROM docker.io/arm64v8/alpine:3.20.10
# definitions in the musl headers.
# Note: we deliberately do NOT pull clang's compiler-rt or libgcc — the
# soft-float / TF / 128-bit-int helpers (__extenddftf2 etc.) come from
-# our own rt/ build (rt/build/aarch64-linux/libcfree_rt.a).
+# our own rt/ build (build/rt/aarch64-linux/libcfree_rt.a).
RUN apk add --no-cache musl-dev linux-headers
# Stage the artifacts the linker needs into one tree so the host extract
diff --git a/test/libc/musl/run.sh b/test/libc/musl/run.sh
@@ -34,7 +34,7 @@ CASES_DIR="$ROOT/test/libc/cases"
BUILD_DIR="$ROOT/build/musl"
SYSROOT="$ROOT/build/musl-sysroot"
CFREE="$ROOT/build/cfree"
-CFREE_RT="$ROOT/rt/build/aarch64-linux/libcfree_rt.a"
+CFREE_RT="$ROOT/build/rt/aarch64-linux/libcfree_rt.a"
if [ ! -d "$SYSROOT" ]; then
echo "musl sysroot missing — run test/libc/musl/extract.sh first" >&2
diff --git a/test/parse/harness/parse_runner.c b/test/parse/harness/parse_runner.c
@@ -310,12 +310,12 @@ static int add_runtime_archive(CfreeJitLinkOptions* opts,
uint8_t* data = NULL;
size_t len = 0;
const char* arch = cfree_test_arch_name();
- const char* path = "rt/build/aarch64-linux/libcfree_rt.a";
+ const char* path = "build/rt/aarch64-linux/libcfree_rt.a";
if (!strcmp(arch, "rv64") || !strcmp(arch, "riscv64"))
- path = "rt/build/riscv64-linux/libcfree_rt.a";
+ path = "build/rt/riscv64-linux/libcfree_rt.a";
else if (!strcmp(arch, "x64") || !strcmp(arch, "x86_64") ||
!strcmp(arch, "amd64"))
- path = "rt/build/x86_64-linux/libcfree_rt.a";
+ path = "build/rt/x86_64-linux/libcfree_rt.a";
if (read_file(path, &data, &len) != 0)
return 0;
memset(&rt_archive, 0, sizeof rt_archive);
diff --git a/test/parse/run.sh b/test/parse/run.sh
@@ -72,9 +72,9 @@ esac
export CFREE_TEST_ARCH
case "$TEST_ARCH" in
- aa64) RT_AR="$ROOT/rt/build/aarch64-linux/libcfree_rt.a" ;;
- x64) RT_AR="$ROOT/rt/build/x86_64-linux/libcfree_rt.a" ;;
- rv64) RT_AR="$ROOT/rt/build/riscv64-linux/libcfree_rt.a" ;;
+ aa64) RT_AR="$ROOT/build/rt/aarch64-linux/libcfree_rt.a" ;;
+ x64) RT_AR="$ROOT/build/rt/x86_64-linux/libcfree_rt.a" ;;
+ rv64) RT_AR="$ROOT/build/rt/riscv64-linux/libcfree_rt.a" ;;
esac
RT_LINK_ARGS=()
if [ -f "$RT_AR" ]; then
diff --git a/test/rt/run.sh b/test/rt/run.sh
@@ -64,9 +64,9 @@ arch_triple() {
rt_archive() {
case "$1" in
- aa64) echo "$ROOT/rt/build/aarch64-linux/libcfree_rt.a" ;;
- x64) echo "$ROOT/rt/build/x86_64-linux/libcfree_rt.a" ;;
- rv64) echo "$ROOT/rt/build/riscv64-linux/libcfree_rt.a" ;;
+ aa64) echo "$ROOT/build/rt/aarch64-linux/libcfree_rt.a" ;;
+ x64) echo "$ROOT/build/rt/x86_64-linux/libcfree_rt.a" ;;
+ rv64) echo "$ROOT/build/rt/riscv64-linux/libcfree_rt.a" ;;
*) return 1 ;;
esac
}
diff --git a/test/test.mk b/test/test.mk
@@ -279,7 +279,7 @@ test-smoke-rv64:
# test-musl — Alpine 3.20 + musl 1.2.5 (test/libc/musl/)
# test-glibc — Debian bookworm + glibc 2.36 (test/libc/glibc/)
#
-# Both build rt/build/aarch64-linux/libcfree_rt.a for soft-float / TF
+# Both build build/rt/aarch64-linux/libcfree_rt.a for soft-float / TF
# builtins, and run `cfree ld` against the real libc.a (static) and
# libc.so / libc.so.6 (dynamic). Excluded from the
# default `test` target because they need podman; opt-in via