pthbs

Packaging Through Hashed Build Scripts
git clone https://ccx.te2000.cz/git/pthbs
Log | Files | Refs | Submodules | README

commit 5c9723e3378ec351a025cbad714b55061d50f535
parent 97b7a3505c270ce2fcc719c623b6871e67eb90be
Author: Jan Pobříslo <ccx@te2000.cz>
Date:   Wed, 31 May 2023 13:12:34 +0200

Prototype makefile generator

Diffstat:
AMakefile | 17+++++++++++++++++
Mcommand/pthbs-build | 7+++++--
Acommand/pthbs-getenvhash | 2++
Acommand/pthbs-makegen | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/busybox | 9+++++----
Apackages/busybox:bootstrap | 29+++++++++++++++++++++++++++++
Rpackages/gnu-make -> packages/gnu-make:bootstrap | 0
Rpackages/musl-cross-make -> packages/musl-cross-make:bootstrap | 0
8 files changed, 180 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,17 @@ +VERSIONS:=$(HOME)/versions + +test: /home/ccx/versions/environment.12345678990/.env + +$(VERSIONS)/environment.%/.env: + @echo mkdir "$$(dirname '$@')" + @echo touch '$@' + + +make/package.%.mk: packages/% + pthbs-makegen 'packages/$*' >'$@.new' + mv '$@.new' '$@' + + +pkg_files=$(wildcard packages/*) +mk_files=$(patsubst packages/%,make/package.%.mk,$(pkg_files)) +include $(mk_files) diff --git a/command/pthbs-build b/command/pthbs-build @@ -6,6 +6,9 @@ basedir=$(dirname "$(dirname "$(realpath "$0")")") workdir=$basedir/work/builddir.$$ script=$(realpath "$1") +pthbs_package=${1##*/} +pthbs_package=${pthbs_package%%:*}.$bsh + mkdir -p "$workdir" env \ basedir="$basedir" \ @@ -95,10 +98,10 @@ if env -i \ JOBS="$JOBS" \ pthbs_script="$script" \ pthbs_destdir="$workdir/destdir" \ - pthbs_package="${1##*/}.$bsh" \ + pthbs_package="$pthbs_package" \ sh -xe "$workdir/pthbs-setup" </dev/null; then echo "BUILD SUCCESFUL" - pthbs-install "$workdir/destdir" "${1##*/}.$bsh" || echo "INSTALL FAILED: exitcode $$" + pthbs-install "$workdir/destdir" "$pthbs_package" || echo "INSTALL FAILED: exitcode $$" else echo "BUILD FAILED: exitcode $$" fi diff --git a/command/pthbs-getenvhash b/command/pthbs-getenvhash @@ -0,0 +1,2 @@ +#!/bin/sh +sort -u "$@" | sha256sum | sed 's/ .*//' diff --git a/command/pthbs-makegen b/command/pthbs-makegen @@ -0,0 +1,122 @@ +#!/bin/sh +set -x +bsh=$(sha256sum $1) || exit $? +bsh=${bsh%% *} +basedir=$(dirname "$(dirname "$(realpath "$0")")") +workdir=$basedir/work/builddir.$$ +script=$(realpath "$1") + +pthbs_package=${1##*/} +pthbs_package=${pthbs_package%%:*}.$bsh + +mkdir -p "$workdir" +exec env \ + basedir="$basedir" \ + workdir="$workdir" \ + script="$script" \ + bsh="$bsh" \ + package="$pthbs_package" \ + awk -v single_quote="'" ' +BEGIN { + while(getline <"downloadlist.sha256") { + downloadable_hashes["sha256",$1] = 1 + } + close("downloadlist.sha256") + + sandbox = 1 + dep_count = 0 + env_count = 0 + FS=":" +} + +function q(s) { # quote string for sh + gsub(single_quote, single_quote "\\" single_quote single_quote, s) + return single_quote s single_quote +} + +function fatal(msg) { + printf "FATAL: %s %s:%d: \"%s\"\n", msg, FILENAME, FNR, $0 >"/dev/stderr" + exit 1 +} + +function have_file(hash_type, file_hash) { + if(!((hash_type, file_hash) in downloadable_hashes)) { + return + } + deps[++dep_count] = "make/file."hash_type"."file_hash".downloaded" +} + +function have_envdep(package) { + if(match(package, "[.][0-9a-f]{64}$") == 0) { + fatal("invalid syntax for @sha256:") + } + env[++env_count] = package + package_hash = substr(package, 64, RSTART+1) + envdep[env_count] = "$(VERSIONS)/"package"/.install-links" +} + +/^#!/ { next } +/^#\+/ { + if($0 == "#+*") { + sandbox = 0 + next + } else { + have_envdep(substr($0, 3)) + } +} +/^#@/ { + if($1 == "#@git") { + next + } else if($1 == "#@sha256") { + if(match($0, "^#@sha256:[0-9a-f]+:") == 0) { + fatal("invalid syntax for @sha256:") + } + have_file("sha256", $2) + } else if($1 == "#@untar") { + if(match($0, "^#@untar:[^:]*:sha256:[0-9a-f]+:") == 0) { + fatal("invalid syntax for @untar:") + } + have_file("sha256", $4) + } else { + fatal("unrecognized @command:") + } + next +} +/^$/ { + if(sandbox && env_count) { + envfile = "make/package.sha256."ENVIRON["bsh"]".env" + for(n=1; n<=env_count; n++) { + print env[n] >envfile + } + close(envfile) + if(("pthbs-getenvhash "q(envfile) | getline) < 1) { + fatal("Error getting envhash from "q(envfile)) + } + envhash=$0 + if(match(envhash, "^[0-9a-f]{64}$") == 0) { + fatal("received invalid envhash: "q(envhash)) + } + deps[++dep_count] = "$(VERSIONS)/env."envhash"/.pthbs-env" + printf "%s:", "$(VERSIONS)/env."envhash"/.pthbs-env" + for(n=1; n<=env_count; n++) { + printf " %s", envdep[n] + } + for(n=1; n<=env_count; n++) { + printf "\n\t%s", "pthbs-link "q("$(VERSIONS)/"env[n])" "q("$(VERSIONS)/env."envhash) + } + printf "\n\t%s\n\n", "touch "q("$@") + + } + if(dep_count) { + printf "%s", "$(VERSIONS)/"ENVIRON["package"]"/.install-links:" + for(n=1; n<=dep_count; n++) { + printf " %s", dep[n] + } + printf "\n\t%s\n\n", "pthbs-build "q(ENVIRON["script"]) + } + exit 0 +} +{ + fatal("unexpected line") +} +' diff --git a/packages/busybox b/packages/busybox @@ -1,14 +1,15 @@ #!/usr/bin/env pthbs-build #+* #@git:aa4d303a3139107919f73cece4eaf85a7dc75db6:busybox -#@sha256:d8cf7230674d830c32d679dcbaf8123ff1f157ae10b12fa350b475c6787bf8d7:busybox/.config +#@sha256:e653a2f29743ec8f96d68f62c4db7c76db5ff769ec9e7cd6671397c7cc2b942f:busybox/.config : ${JOBS:=1} pthbs_versions=/home/ccx/versions -mcm=/home/ccx/versions/musl-cross-make.28f276dc3ccb79d848faef27306550919ffb3fe7ea079f400aa938663f00255a -make=/home/ccx/versions/gnu-make.74047112114e76692c8ccca7573fcc41e6919135d4f63a14382c931be01101ae/bin/make +mcm=$pthbs_versions/musl-cross-make.28f276dc3ccb79d848faef27306550919ffb3fe7ea079f400aa938663f00255a +make=$pthbs_versions/gnu-make.74047112114e76692c8ccca7573fcc41e6919135d4f63a14382c931be01101ae/bin/make +bb=$pthbs_versions/busybox.bb79828839f20c5ca7289b60219896456264b237bb0107ee9c9407b01704a2cc -export PATH="$mcm/bin:/home/ccx/current/command:$PATH" +export PATH="$bb/$mcm/bin:/home/ccx/current/command:$PATH" export CC="$mcm/bin/x86_64-linux-musl-gcc" export CXX="$mcm/bin/x86_64-linux-musl-g++" export CFLAGS="-D_GNU_SOURCE" diff --git a/packages/busybox:bootstrap b/packages/busybox:bootstrap @@ -0,0 +1,29 @@ +#!/usr/bin/env pthbs-build +#+* +#@git:aa4d303a3139107919f73cece4eaf85a7dc75db6:busybox +#@sha256:e653a2f29743ec8f96d68f62c4db7c76db5ff769ec9e7cd6671397c7cc2b942f:busybox/.config + +: ${JOBS:=1} +pthbs_versions=/home/ccx/versions +mcm=/home/ccx/versions/musl-cross-make.28f276dc3ccb79d848faef27306550919ffb3fe7ea079f400aa938663f00255a +make=/home/ccx/versions/gnu-make.74047112114e76692c8ccca7573fcc41e6919135d4f63a14382c931be01101ae/bin/make + +export PATH="$mcm/bin:/home/ccx/current/command:$PATH" +export CC="$mcm/bin/x86_64-linux-musl-gcc" +export CXX="$mcm/bin/x86_64-linux-musl-g++" +export CFLAGS="-D_GNU_SOURCE" +export LDFLAGS="-static" + +cd busybox +$make V=1 LDFLAGS=-static HOSTLDFLAGS=-static \ + HOSTCC="$CC -static" CC="$CC -static" HOSTCFLAGS=-D_GNU_SOURCE -j$JOBS + +mkdir -p "$pthbs_destdir/${pthbs_versions%/}/$pthbs_package/command" +cp -a busybox "$pthbs_destdir/${pthbs_versions%/}/$pthbs_package/command/" +cd "$pthbs_destdir/${pthbs_versions%/}/$pthbs_package" +echo false | ./command/busybox --list >/dev/null # test if it works +./command/busybox --list | awk ' +{ print "./command/busybox\t./command/busybox" $0 } +END { print "./command/busybox\t./command/busybox" } +' >.install-links.new +mv .install-links.new .install-links diff --git a/packages/gnu-make b/packages/gnu-make:bootstrap diff --git a/packages/musl-cross-make b/packages/musl-cross-make:bootstrap