summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach van Rijn <me@zv.io>2023-02-04 01:03:24 -0600
committerZach van Rijn <me@zv.io>2023-10-05 17:42:06 +0000
commit3bf2e72cdfa79a465e94ef3102eeb0120407fe79 (patch)
tree177502f877c6a886a2a2c3192b7f991a3e2efed5
parentd2881162a4b8d50c765e7d8c5aa5c9b38b0daa46 (diff)
downloadpackages-zv/genmake.tar.gz
packages-zv/genmake.tar.bz2
packages-zv/genmake.tar.xz
packages-zv/genmake.zip
scripts/*: add Makefile generator.zv/genmake
This commit adds a few scripts to the packages repository: * configure Typical 'configure' script; run to see usage. * scripts/genmake Generates a top-level 'Makefile' that will either build packages in the correct order, or sleep to simulate package builds. The main purpose of this tool is to enable concurrent package builds, and to provide a framework to analyze build strategies. When a dependency is updated, it is the responsibility of the maintainer to relbump all dependent packages. This tool is intended to facilitate concurrent package builds, not be a comprehensive maintenance tool.
-rw-r--r--.gitignore2
-rwxr-xr-xconfigure103
-rwxr-xr-xscripts/genmake93
3 files changed, 198 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 5c5ff1687..4d70126d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@ pkg
scripts/sgrep
scripts/tsort
scripts/.index
+Makefile
+built
diff --git a/configure b/configure
new file mode 100755
index 000000000..72abed07d
--- /dev/null
+++ b/configure
@@ -0,0 +1,103 @@
+#!/bin/sh -e
+
+HERE="$(dirname $(readlink -f ${0}))";
+
+##
+# Full list of all possible repositories.
+#
+repos=$(grep -v ^# <<EOF
+system
+user
+legacy
+experimental
+EOF
+);
+
+##
+# Do not build any repos by default.
+#
+build="";
+
+##
+# Usage.
+#
+usage ()
+{
+ printf "Usage: %s OPTION [OPTION] ...\n" "${0}";
+
+ printf "\nOptions:\n\n";
+ cat <<"EOF"
+ --simulate Sleep 1 second instead of build
+EOF
+
+ printf "\nRepositories:\n\n";
+ for k in ${repos}; do
+ printf " --enable-%s\n" "${k}";
+ done
+ printf "\n";
+}
+
+##
+# Enable repositories only explicitly.
+#
+_find=;
+_fake=0; # default not a simulation
+for arg; do
+ case "${arg}" in
+ --enable-*)
+ for repo in ${repos}; do
+ _find=0;
+ if test "${arg##*-}" = "${repo}"; then
+ build="${build} ${repo}";
+ _find=1;
+ break;
+ fi
+ done
+ if test ${_find} -eq 0; then
+ printf "E: Repository '%s' is not supported!\n" "${arg##*-}";
+ exit 1;
+ fi
+ ;;
+ --simulate)
+ _fake=1;
+ ;;
+ *)
+ printf "E: Option '%s' is not supported!\n" "${arg}";
+ exit 1;
+ ;;
+ esac
+done
+
+##
+# Sorted order.
+#
+build=$(printf "%s\n" "${build}" | tr ' ' '\n' | sort | uniq | xargs);
+
+##
+# Sanity checks.
+#
+if test "${#build}" -eq 0; then
+ usage;
+ exit 0;
+fi
+
+##
+# Generate Makefile.
+#
+printf "Generating subpackage index ...\n";
+"${HERE}"/scripts/setup;
+printf "Generating dependency list ...\n";
+"${HERE}"/scripts/deplist ${build} | "${HERE}"/scripts/genmake ${_fake};
+
+##
+# Generate report.
+#
+printf "\nSuccess!\n\n";
+
+_numpkgs=$(grep -E '^.*/.*:' "${HERE}"/Makefile | wc -l);
+printf " Packages\t: %s\n" "${_numpkgs}";
+printf "\n";
+
+if test ${_fake} -eq 1; then
+ printf "SIMULATION ONLY! NO PACKAGES WILL BE BUILT!\n\n";
+fi
diff --git a/scripts/genmake b/scripts/genmake
new file mode 100755
index 000000000..79a89175a
--- /dev/null
+++ b/scripts/genmake
@@ -0,0 +1,93 @@
+#!/bin/sh -e
+
+# ./scripts/deplist system | ./scripts/genmake [0|1]
+
+##
+# This script reads from stdin and generates
+# a Makefile in the repository's root.
+#
+# The first argument to this script is a value {0,1}
+# indicating whether to generate real rules or fake
+# (simulation) rules. Fake rules might be 'sleep 1'
+# or can be user-defined.
+#
+# NOTE: out-of-tree builds are not supported.
+#
+
+HERE="$(dirname $(readlink -f ${0}))";
+DEST="${HERE}"/../Makefile;
+TEMP="$(mktemp)";
+
+##
+# Build recipes.
+#
+# FIXME: is $(@D) POSIX or $(%/built=%) required?
+#
+rule_real=$(cat <<"EOF"
+ @cd $(@D) && abuild -r
+EOF
+);
+rule_fake=$(cat <<"EOF"
+ @echo $(@D)
+ @sleep 1
+EOF
+);
+
+##
+# Read deplist from stdin, synthesize Makefile targets.
+#
+awk '{ $(NF+1)=$1; print $0 }' `# duplicate first column to last` \
+ | sed > "${TEMP}" -E `# use extended regex, write to temp file ` \
+ -e 's/ /: /' `# append colon to first column` \
+ -e '/: /s@( |$)@/built @2g' `# append '/built' to all dependencies` \
+ -e 's/ $//g' `# trim trailing spaces` \
+ ;
+
+##
+# Internal; convenience only.
+#
+list=$(grep : "${TEMP}" \
+ | cut -d: -f1 \
+ | xargs \
+);
+
+##
+# Create (or truncate) the output Makefile.
+#
+# Default target builds everything.
+#
+printf "all: %s\n" "${list}" > "${DEST}";
+
+##
+# Append generic target build recipe.
+#
+rule=;
+case ${1} in
+ 0) rule="${rule_real}"; ;;
+ 1) rule="${rule_fake}"; ;;
+ *) printf "E: Invalid mode '%s'\n" "${1}"; exit 1; ;;
+esac
+cat >> "${DEST}" <<EOF
+%/built: %/APKBUILD
+${rule}
+ @touch \$@
+clean:
+ @find \$(CURDIR) -type f -name built -print -delete
+distclean:
+ @rm -fv \
+ \$(CURDIR)/Makefile \
+ \$(CURDIR)/scripts/.index \
+ \$(CURDIR)/scripts/sgrep \
+ \$(CURDIR)/scripts/tsort \
+ ;
+EOF
+
+##
+# Append target rules to output Makefile.
+#
+cat >> "${DEST}" "${TEMP}";
+
+##
+# Clean up.
+#
+rm "${TEMP}";