commit 1d8a0709812339daa71b951340a748b764f03485
parent 85d2a637cf60fafa063216858e6129efb74d7087
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Tue, 2 Jun 2026 11:25:40 -0700
dist: ship libcfree + headers; keep on-demand rt out of install tree
make dist now bundles libcfree.a (lib/) and the public include/ tree
alongside the cfree binary and rt sources, so the distribution is a
complete toolchain SDK.
Also fix the on-demand rt builder: in a distribution the resolved
support_root is <dist>/support, so writing the primary archive to
<support_root>/build/rt polluted the install tree. Mark the
<bindir>/support/rt sibling layout as an install (install_layout) in
driver_runtime_resolve, and in driver_runtime_ensure_archive prefer the
user cache dir for installs (in-tree build/rt only as fallback).
Checkouts and explicit --support-dir keep the historical in-tree-first
order, sharing make rt's build/rt cache per checkout.
Diffstat:
3 files changed, 51 insertions(+), 21 deletions(-)
diff --git a/Makefile b/Makefile
@@ -588,8 +588,10 @@ bench-opt:
dist:
$(MAKE) RELEASE=1 bin
@rm -rf $(DIST_STAGING)
- @mkdir -p $(DIST_STAGING)/support/rt
+ @mkdir -p $(DIST_STAGING)/support/rt $(DIST_STAGING)/lib
cp build/release/cfree $(DIST_STAGING)/cfree
+ cp build/release/libcfree.a $(DIST_STAGING)/lib/libcfree.a
+ cp -r include $(DIST_STAGING)/include
cp -r rt/include $(DIST_STAGING)/support/rt/include
cp -r rt/lib $(DIST_STAGING)/support/rt/lib
cd build/dist && tar czf cfree.tar.gz cfree
diff --git a/driver/lib/runtime.c b/driver/lib/runtime.c
@@ -282,6 +282,10 @@ int driver_runtime_resolve(DriverEnv* env, const char* explicit_support_dir,
rc = 0;
} else {
rc = rt_try_argv0_support(env, argv0, out);
+ /* rt found as a <bindir>/support/rt sibling: this is a distribution
+ * install, not a build tree. Mark it so the on-demand rt archive lands
+ * in the user cache dir rather than polluting the install. */
+ if (rc == 0) out->install_layout = 1;
}
if (rc == 0) out->tool_path = argv0;
return rc;
@@ -745,10 +749,12 @@ int driver_runtime_ensure_archive(DriverEnv* env, const char* tool,
char** out_path, size_t* out_path_size) {
const RuntimeVariant* variant = rt_variant_for_target(target);
const char* diag_tool = tool ? tool : "rt";
- char* primary_dir = NULL;
- char* fallback_dir = NULL;
- size_t primary_dir_size = 0;
- size_t fallback_dir_size = 0;
+ char* in_tree_dir = NULL; /* <support_root>/build/rt/<variant> */
+ char* cache_dir = NULL; /* <env->cache_dir>/<variant> */
+ size_t in_tree_dir_size = 0;
+ size_t cache_dir_size = 0;
+ char* primary_dir;
+ char* fallback_dir;
int primary_rc;
int fallback_rc = 1;
@@ -760,38 +766,55 @@ int driver_runtime_ensure_archive(DriverEnv* env, const char* tool,
return 1;
}
- primary_dir = rt_archive_dir_for_root(env, support->support_root, variant,
- &primary_dir_size);
- if (!primary_dir) {
+ /* In-tree location, shared with `make rt` when support_root is a checkout. */
+ in_tree_dir = rt_archive_dir_for_root(env, support->support_root, variant,
+ &in_tree_dir_size);
+ if (!in_tree_dir) {
driver_errf(diag_tool, "out of memory");
return 1;
}
+ /* User cache location, outside any support/install tree. */
+ if (env->cache_dir) {
+ cache_dir = rt_join(env, env->cache_dir, variant->key, &cache_dir_size);
+ if (!cache_dir) {
+ driver_free(env, in_tree_dir, in_tree_dir_size);
+ driver_errf(diag_tool, "out of memory");
+ return 1;
+ }
+ }
+
+ /* A distribution install is not a build tree: prefer the user cache dir and
+ * keep the in-tree dir only as a fallback so the build never writes into the
+ * install. A checkout (or explicit --support-dir) keeps the historical
+ * in-tree-first order, sharing `make rt`'s build/rt cache per checkout. */
+ if (support->install_layout && cache_dir) {
+ primary_dir = cache_dir;
+ fallback_dir = in_tree_dir;
+ } else {
+ primary_dir = in_tree_dir;
+ fallback_dir = cache_dir;
+ }
primary_rc = rt_archive_try_dir(env, diag_tool, support, variant, epoch,
primary_dir, out_path, out_path_size);
if (primary_rc == 0) {
- driver_free(env, primary_dir, primary_dir_size);
+ if (cache_dir) driver_free(env, cache_dir, cache_dir_size);
+ driver_free(env, in_tree_dir, in_tree_dir_size);
return 0;
}
if (primary_rc != 2) {
- driver_free(env, primary_dir, primary_dir_size);
+ if (cache_dir) driver_free(env, cache_dir, cache_dir_size);
+ driver_free(env, in_tree_dir, in_tree_dir_size);
return 1;
}
- if (env->cache_dir) {
- fallback_dir =
- rt_join(env, env->cache_dir, variant->key, &fallback_dir_size);
- if (!fallback_dir) {
- driver_free(env, primary_dir, primary_dir_size);
- driver_errf(diag_tool, "out of memory");
- return 1;
- }
+ if (fallback_dir) {
fallback_rc = rt_archive_try_dir(env, diag_tool, support, variant, epoch,
fallback_dir, out_path, out_path_size);
}
- if (fallback_rc == 2 || !env->cache_dir) {
+ if (fallback_rc == 2 || !fallback_dir) {
driver_errf(diag_tool, "failed to create runtime cache: %.*s",
CFREE_SLICE_ARG(cfree_slice_cstr(primary_dir)));
if (fallback_dir) {
@@ -799,8 +822,8 @@ int driver_runtime_ensure_archive(DriverEnv* env, const char* tool,
CFREE_SLICE_ARG(cfree_slice_cstr(fallback_dir)));
}
}
- if (fallback_dir) driver_free(env, fallback_dir, fallback_dir_size);
- driver_free(env, primary_dir, primary_dir_size);
+ if (cache_dir) driver_free(env, cache_dir, cache_dir_size);
+ driver_free(env, in_tree_dir, in_tree_dir_size);
return fallback_rc == 0 ? 0 : 1;
}
diff --git a/driver/lib/runtime.h b/driver/lib/runtime.h
@@ -14,6 +14,11 @@ typedef struct DriverRuntimeSupport {
char* include_dir;
size_t include_dir_size;
const char* tool_path;
+ /* Set when rt was resolved as a <bindir>/support/rt sibling, i.e. a
+ * distribution install rather than a source checkout. Steers the on-demand
+ * rt archive build toward the user cache dir instead of writing into the
+ * (read-only-by-convention) install tree. See driver_runtime_ensure_archive. */
+ uint8_t install_layout;
} DriverRuntimeSupport;
typedef struct DriverRuntimeArchive {