Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/src/lib/build/build.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/build/build.sh')
-rw-r--r--src/lib/build/build.sh178
1 files changed, 139 insertions, 39 deletions
diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh
index 3394395..171bb9a 100644
--- a/src/lib/build/build.sh
+++ b/src/lib/build/build.sh
@@ -14,18 +14,25 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/update.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh
# shellcheck source=src/lib/util/git.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh
+# shellcheck source=src/lib/util/srcinfo.sh
+source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/srcinfo.sh
# shellcheck source=src/lib/util/pacman.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh
+# shellcheck source=src/lib/util/pkgbuild.sh
+source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pkgbuild.sh
+# shellcheck source=src/lib/valid-build-install.sh
+source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh
# shellcheck source=src/lib/valid-repos.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh
# shellcheck source=src/lib/valid-tags.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh
+# shellcheck source=src/lib/valid-inspect.sh
+source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
source /usr/share/makepkg/util/config.sh
source /usr/share/makepkg/util/message.sh
-set -e
-set -o pipefail
+set -eo pipefail
pkgctl_build_usage() {
@@ -42,19 +49,24 @@ pkgctl_build_usage() {
BUILD OPTIONS
--arch ARCH Specify architectures to build for (disables auto-detection)
- --repo REPO Specify a target repository (disables auto-detection)
+ --repo REPO Specify target repository for new packages not in any official repo
-s, --staging Build against the staging counterpart of the auto-detected repo
-t, --testing Build against the testing counterpart of the auto-detected repo
-o, --offload Build on a remote server and transfer artifacts afterwards
-c, --clean Recreate the chroot before building
- -I, --install FILE Install a package into the working copy of the chroot
+ --inspect WHEN Spawn an interactive shell to inspect the chroot (never, always, failure)
-w, --worker SLOT Name of the worker slot, useful for concurrent builds (disables automatic names)
--nocheck Do not run the check() function in the PKGBUILD
+ INSTALL OPTIONS
+ -I, --install-to-chroot FILE Install a package to the working copy of the chroot
+ -i, --install-to-host MODE Install the built package to the host system, possible modes are 'all' and 'auto'
+
PKGBUILD OPTIONS
--pkgver=PKGVER Set pkgver, reset pkgrel and update checksums
--pkgrel=PKGREL Set pkgrel to a given value
--rebuild Increment the current pkgrel variable
+ --update-checksums Force computation and update of the checksums (disables auto-detection)
-e, --edit Edit the PKGBUILD before building
RELEASE OPTIONS
@@ -77,8 +89,7 @@ pkgctl_build_check_option_group_repo() {
local repo=$2
local testing=$3
local staging=$4
- if ( (( testing )) && (( staging )) ) ||
- ( [[ $repo =~ ^.*-(staging|testing)$ ]] && ( (( testing )) || (( staging )) )); then
+ if [[ -n "${repo}" ]] || (( testing )) || (( staging )); then
die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}"
exit 1
fi
@@ -104,7 +115,7 @@ pkgctl_build() {
exit 1
fi
- local UPDPKGSUMS=0
+ local UPDATE_CHECKSUMS=0
local EDIT=0
local REBUILD=0
local OFFLOAD=0
@@ -112,6 +123,7 @@ pkgctl_build() {
local TESTING=0
local RELEASE=0
local DB_UPDATE=0
+ local INSTALL_TO_HOST=none
local REPO=
local PKGVER=
@@ -124,12 +136,13 @@ pkgctl_build() {
local MAKECHROOT_OPTIONS=()
local RELEASE_OPTIONS=()
local MAKEPKG_OPTIONS=()
+ local INSTALL_HOST_PACKAGES=()
local WORKER=
local WORKER_SLOT=
# variables
- local path pkgbase pkgrepo source
+ local _arch path pkgbase pkgrepo source pkgbuild_checksum current_checksum
while (( $# )); do
case $1 in
@@ -139,18 +152,19 @@ pkgctl_build() {
;;
--repo)
(( $# <= 1 )) && die "missing argument for %s" "$1"
- REPO="${2}"
pkgctl_build_check_option_group_repo '--repo' "${REPO}" "${TESTING}" "${STAGING}"
+ REPO="${2}"
+ RELEASE_OPTIONS+=("--repo" "${REPO}")
shift 2
;;
--arch)
(( $# <= 1 )) && die "missing argument for %s" "$1"
if [[ ${2} == all ]]; then
- BUILD_ARCH=("${_arch[@]::${#_arch[@]}-1}")
+ BUILD_ARCH=("${DEVTOOLS_VALID_ARCHES[@]::${#DEVTOOLS_VALID_ARCHES[@]}-1}")
elif [[ ${2} == any ]]; then
- BUILD_ARCH=("${_arch[0]}")
+ BUILD_ARCH=("${DEVTOOLS_VALID_ARCHES[0]}")
elif ! in_array "${2}" "${BUILD_ARCH[@]}"; then
- if ! in_array "${2}" "${_arch[@]}"; then
+ if ! in_array "${2}" "${DEVTOOLS_VALID_ARCHES[@]}"; then
die 'invalid architecture: %s' "${2}"
fi
BUILD_ARCH+=("${2}")
@@ -161,7 +175,7 @@ pkgctl_build() {
pkgctl_build_check_option_group_ver '--pkgver' "${PKGVER}" "${PKGREL}" "${REBUILD}"
PKGVER="${1#*=}"
PKGREL=1
- UPDPKGSUMS=1
+ UPDATE_CHECKSUMS=1
shift
;;
--pkgrel=*)
@@ -169,6 +183,10 @@ pkgctl_build() {
PKGREL="${1#*=}"
shift
;;
+ --update-checksums)
+ UPDATE_CHECKSUMS=1
+ shift
+ ;;
--rebuild)
# shellcheck source=src/lib/util/git.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh
@@ -185,23 +203,37 @@ pkgctl_build() {
shift
;;
-s|--staging)
- STAGING=1
pkgctl_build_check_option_group_repo '--staging' "${REPO}" "${TESTING}" "${STAGING}"
+ STAGING=1
+ RELEASE_OPTIONS+=("--staging")
shift
;;
-t|--testing)
- TESTING=1
pkgctl_build_check_option_group_repo '--testing' "${REPO}" "${TESTING}" "${STAGING}"
+ TESTING=1
+ RELEASE_OPTIONS+=("--testing")
shift
;;
-c|--clean)
BUILD_OPTIONS+=("-c")
shift
;;
- -I|--install)
+ -I|--install-to-chroot)
+ (( $# <= 1 )) && die "missing argument for %s" "$1"
+ if (( OFFLOAD )); then
+ MAKECHROOT_OPTIONS+=("-I" "$2")
+ else
+ MAKECHROOT_OPTIONS+=("-I" "$(realpath "$2")")
+ fi
+ warning 'installing packages to the chroot may break reproducible builds, use with caution!'
+ shift 2
+ ;;
+ -i|--install-to-host)
(( $# <= 1 )) && die "missing argument for %s" "$1"
- MAKECHROOT_OPTIONS+=("-I" "$2")
- warning 'installing packages into the chroot may break reproducible builds, use with caution!'
+ if ! in_array "$2" "${DEVTOOLS_VALID_BUILD_INSTALL[@]}"; then
+ die 'invalid install mode: %s' "${2}"
+ fi
+ INSTALL_TO_HOST=$2
shift 2
;;
--nocheck)
@@ -209,6 +241,14 @@ pkgctl_build() {
warning 'not running checks is disallowed for official packages, except for bootstrapping. Please rebuild after bootstrapping is completed!'
shift
;;
+ --inspect)
+ (( $# <= 1 )) && die "missing argument for %s" "$1"
+ if ! in_array "${2}" "${DEVTOOLS_VALID_INSPECT_MODES[@]}"; then
+ die "Invalid inspect mode: %s" "${2}"
+ fi
+ MAKECHROOT_OPTIONS+=("-x" "${2}")
+ shift 2
+ ;;
-r|--release)
# shellcheck source=src/lib/release.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh
@@ -274,7 +314,7 @@ pkgctl_build() {
if [[ -z ${REPO} ]]; then
update_pacman_repo_cache
# Check valid repos if not resolved dynamically
- elif ! in_array "${REPO}" "${_repos[@]}"; then
+ elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then
die "Invalid repository target: %s" "${REPO}"
fi
@@ -290,18 +330,32 @@ pkgctl_build() {
. ./PKGBUILD
pkgbase=${pkgbase:-$pkgname}
pkgrepo=${REPO}
+ pkgbuild_checksum=$(b2sum PKGBUILD | awk '{print $1}')
msg "Building ${pkgbase}"
- # auto-detection of build target
- if [[ -z ${pkgrepo} ]]; then
- if ! pkgrepo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
- die 'failed to get pacman repo'
- fi
- if [[ -z "${pkgrepo}" ]]; then
- die 'unknown repo, specify --repo for packages not currently in any official repo'
+ # auto-detect target repository
+ if ! repo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
+ die 'Failed to query pacman repo'
+ fi
+
+ # fail if an existing package specifies --repo
+ if [[ -n "${repo}" ]] && [[ -n ${pkgrepo} ]]; then
+ # allow unstable to use --repo
+ if [[ ${pkgrepo} == *unstable ]]; then
+ repo=${pkgrepo}
+ else
+ die 'Using --repo for packages that exist in official repositories is disallowed'
fi
fi
+ # assign auto-detected target repository
+ if [[ -n ${repo} ]]; then
+ pkgrepo=${repo}
+ # fallback to extra for unreleased packages
+ elif [[ -z ${pkgrepo} ]]; then
+ pkgrepo=extra
+ fi
+
# special cases to resolve final build target
if (( TESTING )); then
pkgrepo="${pkgrepo}-testing"
@@ -316,9 +370,15 @@ pkgctl_build() {
BUILD_ARCH=("")
elif (( ${#BUILD_ARCH[@]} == 0 )); then
if in_array any "${arch[@]}"; then
- BUILD_ARCH=("${_arch[0]}")
+ BUILD_ARCH=("${DEVTOOLS_VALID_ARCHES[0]}")
else
- BUILD_ARCH+=("${arch[@]}")
+ for _arch in "${arch[@]}"; do
+ if in_array "${_arch}" "${DEVTOOLS_VALID_ARCHES[@]}"; then
+ BUILD_ARCH+=("$_arch")
+ else
+ warning 'invalid architecture, not building for: %s' "${_arch}"
+ fi
+ done
fi
fi
@@ -329,7 +389,7 @@ pkgctl_build() {
# increment pkgrel on rebuild
if (( REBUILD )); then
- # try to figure out of pkgrel has been changed
+ # try to figure out if pkgrel has been changed
if ! old_pkgrel=$(git_diff_tree HEAD PKGBUILD | grep --perl-regexp --only-matching --max-count=1 '^-pkgrel=\K\w+'); then
old_pkgrel=${pkgrel}
fi
@@ -346,20 +406,14 @@ pkgctl_build() {
# update pkgver
if [[ -n ${PKGVER} ]]; then
- if [[ $(type -t pkgver) == function ]]; then
- # TODO: check if die or warn, if we provide _commit _gitcommit setter maybe?
- warning 'setting pkgver variable has no effect if the PKGBUILD has a pkgver() function'
- fi
msg "Bumping pkgver to ${PKGVER}"
- grep --extended-regexp --quiet --max-count=1 "^pkgver=${pkgver}$" PKGBUILD || die "Non-standard pkgver declaration"
- sed --regexp-extended "s|^(pkgver=)${pkgver}$|\1${PKGVER}|g" -i PKGBUILD
+ pkgbuild_set_pkgver "${PKGVER}"
fi
# update pkgrel
if [[ -n ${PKGREL} ]]; then
msg "Bumping pkgrel to ${PKGREL}"
- grep --extended-regexp --quiet --max-count=1 "^pkgrel=${pkgrel}$" PKGBUILD || die "Non-standard pkgrel declaration"
- sed --regexp-extended "s|^(pkgrel=)${pkgrel}$|\1${PKGREL}|g" -i PKGBUILD
+ pkgbuild_set_pkgrel "${PKGREL}"
fi
# edit PKGBUILD
@@ -381,10 +435,18 @@ pkgctl_build() {
# update checksums if any sources are declared
- if (( UPDPKGSUMS )) && (( ${#source[@]} >= 1 )); then
+ if (( UPDATE_CHECKSUMS )) && (( ${#source[@]} >= 1 )); then
updpkgsums
fi
+ # re-source the PKGBUILD if it changed
+ current_checksum="$(b2sum PKGBUILD | awk '{print $1}')"
+ if [[ ${pkgbuild_checksum} != "${current_checksum}" ]]; then
+ pkgbuild_checksum=${current_checksum}
+ # shellcheck source=contrib/makepkg/PKGBUILD.proto
+ . ./PKGBUILD
+ fi
+
# execute build
for arch in "${BUILD_ARCH[@]}"; do
if [[ -n $arch ]]; then
@@ -402,9 +464,41 @@ pkgctl_build() {
fi
done
+ # re-source the PKGBUILD if it changed
+ current_checksum="$(b2sum PKGBUILD | awk '{print $1}')"
+ if [[ ${pkgbuild_checksum} != "${current_checksum}" ]]; then
+ pkgbuild_checksum=${current_checksum}
+ # shellcheck source=contrib/makepkg/PKGBUILD.proto
+ . ./PKGBUILD
+ fi
+
+ # auto generate .SRCINFO
+ # shellcheck disable=SC2119
+ write_srcinfo_file
+
+ # test-install (some of) the produced packages
+ if [[ ${INSTALL_TO_HOST} == auto ]] || [[ ${INSTALL_TO_HOST} == all ]]; then
+ # shellcheck disable=2119
+ load_makepkg_config
+
+ # this is inspired by print_all_package_names from libmakepkg
+ local version pkg_architecture pkg pkgfile
+ version=$(get_full_version)
+
+ for pkg in "${pkgname[@]}"; do
+ pkg_architecture=$(get_pkg_arch "$pkg")
+ pkgfile=$(realpath "$(printf "%s/%s-%s-%s%s\n" "${PKGDEST:-.}" "$pkg" "$version" "$pkg_architecture" "$PKGEXT")")
+
+ # check if we install all packages or if the (split-)package is already installed
+ if [[ ${INSTALL_TO_HOST} == all ]] || ( [[ ${INSTALL_TO_HOST} == auto ]] && pacman -Qq -- "$pkg" &>/dev/null ); then
+ INSTALL_HOST_PACKAGES+=("$pkgfile")
+ fi
+ done
+ fi
+
# release the build
if (( RELEASE )); then
- pkgctl_release --repo "${pkgrepo}" "${RELEASE_OPTIONS[@]}"
+ pkgctl_release "${RELEASE_OPTIONS[@]}"
fi
# reset common PKGBUILD variables
@@ -412,6 +506,12 @@ pkgctl_build() {
popd >/dev/null
done
+ # install all collected packages to the host system
+ if (( ${#INSTALL_HOST_PACKAGES[@]} )); then
+ msg "Installing built packages to the host system"
+ sudo pacman -U -- "${INSTALL_HOST_PACKAGES[@]}"
+ fi
+
# update the binary package repo db as last action
if (( RELEASE )) && (( DB_UPDATE )); then
# shellcheck disable=2119