#!/bin/bash # set -x # uncomment for debug # Builds packages from ABS recursively. It tries to find dependencies that # aren't built or need update and then makepkg them in order. # TODO: fullpkg-find should find packages wich depend on the # package to be build, so we can avoid "missing $name.so errors" # Get repo name. Asumes ${ABSROOT}/repo/package/PKGBUILD guess_repo() { basename $(dirname $(pwd)) } # This function is stolen from makechrootpkg. # That probably has some copyright/licensing implications. copy_files() { local copydir="$build_dir/${pkgbase:-${pkgname[0]}}" mkdir -p "$copydir" # Copy PKGBUILD and sources cp PKGBUILD "$copydir" ( load_PKGBUILD for file in "${source[@]}"; do file="${file%%::*}" file="${file##*://*/}" if [[ -f $file ]]; then cp "$file" "$copydir/" elif [[ -f $SRCDEST/$file ]]; then cp "$SRCDEST/$file" "$copydir/" fi done # Find all changelog and install files, even inside functions for i in 'changelog' 'install'; do while read -r file; do # evaluate any bash variables used eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\" [[ -f $file ]] && cp "$file" "$copydir" done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) done ) } # Checks ABSROOT and look for target pkg deps. Adds them if not built or outdated. find_deps() { # Check this level load_PKGBUILD local repo="${repo:-$(guess_repo)}" local pkgbase="${pkgbase:-${pkgname[0]}}" if ! pkgbuild-check-nonfree > /dev/null 2> /dev/null; then if [ "$?" -eq 15 ]; then error "pkgbase" has nonfree issues return 15 fi fi # Checking any package built, since otherwise e.g. kdebase would # be always considered outdated: there is no package built named kdebase. # TODO: maybe check for the package requested in case of recursive calls, # instead of the first one listed? if is_built "${pkgname[0]}" "$(get_full_version "${pkgname[0]}")"; then exit 0 # pkg is built and updated fi # greater levels are built first echo "${LEVEL}:${pkgbase}" >>"$build_dir/BUILDORDER" # PKGBUILD is already there if [ -d "${build_dir}/${pkgbase}" ]; then exit 0 # Copy dir to build_dir else copy_files # to identify repo later echo "repo=$repo" > "${build_dir}/${pkgbase}/.INFO" fi # current package plus a space for every level msg2 "%${LEVEL}s${pkgbase}-$(get_full_version)" ## Check next levels declare -i next_level=$LEVEL+1 # All deps in separate line, only once, without version. deps=($(echo "${depends[@]} ${makedepends[@]}" | \ sed "s/[=<>]\+[^ ]\+//g" | \ tr ' ' "\n" | \ sort -u)) for _dep in ${deps[@]}; do local found=false # May fail, e.g. since abslibre-mips64el doesn't include # arch=any packages. local pkgdir=$(toru -p ${_dep}) || true if [ -n "$pkgdir" -a -d "${pkgdir}" ]; then found=true pushd "${pkgdir}" > /dev/null # runs itself on dep's PKGBUILD dir $0 -l ${next_level} ${build_dir} || return $? popd > /dev/null fi if ! (( found )); then echo "dep_not_found:$_dep" >>$build_dir/log fi done ## End variable block unset next_level dir } . libremessages . $(librelib conf.sh) load_files makepkg LEVEL=0 MAXLEVEL=20 CLEANFIRST='false' UPDATEDB='true' usage() { echo "" echo "cd to a dir containing a PKGBUILD and run:" echo "$(basename $0) [options] " echo "" echo "This script will create a build_dir for recursive building" echo "it tries to find dependencies that aren't built or need update." echo "" echo "If no is specified, the script works on a tempdir" echo "" echo "OPTIONS:" echo " -h : this message." echo " -A : use this ABSROOT." echo " -c : clean before working." echo " -m : check deps until this level" echo " -n : don't update pacman db." echo "" exit 1 } while getopts 'hA:l:cmn' arg; do case "$arg" in h) usage ;; A) ABSROOT="$OPTARG" ;; l) LEVEL="$OPTARG" ;; # hidden option to know dep level. c) CLEANFIRST='true' ;; m) MAXLEVEL="$OPTARG" ;; n) UPDATEDB='false' ;; esac done if [ ! -r PKGBUILD ]; then error "This directory doesnt contain a PKGBUILD" usage fi shift $(( OPTIND - 1 )) build_dir="${1}" if [ "$LEVEL" -eq 0 ]; then build_dir="${1:-$(mktemp -d /tmp/fullpkg.XXXXXX)}" if [ ! -d "$build_dir" ]; then mkdir -p "$build_dir" elif "$CLEANFIRST"; then # Erase files already in dir msg "Cleaning up files in dir" find "$build_dir" -mindepth 1 -delete fi if "$UPDATEDB"; then msg "Updating pacman db" sudo pacman -Sy --noconfirm || true fi # make files for log and buildorder touch "${build_dir}"/{log,BUILDORDER} buildorder="${build_dir}/BUILDORDER" msg "Checking dependencies" fi find_deps exit 0