From 84d0d0d0e541ae5bd5f141eda51bb18fab84498c Mon Sep 17 00:00:00 2001 From: nkraetzschmar <9020053+nkraetzschmar@users.noreply.github.com> Date: Mon, 9 Oct 2023 15:15:13 +0200 Subject: [PATCH] split build into stages --- .github/workflows/build.yml | 9 +-- build | 138 ++-------------------------------- build.containerfile | 3 + build_archdep | 29 ++++++++ build_indep | 28 +++++++ build_source | 143 ++++++++++++++++++++++++++++++++++++ crossbuild.containerfile | 3 + 7 files changed, 213 insertions(+), 140 deletions(-) mode change 100644 => 100755 build.containerfile create mode 100755 build_archdep create mode 100755 build_indep create mode 100755 build_source diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3e50e28..7c30ba7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,13 +9,8 @@ jobs: target: [ amd64, arm64v8 ] steps: - uses: actions/checkout@v3 - - name: setup - run: | - ls -lah /proc/sys/fs/binfmt_misc - wget -q http://deb.debian.org/debian/pool/main/q/qemu/qemu-user-static_8.0.4+dfsg-3+b1_amd64.deb - sudo dpkg -i qemu-user-static_8.0.4+dfsg-3+b1_amd64.deb - sudo dd bs=1M if=/usr/lib/binfmt.d/qemu-aarch64.conf of=/proc/sys/fs/binfmt_misc/register - ls -lah /proc/sys/fs/binfmt_misc + - name: setup binfmt + run: sudo podman run --privileged -v /proc/sys/fs/binfmt_misc:/proc/sys/fs/binfmt_misc "ghcr.io/gardenlinux/binfmt_container" - name: build run: | set -x diff --git a/build b/build index cee0644..7f4525e 100755 --- a/build +++ b/build @@ -2,138 +2,10 @@ set -exuo pipefail -main() ( - debian_source= - while [ $# -gt 0 ]; do - case "$1" in - --debian-source) - debian_source="$2" - shift 2 - ;; - *) - break - ;; - esac - done +exec 3>&1 +exec 1>&2 - source="$1" - shift +pkg="$(build_source "$@")" - patches=() - - while [ $# -gt 0 ]; do - patches+=("$1") - shift - done - - if [[ "$source" = "git+"* ]]; then - git_source "${source#git+}" - else - apt_source "$source" - fi - - if [ -n "$debian_source" ]; then - mkdir debian_src - cd debian_src - if [[ "$debian_source" = "git+"* ]]; then - git_source "${debian_source#git+}" - else - apt_source "$debian_source" - fi - rm -rf ../src/debian - mv src/debian ../src/ - cd .. - rm -rf debian_src - fi - - cd src - - for patch in "${patches[@]}"; do - apply_patches "$patch" - done - - name="$(dpkg-parsechangelog --show-field Source)" - version="$(dpkg-parsechangelog --show-field Version)" - version_orig="${version%-*}" - gzip < ../orig.tar > "../${name}_${version_orig}.orig.tar.gz" - rm ../orig.tar - - sudo apt-get build-dep --no-install-recommends -y . - DEB_BUILD_OPTIONS="terse ${DEB_BUILD_OPTIONS-}" dpkg-buildpackage --no-sign - - cd .. - rm -rf src - ls -lah -) - -apt_source() ( - apt-get source --only-source --download-only "$1" - orig=(*.orig.tar.*) - debian=(*.debian.tar.*) - dsc=(*.dsc) - auto_decompress "$orig" > orig.tar - mkdir src - tar -C src -x --strip-components 1 < orig.tar - auto_decompress "$debian" | tar -C src -xv - rm "$orig" "$debian" "$dsc" -) - -git_source() ( - IFS='#' read -r url ref <<< "$1" - git clone --bare --branch "$ref" --depth 1 "$url" src.git - GIT_DIR=src.git git archive --prefix src/ "$ref" > orig.tar - rm -rf src.git - tar -x < orig.tar -) - -auto_decompress() ( - case "${1##*.}" in - gz) - gzip -d < "$1" - ;; - xz) - xz -d < "$1" - ;; - *) - exit 1 - ;; - esac -) - -apply_patches() ( - git_dir="$(realpath $(mktemp -u ../patches.tmp.XXXX))" - if [[ "$1" = "git+"* ]]; then - IFS='#' read -r url ref <<< "${1#git+}" - git clone --branch "$ref" --depth 1 "$url" "$git_dir" - dir="$git_dir" - else - dir="$(cd .. && realpath "$1")" - fi - - if [ -x "$dir/exec.pre" ]; then - SOURCE="$source" "$dir/exec.pre" - fi - - if [ -f "$dir/patches/series" ]; then - while read -r patch; do - patch -p1 < "$dir/patches/$patch" - done < "$dir/patches/series" - fi - - version="$(yq -r .version < "$dir/changelog_config.yaml")" - [ "$version" != null ] || version="$(dpkg-parsechangelog --show-field Version)" - email="$(yq -r .email < "$dir/changelog_config.yaml")" - name="$(yq -r .name < "$dir/changelog_config.yaml")" - distribution="$(yq -r .distribution < "$dir/changelog_config.yaml")" - version_suffix="$(yq -r .version_suffix < "$dir/changelog_config.yaml")" - message="$(yq -r .message < "$dir/changelog_config.yaml")" - DEBEMAIL="$email" DEBFULLNAME="$name" dch --newversion "$version$version_suffix" --distribution "$distribution" --force-distribution -- "$message" - - if [ -x "$dir/exec.post" ]; then - SOURCE="$source" "$dir/exec.post" - fi - - [ ! -e "$git_dir" ] || rm -rf "$git_dir" -) - -main "$@" +build_indep "$pkg.dsc" +build_archdep "$pkg.dsc" diff --git a/build.containerfile b/build.containerfile old mode 100644 new mode 100755 index feba081..d594c3d --- a/build.containerfile +++ b/build.containerfile @@ -15,6 +15,9 @@ COPY pkgs ./ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y build-essential ca-certificates debhelper devscripts git sudo yq $(awk '{ print $1 }' pkgs) RUN apt-mark hold $(awk '{ print $1 }' pkgs) RUN gcc --print-search-dir && echo 'int main() { return 0; }' > main.c && gcc -o main main.c && ./main +COPY build_source /usr/local/bin/ +COPY build_indep /usr/local/bin/ +COPY build_archdep /usr/local/bin/ COPY build /usr/local/bin/ RUN find /tmp -mindepth 1 -delete COPY --from=mini_sudo /usr/local/bin/sudo /usr/local/bin/sudo diff --git a/build_archdep b/build_archdep new file mode 100755 index 0000000..10f0f9d --- /dev/null +++ b/build_archdep @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -exuo pipefail + +exec 3>&1 +exec 1>&2 + +main() ( + dsc="$(realpath "$1")" + dpkg_arch="$(dpkg --print-architecture)" + dsc_arch="$(grep -oP '(?<=^Architecture: ).*' < "$dsc" | tr ' ' '\n')" + + grep -P '^(linux-)?(any|'"$dpkg_arch"')$' <<< "$dsc_arch" || exit 0 + + sudo apt-get build-dep --no-install-recommends -y "$dsc" + + dpkg-source --extract "$dsc" src + cd src + name="$(dpkg-parsechangelog --show-field Source)" + version="$(dpkg-parsechangelog --show-field Version)" + DEB_BUILD_OPTIONS="terse ${DEB_BUILD_OPTIONS-}" dpkg-buildpackage --no-sign --build=any + cd .. + rm -rf src + ls -lah + + echo "${name}_${version}_${dpkg_arch}" >&3 +) + +main "$@" diff --git a/build_indep b/build_indep new file mode 100755 index 0000000..c8fc3ee --- /dev/null +++ b/build_indep @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +set -exuo pipefail + +exec 3>&1 +exec 1>&2 + +main() ( + dsc="$(realpath "$1")" + dsc_arch="$(grep -oP '(?<=^Architecture: ).*' < "$dsc" | tr ' ' '\n')" + + grep -P '^(linux-)?all$' <<< "$dsc_arch" || exit 0 + + sudo apt-get build-dep --no-install-recommends -y "$dsc" + + dpkg-source --extract "$dsc" src + cd src + name="$(dpkg-parsechangelog --show-field Source)" + version="$(dpkg-parsechangelog --show-field Version)" + DEB_BUILD_OPTIONS="terse ${DEB_BUILD_OPTIONS-}" dpkg-buildpackage --no-sign --build=all + cd .. + rm -rf src + ls -lah + + echo "${name}_${version}_all" >&3 +) + +main "$@" diff --git a/build_source b/build_source new file mode 100755 index 0000000..7fc42d0 --- /dev/null +++ b/build_source @@ -0,0 +1,143 @@ +#!/usr/bin/env bash + +set -exuo pipefail + +exec 3>&1 +exec 1>&2 + +main() ( + debian_source= + while [ $# -gt 0 ]; do + case "$1" in + --debian-source) + debian_source="$2" + shift 2 + ;; + *) + break + ;; + esac + done + + source="$1" + shift + + patches=() + + while [ $# -gt 0 ]; do + patches+=("$1") + shift + done + + if [[ "$source" = "git+"* ]]; then + git_source "${source#git+}" + else + apt_source "$source" + fi + + if [ -n "$debian_source" ]; then + mkdir debian_src + cd debian_src + if [[ "$debian_source" = "git+"* ]]; then + git_source "${debian_source#git+}" + else + apt_source "$debian_source" + fi + rm -rf ../src/debian + mv src/debian ../src/ + cd .. + rm -rf debian_src + fi + + cd src + + for patch in "${patches[@]}"; do + apply_patches "$patch" + done + + name="$(dpkg-parsechangelog --show-field Source)" + version="$(dpkg-parsechangelog --show-field Version)" + version_orig="${version%-*}" + gzip < ../orig.tar > "../${name}_${version_orig}.orig.tar.gz" + rm ../orig.tar + + dpkg-source --build . + + cd .. + rm -rf src + ls -lah + + echo "${name}_${version}" >&3 +) + +apt_source() ( + apt-get source --only-source --download-only "$1" + orig=(*.orig.tar.*) + debian=(*.debian.tar.*) + dsc=(*.dsc) + auto_decompress "$orig" > orig.tar + mkdir src + tar -C src -x --strip-components 1 < orig.tar + auto_decompress "$debian" | tar -C src -xv + rm "$orig" "$debian" "$dsc" +) + +git_source() ( + IFS='#' read -r url ref <<< "$1" + git clone --bare --branch "$ref" --depth 1 "$url" src.git + GIT_DIR=src.git git archive --prefix src/ "$ref" > orig.tar + rm -rf src.git + tar -x < orig.tar +) + +auto_decompress() ( + case "${1##*.}" in + gz) + gzip -d < "$1" + ;; + xz) + xz -d < "$1" + ;; + *) + exit 1 + ;; + esac +) + +apply_patches() ( + git_dir="$(realpath $(mktemp -u ../patches.tmp.XXXX))" + if [[ "$1" = "git+"* ]]; then + IFS='#' read -r url ref <<< "${1#git+}" + git clone --branch "$ref" --depth 1 "$url" "$git_dir" + dir="$git_dir" + else + dir="$(cd .. && realpath "$1")" + fi + + if [ -x "$dir/exec.pre" ]; then + SOURCE="$source" "$dir/exec.pre" + fi + + if [ -f "$dir/patches/series" ]; then + while read -r patch; do + patch -p1 < "$dir/patches/$patch" + done < "$dir/patches/series" + fi + + version="$(yq -r .version < "$dir/changelog_config.yaml")" + [ "$version" != null ] || version="$(dpkg-parsechangelog --show-field Version)" + email="$(yq -r .email < "$dir/changelog_config.yaml")" + name="$(yq -r .name < "$dir/changelog_config.yaml")" + distribution="$(yq -r .distribution < "$dir/changelog_config.yaml")" + version_suffix="$(yq -r .version_suffix < "$dir/changelog_config.yaml")" + message="$(yq -r .message < "$dir/changelog_config.yaml")" + DEBEMAIL="$email" DEBFULLNAME="$name" dch --newversion "$version$version_suffix" --distribution "$distribution" --force-distribution -- "$message" + + if [ -x "$dir/exec.post" ]; then + SOURCE="$source" "$dir/exec.post" + fi + + [ ! -e "$git_dir" ] || rm -rf "$git_dir" +) + +main "$@" diff --git a/crossbuild.containerfile b/crossbuild.containerfile index ea91470..92f0903 100644 --- a/crossbuild.containerfile +++ b/crossbuild.containerfile @@ -27,6 +27,9 @@ COPY --from=native /native /native COPY setup_native ./ RUN [ "/native/bash", "-c", "PATH=/native:$PATH ./setup_native import $(awk '{ print $1 }' pkgs)" ] RUN gcc --print-search-dir && echo 'int main() { return 0; }' > main.c && gcc -o main main.c && ./main +COPY build_source /usr/local/bin/ +COPY build_indep /usr/local/bin/ +COPY build_archdep /usr/local/bin/ COPY build /usr/local/bin/ RUN find /tmp -mindepth 1 -delete COPY --from=mini_sudo /usr/local/bin/sudo /usr/local/bin/sudo