kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 8406232ec0dc65db7ff231a12bffff91975c3ab7
parent dffe56c37dd005738f5890335a4b76cb65d2b1f9
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Fri, 29 May 2026 12:38:02 -0700

Auto-link cfree runtime from ld

Diffstat:
MMakefile | 2+-
Mdriver/cc.c | 27+++++++++++++++------------
Mdriver/ld.c | 104++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Mdriver/runtime.c | 180+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Mdriver/runtime.h | 17++++++++++++++++-
Mtest/driver/run.sh | 20++++++++++++++++++++
6 files changed, 259 insertions(+), 91 deletions(-)

diff --git a/Makefile b/Makefile @@ -375,7 +375,7 @@ endif ifneq ($(filter 1,$(CFREE_TOOL_CC_ENABLED) $(CFREE_TOOL_CHECK_ENABLED) $(CFREE_TOOL_RUN_ENABLED)),) DRIVER_SRCS += driver/hosted.c endif -ifneq ($(filter 1,$(CFREE_TOOL_CC_ENABLED) $(CFREE_TOOL_CHECK_ENABLED)),) +ifneq ($(filter 1,$(CFREE_TOOL_CC_ENABLED) $(CFREE_TOOL_CHECK_ENABLED) $(CFREE_TOOL_LD_ENABLED)),) DRIVER_SRCS += driver/runtime.c endif ifneq ($(filter 1,$(CFREE_TOOL_AR_ENABLED) $(CFREE_TOOL_RANLIB_ENABLED) $(CFREE_TOOL_STRIP_ENABLED) $(CFREE_TOOL_DBG_ENABLED) $(CFREE_TOOL_RUN_ENABLED)),) diff --git a/driver/cc.c b/driver/cc.c @@ -615,15 +615,17 @@ static int cc_append_hosted_input(CcOptions* o, const DriverHostedInput* in, return 0; } -static void cc_insert_owned_archive(CcOptions* o, char* path, size_t path_size, - uint32_t insert_pos) { +static void cc_insert_runtime_archive(CcOptions* o, DriverRuntimeArchive* rt, + uint32_t insert_pos) { CcArchiveInput* ar = &o->archives[o->narchives++]; - ar->path = path; + ar->path = rt->path; ar->owned = 1; - ar->owned_size = path_size; - ar->whole_archive = 0; - ar->link_mode = CFREE_LM_STATIC; - ar->group_id = 0; + ar->owned_size = rt->path_size; + ar->whole_archive = rt->whole_archive; + ar->link_mode = rt->link_mode; + ar->group_id = rt->group_id; + rt->path = NULL; + rt->path_size = 0; cc_insert_link_item(o, insert_pos, CC_LINK_ARCHIVE, o->narchives - 1u); } @@ -2806,8 +2808,7 @@ static int driver_cc_main(int argc, char** argv, int force_check) { } if (link_action && !co.no_stdlib && !co.no_defaultlibs) { - char* rt_path = NULL; - size_t rt_path_size = 0; + DriverRuntimeArchive rt_archive = {0}; uint32_t insert_pos; if (!runtime_resolved) { driver_errf(CC_TOOL, "support dir not found"); @@ -2815,8 +2816,9 @@ static int driver_cc_main(int argc, char** argv, int force_check) { driver_env_fini(&env); return 1; } - if (driver_runtime_ensure_archive(&env, &runtime, co.target, co.epoch, - &rt_path, &rt_path_size) != 0) { + if (driver_runtime_prepare_archive(&env, CC_TOOL, &runtime, co.target, + co.epoch, &rt_archive) != 0) { + driver_runtime_archive_fini(&env, &rt_archive); driver_runtime_support_fini(&env, &runtime); cc_options_release(&co); driver_env_fini(&env); @@ -2824,7 +2826,8 @@ static int driver_cc_main(int argc, char** argv, int force_check) { } insert_pos = co.nlink_items; if (co.hosted.nfinal <= insert_pos) insert_pos -= co.hosted.nfinal; - cc_insert_owned_archive(&co, rt_path, rt_path_size, insert_pos); + cc_insert_runtime_archive(&co, &rt_archive, insert_pos); + driver_runtime_archive_fini(&env, &rt_archive); } driver_cflags_fill_pp(&co.cf, &pp); diff --git a/driver/ld.c b/driver/ld.c @@ -6,6 +6,7 @@ #include "driver.h" #include "lib_resolve.h" +#include "runtime.h" /* `cfree ld` — link object/archive inputs into an executable, shared * library, or relocatable object. The driver loads each input via @@ -18,6 +19,7 @@ * -o out output path (required, exactly one) * -e symbol entry symbol * -T script.ld linker script (parsed, not raw) + * --support-dir DIR cfree support root for compiler rt * -L dir library search path (-l targets) * -l name resolves to lib<name>.a via -L * -static / -pie / -no-pie target.pic @@ -66,6 +68,7 @@ typedef struct LdDso { typedef struct LdOptions { DriverEnv* env; + const char* driver_path; size_t argv_bound; CfreeTarget target; @@ -74,6 +77,7 @@ typedef struct LdOptions { int output_seen; const char* entry; /* -e */ const char* script_path; /* -T */ + const char* support_dir; /* --support-dir */ uint16_t pe_subsystem; /* CfreePeSubsystem */ /* PT_INTERP path. NULL means "let libcfree pick the target default * (e.g. /lib/ld-musl-aarch64.so.1)". Set by -dynamic-linker / @@ -172,6 +176,8 @@ void driver_help_ld(void) { " -static Non-PIC, non-PIE\n" " -pie Position-independent executable\n" " -no-pie Disable PIE\n" + " --support-dir DIR cfree support root for compiler " + "runtime\n" " (target is otherwise auto-detected from the first object input)\n" "\n" "LIBRARY RESOLUTION\n" @@ -227,7 +233,7 @@ void driver_help_ld(void) { /* ---------- argv-sized scratch arrays ---------- */ static int ld_alloc_arrays(LdOptions* o, int argc) { - size_t bound = (size_t)argc; + size_t bound = (size_t)argc + 16u; o->argv_bound = bound; o->object_files = driver_alloc_zeroed(o->env, bound * sizeof(*o->object_files)); @@ -267,6 +273,19 @@ static void ld_push_archive(LdOptions* o, const char* path, int owned, ld_push_order(o, CFREE_LINK_INPUT_ARCHIVE, o->narchives - 1u); } +static void ld_push_runtime_archive(LdOptions* o, DriverRuntimeArchive* rt) { + LdArchive* a = &o->archives[o->narchives++]; + a->path = rt->path; + a->owned = 1; + a->owned_size = rt->path_size; + a->whole_archive = rt->whole_archive; + a->link_mode = rt->link_mode; + a->group_id = rt->group_id; + rt->path = NULL; + rt->path_size = 0; + ld_push_order(o, CFREE_LINK_INPUT_ARCHIVE, o->narchives - 1u); +} + static void ld_push_dso(LdOptions* o, const char* path, int owned, size_t owned_size) { LdDso* d = &o->dsos[o->ndsos++]; @@ -639,6 +658,18 @@ static int ld_parse(int argc, char** argv, LdOptions* o) { o->script_path = argv[i]; continue; } + if (driver_streq(a, "--support-dir")) { + if (++i >= argc) { + driver_errf(LD_TOOL, "--support-dir requires an argument"); + return 1; + } + o->support_dir = argv[i]; + continue; + } + if (driver_strneq(a, "--support-dir=", 14)) { + o->support_dir = a + 14; + continue; + } if (driver_strneq(a, "-L", 2)) { const char* dir = a[2] ? a + 2 : (++i < argc ? argv[i] : NULL); @@ -1062,7 +1093,10 @@ static int ld_run_link(LdOptions* o) { CfreeSlice* dso_in = NULL; CfreeLinkScript* script = NULL; CfreeLinkSession* link = NULL; + DriverRuntimeSupport runtime = {0}; + DriverRuntimeArchive rt_archive = {0}; uint32_t i; + int runtime_resolved = 0; int rc = 1; if (!io || !io->read_all || !io->open_writer) { @@ -1070,7 +1104,8 @@ static int ld_run_link(LdOptions* o) { return 1; } - /* Allocate scratch parallel arrays sized to the actual input counts. */ + /* Load object files first so the final target is known before deciding + * which compiler-runtime archive to auto-link. */ if (o->nobject_files) { obj_lf = driver_alloc_zeroed(o->env, o->nobject_files * sizeof(*obj_lf)); obj_in = driver_alloc_zeroed(o->env, o->nobject_files * sizeof(*obj_in)); @@ -1079,6 +1114,42 @@ static int ld_run_link(LdOptions* o) { goto out; } } + for (i = 0; i < o->nobject_files; ++i) { + const char* path = o->object_files[i]; + if (load_file(io, path, &obj_lf[i]) != 0) { + driver_errf(LD_TOOL, "failed to read: %.*s", + CFREE_SLICE_ARG(cfree_slice_cstr(path))); + goto out; + } + obj_in[i].data = obj_lf[i].data.data; + obj_in[i].len = obj_lf[i].data.size; + } + + /* Auto-detect target from the first object input, falling back to + * the host target. PIC overrides parsed from flags are preserved. */ + if (o->nobject_files > 0) { + CfreeTarget detected; + if (cfree_detect_target(obj_lf[0].data.data, obj_lf[0].data.size, + &detected) == CFREE_OK) { + uint8_t pic = o->target.pic; + o->target = detected; + if (pic != CFREE_PIC_NONE) o->target.pic = pic; + } + } + + if (!o->relocatable) { + if (driver_runtime_resolve(o->env, o->support_dir, o->driver_path, + &runtime) != 0) { + driver_errf(LD_TOOL, "support dir not found"); + goto out; + } + runtime_resolved = 1; + if (driver_runtime_prepare_archive(o->env, LD_TOOL, &runtime, o->target, 0, + &rt_archive) != 0) + goto out; + ld_push_runtime_archive(o, &rt_archive); + } + if (o->narchives) { arch_lf = driver_alloc_zeroed(o->env, o->narchives * sizeof(*arch_lf)); arch_in = driver_alloc_zeroed(o->env, o->narchives * sizeof(*arch_in)); @@ -1096,17 +1167,6 @@ static int ld_run_link(LdOptions* o) { } } - /* Load object files. */ - for (i = 0; i < o->nobject_files; ++i) { - const char* path = o->object_files[i]; - if (load_file(io, path, &obj_lf[i]) != 0) { - driver_errf(LD_TOOL, "failed to read: %.*s", - CFREE_SLICE_ARG(cfree_slice_cstr(path))); - goto out; - } - obj_in[i].data = obj_lf[i].data.data; - obj_in[i].len = obj_lf[i].data.size; - } /* Load archives. */ for (i = 0; i < o->narchives; ++i) { const LdArchive* a = &o->archives[i]; @@ -1145,18 +1205,6 @@ static int ld_run_link(LdOptions* o) { } } - /* Auto-detect target from the first object input, falling back to - * the host target. PIC overrides parsed from flags are preserved. */ - if (o->nobject_files > 0) { - CfreeTarget detected; - if (cfree_detect_target(obj_lf[0].data.data, obj_lf[0].data.size, - &detected) == CFREE_OK) { - uint8_t pic = o->target.pic; - o->target = detected; - if (pic != CFREE_PIC_NONE) o->target.pic = pic; - } - } - if (driver_compiler_new(o->target, &ctx, &compiler) != CFREE_OK) { driver_errf(LD_TOOL, "failed to initialize compiler"); goto out; @@ -1210,8 +1258,7 @@ static int ld_run_link(LdOptions* o) { lopts.build_id_len = o->build_id_len; lopts.gc_sections = o->gc_sections; lopts.strip_debug = o->strip_debug; - lopts.pie = - driver_link_pie(o->target, o->pie, o->shared, o->relocatable); + lopts.pie = driver_link_pie(o->target, o->pie, o->shared, o->relocatable); lopts.pe_subsystem = o->pe_subsystem; lopts.interp_path = cfree_slice_cstr(o->interp_path); lopts.soname = cfree_slice_cstr(o->soname); @@ -1285,6 +1332,8 @@ out: } if (script) cfree_link_script_free(&ctx, script); if (compiler) driver_compiler_free(compiler); + driver_runtime_archive_fini(o->env, &rt_archive); + if (runtime_resolved) driver_runtime_support_fini(o->env, &runtime); release_file(&script_lf); release_all(arch_lf, o->narchives); release_all(obj_lf, o->nobject_files); @@ -1310,6 +1359,7 @@ int driver_ld(int argc, char** argv) { driver_env_init(&env); lo.env = &env; + lo.driver_path = argv[0]; if (ld_parse(argc, argv, &lo) != 0) { ld_options_release(&lo); diff --git a/driver/runtime.c b/driver/runtime.c @@ -7,8 +7,6 @@ #include <stdint.h> #include <string.h> -#define RT_TOOL "cc" - typedef struct RuntimeVariant { const char* key; CfreeArchKind arch; @@ -163,7 +161,6 @@ static void rt_store_const_ptr(const char** slot, const char* value) { *slot = value; } - static void rt_free_str(DriverEnv* env, char** p, size_t* n) { if (*p) driver_free(env, *p, *n); *p = NULL; @@ -204,8 +201,7 @@ static int rt_try_support_root(DriverEnv* env, const char* root, rt_root = rt_join(env, root, "rt", &rt_root_size); if (!rt_root) return 1; - ok = rt_has_layout(rt_root) && - rt_set_layout(env, out, root, rt_root) == 0; + ok = rt_has_layout(rt_root) && rt_set_layout(env, out, root, rt_root) == 0; driver_free(env, rt_root, rt_root_size); return ok ? 0 : 1; } @@ -461,7 +457,7 @@ static void rt_free_pp(DriverEnv* env, CfreePreprocessOptions* pp, static int rt_compile_source(DriverEnv* env, const DriverRuntimeSupport* support, - const RuntimeVariant* variant, + const RuntimeVariant* variant, const char* tool, CfreeCompiler* compiler, const char* rel, CfreeArInput* member, CfreeWriter** obj_writer) { CfreeContext ctx = driver_env_to_context(env); @@ -485,7 +481,7 @@ static int rt_compile_source(DriverEnv* env, if (!lib_path) goto out; src_path = rt_join(env, lib_path, rel, &src_path_size); if (!src_path) goto out; - if (driver_load_bytes(ctx.file_io, RT_TOOL, src_path, &src_load, &input) != 0) + if (driver_load_bytes(ctx.file_io, tool, src_path, &src_load, &input) != 0) goto out; if (cfree_writer_mem(ctx.heap, &writer) != CFREE_OK) goto out; @@ -563,7 +559,7 @@ static int rt_compile_source(DriverEnv* env, rt_free_pp(env, &copts.preprocess, owned_dirs, owned_sizes, owned_count); } if (st != CFREE_OK || cfree_writer_status(writer) != CFREE_OK) { - driver_errf(RT_TOOL, "failed to build runtime source: %.*s", + driver_errf(tool, "failed to build runtime source: %.*s", CFREE_SLICE_ARG(cfree_slice_cstr(src_path))); goto out; } @@ -586,8 +582,8 @@ out: } static int rt_build_archive(DriverEnv* env, const DriverRuntimeSupport* support, - const RuntimeVariant* variant, uint64_t epoch, - const char* archive_path) { + const RuntimeVariant* variant, const char* tool, + uint64_t epoch, const char* archive_path) { CfreeContext ctx = driver_env_to_context(env); CfreeCompiler* compiler = NULL; CfreeWriter* archive_writer = NULL; @@ -603,7 +599,7 @@ static int rt_build_archive(DriverEnv* env, const DriverRuntimeSupport* support, obj_writers = (CfreeWriter**)driver_alloc_zeroed( env, (size_t)variant->nsources * sizeof(*obj_writers)); if (!members || !obj_writers) { - driver_errf(RT_TOOL, "out of memory"); + driver_errf(tool, "out of memory"); goto out; } @@ -617,19 +613,20 @@ static int rt_build_archive(DriverEnv* env, const DriverRuntimeSupport* support, target.code_model = CFREE_CM_DEFAULT; if (driver_compiler_new(target, &ctx, &compiler) != CFREE_OK) { - driver_errf(RT_TOOL, "failed to initialize compiler for runtime"); + driver_errf(tool, "failed to initialize compiler for runtime"); goto out; } for (i = 0; i < variant->nsources; ++i) { - if (rt_compile_source(env, support, variant, compiler, variant->sources[i], - &members[i], &obj_writers[i]) != 0) + if (rt_compile_source(env, support, variant, tool, compiler, + variant->sources[i], &members[i], + &obj_writers[i]) != 0) goto out; } if (ctx.file_io->open_writer(ctx.file_io->user, archive_path, &archive_writer) != CFREE_OK) { - driver_errf(RT_TOOL, "failed to open runtime archive: %.*s", + driver_errf(tool, "failed to open runtime archive: %.*s", CFREE_SLICE_ARG(cfree_slice_cstr(archive_path))); goto out; } @@ -638,7 +635,7 @@ static int rt_build_archive(DriverEnv* env, const DriverRuntimeSupport* support, ar_opts.long_names = 1; if (cfree_ar_write(archive_writer, members, variant->nsources, &ar_opts) != CFREE_OK) { - driver_errf(RT_TOOL, "failed to write runtime archive: %.*s", + driver_errf(tool, "failed to write runtime archive: %.*s", CFREE_SLICE_ARG(cfree_slice_cstr(archive_path))); goto out; } @@ -691,61 +688,144 @@ static int rt_is_archive_stale(DriverEnv* env, return 0; } -int driver_runtime_ensure_archive(DriverEnv* env, +static char* rt_archive_dir_for_root(DriverEnv* env, const char* root, + const RuntimeVariant* variant, + size_t* out_size) { + char* build_rt; + char* dir = NULL; + size_t build_rt_size = 0; + size_t dir_size = 0; + build_rt = rt_join(env, root, "build/rt", &build_rt_size); + if (!build_rt) return NULL; + dir = rt_join(env, build_rt, variant->key, &dir_size); + driver_free(env, build_rt, build_rt_size); + if (out_size) *out_size = dir ? dir_size : 0; + return dir; +} + +static int rt_archive_try_dir(DriverEnv* env, const char* tool, + const DriverRuntimeSupport* support, + const RuntimeVariant* variant, uint64_t epoch, + const char* cache_dir, char** out_path, + size_t* out_path_size) { + char* archive_path; + size_t archive_path_size = 0; + + archive_path = rt_join(env, cache_dir, "libcfree_rt.a", &archive_path_size); + if (!archive_path) { + driver_errf(tool, "out of memory"); + return 1; + } + + if (!driver_path_exists(archive_path) || + rt_is_archive_stale(env, support, variant, archive_path)) { + if (driver_mkdir_p(env, cache_dir) != 0) { + driver_free(env, archive_path, archive_path_size); + return 2; + } + if (rt_build_archive(env, support, variant, tool, epoch, archive_path) != + 0) { + driver_errf(tool, "compiler runtime for %.*s could not be built", + CFREE_SLICE_ARG(cfree_slice_cstr(variant->key))); + driver_errf(tool, "support dir: %.*s", + CFREE_SLICE_ARG(cfree_slice_cstr(support->support_root))); + driver_free(env, archive_path, archive_path_size); + return 1; + } + } + + *out_path = archive_path; + *out_path_size = archive_path_size; + return 0; +} + +int driver_runtime_ensure_archive(DriverEnv* env, const char* tool, const DriverRuntimeSupport* support, CfreeTarget target, uint64_t epoch, char** out_path, size_t* out_path_size) { const RuntimeVariant* variant = rt_variant_for_target(target); - char* cache_dir = NULL; - char* archive_path = NULL; - size_t cache_dir_size = 0; - size_t archive_path_size = 0; + 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; + int primary_rc; + int fallback_rc = 1; *out_path = NULL; *out_path_size = 0; if (!variant) { - driver_errf(RT_TOOL, "compiler runtime is not available for this target"); + driver_errf(diag_tool, "compiler runtime is not available for this target"); return 1; } - if (!env->cache_dir) { - driver_errf(RT_TOOL, "no cache directory configured"); + + primary_dir = rt_archive_dir_for_root(env, support->support_root, variant, + &primary_dir_size); + if (!primary_dir) { + driver_errf(diag_tool, "out of memory"); return 1; } - cache_dir = rt_join(env, env->cache_dir, variant->key, &cache_dir_size); - if (!cache_dir) { - driver_errf(RT_TOOL, "out of memory"); - return 1; + + 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); + return 0; } - archive_path = rt_join(env, cache_dir, "libcfree_rt.a", &archive_path_size); - if (!archive_path) { - driver_free(env, cache_dir, cache_dir_size); - driver_errf(RT_TOOL, "out of memory"); + + if (primary_rc != 2) { + driver_free(env, primary_dir, primary_dir_size); return 1; } - if (!driver_path_exists(archive_path) || - rt_is_archive_stale(env, support, variant, archive_path)) { - if (driver_mkdir_p(env, cache_dir) != 0) { - driver_errf(RT_TOOL, "failed to create runtime cache: %.*s", - CFREE_SLICE_ARG(cfree_slice_cstr(cache_dir))); - driver_free(env, archive_path, archive_path_size); - driver_free(env, cache_dir, cache_dir_size); + 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 (rt_build_archive(env, support, variant, epoch, archive_path) != 0) { - driver_errf(RT_TOOL, "compiler runtime for %.*s could not be built", - CFREE_SLICE_ARG(cfree_slice_cstr(variant->key))); - driver_errf(RT_TOOL, "support dir: %.*s", - CFREE_SLICE_ARG(cfree_slice_cstr(support->support_root))); - driver_free(env, archive_path, archive_path_size); - driver_free(env, cache_dir, cache_dir_size); - return 1; + 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) { + driver_errf(diag_tool, "failed to create runtime cache: %.*s", + CFREE_SLICE_ARG(cfree_slice_cstr(primary_dir))); + if (fallback_dir) { + driver_errf(diag_tool, "failed to create runtime cache: %.*s", + 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); + return fallback_rc == 0 ? 0 : 1; +} - driver_free(env, cache_dir, cache_dir_size); - *out_path = archive_path; - *out_path_size = archive_path_size; +int driver_runtime_prepare_archive(DriverEnv* env, const char* tool, + const DriverRuntimeSupport* support, + CfreeTarget target, uint64_t epoch, + DriverRuntimeArchive* out) { + DriverRuntimeArchive z = {0}; + if (!out) return 1; + *out = z; + if (driver_runtime_ensure_archive(env, tool, support, target, epoch, + &out->path, &out->path_size) != 0) + return 1; + out->whole_archive = 0; + out->link_mode = CFREE_LM_STATIC; + out->group_id = 0; return 0; } + +void driver_runtime_archive_fini(DriverEnv* env, DriverRuntimeArchive* a) { + if (!a) return; + if (a->path) driver_free(env, a->path, a->path_size); + a->path = NULL; + a->path_size = 0; + a->whole_archive = 0; + a->link_mode = 0; + a->group_id = 0; +} diff --git a/driver/runtime.h b/driver/runtime.h @@ -1,6 +1,8 @@ #ifndef CFREE_DRIVER_RUNTIME_H #define CFREE_DRIVER_RUNTIME_H +#include <cfree/link.h> + #include "cflags.h" #include "driver.h" @@ -14,6 +16,14 @@ typedef struct DriverRuntimeSupport { const char* tool_path; } DriverRuntimeSupport; +typedef struct DriverRuntimeArchive { + char* path; + size_t path_size; + uint8_t whole_archive; + uint8_t link_mode; + uint8_t group_id; +} DriverRuntimeArchive; + int driver_runtime_resolve(DriverEnv* env, const char* explicit_support_dir, const char* argv0, DriverRuntimeSupport* out); void driver_runtime_support_fini(DriverEnv* env, DriverRuntimeSupport* s); @@ -23,9 +33,14 @@ int driver_runtime_add_freestanding_headers(const DriverRuntimeSupport* s, int driver_runtime_append_freestanding_headers(const DriverRuntimeSupport* s, DriverCflags* cf); -int driver_runtime_ensure_archive(DriverEnv* env, +int driver_runtime_ensure_archive(DriverEnv* env, const char* tool, const DriverRuntimeSupport* support, CfreeTarget target, uint64_t epoch, char** out_path, size_t* out_path_size); +int driver_runtime_prepare_archive(DriverEnv* env, const char* tool, + const DriverRuntimeSupport* support, + CfreeTarget target, uint64_t epoch, + DriverRuntimeArchive* out); +void driver_runtime_archive_fini(DriverEnv* env, DriverRuntimeArchive* a); #endif diff --git a/test/driver/run.sh b/test/driver/run.sh @@ -352,6 +352,26 @@ else fail=$((fail + 1)) fi +mkdir -p "$work/ld-rt-support/rt" +cp -R "$repo_root/rt/include" "$work/ld-rt-support/rt/include" +cp -R "$repo_root/rt/lib" "$work/ld-rt-support/rt/lib" +if "$CFREE" cc --support-dir "$work/ld-rt-support" -target aarch64-linux \ + -c "$work/rt-div.c" -o "$work/ld-rt-div.o" \ + > "$work/ld-rt-div-cc.out" 2> "$work/ld-rt-div-cc.err" && + "$CFREE" ld --support-dir "$work/ld-rt-support" \ + -e _start "$work/ld-rt-div.o" -o "$work/ld-rt-div" \ + > "$work/ld-rt-div.out" 2> "$work/ld-rt-div.err" && + [ -f "$work/ld-rt-support/build/rt/aarch64-linux/libcfree_rt.a" ]; then + printf 'PASS %s\n' "ld-auto-builds-and-links-libcfree-rt" + pass=$((pass + 1)) +else + printf 'FAIL %s (cfree ld failed)\n' \ + "ld-auto-builds-and-links-libcfree-rt" + sed 's/^/ | /' "$work/ld-rt-div-cc.err" + sed 's/^/ | /' "$work/ld-rt-div.err" 2>/dev/null || true + fail=$((fail + 1)) +fi + if "$CFREE" ld "$work/main.o" --output="$work/ld-long-output" \ > "$work/ld-long-output.out" 2> "$work/ld-long-output.err" && [ -f "$work/ld-long-output" ]; then