#!/usr/bin/env bash # set -x # uncomment for debug # Copyright (C) 2011-2012 Joshua Ismael Haase Hernández (xihh) # Copyright (C) 2011-2012 Nicolás Reynolds # Copyright (C) 2012 Michał Masłowski # Copyright (C) 2013-2014 Luke Shumaker # # The copy_files() function is taken from makechrootpkg: # Copyright (C) 2007 Armin Luntzer # Copyright (C) 2007 Jason Chu # Copyright (C) 2007, 2011 Dan McGee # Copyright (C) 2007-2008 Travis Willard # Copyright (C) 2007-2009 Aaron Griffin # Copyright (C) 2008 Simo Leone # Copyright (C) 2009 Biru Ionut # Copyright (C) 2009 Evangelos Foutras # Copyright (C) 2009 Francois Charette # Copyright (C) 2009 Nezmer # Copyright (C) 2009 Ronald van Haren # Copyright (C) 2009-2011 Andrea Scarpino # Copyright (C) 2009-2012 Allan McRae # Copyright (C) 2009-2012 Eric Bélanger # Copyright (C) 2009-2012 Pierre Schmitz # Copyright (C) 2010 Byron Clark # Copyright (C) 2011 Ionut Biru # Copyright (C) 2011 Lukas Fleischer # Copyright (C) 2011-2012 Florian Pritz # Copyright (C) 2011-2013 Jan Alexander Steffens (heftig) # Copyright (C) 2013 Sébastien Luttringer # # Because of the code from makechrootpkg, this file is GPLv2, instead of GPLv3 # like most of libretools. # # License: GNU GPLv2 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # 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. 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]}}" # 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%s" '' "${pkgbase}-$(get_full_version)" ## Check next levels declare -i next_level=$LEVEL+1 # All deps local deps=("${depends[@]}" "${makedepends[@]}" "${checkdepends[@]}") # Strip version specifiers deps=("${deps[@]%%[=<>]*}") # Filter out duplicates read -d $'\n' -a deps <<<"$(printf '%s\n' "${deps[@]}"|sort -u)" local _dep 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" ]] && [[ -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() { print "Usage: %s [OPTIONS] [BUILD_DIR]" "${0##*/}" print "Finds package dependencies and sets up a build order" echo prose "Run this from a directory containing a PKGBUILD." echo prose "This script will create a BUILD_DIR for recursive building; it tries to find dependencies that aren't built or need update." echo prose "If no BUILD_DIR is specified, it will create a temporary directory." echo print "Options:" flag "-h" "Show this message" flag "-A <$(_ ABSROOT)>" "Use ABSROOT as the root of the ABS tree" flag "-c" "Clean BUILD_DIR before working." flag "-m <$(_ MAX_LEVEL)>" "Limit the depth of the dependency recursion" flag "-n" "Don't update pacman DB" } while getopts 'hA:l:cmn' arg; do case "$arg" in h) usage; exit 0 ;; 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 doesn't contain a PKGBUILD" usage exit 1 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