kit

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

commit 68162c4ade84c734b1bbaecc249b14ce28cc95ab
parent 22a683dab70880013e144eb59abf7c28003abaf6
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Mon, 22 Jun 2026 23:20:33 -0700

Add coordinator build for kit

Diffstat:
ABUILD.kit | 7+++++++
Mdoc/BUILD_COORDINATOR.md | 14++++++++++++++
Arecipes/buildkit/common.sh | 654+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arecipes/buildkit/driver.sh | 30++++++++++++++++++++++++++++++
Arecipes/buildkit/kit.sh | 30++++++++++++++++++++++++++++++
Arecipes/buildkit/libkit.sh | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/build/build.h | 10++++++++++
Msrc/build/resolve.c | 20++++++++++----------
Msrc/build/runner.c | 28++++++++++++++--------------
9 files changed, 825 insertions(+), 24 deletions(-)

diff --git a/BUILD.kit b/BUILD.kit @@ -0,0 +1,7 @@ +kit-build 1 +[target driver] +recipe recipes/buildkit/driver.sh +[target kit] +recipe recipes/buildkit/kit.sh +[target libkit] +recipe recipes/buildkit/libkit.sh diff --git a/doc/BUILD_COORDINATOR.md b/doc/BUILD_COORDINATOR.md @@ -12,6 +12,20 @@ built (Makefile products, `KIT_*_ENABLED` component gating, and the staged self-build). The coordinator described here builds arbitrary projects by running declared recipes and caching their output trees by content. +The kit repository also carries a coordinator-based build for the host `kit` +binary itself as a Makefile alternative. From the repository root, build +`//:kit` with an existing kit binary that has the `build` tool enabled: + +``` +build/kit build --store build/buildkit-store --root . --def BUILD.kit \ + --env KIT=./build/kit //:kit +``` + +The target graph is intentionally limited to the kit binary path, not the test +suites: `//:libkit` builds `libkit.a`, `//:driver` builds the hosted driver +objects, and `//:kit` links them into an output tree containing `kit`, +`libkit.a`, and a regular-file `support/rt` runtime tree. + Historical implementation notes remain in [plan/BUILD_INTERNALS.md](plan/BUILD_INTERNALS.md) and [plan/BUILD_TESTING.md](plan/BUILD_TESTING.md); this document is the durable diff --git a/recipes/buildkit/common.sh b/recipes/buildkit/common.sh @@ -0,0 +1,654 @@ +#!/bin/sh + +set -eu + +PATH=${PATH:-/usr/bin:/bin:/usr/sbin:/sbin} +export PATH + +: "${KIT:=./build/kit}" + +bk_source() { + "$KIT" build source "$1" +} + +bk_config() { + key=$1 + def=$2 + "$KIT" build config-get --default "$def" "$key" +} + +bk_glob() { + "$KIT" build glob "$1" +} + +bk_depfile() { + if [ -s "$1" ]; then + norm="$1.norm" + sed -e 's@driver/cmd/\.\./\.\./@@g' \ + -e 's@driver/env/\.\./@driver/@g' \ + -e 's@src/build/\.\./@src/@g' \ + "$1" > "$norm" + "$KIT" build depfile "$norm" >/dev/null + rm -f "$1" "$norm" + fi +} + +bk_host_detect() { + uname_s=$(uname -s) + uname_m=$(uname -m) + case "$uname_s" in + Darwin) BK_HOST_OS=darwin ;; + Linux) BK_HOST_OS=linux ;; + FreeBSD) BK_HOST_OS=freebsd ;; + MINGW*|MSYS*|CYGWIN*) BK_HOST_OS=windows ;; + *) echo "unsupported host OS: $uname_s" >&2; exit 1 ;; + esac + case "$uname_m" in + x86_64|amd64) BK_HOST_ARCH=x86_64 ;; + aarch64|arm64) BK_HOST_ARCH=aarch64 ;; + riscv64) BK_HOST_ARCH=rv64 ;; + *) echo "unsupported host arch: $uname_m" >&2; exit 1 ;; + esac + + BK_HOST_OS=$(bk_config host.os "$BK_HOST_OS") + BK_HOST_ARCH=$(bk_config host.arch "$BK_HOST_ARCH") +} + +bk_cfg_file=${BK_CFG_FILE:-} +bk_cfg_init() { + if [ -z "$bk_cfg_file" ]; then + bk_cfg_file=$(bk_source include/kit/config.h) + fi +} + +bk_cfg() { + bk_cfg_init + awk -v k="$1" '$1 == "#define" && $2 == k { print $3; found = 1 } + END { if (!found) print "" }' "$bk_cfg_file" +} + +bk_enabled() { + [ "$(bk_cfg "$1")" = "1" ] +} + +bk_filter_out() { + pat=$1 + shift + for x in "$@"; do + case "$x" in + $pat) ;; + *) printf '%s\n' "$x" ;; + esac + done +} + +bk_find_sources() { + pat=$1 + case "$pat" in + *'/**/*.c') + dir=$(dirname "$(dirname "$pat")") + find "$dir" -type f -name '*.c' 2>/dev/null | sort + ;; + *'/*.c') + dir=$(dirname "$pat") + find "$dir" -type f -name '*.c' 2>/dev/null | + awk -v p="$dir/" 'index($0, p) == 1 { + rest = substr($0, length(p) + 1) + if (rest !~ /\//) print + }' | sort + ;; + *) + find . -type f -path "./$pat" 2>/dev/null | sed 's@^\./@@' | sort + ;; + esac +} + +bk_cc_supports() { + flag=$1 + if "$BK_CC" "$flag" -x c -E /dev/null >/dev/null 2>&1; then + printf '%s' "$flag" + fi +} + +bk_flags_init() { + bk_host_detect + + BK_CC=$(bk_config cc "${CC:-clang}") + BK_AR=$(bk_config ar "${AR:-ar}") + BK_MODE=$(bk_config mode "${RELEASE:-debug}") + BK_PROFILE=$(bk_config profile "${PROFILE:-0}") + + case "$BK_MODE" in + 1|release) + BK_HOST_OPTFLAGS=$(bk_config host.optflags "-O2") + BK_HOST_MODE_CPPFLAGS="-DNDEBUG" + BK_HOST_MODE_CFLAGS="-ffunction-sections -fdata-sections" + if [ "$BK_PROFILE" = "1" ]; then + BK_HOST_MODE_CFLAGS="$BK_HOST_MODE_CFLAGS -g -fno-omit-frame-pointer" + fi + case "$BK_HOST_OS" in + darwin) BK_HOST_MODE_LDFLAGS="-Wl,-dead_strip" ;; + *) BK_HOST_MODE_LDFLAGS="-Wl,--gc-sections" ;; + esac + if [ "$BK_PROFILE" != "1" ]; then + BK_HOST_MODE_LDFLAGS="$BK_HOST_MODE_LDFLAGS -Wl,-S" + fi + ;; + *) + BK_HOST_OPTFLAGS=$(bk_config host.optflags "-O0") + BK_HOST_MODE_CPPFLAGS="" + BK_HOST_MODE_CFLAGS="-g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address,undefined -fno-sanitize-recover=address,undefined -fsanitize-address-use-after-scope" + BK_HOST_MODE_LDFLAGS="-fsanitize=address,undefined" + ;; + esac + + BK_HOST_SYSROOT_CFLAGS="" + BK_HOST_SYSROOT_LDFLAGS="" + if [ "$BK_HOST_OS" = darwin ]; then + sdk=$(xcrun --show-sdk-path 2>/dev/null || true) + sdk=$(bk_config host.sysroot "$sdk") + if [ -n "$sdk" ]; then + BK_HOST_SYSROOT_CFLAGS="-isysroot $sdk" + BK_HOST_SYSROOT_LDFLAGS="-isysroot $sdk" + fi + fi + + auto_init=$(bk_cc_supports -ftrivial-auto-var-init=zero) + no_default_config=$(bk_cc_supports --no-default-config) + BK_AUTO_INIT_CFLAGS=$(bk_config cflags.auto-init "$auto_init") + BK_FREESTANDING_CONFIG_CFLAGS=$(bk_config cflags.freestanding-config "$no_default_config") + + BK_CFLAGS_COMMON="$BK_HOST_OPTFLAGS $BK_HOST_MODE_CPPFLAGS $BK_HOST_MODE_CFLAGS $BK_AUTO_INIT_CFLAGS -std=c11 -Wpedantic -Wall -Wextra -Werror" + BK_HOST_CFLAGS="$BK_CFLAGS_COMMON $BK_HOST_SYSROOT_CFLAGS" + BK_HOST_LDFLAGS="$BK_HOST_SYSROOT_LDFLAGS $BK_HOST_MODE_LDFLAGS" + BK_FREESTANDING_CFLAGS="$BK_CFLAGS_COMMON $BK_FREESTANDING_CONFIG_CFLAGS -ffreestanding -nostdinc -Irt/include" + BK_LIB_VISIBILITY_CFLAGS="-fvisibility=hidden" + BK_LIB_CFLAGS="$BK_FREESTANDING_CFLAGS $BK_LIB_VISIBILITY_CFLAGS -Iinclude -Isrc -Ivendor" + BK_DRIVER_CFLAGS="$BK_FREESTANDING_CFLAGS -Iinclude -Ilang -Idriver -Idriver/lib" + BK_DRIVER_ENV_CFLAGS="$BK_HOST_CFLAGS -Iinclude -Ilang -Idriver -Idriver/lib" + BK_HOST_LDLIBS="" + BK_DRIVER_ENV_OS_CFLAGS="" + + case "$BK_HOST_OS" in + darwin) + BK_DRIVER_ENV_OS_CFLAGS="-D_XOPEN_SOURCE=600 -D_DARWIN_C_SOURCE=1" + ;; + linux) + BK_DRIVER_ENV_OS_CFLAGS="-D_GNU_SOURCE=1" + ;; + freebsd) + BK_HOST_LDLIBS="-lpthread" + BK_HOST_LDFLAGS="$BK_HOST_LDFLAGS -rdynamic" + ;; + windows) + BK_DRIVER_ENV_OS_CFLAGS="-D_WIN32_WINNT=0x0601" + BK_HOST_LDLIBS="-lpsapi" + ;; + esac +} + +bk_list_to_args() { + file=$1 + shift + : > "$file" + for x in "$@"; do + [ -n "$x" ] && printf '%s\n' "$x" >> "$file" + done +} + +bk_compile() { + src=$1 + obj=$2 + flags=$3 + mkdir -p "$(dirname "$obj")" + dep="$obj.d" + "$BK_CC" $flags -MMD -MP -MF "$dep" -c "$src" -o "$obj" + bk_depfile "$dep" +} + +bk_flat_obj() { + src=$1 + root=$2 + dest=$3 + rel=${src#"$root"/} + dir=$(dirname "$rel") + base=${rel%.c} + flat=$(printf '%s' "$base" | tr '/' '_').o + printf '%s/%s/%s/%s\n' "$KIT_BUILD_OUT" "$dest" "$dir" "$flat" +} + +bk_driver_obj() { + src=$1 + rel=${src#driver/} + printf '%s/driver/%s.o\n' "$KIT_BUILD_OUT" "${rel%.c}" +} + +bk_sort_words() { + printf '%s\n' "$@" | awk 'NF' | sort -u +} + +bk_lib_sources() { + bk_cfg_init + src_api=$(bk_find_sources 'src/api/*.c') + src_arch=$(bk_find_sources 'src/arch/*.c') + src_asm=$(bk_find_sources 'src/asm/*.c') + src_cg=$(bk_find_sources 'src/cg/*.c') + src_core=$(bk_find_sources 'src/core/*.c') + src_obj=$(bk_find_sources 'src/obj/*.c') + + lib_srcs=" +src/abi/abi.c +src/abi/registry.c +$(printf '%s\n' $src_api | awk '$0!="src/api/archive.c" && $0!="src/api/disasm.c" && $0!="src/api/link.c" && $0!="src/api/build.c" && $0!="src/api/cas.c" && $0!="src/api/build_coord.c" && $0!="src/api/package.c" && $0!="src/api/compress.c" && $0!="src/api/image.c" && $0!="src/api/stubs.c"') +$(printf '%s\n' $src_arch | awk '$0 !~ /_stubs[.]c$/') +$src_asm +$src_cg +$src_core +$(printf '%s\n' $src_obj | awk '$0 !~ /_stubs[.]c$/ && $0!="src/obj/image.c"') +src/os/registry.c +" + + aa64=$(bk_find_sources 'src/arch/aa64/**/*.c') + x64=$(bk_find_sources 'src/arch/x64/**/*.c') + arm32=$(bk_find_sources 'src/arch/arm32/**/*.c') + riscv=$(bk_find_sources 'src/arch/riscv/**/*.c') + wasm_arch=$(bk_find_sources 'src/arch/wasm/**/*.c') + c_target=$(bk_find_sources 'src/arch/c_target/**/*.c') + + if ! bk_enabled KIT_OPT_ENABLED; then + aa64=$(printf '%s\n' $aa64 | awk '$0 !~ /\/opt_coord[.]c$/') + x64=$(printf '%s\n' $x64 | awk '$0 !~ /\/opt_coord[.]c$/') + arm32=$(printf '%s\n' $arm32 | awk '$0 !~ /\/opt_coord[.]c$/') + riscv=$(printf '%s\n' $riscv | awk '$0 !~ /\/opt_coord[.]c$/') + fi + if ! bk_enabled KIT_DISASM_ENABLED; then + aa64=$(printf '%s\n' $aa64 | awk '$0 !~ /\/disasm[.]c$/') + x64=$(printf '%s\n' $x64 | awk '$0 !~ /\/disasm[.]c$/') + arm32=$(printf '%s\n' $arm32 | awk '$0 !~ /\/disasm[.]c$/') + riscv=$(printf '%s\n' $riscv | awk '$0 !~ /\/disasm[.]c$/') + lib_srcs="$lib_srcs +src/arch/disasm_stubs.c" + fi + if ! bk_enabled KIT_LINK_ENABLED; then + aa64=$(printf '%s\n' $aa64 | awk '$0 !~ /\/link[.]c$/') + x64=$(printf '%s\n' $x64 | awk '$0 !~ /\/link[.]c$/') + arm32=$(printf '%s\n' $arm32 | awk '$0 !~ /\/link[.]c$/') + riscv=$(printf '%s\n' $riscv | awk '$0 !~ /\/link[.]c$/') + lib_srcs="$lib_srcs +src/arch/link_stubs.c" + fi + if ! bk_enabled KIT_DBG_ENABLED; then + aa64=$(printf '%s\n' $aa64 | awk '$0 !~ /\/dbg[.]c$/') + x64=$(printf '%s\n' $x64 | awk '$0 !~ /\/dbg[.]c$/') + arm32=$(printf '%s\n' $arm32 | awk '$0 !~ /\/dbg[.]c$/') + riscv=$(printf '%s\n' $riscv | awk '$0 !~ /\/dbg[.]c$/') + lib_srcs="$lib_srcs +src/arch/dbg_stubs.c" + fi + if ! bk_enabled KIT_EMU_ENABLED; then + riscv=$(printf '%s\n' $riscv | awk '$0 !~ /\/emu[.]c$/') + lib_srcs="$lib_srcs +src/arch/emu_stubs.c" + fi + if ! bk_enabled KIT_INTERP_ENABLED; then + lib_srcs="$lib_srcs +src/interp/interp_stubs.c" + fi + + obj_elf=$(bk_find_sources 'src/obj/elf/**/*.c') + obj_macho=$(bk_find_sources 'src/obj/macho/**/*.c') + obj_coff=$(bk_find_sources 'src/obj/coff/**/*.c') + obj_wasm=$(bk_find_sources 'src/obj/wasm/**/*.c') + + bk_enabled KIT_ARCH_AA64_ENABLED || { + obj_elf=$(printf '%s\n' $obj_elf | awk '$0 !~ /\/reloc_aarch64[.]c$/') + obj_macho=$(printf '%s\n' $obj_macho | awk '$0 !~ /\/reloc_aarch64[.]c$/') + obj_coff=$(printf '%s\n' $obj_coff | awk '$0 !~ /\/reloc_aarch64[.]c$/') + } + bk_enabled KIT_ARCH_X64_ENABLED || { + obj_elf=$(printf '%s\n' $obj_elf | awk '$0 !~ /\/reloc_x86_64[.]c$/') + obj_macho=$(printf '%s\n' $obj_macho | awk '$0 !~ /\/reloc_x86_64[.]c$/') + obj_coff=$(printf '%s\n' $obj_coff | awk '$0 !~ /\/reloc_x86_64[.]c$/') + } + if ! bk_enabled KIT_ARCH_RV32_ENABLED && ! bk_enabled KIT_ARCH_RV64_ENABLED; then + obj_elf=$(printf '%s\n' $obj_elf | awk '$0 !~ /\/reloc_riscv(32|64)[.]c$/') + fi + bk_enabled KIT_ARCH_ARM32_ENABLED || { + obj_elf=$(printf '%s\n' $obj_elf | awk '$0 !~ /\/reloc_arm[.]c$/') + } + if ! bk_enabled KIT_LINK_ENABLED; then + obj_elf=$(printf '%s\n' $obj_elf | awk '$0 !~ /\/link(_dyn)?[.]c$/') + obj_macho=$(printf '%s\n' $obj_macho | awk '$0 !~ /\/link[.]c$/') + obj_coff=$(printf '%s\n' $obj_coff | awk '$0 !~ /\/link[.]c$/') + lib_srcs="$lib_srcs +src/obj/link_stubs.c" + fi + if ! bk_enabled KIT_EMU_ENABLED; then + obj_elf=$(printf '%s\n' $obj_elf | awk '$0 !~ /\/emu_load[.]c$/') + lib_srcs="$lib_srcs +src/obj/emu_stubs.c" + fi + if ! bk_enabled KIT_AR_ENABLED; then + obj_coff=$(printf '%s\n' $obj_coff | awk '$0 !~ /\/archive[.]c$/') + lib_srcs="$lib_srcs +src/obj/archive_stubs.c" + fi + + bk_enabled KIT_OPT_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'src/opt/**/*.c' | awk '$0!="src/opt/pass_o2.c"')" + bk_enabled KIT_INTERP_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'src/interp/**/*.c' | awk '$0 !~ /\/interp_stubs[.]c$/')" + bk_enabled KIT_AR_ENABLED && lib_srcs="$lib_srcs +src/api/archive.c" + bk_enabled KIT_DISASM_ENABLED && lib_srcs="$lib_srcs +src/api/disasm.c" + bk_enabled KIT_DWARF_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'src/debug/**/*.c')" + bk_enabled KIT_LINK_ENABLED && lib_srcs="$lib_srcs +src/api/link.c +src/api/build.c +$(bk_find_sources 'src/link/**/*.c')" + if ! bk_enabled KIT_JIT_ENABLED; then + lib_srcs=$(printf '%s\n' $lib_srcs | awk '$0 !~ /\/link_jit[.]c$/') + fi + bk_enabled KIT_BUILD_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'src/build/**/*.c') +src/api/build_coord.c" + bk_enabled KIT_IMAGE_ENABLED && lib_srcs="$lib_srcs +src/api/image.c +src/obj/image.c" + bk_enabled KIT_DBG_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'src/dbg/**/*.c')" + bk_enabled KIT_EMU_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'src/emu/**/*.c') +src/os/linux/linux.c" + bk_enabled KIT_GRAM_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'src/gram/**/*.c')" + bk_enabled KIT_CAS_ENABLED && lib_srcs="$lib_srcs +src/api/cas.c +src/dist/dist.c +src/dist/blake2b.c +src/dist/blob.c +src/dist/tree.c +src/dist/cas.c +vendor/monocypher/monocypher.c" + need_codec=0 + if bk_enabled KIT_COMPRESS_ENABLED; then + lib_srcs="$lib_srcs +src/api/compress.c +src/dist/lz4frame.c" + need_codec=1 + fi + if bk_enabled KIT_PKG_ENABLED; then + lib_srcs="$lib_srcs +src/api/package.c +src/dist/b64.c +src/dist/ed25519.c +src/dist/minisig.c +src/dist/tar.c +src/dist/kpkg.c +src/dist/manifest.c +src/dist/release.c +src/dist/trust.c +vendor/monocypher/monocypher-ed25519.c" + need_codec=1 + fi + [ "$need_codec" = 1 ] && lib_srcs="$lib_srcs +src/dist/deflate.c +src/dist/lz4.c" + + bk_enabled KIT_ARCH_AA64_ENABLED && lib_srcs="$lib_srcs +$aa64" + bk_enabled KIT_ARCH_X64_ENABLED && lib_srcs="$lib_srcs +$x64" + bk_enabled KIT_ARCH_ARM32_ENABLED && lib_srcs="$lib_srcs +$arm32" + if bk_enabled KIT_ARCH_RV32_ENABLED || bk_enabled KIT_ARCH_RV64_ENABLED; then + lib_srcs="$lib_srcs +$riscv" + fi + bk_enabled KIT_ARCH_WASM_ENABLED && lib_srcs="$lib_srcs +$wasm_arch" + bk_enabled KIT_ARCH_C_TARGET_ENABLED && lib_srcs="$lib_srcs +$c_target" + if bk_enabled KIT_ARCH_WASM_ENABLED || bk_enabled KIT_OBJ_WASM_ENABLED || bk_enabled KIT_LANG_WASM_ENABLED; then + lib_srcs="$lib_srcs +$(bk_find_sources 'src/wasm/**/*.c') +$obj_wasm" + fi + bk_enabled KIT_OBJ_ELF_ENABLED && lib_srcs="$lib_srcs +$obj_elf" + bk_enabled KIT_OBJ_MACHO_ENABLED && lib_srcs="$lib_srcs +$obj_macho" + bk_enabled KIT_OBJ_COFF_ENABLED && lib_srcs="$lib_srcs +$obj_coff" + if bk_enabled KIT_OBJ_ELF_ENABLED || bk_enabled KIT_OBJ_MACHO_ENABLED || bk_enabled KIT_OBJ_COFF_ENABLED; then + lib_srcs="$lib_srcs +src/os/hosted.c" + fi + if bk_enabled KIT_OBJ_ELF_ENABLED || bk_enabled KIT_EMU_ENABLED; then + lib_srcs="$lib_srcs +src/os/linux/os.c" + fi + bk_enabled KIT_OBJ_ELF_ENABLED && lib_srcs="$lib_srcs +src/os/linux/hosted.c +src/os/freebsd/os.c +src/os/freebsd/hosted.c +src/os/android/os.c +src/os/android/hosted.c" + bk_enabled KIT_OBJ_MACHO_ENABLED && lib_srcs="$lib_srcs +src/os/macos/os.c +src/os/macos/hosted.c" + bk_enabled KIT_OBJ_COFF_ENABLED && lib_srcs="$lib_srcs +src/os/windows/os.c +src/os/windows/hosted.c" + + if bk_enabled KIT_ARCH_AA64_ENABLED || bk_enabled KIT_ARCH_C_TARGET_ENABLED; then + if bk_enabled KIT_OBJ_ELF_ENABLED || bk_enabled KIT_OBJ_MACHO_ENABLED || bk_enabled KIT_OBJ_COFF_ENABLED; then + lib_srcs="$lib_srcs +src/abi/abi_aapcs64.c" + fi + bk_enabled KIT_OBJ_MACHO_ENABLED && lib_srcs="$lib_srcs +src/abi/abi_apple_arm64.c" + bk_enabled KIT_OBJ_COFF_ENABLED && lib_srcs="$lib_srcs +src/abi/abi_aapcs64_windows.c" + fi + if bk_enabled KIT_ARCH_X64_ENABLED || bk_enabled KIT_ARCH_C_TARGET_ENABLED; then + if bk_enabled KIT_OBJ_ELF_ENABLED || bk_enabled KIT_OBJ_MACHO_ENABLED; then + lib_srcs="$lib_srcs +src/abi/abi_sysv_x64.c" + fi + bk_enabled KIT_OBJ_MACHO_ENABLED && lib_srcs="$lib_srcs +src/abi/abi_apple_x64.c" + bk_enabled KIT_OBJ_COFF_ENABLED && lib_srcs="$lib_srcs +src/abi/abi_win64_x64.c" + fi + if bk_enabled KIT_ARCH_RV32_ENABLED || bk_enabled KIT_ARCH_RV64_ENABLED || bk_enabled KIT_ARCH_C_TARGET_ENABLED; then + bk_enabled KIT_OBJ_ELF_ENABLED && lib_srcs="$lib_srcs +src/abi/abi_rv64.c" + fi + if bk_enabled KIT_ARCH_ARM32_ENABLED || bk_enabled KIT_ARCH_C_TARGET_ENABLED; then + bk_enabled KIT_OBJ_ELF_ENABLED && lib_srcs="$lib_srcs +src/abi/abi_aapcs32.c" + fi + + bk_enabled KIT_LANG_CPP_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'lang/cpp/**/*.c')" + bk_enabled KIT_LANG_C_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'lang/c/**/*.c')" + bk_enabled KIT_LANG_WASM_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'lang/wasm/**/*.c')" + bk_enabled KIT_LANG_TOY_ENABLED && lib_srcs="$lib_srcs +$(bk_find_sources 'lang/toy/*.c')" + + printf '%s\n' $lib_srcs | awk 'NF && $0 != "src/opt/pass_o2.c"' | sort -u +} + +bk_driver_sources() { + bk_cfg_init + env_srcs="driver/env/common.c" + case "$BK_HOST_OS" in + windows) + env_srcs="$env_srcs +driver/env/windows.c" + ;; + darwin) + env_srcs="$env_srcs +driver/env/posix.c +driver/env/posix_dbg.c +driver/env/macos.c" + case "$BK_HOST_ARCH" in + aarch64) env_srcs="$env_srcs +driver/env/icache_arm.c +driver/env/uctx_aarch64_macos.c" ;; + x86_64) env_srcs="$env_srcs +driver/env/icache_x86.c +driver/env/uctx_x86_64_macos.c" ;; + *) echo "no Darwin ucontext for $BK_HOST_ARCH" >&2; exit 1 ;; + esac + ;; + linux) + env_srcs="$env_srcs +driver/env/posix.c +driver/env/posix_dbg.c +driver/env/linux.c" + case "$BK_HOST_ARCH" in + x86_64) env_srcs="$env_srcs +driver/env/linux_exec_hint_x86_64.c +driver/env/icache_x86.c +driver/env/uctx_x86_64_linux.c" ;; + aarch64) env_srcs="$env_srcs +driver/env/linux_exec_hint_default.c +driver/env/icache_arm.c +driver/env/uctx_aarch64_linux.c" ;; + rv64) env_srcs="$env_srcs +driver/env/linux_exec_hint_default.c +driver/env/icache_riscv.c +driver/env/uctx_rv64_linux.c" ;; + *) echo "no Linux ucontext for $BK_HOST_ARCH" >&2; exit 1 ;; + esac + ;; + freebsd) + env_srcs="$env_srcs +driver/env/posix.c +driver/env/posix_dbg.c +driver/env/freebsd.c" + case "$BK_HOST_ARCH" in + x86_64) env_srcs="$env_srcs +driver/env/icache_x86.c +driver/env/uctx_x86_64_freebsd.c" ;; + aarch64) env_srcs="$env_srcs +driver/env/icache_arm.c +driver/env/uctx_aarch64_freebsd.c" ;; + rv64) env_srcs="$env_srcs +driver/env/icache_riscv.c +driver/env/uctx_rv64_freebsd.c" ;; + *) echo "no FreeBSD ucontext for $BK_HOST_ARCH" >&2; exit 1 ;; + esac + ;; + esac + + tool_srcs="" + bk_enabled KIT_TOOL_CC_ENABLED && tool_srcs="$tool_srcs driver/cmd/cc.c" + bk_enabled KIT_TOOL_CHECK_ENABLED && tool_srcs="$tool_srcs driver/cmd/cc.c" + bk_enabled KIT_TOOL_BUILD_EXE_ENABLED && tool_srcs="$tool_srcs driver/cmd/build.c" + bk_enabled KIT_TOOL_BUILD_LIB_ENABLED && tool_srcs="$tool_srcs driver/cmd/build.c" + bk_enabled KIT_TOOL_BUILD_OBJ_ENABLED && tool_srcs="$tool_srcs driver/cmd/build.c" + bk_enabled KIT_TOOL_BUILD_ENABLED && tool_srcs="$tool_srcs driver/cmd/build_coord.c" + bk_enabled KIT_TOOL_INSTALL_ENABLED && tool_srcs="$tool_srcs driver/cmd/install.c" + bk_enabled KIT_TOOL_CPP_ENABLED && tool_srcs="$tool_srcs driver/cmd/cpp.c" + bk_enabled KIT_TOOL_AS_ENABLED && tool_srcs="$tool_srcs driver/cmd/as.c" + bk_enabled KIT_TOOL_LD_ENABLED && tool_srcs="$tool_srcs driver/cmd/ld.c" + bk_enabled KIT_TOOL_AR_ENABLED && tool_srcs="$tool_srcs driver/cmd/ar.c" + bk_enabled KIT_TOOL_CPIO_ENABLED && tool_srcs="$tool_srcs driver/cmd/cpio.c" + bk_enabled KIT_TOOL_RANLIB_ENABLED && tool_srcs="$tool_srcs driver/cmd/ranlib.c" + bk_enabled KIT_TOOL_STRIP_ENABLED && tool_srcs="$tool_srcs driver/cmd/strip.c" + bk_enabled KIT_TOOL_OBJCOPY_ENABLED && tool_srcs="$tool_srcs driver/cmd/objcopy.c" + bk_enabled KIT_TOOL_IMAGE_ENABLED && tool_srcs="$tool_srcs driver/cmd/image.c" + bk_enabled KIT_TOOL_OBJDUMP_ENABLED && tool_srcs="$tool_srcs driver/cmd/objdump.c" + bk_enabled KIT_TOOL_DBG_ENABLED && tool_srcs="$tool_srcs driver/cmd/dbg.c" + bk_enabled KIT_TOOL_RUN_ENABLED && tool_srcs="$tool_srcs driver/cmd/run.c" + bk_enabled KIT_TOOL_EMU_ENABLED && tool_srcs="$tool_srcs driver/cmd/emu.c" + bk_enabled KIT_TOOL_NM_ENABLED && tool_srcs="$tool_srcs driver/cmd/nm.c" + bk_enabled KIT_TOOL_SIZE_ENABLED && tool_srcs="$tool_srcs driver/cmd/size.c" + bk_enabled KIT_TOOL_ADDR2LINE_ENABLED && tool_srcs="$tool_srcs driver/cmd/addr2line.c" + bk_enabled KIT_TOOL_SYMBOLIZE_ENABLED && tool_srcs="$tool_srcs driver/cmd/symbolize.c" + bk_enabled KIT_TOOL_STRINGS_ENABLED && tool_srcs="$tool_srcs driver/cmd/strings.c" + bk_enabled KIT_TOOL_CAS_ENABLED && tool_srcs="$tool_srcs driver/cmd/cas.c" + bk_enabled KIT_TOOL_PKG_ENABLED && tool_srcs="$tool_srcs driver/cmd/pkg.c" + bk_enabled KIT_TOOL_XXD_ENABLED && tool_srcs="$tool_srcs driver/cmd/xxd.c" + bk_enabled KIT_TOOL_CMP_ENABLED && tool_srcs="$tool_srcs driver/cmd/cmp.c" + bk_enabled KIT_TOOL_HASH_ENABLED && tool_srcs="$tool_srcs driver/cmd/hash.c" + bk_enabled KIT_TOOL_COMPRESS_ENABLED && tool_srcs="$tool_srcs driver/cmd/compress.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_UPDATE_ENABLED && tool_srcs="$tool_srcs driver/cmd/update.c" + + shared="" + if bk_enabled KIT_TOOL_CC_ENABLED || bk_enabled KIT_TOOL_CHECK_ENABLED || bk_enabled KIT_TOOL_BUILD_EXE_ENABLED || bk_enabled KIT_TOOL_BUILD_LIB_ENABLED || bk_enabled KIT_TOOL_BUILD_OBJ_ENABLED || bk_enabled KIT_TOOL_CPP_ENABLED || bk_enabled KIT_TOOL_AS_ENABLED || bk_enabled KIT_TOOL_DBG_ENABLED || bk_enabled KIT_TOOL_RUN_ENABLED; then + shared="$shared driver/lib/cflags.c" + fi + if bk_enabled KIT_TOOL_CC_ENABLED || bk_enabled KIT_TOOL_CHECK_ENABLED || bk_enabled KIT_TOOL_BUILD_EXE_ENABLED || bk_enabled KIT_TOOL_BUILD_LIB_ENABLED || bk_enabled KIT_TOOL_BUILD_OBJ_ENABLED || bk_enabled KIT_TOOL_LD_ENABLED || bk_enabled KIT_TOOL_RUN_ENABLED; then + shared="$shared driver/lib/lib_resolve.c" + fi + if bk_enabled KIT_TOOL_CC_ENABLED || bk_enabled KIT_TOOL_CHECK_ENABLED || bk_enabled KIT_TOOL_BUILD_EXE_ENABLED || bk_enabled KIT_TOOL_BUILD_LIB_ENABLED || bk_enabled KIT_TOOL_BUILD_OBJ_ENABLED || bk_enabled KIT_TOOL_RUN_ENABLED; then + shared="$shared driver/lib/hosted.c" + fi + if bk_enabled KIT_TOOL_CC_ENABLED || bk_enabled KIT_TOOL_CHECK_ENABLED || bk_enabled KIT_TOOL_BUILD_EXE_ENABLED || bk_enabled KIT_TOOL_BUILD_LIB_ENABLED || bk_enabled KIT_TOOL_BUILD_OBJ_ENABLED || bk_enabled KIT_TOOL_LD_ENABLED; then + shared="$shared driver/lib/runtime.c" + fi + if bk_enabled KIT_TOOL_CC_ENABLED || bk_enabled KIT_TOOL_CHECK_ENABLED || bk_enabled KIT_TOOL_BUILD_EXE_ENABLED || bk_enabled KIT_TOOL_BUILD_LIB_ENABLED || bk_enabled KIT_TOOL_BUILD_OBJ_ENABLED; then + shared="$shared driver/lib/link_flags.c driver/lib/link_inputs.c" + fi + if bk_enabled KIT_TOOL_BUILD_EXE_ENABLED || bk_enabled KIT_TOOL_BUILD_LIB_ENABLED || bk_enabled KIT_TOOL_BUILD_OBJ_ENABLED; then + shared="$shared driver/lib/archive_engine.c" + fi + if bk_enabled KIT_TOOL_CC_ENABLED || bk_enabled KIT_TOOL_CHECK_ENABLED || bk_enabled KIT_TOOL_AR_ENABLED || bk_enabled KIT_TOOL_RANLIB_ENABLED || bk_enabled KIT_TOOL_STRIP_ENABLED || bk_enabled KIT_TOOL_DBG_ENABLED || bk_enabled KIT_TOOL_RUN_ENABLED || bk_enabled KIT_TOOL_BUILD_EXE_ENABLED || bk_enabled KIT_TOOL_BUILD_LIB_ENABLED || bk_enabled KIT_TOOL_BUILD_OBJ_ENABLED; then + shared="$shared driver/lib/inputs.c" + fi + if bk_enabled KIT_TOOL_STRIP_ENABLED || bk_enabled KIT_TOOL_OBJCOPY_ENABLED; then + shared="$shared driver/lib/objedit.c" + fi + bk_enabled KIT_TOOL_RUN_ENABLED && shared="$shared driver/lib/wasm_run.c" + if bk_enabled KIT_TOOL_CAS_ENABLED || bk_enabled KIT_TOOL_PKG_ENABLED || bk_enabled KIT_TOOL_BUILD_ENABLED || bk_enabled KIT_TOOL_UPDATE_ENABLED; then + shared="$shared driver/lib/dist_host.c" + fi + if bk_enabled KIT_TOOL_BUILD_ENABLED; then + case "$BK_HOST_OS" in + windows) shared="$shared driver/env/build_host_windows.c" ;; + *) shared="$shared driver/env/build_host_posix.c" ;; + esac + fi + if bk_enabled KIT_TOOL_INSTALL_ENABLED || bk_enabled KIT_TOOL_UPDATE_ENABLED; then + shared="$shared driver/lib/install_links.c" + fi + bk_enabled KIT_TOOL_UPDATE_ENABLED && shared="$shared driver/release_key.c" + if bk_enabled KIT_TOOL_ADDR2LINE_ENABLED || bk_enabled KIT_TOOL_SYMBOLIZE_ENABLED; then + shared="$shared driver/lib/dwarfsym.c" + fi + if bk_enabled KIT_TOOL_DBG_ENABLED || bk_enabled KIT_TOOL_RUN_ENABLED; then + shared="$shared driver/lib/backtrace.c" + fi + + printf '%s\n' driver/main.c driver/version.c driver/lib/target.c $env_srcs $tool_srcs $shared | + awk 'NF' | sort -u +} + +bk_version_defs() { + version_file=$(bk_source VERSION) + version=$(sed -n '1p' "$version_file") + [ -n "$version" ] || version=0.0.0 + build_id=$(bk_config build.id buildcoord) + case "$BK_HOST_ARCH" in + rv64) triple_arch=riscv64 ;; + *) triple_arch=$BK_HOST_ARCH ;; + esac + case "$BK_HOST_OS" in + darwin) triple_os=macos ;; + linux) triple_os=linux-gnu ;; + *) triple_os=$BK_HOST_OS ;; + esac + host_triple=$(bk_config host.triple "$triple_arch-$triple_os") + printf '%s\n' "-DKIT_VERSION_STR=\"$version\" -DKIT_BUILD_ID=\"$build_id\" -DKIT_HOST_TRIPLE=\"$host_triple\"" +} diff --git a/recipes/buildkit/driver.sh b/recipes/buildkit/driver.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -eu + +: "${KIT:=./build/kit}" +common=$("$KIT" build source recipes/buildkit/common.sh) +. "$common" + +bk_flags_init +mkdir -p "$KIT_BUILD_OUT" + +objects="$KIT_BUILD_OUT/objects.list" +: > "$objects" +version_defs=$(bk_version_defs) + +for src in $(bk_driver_sources); do + flags=$BK_DRIVER_CFLAGS + case "$src" in + driver/env/*) + flags="$BK_DRIVER_ENV_CFLAGS $BK_DRIVER_ENV_OS_CFLAGS" + ;; + esac + case "$src" in + driver/version.c) + flags="$flags $version_defs" + ;; + esac + obj=$(bk_driver_obj "$src") + bk_compile "$src" "$obj" "$flags" + printf '%s\n' "${obj#"$KIT_BUILD_OUT"/}" >> "$objects" +done diff --git a/recipes/buildkit/kit.sh b/recipes/buildkit/kit.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -eu + +: "${KIT:=./build/kit}" +common=$("$KIT" build source recipes/buildkit/common.sh) +. "$common" + +bk_flags_init +mkdir -p "$KIT_BUILD_OUT" + +driver_dir=$("$KIT" build need //:driver) +lib_dir=$("$KIT" build need //:libkit) + +objs= +while IFS= read -r obj; do + [ -n "$obj" ] || continue + objs="$objs $driver_dir/$obj" +done < "$driver_dir/objects.list" + +# shellcheck disable=SC2086 +"$BK_CC" $BK_HOST_LDFLAGS -o "$KIT_BUILD_OUT/kit" $objs \ + "$lib_dir/libkit.a" $BK_HOST_LDLIBS +cp "$lib_dir/libkit.a" "$KIT_BUILD_OUT/libkit.a" + +find rt -type f | sort | while IFS= read -r rt_file; do + src=$(bk_source "$rt_file") + dst="$KIT_BUILD_OUT/support/rt/$rt_file" + mkdir -p "$(dirname "$dst")" + cp "$src" "$dst" +done diff --git a/recipes/buildkit/libkit.sh b/recipes/buildkit/libkit.sh @@ -0,0 +1,56 @@ +#!/bin/sh +set -eu + +: "${KIT:=./build/kit}" +common=$("$KIT" build source recipes/buildkit/common.sh) +. "$common" + +bk_flags_init +mkdir -p "$KIT_BUILD_OUT" + +objects="$KIT_BUILD_OUT/objects.list" +: > "$objects" + +for src in $(bk_lib_sources); do + flags=$BK_LIB_CFLAGS + root=src + dest=lib + case "$src" in + src/api/lang_registry.c) + flags="$BK_FREESTANDING_CFLAGS $BK_LIB_VISIBILITY_CFLAGS -Iinclude -Ilang -Isrc" + ;; + lang/cpp/*) + flags="$BK_FREESTANDING_CFLAGS $BK_LIB_VISIBILITY_CFLAGS -Iinclude -Ilang/cpp" + root=lang + dest=lang + ;; + lang/c/*) + flags="$BK_FREESTANDING_CFLAGS $BK_LIB_VISIBILITY_CFLAGS -Iinclude -Ilang/cpp -Ilang/c" + root=lang + dest=lang + ;; + lang/wasm/*) + flags="$BK_FREESTANDING_CFLAGS $BK_LIB_VISIBILITY_CFLAGS -Iinclude -Isrc -Ilang/wasm" + root=lang + dest=lang + ;; + lang/toy/*) + flags="$BK_FREESTANDING_CFLAGS $BK_LIB_VISIBILITY_CFLAGS -Iinclude -Ilang/toy" + root=lang + dest=lang + ;; + vendor/*) + root=vendor + dest=vendor + ;; + esac + obj=$(bk_flat_obj "$src" "$root" "$dest") + bk_compile "$src" "$obj" "$flags" + printf '%s\n' "$obj" >> "$objects" +done + +rm -f "$KIT_BUILD_OUT/libkit.a" +# shellcheck disable=SC2046 +"$BK_AR" rcs "$KIT_BUILD_OUT/libkit.a" $(cat "$objects") +find "$KIT_BUILD_OUT" -type f ! -name libkit.a -delete +find "$KIT_BUILD_OUT" -type d -empty -delete diff --git a/src/build/build.h b/src/build/build.h @@ -74,6 +74,16 @@ #define BUILD_URL_MAX 1024u /* one fetch URL hint */ #define BUILD_PATTERN_MAX 256u /* glob pattern */ +/* Per-recipe trace section capacities. These are aggregate limits for one + * recipe execution, not row-size limits. They need to fit real C-library + * recipes that log one source leaf per compiled source/header while staying + * fixed-size and VLA-free. */ +#define BUILD_RECIPE_CONFIG_CAP 256u +#define BUILD_RECIPE_SOURCE_CAP 1024u +#define BUILD_RECIPE_GLOB_CAP 256u +#define BUILD_RECIPE_BLOB_CAP 256u +#define BUILD_RECIPE_DEP_CAP 256u + /* The two kinds of trace a build records. Written together on every real * build; resolution picks whichever fits the change it sees. */ typedef enum BuildTraceKind { diff --git a/src/build/resolve.c b/src/build/resolve.c @@ -716,11 +716,11 @@ scan_record: } for (i = 0; i < rec.n_rows; ++i) { KitFileData fd; - BuildConfigLeaf configs[128]; - BuildSourceLeaf sources[128]; - BuildGlobLeaf globs[128]; - BuildBlobLeaf blobs[128]; - BuildDepEdge deps[128]; + BuildConfigLeaf configs[BUILD_RECIPE_CONFIG_CAP]; + BuildSourceLeaf sources[BUILD_RECIPE_SOURCE_CAP]; + BuildGlobLeaf globs[BUILD_RECIPE_GLOB_CAP]; + BuildBlobLeaf blobs[BUILD_RECIPE_BLOB_CAP]; + BuildDepEdge deps[BUILD_RECIPE_DEP_CAP]; BuildShallowTrace st; size_t rows; if (rec.rows[i].kind != (uint8_t)BUILD_TRACE_SHALLOW) continue; @@ -885,11 +885,11 @@ scan_record: } for (i = 0; i < rec.n_rows; ++i) { KitFileData fd; - BuildConfigLeaf configs[128]; - BuildSourceLeaf sources[128]; - BuildGlobLeaf globs[128]; - BuildBlobLeaf blobs[128]; - BuildDepEdge deps[128]; + BuildConfigLeaf configs[BUILD_RECIPE_CONFIG_CAP]; + BuildSourceLeaf sources[BUILD_RECIPE_SOURCE_CAP]; + BuildGlobLeaf globs[BUILD_RECIPE_GLOB_CAP]; + BuildBlobLeaf blobs[BUILD_RECIPE_BLOB_CAP]; + BuildDepEdge deps[BUILD_RECIPE_DEP_CAP]; BuildShallowTrace st; size_t nrows; if (rec.rows[i].kind != (uint8_t)BUILD_TRACE_SHALLOW) continue; diff --git a/src/build/runner.c b/src/build/runner.c @@ -379,13 +379,13 @@ static int build_run_recipe_impl(KitBuildCoordinator* c, KitSlice target, size_t argc = 0, nenv = 0, i; int exit_code = 1; int ok = BUILD_ERR; - BuildConfigLeaf configs[128]; - BuildSourceLeaf sources[128]; - BuildGlobLeaf globs[128]; - BuildBlobLeaf blobs[128]; - BuildDepEdge deps[128]; - const BuildLeafSet* child_leafsets[128]; - BuildPendingNeed pending[128]; + BuildConfigLeaf configs[BUILD_RECIPE_CONFIG_CAP]; + BuildSourceLeaf sources[BUILD_RECIPE_SOURCE_CAP]; + BuildGlobLeaf globs[BUILD_RECIPE_GLOB_CAP]; + BuildBlobLeaf blobs[BUILD_RECIPE_BLOB_CAP]; + BuildDepEdge deps[BUILD_RECIPE_DEP_CAP]; + const BuildLeafSet* child_leafsets[BUILD_RECIPE_DEP_CAP]; + BuildPendingNeed pending[BUILD_RECIPE_DEP_CAP]; BuildDepLog log; if (!c || !cfg || !argv || !out || !c->host.exec || !c->host.transport) @@ -505,13 +505,13 @@ static int build_run_test_recipe_impl(KitBuildCoordinator* c, KitSlice target, size_t argc = 0, nenv = 0, i; int exit_code = 1; int ok = BUILD_ERR; - BuildConfigLeaf configs[128]; - BuildSourceLeaf sources[128]; - BuildGlobLeaf globs[128]; - BuildBlobLeaf blobs[128]; - BuildDepEdge deps[128]; - const BuildLeafSet* child_leafsets[128]; - BuildPendingNeed pending[128]; + BuildConfigLeaf configs[BUILD_RECIPE_CONFIG_CAP]; + BuildSourceLeaf sources[BUILD_RECIPE_SOURCE_CAP]; + BuildGlobLeaf globs[BUILD_RECIPE_GLOB_CAP]; + BuildBlobLeaf blobs[BUILD_RECIPE_BLOB_CAP]; + BuildDepEdge deps[BUILD_RECIPE_DEP_CAP]; + const BuildLeafSet* child_leafsets[BUILD_RECIPE_DEP_CAP]; + BuildPendingNeed pending[BUILD_RECIPE_DEP_CAP]; BuildDepLog log; if (!c || !cfg || !argv || !out || !c->host.exec || !c->host.transport ||