kit

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

commit b02403a3bef7110de12cc1abf50be58fdb36f6cd
parent 1a1d67691c24338bdec361ea3ffe2a3f11982c11
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Thu, 16 Jul 2026 10:10:50 -0700

hosted: canonicalize support and native SDK discovery

Diffstat:
Mdriver/cmd/build.c | 147++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mdriver/cmd/cpp.c | 90++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mdriver/lib/hosted.c | 12++++++++++--
Minclude/kit/os.h | 6++++++
Mrecipes/buildkit/common.sh | 1+
Mscripts/hosted.sh | 55++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/os/android/hosted.c | 8+++++---
Msrc/os/hosted.c | 29+++++++++++++++++++++++++++++
Msrc/os/hosted_internal.h | 4++++
Msrc/os/macos/hosted.c | 5++++-
Mtest/buildcmds/run.sh | 5++---
11 files changed, 281 insertions(+), 81 deletions(-)

diff --git a/driver/cmd/build.c b/driver/cmd/build.c @@ -116,6 +116,7 @@ typedef struct BuildOptions { int function_sections; /* -ffunction-sections */ int data_sections; /* -fdata-sections */ int auto_var_init; /* -ftrivial-auto-var-init= (KitAutoVarInit) */ + int stack_protector; /* KitStackProtectorMode */ int lto; /* -flto/-fno-lto */ uint64_t disabled_backend_features; uint8_t default_visibility; /* KitSymVis */ @@ -172,6 +173,26 @@ static int build_lang_from_name(BuildOptions* o, const char* name, return 0; } +static void build_err_unknown_language(BuildOptions* o, const char* flag, + const char* value) { + const char* const known[] = {"c", "asm", "assembler", "s", + "toy", "wasm", "wat"}; + const char* candidates[sizeof known / sizeof known[0]]; + DriverSuggestion suggestions[3]; + size_t i, count = 0, n; + for (i = 0; i < sizeof known / sizeof known[0]; ++i) { + KitLanguage lang; + if (build_lang_from_name(o, known[i], &lang) == 0) + candidates[count++] = known[i]; + } + n = driver_suggest_values(value, candidates, count, suggestions, 3); + if (n) + driver_errf(o->tool, "unsupported %s language: %s; did you mean '%s'?", + flag, value, suggestions[0].value); + else + driver_errf(o->tool, "unsupported %s language: %s", flag, value); +} + /* ===================================================================== */ /* allocation / lifetime */ /* ===================================================================== */ @@ -323,8 +344,7 @@ static int build_try_scopable(BuildOptions* o, BuildGroup* g, int argc, return -1; } if (build_lang_from_name(o, argv[*i], &lang) != 0) { - driver_errf(o->tool, "unsupported -x language: %.*s", - KIT_SLICE_ARG(kit_slice_cstr(argv[*i]))); + build_err_unknown_language(o, "-x", argv[*i]); return -1; } g->forced_lang = lang; @@ -334,8 +354,7 @@ static int build_try_scopable(BuildOptions* o, BuildGroup* g, int argc, KitLanguage lang; BuildFeFlag* f; if (build_lang_from_name(o, a + 2, &lang) != 0) { - driver_errf(o->tool, "unsupported -X language: %.*s", - KIT_SLICE_ARG(kit_slice_cstr(a + 2))); + build_err_unknown_language(o, "-X", a + 2); return -1; } if (++(*i) >= argc) { @@ -614,11 +633,23 @@ static int build_parse(int argc, char** argv, BuildOptions* o) { continue; } if (driver_streq(a, "-fno-stack-protector")) { + o->stack_protector = KIT_STACK_PROTECTOR_NONE; + continue; + } + if (driver_streq(a, "-fstack-protector")) { + o->stack_protector = KIT_STACK_PROTECTOR_BASIC; + continue; + } + if (driver_streq(a, "-fstack-protector-strong")) { + o->stack_protector = KIT_STACK_PROTECTOR_STRONG; + continue; + } + if (driver_streq(a, "-fstack-protector-all")) { + o->stack_protector = KIT_STACK_PROTECTOR_ALL; continue; } if (driver_strneq(a, "-fstack-protector", 17)) { - driver_errf(o->tool, - "%.*s is not supported yet; use -fno-stack-protector", + driver_errf(o->tool, "unsupported stack protector mode: %.*s", KIT_SLICE_ARG(kit_slice_cstr(a))); return 1; } @@ -1003,8 +1034,7 @@ static int build_parse(int argc, char** argv, BuildOptions* o) { return 1; } if (driver_target_from_triple(argv[i], &t) != 0) { - driver_errf(o->tool, "unrecognized target triple: %.*s", - KIT_SLICE_ARG(kit_slice_cstr(argv[i]))); + driver_err_unknown_target(o->tool, argv[i]); return 1; } pic = o->target.pic; @@ -1019,8 +1049,7 @@ static int build_parse(int argc, char** argv, BuildOptions* o) { KitTargetSpec t; uint8_t pic; if (driver_target_from_triple(a + 9, &t) != 0) { - driver_errf(o->tool, "unrecognized target triple: %.*s", - KIT_SLICE_ARG(kit_slice_cstr(a + 9))); + driver_err_unknown_target(o->tool, a + 9); return 1; } pic = o->target.pic; @@ -1089,38 +1118,39 @@ static int build_is_link_output(const BuildOptions* o) { return o->kind == BUILD_OUT_EXE || (o->kind == BUILD_OUT_LIB && o->dynamic); } -/* A sysroot on its own engages the hosted libc profile (matching clang/gcc). - * -ffreestanding / -nostdinc / -nostdlib opt back out; -dynamic (shared) keeps - * its standalone meaning. */ +/* A sysroot on its own engages the hosted compiler profile (matching + * clang/gcc). -ffreestanding / -nostdinc opt out of hosted headers; the + * -nostdlib family only suppresses link additions. */ static void build_enable_hosted_for_sysroot(BuildOptions* o) { if (o->wants_hosted_libc) return; if (o->shared && !driver_target_shared_uses_hosted(o->target)) return; if (!o->sysroot || !o->sysroot[0]) return; if (o->freestanding || o->nostdinc) return; - if (o->no_stdlib || o->no_defaultlibs) return; o->wants_hosted_libc = 1; } static void build_apply_default_hosted_profile(BuildOptions* o) { + KitTargetSpec host; + int native_macos; if (!driver_target_default_hosted_profile(o->target)) return; - if (o->no_stdlib || o->no_defaultlibs || o->wants_hosted_libc) return; - if (!o->sysroot || !o->sysroot[0]) return; + if (o->wants_hosted_libc) return; + if (o->freestanding || o->nostdinc) return; + host = driver_host_target(); + native_macos = host.os == KIT_OS_MACOS && o->target.os == KIT_OS_MACOS; + if ((!o->sysroot || !o->sysroot[0]) && !native_macos) return; o->wants_hosted_libc = 1; } static int build_apply_hosted_profile(BuildOptions* o) { + int link_action; int shared_hosted = o->shared && driver_target_shared_uses_hosted(o->target); if (!o->wants_hosted_libc || (o->shared && !shared_hosted)) return 0; - if (o->no_stdlib || o->no_defaultlibs) { - driver_errf(o->tool, - "-lc hosted expansion is disabled by -nostdlib/-nodefaultlibs"); - return 1; - } - /* build-* always links (or archives) its outputs, so the crt inputs always - * apply: pass link_action = 1. */ + link_action = build_is_link_output(o) && !o->no_stdlib && !o->no_defaultlibs; + /* Hosted defines/includes apply to every build-* compile. Only an executable + * or dynamic-library output consumes CRT/libc link inputs. */ return driver_link_inputs_apply_hosted( &o->inputs, &o->hosted, &o->groups[0].cf, &o->link, o->target, o->sysroot, - o->static_link, o->shared, o->no_startfiles, 1); + o->static_link, o->shared, o->no_startfiles, link_action); } /* ===================================================================== */ @@ -1309,6 +1339,7 @@ static void build_fill_code(const BuildOptions* o, KitCodeOptions* code) { code->data_sections = o->data_sections ? true : false; code->disabled_backend_features = o->disabled_backend_features; code->trivial_auto_var_init = (uint8_t)o->auto_var_init; + code->stack_protector = (uint8_t)o->stack_protector; code->lto = o->lto ? true : false; code->epoch = o->epoch; } @@ -2429,18 +2460,35 @@ static int build_main(int argc, char** argv, int kind, const char* tool, if (driver_runtime_resolve(&env, o.support_dir, o.driver_path, &runtime) == 0) { runtime_resolved = 1; - if (driver_runtime_add_freestanding_headers(&runtime, &o.groups[0].cf) != - 0) { - driver_errf(tool, "failed to add freestanding headers"); - rc = 1; - goto done; - } } else { driver_errf(tool, "support dir not found"); rc = 1; goto done; } + /* Hosted defines/includes are a compile property and therefore apply to + * build-obj/build-lib as well as executable links. Link-only search paths, + * CRT objects, and libraries stay inside the link-output branch below. */ + build_enable_hosted_for_sysroot(&o); + build_apply_default_hosted_profile(&o); + if (build_apply_hosted_profile(&o) != 0) { + rc = 1; + goto done; + } + /* Hosted system headers precede Kit's freestanding fallback headers. This + * keeps <stdlib.h> on the native SDK while retaining compiler builtins that + * the SDK does not provide. */ + if (!o.nostdinc && + (o.hosted.profile_name + ? driver_runtime_append_freestanding_headers(&runtime, + &o.groups[0].cf) + : driver_runtime_add_freestanding_headers(&runtime, + &o.groups[0].cf)) != 0) { + driver_errf(tool, "failed to add freestanding headers"); + rc = 1; + goto done; + } + if (build_is_link_output(&o)) { if (driver_link_inputs_append_windows_lib_dirs(&o.inputs, &o.sysroot, o.target) != 0) { @@ -2452,12 +2500,6 @@ static int build_main(int argc, char** argv, int kind, const char* tool, rc = 1; goto done; } - build_enable_hosted_for_sysroot(&o); - build_apply_default_hosted_profile(&o); - if (build_apply_hosted_profile(&o) != 0) { - rc = 1; - goto done; - } if (driver_link_inputs_resolve_pending(&o.inputs, o.target, o.static_link) != 0) { rc = 1; @@ -2601,22 +2643,17 @@ void driver_help_build_exe(void) { " -h, --help Show this help\n" " --version Show Kit version\n" "\n" - "CURRENT RELEASE REQUIREMENTS\n" - " Use --support-dir \"$DIST/support\" from a relocated tree. Hosted\n" - " cross builds require --sysroot. Native macOS builds currently\n" - " require -isysroot \"$(kit cc -print-sysroot)\". Pass linker\n" - " scripts and entries directly as -T SCRIPT -e SYMBOL; the common\n" - " -Wl,-T,... spelling is not accepted in this release.\n" + "DISCOVERY AND REQUIREMENTS\n" + " Relocated distributions discover sibling support automatically;\n" + " --support-dir remains an authoritative override. Native macOS uses\n" + " the discovered SDK by default. Hosted cross builds require --sysroot.\n" "\n" "EXAMPLES\n" " DIST=\"$PWD/kit\"; K=\"$DIST/bin/kit\"\n" - " SDK=\"$(\"$K\" cc -print-sysroot)\"\n" - " \"$K\" build-exe --support-dir \"$DIST/support\" \\\n" - " -isysroot \"$SDK\" main.c util.c -o app\n" + " \"$K\" build-exe main.c util.c -o app\n" "\n" " # Flag-scoped C groups plus an assembly source.\n" - " \"$K\" build-exe --support-dir \"$DIST/support\" \\\n" - " -isysroot \"$SDK\" --group -DLEFT=20 -- left.c \\\n" + " \"$K\" build-exe --group -DLEFT=20 -- left.c \\\n" " --group -DRIGHT=22 -- right.c main.c helper.s -o grouped\n" "\n" " # Freestanding: provide startup code and a linker script.\n" @@ -2666,10 +2703,11 @@ void driver_help_build_lib(void) { " -h, --help Show this help\n" " --version Show Kit version\n" "\n" - "CURRENT RELEASE REQUIREMENTS\n" - " Use --support-dir \"$DIST/support\" from a relocated tree and an\n" - " explicit SDK/sysroot for hosted headers. Static .a output is the\n" - " portable library shape; -dynamic/-shared is ELF-only.\n" + "DISCOVERY AND REQUIREMENTS\n" + " Relocated distributions discover sibling support automatically.\n" + " Native macOS discovers its SDK; hosted cross targets require an\n" + " explicit sysroot. Static .a output is the portable library shape;\n" + " -dynamic/-shared is ELF-only.\n" "\n" "EXAMPLES\n" " DIST=\"$PWD/kit\"; K=\"$DIST/bin/kit\"\n" @@ -2734,9 +2772,10 @@ void driver_help_build_obj(void) { " One-source object/assembly output defaults to <base>.o/.s. -o is\n" " required for multi-source object combination and --emit=c; use\n" " -o for stable IR filenames. -fsyntax-only writes nothing. A\n" - " relocated distribution currently needs --support-dir. Hosted\n" - " headers require an explicit SDK/sysroot. Use --emit=c only at -O0\n" - " in this release; optimized portable-C emission can terminate Kit.\n" + " relocated distribution discovers sibling support automatically.\n" + " Native macOS discovers its SDK; hosted cross targets require an\n" + " explicit sysroot. Portable-C output uses the\n" + " -O0 semantic pipeline; -O1/-O2 are accepted and normalized to -O0.\n" "\n" "EXAMPLES\n" " DIST=\"$PWD/kit\"; K=\"$DIST/bin/kit\"\n" diff --git a/driver/cmd/cpp.c b/driver/cmd/cpp.c @@ -5,6 +5,8 @@ #include "cflags.h" #include "driver.h" +#include "hosted.h" +#include "runtime.h" /* `kit cpp` — standalone C preprocessor. Reads one C source (path or * `-` for stdin), writes the preprocessed token stream to `-o PATH` or @@ -29,6 +31,10 @@ typedef struct CppOptions { const char* output_path; const char* source_path; /* NULL when stdin source */ int from_stdin; + int freestanding; + int nostdinc; + const char* sysroot; + const char* support_dir; KitTargetSpec target; } CppOptions; @@ -120,13 +126,49 @@ static int cpp_parse(int argc, char** argv, CppOptions* o, DriverEnv* env, return 1; } if (driver_target_from_triple(argv[i], &o->target) != 0) { - driver_errf(CPP_TOOL, "unrecognized target: %.*s", - KIT_SLICE_ARG(kit_slice_cstr(argv[i]))); + driver_err_unknown_target(CPP_TOOL, argv[i]); return 1; } continue; } + if (driver_streq(a, "--sysroot") || driver_streq(a, "-isysroot")) { + if (++i >= argc) { + driver_errf(CPP_TOOL, "%s requires an argument", a); + return 1; + } + o->sysroot = argv[i]; + continue; + } + if (driver_strneq(a, "--sysroot=", 10)) { + o->sysroot = a + 10; + continue; + } + if (driver_streq(a, "--support-dir")) { + if (++i >= argc) { + driver_errf(CPP_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_streq(a, "-ffreestanding")) { + o->freestanding = 1; + continue; + } + if (driver_streq(a, "-fhosted")) { + o->freestanding = 0; + continue; + } + if (driver_streq(a, "-nostdinc")) { + o->nostdinc = 1; + continue; + } + { int tr = driver_target_features_try_consume(tf, env, CPP_TOOL, argc, argv, &i); @@ -169,6 +211,8 @@ int driver_cpp(int argc, char** argv) { CppOptions o = {0}; DriverCflags cf = {0}; DriverTargetFeatures tf = {0}; + DriverHostedPlan hosted = {0}; + DriverRuntimeSupport runtime = {0}; KitContext ctx; KitPreprocessOptions pp; KitTarget* target = NULL; @@ -181,6 +225,8 @@ int driver_cpp(int argc, char** argv) { size_t stdin_size = 0; int rc = 1; int loaded = 0; + int runtime_resolved = 0; + int hosted_engaged = 0; if (argc < 2 || driver_argv_wants_help(argc, argv, 1)) { driver_help_cpp(); @@ -189,7 +235,9 @@ int driver_cpp(int argc, char** argv) { driver_env_init(&env); - if (driver_cflags_init(&cf, &env, argc) != 0 || + if (driver_cflags_init(&cf, &env, + argc + DRIVER_HOSTED_MAX_DEFINES + + DRIVER_HOSTED_MAX_INCLUDES) != 0 || driver_target_features_init(&tf, &env, argc) != 0) { driver_errf(CPP_TOOL, "out of memory"); driver_target_features_fini(&tf, &env); @@ -204,10 +252,40 @@ int driver_cpp(int argc, char** argv) { driver_env_fini(&env); return 2; } - driver_cflags_fill_pp(&cf, &pp); - ctx = driver_env_to_context(&env); + if (!o.freestanding && !o.nostdinc && + (o.sysroot || driver_target_default_hosted_profile(o.target))) { + DriverHostedRequest req = {0}; + uint32_t i; + req.env = &env; + req.tool = CPP_TOOL; + req.target = o.target; + req.sysroot = o.sysroot; + req.link_inputs = 0; + if (driver_hosted_resolve(&req, &hosted) != 0) goto out; + hosted_engaged = hosted.profile_name != NULL; + for (i = 0; i < hosted.nsystem_includes; ++i) + cf.system_include_dirs[cf.nsystem_include_dirs++] = + hosted.system_includes[i]; + for (i = 0; i < hosted.ndefines; ++i) + cf.defines[cf.ndefines++] = hosted.defines[i]; + } + + if (driver_runtime_resolve(&env, o.support_dir, argv[0], &runtime) != 0) { + driver_errf(CPP_TOOL, "support dir not found"); + goto out; + } + runtime_resolved = 1; + if (!o.nostdinc && + (hosted_engaged + ? driver_runtime_append_freestanding_headers(&runtime, &cf) + : driver_runtime_add_freestanding_headers(&runtime, &cf)) != 0) { + driver_errf(CPP_TOOL, "failed to add freestanding headers"); + goto out; + } + driver_cflags_fill_pp(&cf, &pp); + if (o.from_stdin) { if (!driver_read_stdin(&env, &stdin_buf, &stdin_size)) { driver_errf(CPP_TOOL, "failed to read stdin"); @@ -260,6 +338,8 @@ out: if (writer) kit_writer_close(writer); if (loaded) ctx.file_io->release(ctx.file_io->user, &src); if (stdin_buf) driver_free(&env, stdin_buf, stdin_size); + if (runtime_resolved) driver_runtime_support_fini(&env, &runtime); + driver_hosted_plan_fini(&env, &hosted); driver_target_features_fini(&tf, &env); driver_cflags_fini(&cf, &env); driver_env_fini(&env); diff --git a/driver/lib/hosted.c b/driver/lib/hosted.c @@ -68,13 +68,22 @@ int driver_hosted_dirs_resolve(const DriverHostedRequest* req, if (env_sysroot && env_sysroot[0]) sysroot = env_sysroot; } if (sysroot) { + if (!driver_path_exists(sysroot)) { + driver_errf(req->tool, "sysroot not found: %.*s", + KIT_SLICE_ARG(kit_slice_cstr(sysroot))); + return 1; + } if (hosted_dirs_from_sysroot(out, req->target, sysroot) != 0) { driver_hosted_dirs_fini(out); return 1; } } else { KitTargetSpec host = driver_host_target(); - if (req->target.os == host.os && req->target.arch == host.arch) + if (host.os == KIT_OS_MACOS && req->target.os == KIT_OS_MACOS) + /* One installed macOS SDK serves both supported Darwin architectures; + * allow native cross-arch x86_64<->aarch64 without xcrun. */ + (void)driver_default_hosted_dirs(req->env, req->target, out); + else if (req->target.os == host.os && req->target.arch == host.arch) (void)driver_default_hosted_dirs(req->env, req->target, out); else if (host.os == KIT_OS_MACOS && (req->target.os == KIT_OS_IOS || @@ -94,7 +103,6 @@ int driver_hosted_resolve(const DriverHostedRequest* req, if (!req || !out || !req->env || !req->tool) return 1; *out = zero; if (driver_hosted_dirs_resolve(req, &dirs) != 0) { - driver_errf(req->tool, "out of memory"); return 1; } ops = hosted_ops_for(req->target); diff --git a/include/kit/os.h b/include/kit/os.h @@ -61,6 +61,12 @@ typedef struct KitOsHostedPlan { size_t owned_system_include_sizes[KIT_OS_HOSTED_MAX_INCLUDES]; uint32_t nsystem_includes; KitDefine defines[KIT_OS_HOSTED_MAX_DEFINES]; + /* Dynamic predefine bodies are copied into plan-owned storage. Literal + * predefines leave these slots NULL. This keeps KitDefine slices valid until + * kit_os_hosted_plan_fini even when a resolver formats a value on its stack + * (for example Android's API level). */ + char* owned_define_bodies[KIT_OS_HOSTED_MAX_DEFINES]; + size_t owned_define_body_sizes[KIT_OS_HOSTED_MAX_DEFINES]; uint32_t ndefines; char* lib_search_dirs[KIT_OS_HOSTED_MAX_LIB_SEARCH_DIRS]; size_t lib_search_dir_sizes[KIT_OS_HOSTED_MAX_LIB_SEARCH_DIRS]; diff --git a/recipes/buildkit/common.sh b/recipes/buildkit/common.sh @@ -622,6 +622,7 @@ driver/env/uctx_rv64_freebsd.c" ;; bk_enabled KIT_TOOL_DISAS_ENABLED && tool_srcs="$tool_srcs driver/cmd/disas.c" bk_enabled KIT_TOOL_MC_ENABLED && tool_srcs="$tool_srcs driver/cmd/mc.c" bk_enabled KIT_TOOL_GRAM_ENABLED && tool_srcs="$tool_srcs driver/cmd/gram.c" + bk_enabled KIT_TOOL_TARGETS_ENABLED && tool_srcs="$tool_srcs driver/cmd/targets.c" bk_enabled KIT_TOOL_UPDATE_ENABLED && tool_srcs="$tool_srcs driver/cmd/update.c" shared="" diff --git a/scripts/hosted.sh b/scripts/hosted.sh @@ -39,16 +39,36 @@ set -u ROOT="$(cd "$(dirname "$0")/.." && pwd)" KIT="${KIT:-$ROOT/build/kit}" -SUPPORT_SET=" -linux-glibc-aa64 linux-glibc-x64 linux-glibc-rv64 -linux-musl-aa64 linux-musl-x64 linux-musl-rv64 -freebsd-aa64 freebsd-x64 freebsd-rv64 -windows-aa64 windows-x64 -android-aa64 -macos-aa64 macos-x64 -freestanding-aa64 freestanding-x64 freestanding-rv64 freestanding-rv32 freestanding-arm32 +SUPPORT_SET_FALLBACK=" +linux-glibc-aa64 linux-musl-aa64 freebsd-aa64 android-aa64 freestanding-aa64 +linux-glibc-x64 linux-musl-x64 freebsd-x64 freestanding-x64 +linux-glibc-rv64 linux-musl-rv64 freebsd-rv64 freestanding-rv64 +freestanding-rv32 freestanding-arm32 +windows-aa64 windows-x64 macos-aa64 macos-x64 " +# A built candidate is the authority for selectors/triples. Keep the literal +# fallback only for bootstrap/provisioning before `make bin`; once `kit +# targets` is available, list/expand/doctor consume its versioned TSV registry. +# iOS/Wasm profiles are intentionally filtered here because this script has no +# provision/run personality for them yet; they remain visible in `kit targets`. +TARGET_REGISTRY_TSV="" +if [ -x "$KIT" ]; then + TARGET_REGISTRY_TSV="$("$KIT" targets --format=tsv 2>/dev/null || true)" +fi +SUPPORT_SET="$SUPPORT_SET_FALLBACK" +if [ -n "$TARGET_REGISTRY_TSV" ]; then + registry_support_set="$(printf '%s\n' "$TARGET_REGISTRY_TSV" | awk -F '\t' ' + $1 ~ /^linux-(glibc|musl)-(aa64|x64|rv64)$/ || + $1 ~ /^freebsd-(aa64|x64|rv64)$/ || + $1 ~ /^windows-(aa64|x64)$/ || + $1 == "android-aa64" || + $1 ~ /^macos-(aa64|x64)$/ || + $1 ~ /^freestanding-(aa64|x64|rv64|rv32|arm32)$/ { print $1 } + ')" + [ -n "$registry_support_set" ] && SUPPORT_SET="$registry_support_set" +fi + die() { printf 'hosted: %s\n' "$*" >&2; exit 1; } # ---- target parsing -------------------------------------------------------- @@ -105,7 +125,17 @@ parse_target() { } triple_of() { + local canonical registry_triple parse_target "$1" + canonical="$(canon_token "$1")" + if [ -n "$TARGET_REGISTRY_TSV" ]; then + registry_triple="$(printf '%s\n' "$TARGET_REGISTRY_TSV" | awk -F '\t' \ + -v selector="$canonical" '$1 == selector { print $2; exit }')" + if [ -n "$registry_triple" ]; then + printf '%s\n' "$registry_triple" + return + fi + fi case "$T_OS" in linux) local suf=gnu; [ "$T_LIBC" = musl ] && suf=musl @@ -241,11 +271,10 @@ cc_target() { local triple sysroot; triple="$(triple_of "$target")"; sysroot="$(path_of "$target")" local args=() if [ "$T_OS" = macos ]; then - # Compile against the Xcode/CLT SDK. A native-arch build omits -target so - # the host default applies; a cross to the other macOS arch (e.g. x86_64 on - # Apple silicon, run via Rosetta) needs the explicit target. - local sdk; sdk="$(xcrun --show-sdk-path 2>/dev/null)" - [ -n "$sdk" ] && args+=(-isysroot "$sdk") + # Kit discovers and applies the native Xcode/CLT SDK itself. A native-arch + # build omits -target so the host default applies; a cross to the other + # macOS arch (e.g. x86_64 on Apple silicon, run via Rosetta) needs only the + # explicit target. No SDK-discovery helper is part of this path. local ha; ha="$(uname -m 2>/dev/null)" case "$T_ARCH:$ha" in x64:arm64|x64:aarch64|aarch64:x86_64|aarch64:amd64) args+=(-target "$triple") ;; diff --git a/src/os/android/hosted.c b/src/os/android/hosted.c @@ -7,7 +7,8 @@ static unsigned android_api_level(KitTargetSpec target) { return api < 21u ? 21u : api; } -static int hosted_add_android_defines(KitOsHostedPlan* plan, +static int hosted_add_android_defines(const KitOsHostedRequest* req, + KitOsHostedPlan* plan, KitTargetSpec target) { char api_buf[4]; int n = snprintf(api_buf, sizeof api_buf, "%u", android_api_level(target)); @@ -19,7 +20,8 @@ static int hosted_add_android_defines(KitOsHostedPlan* plan, kit_os_hosted_add_define(plan, "__linux", "1") != 0 || kit_os_hosted_add_define(plan, "linux", "1") != 0 || kit_os_hosted_add_define(plan, "__ELF__", "1") != 0 || - kit_os_hosted_add_define(plan, "__ANDROID_API__", api_buf) != 0) + kit_os_hosted_add_define_owned(plan, req->host, req->host_user, + "__ANDROID_API__", api_buf) != 0) return 1; return 0; } @@ -46,7 +48,7 @@ static int hosted_resolve_android(const KitOsHostedRequest* req, plan->profile_name = req->shared_link ? "android-bionic-shared" : "android-bionic-dynamic"; if (!req->shared_link) plan->interp_path = "/system/bin/linker64"; - if (hosted_add_android_defines(plan, req->target) != 0 || + if (hosted_add_android_defines(req, plan, req->target) != 0 || kit_os_hosted_add_incdirs(plan, req->host, req->host_user, dirs) != 0) { kit_os_hosted_errf(req->host, req->host_user, req->tool, "out of memory"); return 1; diff --git a/src/os/hosted.c b/src/os/hosted.c @@ -176,6 +176,30 @@ int kit_os_hosted_add_define(KitOsHostedPlan* plan, const char* name, return 0; } +int kit_os_hosted_add_define_owned(KitOsHostedPlan* plan, + const KitOsHostedHost* host, + void* host_user, const char* name, + const char* body) { + size_t index, len, size; + char* copy; + if (!plan || !host || !host->alloc || !host->free || !name || !body) + return 1; + if (plan->ndefines >= KIT_OS_HOSTED_MAX_DEFINES) return 1; + len = strlen(body); + size = len + 1u; + copy = (char*)host->alloc(host_user, size); + if (!copy) return 1; + memcpy(copy, body, size); + index = plan->ndefines; + if (kit_os_hosted_add_define(plan, name, copy) != 0) { + host->free(host_user, copy, size); + return 1; + } + plan->owned_define_bodies[index] = copy; + plan->owned_define_body_sizes[index] = size; + return 0; +} + int kit_os_hosted_add_clang_compat_defines(KitOsHostedPlan* plan) { if (kit_os_hosted_add_define(plan, "__clang__", "1") != 0 || kit_os_hosted_add_define(plan, "__clang_major__", "17") != 0 || @@ -221,6 +245,11 @@ void kit_os_hosted_plan_fini(const KitOsHostedHost* host, void* host_user, host->free(host_user, plan->owned_system_includes[i], plan->owned_system_include_sizes[i]); } + for (i = 0; i < plan->ndefines; ++i) { + if (plan->owned_define_bodies[i]) + host->free(host_user, plan->owned_define_bodies[i], + plan->owned_define_body_sizes[i]); + } for (i = 0; i < plan->nlib_search_dirs; ++i) { if (plan->lib_search_dirs[i]) host->free(host_user, plan->lib_search_dirs[i], diff --git a/src/os/hosted_internal.h b/src/os/hosted_internal.h @@ -25,6 +25,10 @@ int kit_os_hosted_add_incdirs(KitOsHostedPlan* plan, const KitOsHostedDirs* dirs); int kit_os_hosted_add_define(KitOsHostedPlan* plan, const char* name, const char* body); +int kit_os_hosted_add_define_owned(KitOsHostedPlan* plan, + const KitOsHostedHost* host, + void* host_user, const char* name, + const char* body); int kit_os_hosted_add_clang_compat_defines(KitOsHostedPlan* plan); #endif diff --git a/src/os/macos/hosted.c b/src/os/macos/hosted.c @@ -111,7 +111,10 @@ static int hosted_sysroot_layout_darwin(KitOsHostedDirs* dirs, const KitOsHostedOps kit_os_macos_hosted_ops = { .obj = KIT_OBJ_MACHO, - .default_profile = 0, + /* Native Darwin compilation is hosted by default. Driver-side host/OS + * gating prevents this policy from borrowing a Darwin SDK when kit runs + * on another operating system. */ + .default_profile = 1, .needs_sysroot_libdir = 0, .uses_framework_dirs = 1, .resolve = hosted_resolve_darwin, diff --git a/test/buildcmds/run.sh b/test/buildcmds/run.sh @@ -80,10 +80,9 @@ run_fail bo-autovar-pattern-rejected "$KIT" build-obj \ contains bo-autovar-pattern-rejected-diag \ "$work/bo-autovar-pattern-rejected.err" "not yet supported" -run_fail bo-stack-protector-rejected "$KIT" build-obj \ +run_ok bo-stack-protector-strong "$KIT" build-obj \ -fstack-protector-strong -c -Iinc hello.c -o stack_protector.o -contains bo-stack-protector-rejected-diag \ - "$work/bo-stack-protector-rejected.err" "not supported yet" +assert_file_exists bo-stack-protector-strong-file stack_protector.o run_fail bo-general-regs-only-fp "$KIT" build-obj \ -mgeneral-regs-only -c fp.c -o fp.o