mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-23 08:18:51 -05:00
c11bdf19b1
This patch moves the generating of integrity checks to before any error checking takes place in the PKGBUILD file. This allows integrity generation to complete when unrelated errors exist in a PKGBUILD file and allows the removal of multiple checks of the GENINTEG variable that would otherwise be needed. In addition a minor fix is made to a comment. Signed-off-by: Allan McRae <mcrae_allan@hotmail.com> Signed-off-by: Dan McGee <dan@archlinux.org>
1517 lines
42 KiB
Bash
1517 lines
42 KiB
Bash
#!/bin/bash -e
|
|
#
|
|
# makepkg - make packages compatable for use with pacman
|
|
# @configure_input@
|
|
#
|
|
# Copyright (c) 2002-2008 by Judd Vinet <jvinet@zeroflux.org>
|
|
# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
|
# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
|
|
# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
|
|
# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk>
|
|
# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org>
|
|
#
|
|
# 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; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# 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.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
# makepkg uses quite a few external programs during its execution. You
|
|
# need to have at least the following installed for makepkg to function:
|
|
# awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, find (findutils),
|
|
# getopt (util-linux), gettext, grep, gzip, sed
|
|
|
|
# gettext initialization
|
|
export TEXTDOMAIN='pacman'
|
|
export TEXTDOMAINDIR='@localedir@'
|
|
|
|
# file -i does not work on Mac OSX unless legacy mode is set
|
|
export COMMAND_MODE='legacy'
|
|
|
|
# when fileglobbing, we want * in an empty directory to expand to the null
|
|
# string rather than itself
|
|
shopt -s nullglob
|
|
|
|
myver='@PACKAGE_VERSION@'
|
|
confdir='@sysconfdir@'
|
|
startdir="$PWD"
|
|
srcdir="$startdir/src"
|
|
pkgdir="$startdir/pkg"
|
|
known_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'ccache' 'distcc' 'makeflags' 'force')
|
|
readonly -a known_options
|
|
|
|
# Options
|
|
ASROOT=0
|
|
CLEANUP=0
|
|
CLEANCACHE=0
|
|
DEP_BIN=0
|
|
FORCE=0
|
|
INFAKEROOT=0
|
|
GENINTEG=0
|
|
INSTALL=0
|
|
NOBUILD=0
|
|
NODEPS=0
|
|
NOEXTRACT=0
|
|
RMDEPS=0
|
|
REPKG=0
|
|
LOGGING=0
|
|
SOURCEONLY=0
|
|
IGNOREARCH=0
|
|
HOLDVER=0
|
|
|
|
# Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
|
|
# when dealing with svn/cvs/etc PKGBUILDs.
|
|
FORCE_VER=""
|
|
|
|
PACMAN_OPTS=
|
|
|
|
### SUBROUTINES ###
|
|
|
|
plain() {
|
|
local mesg=$1; shift
|
|
if [ -t 2 -a ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then
|
|
printf "\033[1;1m ${mesg}\033[1;0m\n" "$@" >&2
|
|
else
|
|
printf " ${mesg}\n" "$@" >&2
|
|
fi
|
|
}
|
|
|
|
msg() {
|
|
local mesg=$1; shift
|
|
if [ -t 2 -a ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then
|
|
printf "\033[1;32m==>\033[1;0m\033[1;1m ${mesg}\033[1;0m\n" "$@" >&2
|
|
else
|
|
printf "==> ${mesg}\n" "$@" >&2
|
|
fi
|
|
}
|
|
|
|
msg2() {
|
|
local mesg=$1; shift
|
|
if [ -t 2 -a ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then
|
|
printf "\033[1;34m ->\033[1;0m\033[1;1m ${mesg}\033[1;0m\n" "$@" >&2
|
|
else
|
|
printf " -> ${mesg}\n" "$@" >&2
|
|
fi
|
|
}
|
|
|
|
warning() {
|
|
local mesg=$1; shift
|
|
if [ -t 2 -a ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then
|
|
printf "\033[1;33m==> $(gettext "WARNING:")\033[1;0m\033[1;1m ${mesg}\033[1;0m\n" "$@" >&2
|
|
else
|
|
printf "==> $(gettext "WARNING:") ${mesg}\n" "$@" >&2
|
|
fi
|
|
}
|
|
|
|
error() {
|
|
local mesg=$1; shift
|
|
if [ -t 2 -a ! "$USE_COLOR" = "n" -a "$(check_buildenv color)" = "y" ]; then
|
|
printf "\033[1;31m==> $(gettext "ERROR:")\033[1;0m\033[1;1m ${mesg}\033[1;0m\n" "$@" >&2
|
|
else
|
|
printf "==> $(gettext "ERROR:") ${mesg}\n" "$@" >&2
|
|
fi
|
|
}
|
|
|
|
|
|
##
|
|
# Special exit call for traps, Don't print any error messages when inside,
|
|
# the fakeroot call, the error message will be printed by the main call.
|
|
##
|
|
trap_exit() {
|
|
if [ "$INFAKEROOT" = "0" ]; then
|
|
echo
|
|
error "$@"
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
|
|
##
|
|
# Clean up function. Called automatically when the script exits.
|
|
##
|
|
clean_up() {
|
|
local EXIT_CODE=$?
|
|
|
|
if [ "$INFAKEROOT" = "1" ]; then
|
|
# Don't clean up when leaving fakeroot, we're not done yet.
|
|
return
|
|
fi
|
|
|
|
if [ $EXIT_CODE -eq 0 -a "$CLEANUP" = "1" ]; then
|
|
# If it's a clean exit and -c/--clean has been passed...
|
|
msg "$(gettext "Cleaning up...")"
|
|
cd "$startdir"
|
|
rm -rf pkg src
|
|
if [ "$pkgname" != "" ]; then
|
|
# Can't do this unless the BUILDSCRIPT has been sourced.
|
|
rm -f "${pkgname}-${pkgver}-${pkgrel}-${CARCH}.log*"
|
|
fi
|
|
fi
|
|
|
|
remove_deps
|
|
}
|
|
|
|
|
|
##
|
|
# Signal Traps
|
|
##
|
|
trap 'clean_up' 0
|
|
trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
|
|
trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
|
|
trap 'trap_exit "$(gettext "An unknown error has occured. Exiting...")"' ERR
|
|
|
|
|
|
strip_url() {
|
|
echo "$1" | sed 's|^.*://.*/||g'
|
|
}
|
|
|
|
|
|
##
|
|
# Checks to see if options are present in makepkg.conf or PKGBUILD;
|
|
# PKGBUILD options always take precedence.
|
|
#
|
|
# usage : check_option( $option )
|
|
# return : y - enabled
|
|
# n - disabled
|
|
# ? - not found
|
|
##
|
|
check_option() {
|
|
local ret=$(in_opt_array "$1" ${options[@]})
|
|
if [ "$ret" != '?' ]; then
|
|
echo $ret
|
|
return
|
|
fi
|
|
|
|
# fall back to makepkg.conf options
|
|
ret=$(in_opt_array "$1" ${OPTIONS[@]})
|
|
if [ "$ret" != '?' ]; then
|
|
echo $ret
|
|
return
|
|
fi
|
|
|
|
echo '?' # Not Found
|
|
}
|
|
|
|
|
|
##
|
|
# Check if option is present in BUILDENV
|
|
#
|
|
# usage : check_buildenv( $option )
|
|
# return : y - enabled
|
|
# n - disabled
|
|
# ? - not found
|
|
##
|
|
check_buildenv() {
|
|
echo $(in_opt_array "$1" ${BUILDENV[@]})
|
|
}
|
|
|
|
|
|
##
|
|
# usage : in_opt_array( $needle, $haystack )
|
|
# return : y - enabled
|
|
# n - disabled
|
|
# ? - not found
|
|
##
|
|
in_opt_array() {
|
|
local needle=$(echo $1 | tr [:upper:] [:lower:]); shift
|
|
|
|
local opt
|
|
for opt in "$@"; do
|
|
opt=$(echo $opt | tr [:upper:] [:lower:])
|
|
if [ "$opt" = "$needle" ]; then
|
|
echo 'y' # Enabled
|
|
return
|
|
elif [ "$opt" = "!$needle" ]; then
|
|
echo 'n' # Disabled
|
|
return
|
|
fi
|
|
done
|
|
|
|
echo '?' # Not Found
|
|
}
|
|
|
|
|
|
##
|
|
# usage : in_array( $needle, $haystack )
|
|
# return : 0 - found
|
|
# 1 - not found
|
|
##
|
|
in_array() {
|
|
local needle=$1; shift
|
|
[ -z "$1" ] && return 1 # Not Found
|
|
local item
|
|
for item in "$@"; do
|
|
[ "$item" = "$needle" ] && return 0 # Found
|
|
done
|
|
return 1 # Not Found
|
|
}
|
|
|
|
get_downloadclient() {
|
|
# $1 = url with valid protocol prefix
|
|
local url=$1
|
|
local proto=$(echo $netfile | sed 's|://.*||')
|
|
|
|
# loop through DOWNLOAD_AGENTS variable looking for protocol
|
|
local i
|
|
for i in "${DLAGENTS[@]}"; do
|
|
local handler=$(echo $i | sed 's|::.*||')
|
|
if [ "$proto" == "$handler" ]; then
|
|
agent=$(echo $i | sed 's|^.*::||')
|
|
break
|
|
fi
|
|
done
|
|
|
|
# if we didn't find an agent, return an error
|
|
if [ -z "$agent" ]; then
|
|
error "$(gettext "There is no agent set up to handle %s URLs. Check %s.")" "$proto" "$confdir/makepkg.conf"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1 # $E_CONFIG_ERROR
|
|
fi
|
|
|
|
# ensure specified program is installed
|
|
local program="$(echo $agent | awk '{print $1 }')"
|
|
if [ ! -x "$program" ]; then
|
|
local baseprog=$(basename $program)
|
|
error "$(gettext "The download program %s is not installed.")" "$baseprog"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1 # $E_MISSING_PROGRAM
|
|
fi
|
|
|
|
echo "$agent"
|
|
}
|
|
|
|
get_downloadcmd() {
|
|
local dlagent=$1
|
|
local netfile=$2
|
|
local file=$3
|
|
|
|
if echo "$dlagent" | grep -q "%u" ; then
|
|
local dlcmd=$(echo "$dlagent" | sed "s|%o|$file.part|" | sed "s|%u|$netfile|")
|
|
else
|
|
local dlcmd="$dlagent $netfile"
|
|
fi
|
|
|
|
echo "$dlcmd"
|
|
}
|
|
|
|
check_deps() {
|
|
[ $# -gt 0 ] || return
|
|
|
|
pmout=$(pacman $PACMAN_OPTS -T "$@")
|
|
ret=$?
|
|
if [ $ret -eq 127 ]; then #unresolved deps
|
|
echo "$pmout"
|
|
elif [ $ret -ne 0 ]; then
|
|
error "$(gettext "Pacman returned a fatal error (%i): %s")" "$ret" "$pmout"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
handledeps() {
|
|
local R_DEPS_SATISFIED=0
|
|
local R_DEPS_MISSING=1
|
|
|
|
[ $# -eq 0 ] && return $R_DEPS_SATISFIED
|
|
|
|
local deplist="$*"
|
|
local dep depstrip striplist
|
|
for dep in $deplist; do
|
|
depstrip="$(echo $dep | sed -e 's|=.*$||' -e 's|>.*$||' -e 's|<.*$||')"
|
|
striplist="$striplist $depstrip"
|
|
done
|
|
|
|
if [ "$DEP_BIN" = "0" ]; then
|
|
return $R_DEPS_MISSING
|
|
fi
|
|
|
|
if [ "$DEP_BIN" = "1" ]; then
|
|
# install missing deps from binary packages (using pacman -S)
|
|
msg "$(gettext "Installing missing dependencies...")"
|
|
local ret=0
|
|
|
|
if [ "$ASROOT" = 0 ]; then
|
|
sudo pacman $PACMAN_OPTS -S --asdeps $striplist || ret=$?
|
|
else
|
|
pacman $PACMAN_OPTS -S --asdeps $striplist || ret=$?
|
|
fi
|
|
|
|
if [ $ret -ne 0 ]; then
|
|
error "$(gettext "Pacman failed to install missing dependencies.")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
fi
|
|
|
|
# rerun any additional sh scripts found in /etc/profile.d/
|
|
local script
|
|
for script in /etc/profile.d/*.sh; do
|
|
if [ -x $script ]; then
|
|
source $script &>/dev/null
|
|
fi
|
|
done
|
|
|
|
return $R_DEPS_SATISFIED
|
|
}
|
|
|
|
resolve_deps() {
|
|
# $pkgdeps is a GLOBAL variable, used by remove_deps()
|
|
local R_DEPS_SATISFIED=0
|
|
local R_DEPS_MISSING=1
|
|
|
|
local deplist="$(check_deps $*)"
|
|
if [ "$deplist" = "" ]; then
|
|
return $R_DEPS_SATISFIED
|
|
else
|
|
pkgdeps="$pkgdeps $deplist"
|
|
fi
|
|
|
|
if handledeps $deplist; then
|
|
# check deps again to make sure they were resolved
|
|
deplist="$(check_deps $*)"
|
|
[ "$deplist" = "" ] && return $R_DEPS_SATISFIED
|
|
elif [ "$DEP_BIN" = "1" ]; then
|
|
error "$(gettext "Failed to install all missing dependencies.")"
|
|
fi
|
|
|
|
msg "$(gettext "Missing Dependencies:")"
|
|
local dep
|
|
for dep in $deplist; do
|
|
msg2 "$dep"
|
|
done
|
|
|
|
return $R_DEPS_MISSING
|
|
}
|
|
|
|
# fix flyspray bug #5923
|
|
remove_deps() {
|
|
# $pkgdeps is a GLOBAL variable, set by resolve_deps()
|
|
[ "$RMDEPS" = "0" ] && return
|
|
[ "$pkgdeps" = "" ] && return
|
|
|
|
local dep depstrip deplist
|
|
for dep in $pkgdeps; do
|
|
depstrip=$(echo $dep | sed -e 's|=.*$||' -e 's|>.*$||' -e 's|<.*$||')
|
|
deplist="$deplist $depstrip"
|
|
done
|
|
|
|
msg "Removing installed dependencies..."
|
|
local ret=0
|
|
if [ "$ASROOT" = "0" ]; then
|
|
sudo pacman $PACMAN_OPTS -Rns $deplist || ret=$?
|
|
else
|
|
pacman $PACMAN_OPTS -Rns $deplist || ret=$?
|
|
fi
|
|
|
|
# Fixes FS#10039 - exit cleanly as package has built successfully
|
|
if [ $ret -ne 0 ]; then
|
|
warning "$(gettext "Failed to remove installed dependencies.")"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
download_sources() {
|
|
msg "$(gettext "Retrieving Sources...")"
|
|
|
|
if [ ! -w "$SRCDEST" ] ; then
|
|
error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
|
|
pushd "$SRCDEST" &>/dev/null
|
|
|
|
local netfile
|
|
for netfile in ${source[@]}; do
|
|
local file=$(strip_url "$netfile")
|
|
if [ -f "$startdir/$file" ]; then
|
|
msg2 "$(gettext "Found %s in build dir")" "$file"
|
|
rm -f "$srcdir/$file"
|
|
ln -s "$startdir/$file" "$srcdir/"
|
|
continue
|
|
elif [ -f "$SRCDEST/$file" ]; then
|
|
msg2 "$(gettext "Using cached copy of %s")" "$file"
|
|
rm -f "$srcdir/$file"
|
|
ln -s "$SRCDEST/$file" "$srcdir/"
|
|
continue
|
|
fi
|
|
|
|
# if we get here, check to make sure it was a URL, else fail
|
|
if [ "$file" = "$netfile" ]; then
|
|
error "$(gettext "%s was not found in the build directory and is not a URL.")" "$netfile"
|
|
exit 1 # $E_MISSING_FILE
|
|
fi
|
|
|
|
# find the client we should use for this URL
|
|
local dlclient=$(get_downloadclient "$netfile") || exit $?
|
|
|
|
msg2 "$(gettext "Downloading %s...")" "$file"
|
|
# fix flyspray bug #3289
|
|
local ret=0
|
|
$(get_downloadcmd "$dlclient" "$netfile" "$file") || ret=$?
|
|
if [ $ret -gt 0 ]; then
|
|
error "$(gettext "Failure while downloading %s")" "$file"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
if echo "$dlclient" | grep -q "%o" ; then
|
|
mv -f "$SRCDEST/$file.part" "$SRCDEST/$file"
|
|
fi
|
|
rm -f "$srcdir/$file"
|
|
ln -s "$SRCDEST/$file" "$srcdir/"
|
|
done
|
|
|
|
popd &>/dev/null
|
|
}
|
|
|
|
generate_checksums() {
|
|
msg "$(gettext "Generating checksums for source files...")"
|
|
plain ""
|
|
|
|
local integ
|
|
for integ in ${INTEGRITY_CHECK[@]}; do
|
|
integ="$(echo $integ | tr [:upper:] [:lower:])"
|
|
case "$integ" in
|
|
md5|sha1|sha256|sha384|sha512) : ;;
|
|
*)
|
|
error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ"
|
|
exit 1;; # $E_CONFIG_ERROR
|
|
esac
|
|
|
|
if [ ! $(type -p "${integ}sum") ]; then
|
|
error "$(gettext "Cannot find the '%s' program.")" "${integ}sum"
|
|
exit 1 # $E_MISSING_PROGRAM
|
|
fi
|
|
|
|
local ct=0
|
|
local numsrc=${#source[@]}
|
|
echo -n "${integ}sums=("
|
|
|
|
local i=0;
|
|
local indent=''
|
|
while [ $i -lt $((${#integ}+6)) ]; do
|
|
indent="$indent "
|
|
i=$(($i+1))
|
|
done
|
|
|
|
local netfile
|
|
for netfile in ${source[@]}; do
|
|
local file="$(strip_url "$netfile")"
|
|
|
|
if [ ! -f "$file" ] ; then
|
|
if [ ! -f "$SRCDEST/$file" ] ; then
|
|
error "$(gettext "Unable to find source file %s to generate checksum.")" "$file"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
else
|
|
file=$SRCDEST/$file
|
|
fi
|
|
fi
|
|
|
|
local sum="$(${integ}sum "$file" | cut -d ' ' -f 1)"
|
|
[ $ct -gt 0 ] && echo -n "$indent"
|
|
echo -n "'$sum'"
|
|
ct=$(($ct+1))
|
|
[ $ct -lt $numsrc ] && echo
|
|
done
|
|
|
|
echo ")"
|
|
done
|
|
}
|
|
|
|
check_checksums() {
|
|
local integ
|
|
for integ in ${INTEGRITY_CHECK[@]}; do
|
|
integ="$(echo $integ | tr [:upper:] [:lower:])"
|
|
case "$integ" in
|
|
md5|sha1|sha256|sha384|sha512) : ;;
|
|
*)
|
|
error "$(gettext "Invalid integrity algorithm '%s' specified")" "$integ"
|
|
exit 1;; # $E_CONFIG_ERROR
|
|
esac
|
|
|
|
if [ ! $(type -p "${integ}sum") ]; then
|
|
error "$(gettext "Cannot find the '%s' program.")" "${integ}sum"
|
|
exit 1 # $E_MISSING_PROGRAM
|
|
fi
|
|
|
|
local integrity_sums=($(eval echo \${${integ}sums[@]}))
|
|
if [ ${#integrity_sums[@]} -eq ${#source[@]} ]; then
|
|
msg "$(gettext "Validating source files with %s...")" "${integ}sums"
|
|
local errors=0
|
|
local idx=0
|
|
local file
|
|
for file in "${source[@]}"; do
|
|
file="$(strip_url "$file")"
|
|
echo -n " $file ... " >&2
|
|
|
|
if [ ! -f "$file" ] ; then
|
|
if [ ! -f "$file" ] ; then
|
|
echo "$(gettext "NOT FOUND")" >&2
|
|
errors=1
|
|
continue
|
|
else
|
|
file=$SRCDEST/$file
|
|
fi
|
|
fi
|
|
|
|
if echo "${integrity_sums[$idx]} $file" | ${integ}sum --status -c - &>/dev/null; then
|
|
echo "$(gettext "Passed")" >&2
|
|
else
|
|
echo "$(gettext "FAILED")" >&2
|
|
errors=1
|
|
fi
|
|
|
|
idx=$((idx + 1))
|
|
done
|
|
|
|
if [ $errors -gt 0 ]; then
|
|
error "$(gettext "One or more files did not pass the validity check!")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
else
|
|
warning "$(gettext "Integrity checks (%s) are missing or incomplete.")" "$integ"
|
|
fi
|
|
done
|
|
}
|
|
|
|
extract_sources() {
|
|
msg "$(gettext "Extracting Sources...")"
|
|
local netfile
|
|
for netfile in "${source[@]}"; do
|
|
file=$(strip_url "$netfile")
|
|
if in_array "$file" ${noextract[@]}; then
|
|
#skip source files in the noextract=() array
|
|
# these are marked explicitly to NOT be extracted
|
|
continue
|
|
fi
|
|
|
|
if [ ! -f "$file" ] ; then
|
|
if [ ! -f "$SRCDEST/$file" ] ; then
|
|
error "$(gettext "Unable to find source file %s for extraction.")" "$file"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
else
|
|
file=$SRCDEST/$file
|
|
fi
|
|
fi
|
|
|
|
# fix flyspray #6246
|
|
local file_type=$(file -bizL "$file")
|
|
local cmd=''
|
|
case "$file_type" in
|
|
*application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
|
|
cmd="bsdtar -x -f $file" ;;
|
|
*application/x-gzip*)
|
|
cmd="gunzip -d -f $file" ;;
|
|
*application/x-bzip*)
|
|
cmd="bunzip2 -f $file" ;;
|
|
*)
|
|
# Don't know what to use to extract this file,
|
|
# skip to the next file
|
|
continue;;
|
|
esac
|
|
|
|
local ret=0
|
|
msg2 "$cmd"
|
|
$cmd || ret=$?
|
|
if [ $ret -ne 0 ]; then
|
|
error "$(gettext "Failed to extract %s")" "$file"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
if [ $EUID -eq 0 ]; then
|
|
# change perms of all source files to root user & root group
|
|
chown -R 0:0 "$srcdir"
|
|
fi
|
|
}
|
|
|
|
run_build() {
|
|
# use distcc if it is requested (check buildenv and PKGBUILD opts)
|
|
if [ "$(check_buildenv distcc)" = "y" -a "$(check_option distcc)" != "n" ]; then
|
|
[ -d /usr/lib/distcc/bin ] && export PATH="/usr/lib/distcc/bin:$PATH"
|
|
export DISTCC_HOSTS
|
|
elif [ "$(check_option distcc)" = "n" ]; then
|
|
# if it is not wanted, clear the makeflags too
|
|
MAKEFLAGS=""
|
|
fi
|
|
|
|
# use ccache if it is requested (check buildenv and PKGBUILD opts)
|
|
if [ "$(check_buildenv ccache)" = "y" -a "$(check_option ccache)" != "n" ]; then
|
|
[ -d /usr/lib/ccache/bin ] && export PATH="/usr/lib/ccache/bin:$PATH"
|
|
fi
|
|
|
|
# clear user-specified makeflags if requested
|
|
if [ "$(check_option makeflags)" = "n" ]; then
|
|
MAKEFLAGS=""
|
|
fi
|
|
|
|
msg "$(gettext "Starting build()...")"
|
|
cd "$srcdir"
|
|
|
|
# ensure all necessary build variables are exported
|
|
export CFLAGS CXXFLAGS MAKEFLAGS CHOST
|
|
|
|
local ret=0
|
|
if [ "$LOGGING" = "1" ]; then
|
|
BUILDLOG="${startdir}/${pkgname}-${pkgver}-${pkgrel}-${CARCH}.log"
|
|
if [ -f "$BUILDLOG" ]; then
|
|
local i=1
|
|
while true; do
|
|
if [ -f "$BUILDLOG.$i" ]; then
|
|
i=$(($i +1))
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
mv "$BUILDLOG" "$BUILDLOG.$i"
|
|
fi
|
|
|
|
build 2>&1 | tee "$BUILDLOG"; ret=${PIPESTATUS[0]}
|
|
else
|
|
build 2>&1 || ret=$?
|
|
fi
|
|
|
|
if [ $ret -gt 0 ]; then
|
|
error "$(gettext "Build Failed.")"
|
|
plain "$(gettext "Aborting...")"
|
|
remove_deps
|
|
exit 2 # $E_BUILD_FAILED
|
|
fi
|
|
}
|
|
|
|
tidy_install() {
|
|
cd "$pkgdir"
|
|
msg "$(gettext "Tidying install...")"
|
|
|
|
if [ "$(check_option docs)" = "n" ]; then
|
|
msg2 "$(gettext "Removing info/doc files...")"
|
|
#fix flyspray bug #5021
|
|
rm -rf ${DOC_DIRS[@]}
|
|
fi
|
|
|
|
if [ "$(check_option zipman)" = "y" ]; then
|
|
msg2 "$(gettext "Compressing man pages...")"
|
|
local manpage mandirs ext file link hardlinks hl
|
|
mandirs="usr/man usr/share/man usr/local/man usr/local/share/man opt/*/man"
|
|
find ${mandirs} -type f 2>/dev/null |
|
|
while read manpage ; do
|
|
# check file still exists (potentially compressed with hard link)
|
|
if [ -f ${manpage} ]; then
|
|
ext="${manpage##*.}"
|
|
file="${manpage##*/}"
|
|
if [ "$ext" != "gz" -a "$ext" != "bz2" ]; then
|
|
# update symlinks to this manpage
|
|
find ${mandirs} -lname "$file" 2>/dev/null |
|
|
while read link ; do
|
|
rm -f "$link"
|
|
ln -sf "${file}.gz" "${link}.gz"
|
|
done
|
|
# find hard links and remove them
|
|
# the '|| true' part keeps the script from bailing if find returned an
|
|
# error, such as when one of the man directories doesn't exist
|
|
hardlinks="$(find ${mandirs} \! -name "$file" -samefile "$manpage" 2>/dev/null)" || true
|
|
for hl in ${hardlinks}; do
|
|
rm -f "${hl}";
|
|
done
|
|
# compress the original
|
|
gzip -9 "$manpage"
|
|
# recreate hard links removed earlier
|
|
for hl in ${hardlinks}; do
|
|
ln "${manpage}.gz" "${hl}.gz"
|
|
chmod 644 ${hl}.gz
|
|
done
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
|
|
if [ "$(check_option strip)" = "y" ]; then
|
|
msg2 "$(gettext "Stripping debugging symbols from binaries and libraries...")"
|
|
local binary bindirs
|
|
bindirs="bin lib sbin usr/bin usr/lib usr/sbin usr/local/bin usr/local/lib usr/local/sbin opt/*/bin opt/*/lib opt/*/sbin"
|
|
find ${bindirs} -type f 2>/dev/null | while read binary ; do
|
|
case "$(file -biz "$binary")" in
|
|
*application/x-sharedlib*) # Libraries
|
|
/usr/bin/strip --strip-debug "$binary";;
|
|
*application/x-executable*) # Binaries
|
|
/usr/bin/strip "$binary";;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
if [ "$(check_option libtool)" = "n" ]; then
|
|
msg2 "$(gettext "Removing libtool .la files...")"
|
|
find . -type f -name "*.la" -exec rm -f -- '{}' \;
|
|
fi
|
|
|
|
if [ "$(check_option emptydirs)" = "n" ]; then
|
|
msg2 "$(gettext "Removing empty directories...")"
|
|
find . -depth -type d -empty -delete
|
|
fi
|
|
}
|
|
|
|
create_package() {
|
|
if [ ! -d "$pkgdir" ]; then
|
|
error "$(gettext "Missing pkg/ directory.")"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1 # $E_MISSING_PKGDIR
|
|
fi
|
|
|
|
cd "$pkgdir"
|
|
msg "$(gettext "Creating package...")"
|
|
|
|
local builddate=$(date -u "+%s")
|
|
if [ "$PACKAGER" != "" ]; then
|
|
local packager="$PACKAGER"
|
|
else
|
|
local packager="Unknown Packager"
|
|
fi
|
|
local size=$(du -sk | awk '{print $1 * 1024}')
|
|
|
|
# write the .PKGINFO file
|
|
msg2 "$(gettext "Generating .PKGINFO file...")"
|
|
echo "# Generated by makepkg $myver" >.PKGINFO
|
|
if [ "$INFAKEROOT" = "1" ]; then
|
|
echo "# using $(fakeroot -v)" >>.PKGINFO
|
|
fi
|
|
echo "# $(LC_ALL= LANG= date -u)" >>.PKGINFO
|
|
echo "pkgname = $pkgname" >>.PKGINFO
|
|
echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO
|
|
echo "pkgdesc = $pkgdesc" >>.PKGINFO
|
|
echo "url = $url" >>.PKGINFO
|
|
echo "builddate = $builddate" >>.PKGINFO
|
|
echo "packager = $packager" >>.PKGINFO
|
|
echo "size = $size" >>.PKGINFO
|
|
if [ "$CARCH" != "" ]; then
|
|
echo "arch = $CARCH" >>.PKGINFO
|
|
fi
|
|
if [ "$(check_option force)" = "y" ]; then
|
|
echo "force = true" >> .PKGINFO
|
|
fi
|
|
|
|
local it
|
|
for it in "${license[@]}"; do
|
|
echo "license = $it" >>.PKGINFO
|
|
done
|
|
for it in "${replaces[@]}"; do
|
|
echo "replaces = $it" >>.PKGINFO
|
|
done
|
|
for it in "${groups[@]}"; do
|
|
echo "group = $it" >>.PKGINFO
|
|
done
|
|
for it in "${depends[@]}"; do
|
|
echo "depend = $it" >>.PKGINFO
|
|
done
|
|
for it in "${optdepends[@]}"; do
|
|
echo "optdepend = $it" >>.PKGINFO
|
|
done
|
|
for it in "${conflicts[@]}"; do
|
|
echo "conflict = $it" >>.PKGINFO
|
|
done
|
|
for it in "${provides[@]}"; do
|
|
echo "provides = $it" >>.PKGINFO
|
|
done
|
|
for it in "${backup[@]}"; do
|
|
echo "backup = $it" >>.PKGINFO
|
|
done
|
|
|
|
# TODO maybe remove this at some point
|
|
# warn if license array is not present or empty
|
|
if [ "$license" = "" ]; then
|
|
warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
|
|
plain "$(gettext "Example for GPL'ed software: license=('GPL').")"
|
|
fi
|
|
|
|
local comp_files=".PKGINFO"
|
|
|
|
# check for an install script
|
|
if [ "$install" != "" ]; then
|
|
msg2 "$(gettext "Adding install script...")"
|
|
cp "$startdir/$install" .INSTALL
|
|
comp_files="$comp_files .INSTALL"
|
|
fi
|
|
|
|
# do we have a changelog?
|
|
if [ -f "$startdir/ChangeLog" ]; then
|
|
msg2 "$(gettext "Adding package changelog...")"
|
|
cp "$startdir/ChangeLog" .CHANGELOG
|
|
comp_files="$comp_files .CHANGELOG"
|
|
fi
|
|
|
|
# tar it up
|
|
msg2 "$(gettext "Compressing package...")"
|
|
|
|
local pkg_file="$PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}"
|
|
|
|
if ! bsdtar -czf "$pkg_file" $comp_files *; then
|
|
error "$(gettext "Failed to create package file.")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
}
|
|
|
|
create_xdelta() {
|
|
if [ "$(check_buildenv xdelta)" != "y" ]; then
|
|
return
|
|
elif [ ! "$(type -p xdelta)" ]; then
|
|
error "$(gettext "Cannot find the xdelta binary! Is xdelta installed?")"
|
|
return
|
|
fi
|
|
|
|
local pkg_file=$1
|
|
local cache_dir="/var/cache/pacman/pkg" # TODO: autoconf me
|
|
local pkginfo="$(mktemp "$startdir"/xdelta-pkginfo.XXXXXXXXX)"
|
|
|
|
local old_file old_version
|
|
for old_file in $(ls {"$cache_dir","$PKGDEST"}/${pkgname}-*-*{,-$CARCH}$PKGEXT 2>/dev/null); do
|
|
bsdtar -xOf "$old_file" .PKGINFO > "$pkginfo" || continue
|
|
if [ "$(cat "$pkginfo" | grep '^pkgname = ')" != "pkgname = $pkgname" ]; then
|
|
continue # Package name does not match.
|
|
elif [ "$(cat "$pkginfo" | grep '^arch = ')" != "arch = $CARCH" ] ; then
|
|
continue # Not same arch.
|
|
fi
|
|
|
|
old_version="$(cat "$pkginfo" | grep '^pkgver = ' | sed 's/^pkgver = //')"
|
|
|
|
# old_version may include the target package, only use the old versions
|
|
local vercmp=$(vercmp "$old_version" "$latest_version")
|
|
if [ "$old_version" != "$pkgver-$pkgrel" -a $vercmp -gt 0 ]; then
|
|
local latest_version=$old_version
|
|
local base_file=$old_file
|
|
fi
|
|
done
|
|
|
|
rm -f "$pkginfo"
|
|
|
|
if [ "$base_file" != "" ]; then
|
|
msg "$(gettext "Making delta from version %s...")" "$latest_version"
|
|
local delta_file="$PKGDEST/$pkgname-${latest_version}_to_$pkgver-$pkgrel-$CARCH.delta"
|
|
local ret=0
|
|
|
|
# xdelta will decompress base_file & pkg_file into TMP_DIR (or /tmp if
|
|
# TMP_DIR is unset) then perform the delta on the resulting tars
|
|
xdelta delta "$base_file" "$pkg_file" "$delta_file" || ret=$?
|
|
|
|
if [ $ret -eq 0 -o $ret -eq 1 ]; then
|
|
# Generate the final gz using xdelta for compression. xdelta will be our
|
|
# common denominator compression utility between the packager and the
|
|
# users. makepkg and pacman must use the same compression algorithm or
|
|
# the delta generated package may not match, producing md5 checksum
|
|
# errors.
|
|
msg2 "$(gettext "Recreating package tarball from delta to match md5 signatures")"
|
|
msg2 "$(gettext "NOTE: the delta should ONLY be distributed with this tarball")"
|
|
ret=0
|
|
xdelta patch "$delta_file" "$base_file" "$pkg_file" || ret=$?
|
|
if [ $ret -ne 0 ]; then
|
|
error "$(gettext "Could not generate the package from the delta.")"
|
|
exit 1
|
|
fi
|
|
else
|
|
warning "$(gettext "Delta was not able to be created.")"
|
|
fi
|
|
else
|
|
warning "$(gettext "No previous version found, skipping xdelta.")"
|
|
fi
|
|
}
|
|
|
|
create_srcpackage() {
|
|
cd "$startdir"
|
|
if [ "$SOURCEONLY" = "2" ]; then
|
|
# get back to our src directory so we can begin with sources
|
|
mkdir -p "$srcdir"
|
|
cd "$srcdir"
|
|
download_sources
|
|
# we can only check checksums if we have all files
|
|
check_checksums
|
|
cd "$startdir"
|
|
fi
|
|
msg "$(gettext "Creating source package...")"
|
|
local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
|
|
mkdir "${srclinks}"/${pkgname}
|
|
|
|
msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
|
|
ln -s "${startdir}/${BUILDSCRIPT}" "${srclinks}/${pkgname}/"
|
|
|
|
if [ "$install" != "" ]; then
|
|
if [ -f $install ]; then
|
|
msg2 "$(gettext "Adding install script...")"
|
|
ln -s "${startdir}/$install" "${srclinks}/${pkgname}/"
|
|
else
|
|
error "$(gettext "Install script %s not found.")" "$install"
|
|
fi
|
|
fi
|
|
|
|
if [ -f ChangeLog ]; then
|
|
msg2 "$(gettext "Adding %s...")" "ChangeLog"
|
|
ln -s "${startdir}/ChangeLog" "${srclinks}/${pkgname}"
|
|
fi
|
|
|
|
local netfile
|
|
for netfile in ${source[@]}; do
|
|
local file=$(strip_url "$netfile")
|
|
if [ -f $netfile ]; then
|
|
msg2 "$(gettext "Adding %s...")" "$netfile"
|
|
ln -s $netfile ${srclinks}/${pkgname}
|
|
elif [ "$SOURCEONLY" = "2" -a -f "$SRCDEST/$file" ]; then
|
|
msg2 "$(gettext "Adding %s...")" "$file"
|
|
ln -s "$SRCDEST/$file" "${srclinks}/${pkgname}/"
|
|
fi
|
|
done
|
|
|
|
local pkg_file="$PKGDEST/${pkgname}-${pkgver}-${pkgrel}${SRCEXT}"
|
|
|
|
# tar it up
|
|
msg2 "$(gettext "Compressing source package...")"
|
|
cd ${srclinks}
|
|
if ! bsdtar -czLf "$pkg_file" ${pkgname}; then
|
|
error "$(gettext "Failed to create source package file.")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
cd ${startdir}
|
|
rm -rf ${srclinks}
|
|
}
|
|
|
|
install_package() {
|
|
[ "$INSTALL" = "0" ] && return
|
|
msg "$(gettext "Installing package ${pkgname} with pacman -U...")"
|
|
if [ "$ASROOT" = "0" ]; then
|
|
sudo pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} || exit $?
|
|
else
|
|
pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} || exit $?
|
|
fi
|
|
}
|
|
|
|
devel_check() {
|
|
newpkgver=""
|
|
# Only update pkgver if --holdver is not set
|
|
if [ "$HOLDVER" = "1" ]; then
|
|
return
|
|
fi
|
|
if [ "$FORCE_VER" = "" ]; then
|
|
# Check if this is a svn/cvs/etc PKGBUILD; set $newpkgver if so.
|
|
# This will only be used on the first call to makepkg; subsequent
|
|
# calls to makepkg via fakeroot will explicitly pass the version
|
|
# number to avoid having to determine the version number twice.
|
|
# Also do a brief check to make sure we have the VCS tool available.
|
|
oldpkgver=$pkgver
|
|
if [ ! -z ${_darcstrunk} ] && [ ! -z ${_darcsmod} ] ; then
|
|
[ $(type -p darcs) ] || return 0
|
|
msg "$(gettext "Determining latest darcs revision...")"
|
|
newpkgver=$(date +%Y%m%d)
|
|
elif [ ! -z ${_cvsroot} ] && [ ! -z ${_cvsmod} ] ; then
|
|
[ $(type -p cvs) ] || return 0
|
|
msg "$(gettext "Determining latest cvs revision...")"
|
|
newpkgver=$(date +%Y%m%d)
|
|
elif [ ! -z ${_gitroot} ] && [ ! -z ${_gitname} ] ; then
|
|
[ $(type -p git) ] || return 0
|
|
msg "$(gettext "Determining latest git revision...")"
|
|
newpkgver=$(date +%Y%m%d)
|
|
elif [ ! -z ${_svntrunk} ] && [ ! -z ${_svnmod} ] ; then
|
|
[ $(type -p svn) ] || return 0
|
|
msg "$(gettext "Determining latest svn revision...")"
|
|
newpkgver=$(svn log $_svntrunk --limit 1 -q | sed -n 's/^r\([0-9]*\) .*$/\1/p')
|
|
elif [ ! -z ${_bzrtrunk} ] && [ ! -z ${_bzrmod} ] ; then
|
|
[ $(type -p bzr) ] || return 0
|
|
msg "$(gettext "Determining latest bzr revision...")"
|
|
newpkgver=$(bzr revno ${_bzrtrunk})
|
|
elif [ ! -z ${_hgroot} ] && [ ! -z ${_hgrepo} ] ; then
|
|
[ $(type -p hg) ] || return 0
|
|
msg "$(gettext "Determining latest hg revision...")"
|
|
if [ -d ./src/$_hgrepo ] ; then
|
|
cd ./src/$_hgrepo
|
|
hg pull
|
|
hg update
|
|
else
|
|
[[ ! -d ./src/ ]] && mkdir ./src/
|
|
hg clone $_hgroot/$_hgrepo ./src/$_hgrepo
|
|
cd ./src/$_hgrepo
|
|
fi
|
|
newpkgver=$(hg tip | sed -n '1s/[^0-9]*\([^:]*\):.*$/\1/p')
|
|
cd ../../
|
|
fi
|
|
|
|
if [ "$newpkgver" != "" ]; then
|
|
msg2 "$(gettext "Version found: %s")" "$newpkgver"
|
|
pkgver=$newpkgver
|
|
fi
|
|
|
|
else
|
|
# Version number retrieved from fakeroot->makepkg argument
|
|
newpkgver=$FORCE_VER
|
|
fi
|
|
}
|
|
|
|
devel_update() {
|
|
# This is lame, but if we're wanting to use an updated pkgver for
|
|
# retrieving svn/cvs/etc sources, we'll update the PKGBUILD with
|
|
# the new pkgver and then re-source it. This is the most robust
|
|
# method for dealing with PKGBUILDs that use, e.g.:
|
|
#
|
|
# pkgver=23
|
|
# ...
|
|
# _foo=pkgver
|
|
#
|
|
if [ "$newpkgver" != "" ]; then
|
|
if [ "newpkgver" != "$pkgver" ]; then
|
|
sed -i "s/^pkgver=[^ ]*/pkgver=$newpkgver/" ./$BUILDSCRIPT
|
|
source $BUILDSCRIPT
|
|
fi
|
|
fi
|
|
}
|
|
|
|
usage() {
|
|
printf "makepkg (pacman) %s\n" "$myver"
|
|
echo
|
|
printf "$(gettext "Usage: %s [options]")\n" "$0"
|
|
echo
|
|
echo "$(gettext "Options:")"
|
|
printf "$(gettext " -A, --ignorearch Ignore incomplete arch field in %s")\n" "$BUILDSCRIPT"
|
|
echo "$(gettext " -c, --clean Clean up work files after build")"
|
|
echo "$(gettext " -C, --cleancache Clean up source files from the cache")"
|
|
echo "$(gettext " -d, --nodeps Skip all dependency checks")"
|
|
echo "$(gettext " -e, --noextract Do not extract source files (use existing src/ dir)")"
|
|
echo "$(gettext " -f, --force Overwrite existing package")"
|
|
echo "$(gettext " -g, --geninteg Generate integrity checks for source files")"
|
|
echo "$(gettext " -h, --help This help")"
|
|
echo "$(gettext " -i, --install Install package after successful build")"
|
|
echo "$(gettext " -L, --log Log package build process")"
|
|
echo "$(gettext " -m, --nocolor Disable colorized output messages")"
|
|
echo "$(gettext " -o, --nobuild Download and extract files only")"
|
|
printf "$(gettext " -p <buildscript> Use an alternate build script (instead of '%s')")\n" "$BUILDSCRIPT"
|
|
echo "$(gettext " -r, --rmdeps Remove installed dependencies after a successful build")"
|
|
# fix flyspray feature request #2978
|
|
echo "$(gettext " -R, --repackage Repackage contents of pkg/ without building")"
|
|
echo "$(gettext " -s, --syncdeps Install missing dependencies with pacman")"
|
|
echo "$(gettext " --asroot Allow makepkg to run as root user")"
|
|
echo "$(gettext " --holdver Prevent automatic version bumping for development PKGBUILDs")"
|
|
echo "$(gettext " --source Do not build package; generate a source-only tarball")"
|
|
echo
|
|
echo "$(gettext "These options can be passed to pacman:")"
|
|
echo
|
|
echo "$(gettext " --noconfirm Do not ask for confirmation when resolving dependencies")"
|
|
echo "$(gettext " --noprogressbar Do not show a progress bar when downloading files")"
|
|
echo
|
|
printf "$(gettext "If -p is not specified, makepkg will look for '%s'")\n" "$BUILDSCRIPT"
|
|
echo
|
|
}
|
|
|
|
version() {
|
|
printf "makepkg (pacman) %s\n" "$myver"
|
|
printf "$(gettext "\
|
|
Copyright (C) 2002-2007 Judd Vinet <jvinet@zeroflux.org>.\n\n\
|
|
This is free software; see the source for copying conditions.\n\
|
|
There is NO WARRANTY, to the extent permitted by law.\n")"
|
|
}
|
|
|
|
# PROGRAM START
|
|
|
|
# determine whether we have gettext; make it a no-op if we do not
|
|
if [ ! $(type -t gettext) ]; then
|
|
gettext() {
|
|
echo "$@"
|
|
}
|
|
fi
|
|
|
|
ARGLIST=$@
|
|
|
|
#preserve environment variables
|
|
_PKGDEST=${PKGDEST}
|
|
_SRCDEST=${SRCDEST}
|
|
|
|
# Source makepkg.conf; fail if it is not found
|
|
if [ -r "$confdir/makepkg.conf" ]; then
|
|
source "$confdir/makepkg.conf"
|
|
else
|
|
error "$(gettext "%s not found.")" "$confdir/makepkg.conf"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1 # $E_CONFIG_ERROR
|
|
fi
|
|
|
|
# Source user-specific makepkg.conf overrides
|
|
if [ -r ~/.makepkg.conf ]; then
|
|
source ~/.makepkg.conf
|
|
fi
|
|
|
|
# override settings with an environment variable for batch processing
|
|
PKGDEST=${_PKGDEST:-$PKGDEST}
|
|
PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined
|
|
SRCDEST=${_SRCDEST:-$SRCDEST}
|
|
SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined
|
|
|
|
# Parse Command Line Options.
|
|
OPT_SHORT="AbcCdefFghiLmop:rRsV"
|
|
OPT_LONG="allsource,asroot,ignorearch,builddeps,clean,cleancache,nodeps"
|
|
OPT_LONG="$OPT_LONG,noextract,force,forcever:,geninteg,help,holdver"
|
|
OPT_LONG="$OPT_LONG,install,log,nocolor,nobuild,rmdeps,repackage,source"
|
|
OPT_LONG="$OPT_LONG,syncdeps,version"
|
|
# Pacman Options
|
|
OPT_LONG="$OPT_LONG,noconfirm,noprogressbar"
|
|
OPT_TEMP="$(getopt -o "$OPT_SHORT" -l "$OPT_LONG" -n "$(basename "$0")" -- "$@" || echo 'GETOPT GO BANG!')"
|
|
if echo "$OPT_TEMP" | grep -q 'GETOPT GO BANG!'; then
|
|
# This is a small hack to stop the script bailing with 'set -e'
|
|
echo; usage; exit 1 # E_INVALID_OPTION;
|
|
fi
|
|
eval set -- "$OPT_TEMP"
|
|
unset OPT_SHORT OPT_LONG OPT_TEMP
|
|
|
|
while true; do
|
|
case "$1" in
|
|
# Pacman Options
|
|
--noconfirm) PACMAN_OPTS="$PACMAN_OPTS --noconfirm" ;;
|
|
--noprogressbar) PACMAN_OPTS="$PACMAN_OPTS --noprogressbar" ;;
|
|
|
|
# Makepkg Options
|
|
--allsource) SOURCEONLY=2 ;;
|
|
--asroot) ASROOT=1 ;;
|
|
-A|--ignorearch) IGNOREARCH=1 ;;
|
|
-c|--clean) CLEANUP=1 ;;
|
|
-C|--cleancache) CLEANCACHE=1 ;;
|
|
-d|--nodeps) NODEPS=1 ;;
|
|
-e|--noextract) NOEXTRACT=1 ;;
|
|
-f|--force) FORCE=1 ;;
|
|
#hidden opt used by fakeroot call for svn/cvs/etc PKGBUILDs to set pkgver
|
|
--forcever) shift; FORCE_VER=$1;;
|
|
-F) INFAKEROOT=1 ;;
|
|
-g|--geninteg) GENINTEG=1 ;;
|
|
--holdver) HOLDVER=1 ;;
|
|
-i|--install) INSTALL=1 ;;
|
|
-L|--log) LOGGING=1 ;;
|
|
-m|--nocolor) USE_COLOR='n' ;;
|
|
-o|--nobuild) NOBUILD=1 ;;
|
|
-p) shift; BUILDSCRIPT=$1 ;;
|
|
-r|--rmdeps) RMDEPS=1 ;;
|
|
-R|--repackage) REPKG=1 ;;
|
|
--source) SOURCEONLY=1 ;;
|
|
-s|--syncdeps) DEP_BIN=1 ;;
|
|
|
|
-h|--help) usage; exit 0 ;; # E_OK
|
|
-V|--version) version; exit 0 ;; # E_OK
|
|
|
|
--) OPT_IND=0; shift; break;;
|
|
*) usage; exit 1 ;; # E_INVALID_OPTION
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ "$HOLDVER" = "1" -a "$FORCE_VER" != "" ]; then
|
|
# The '\\0' is here to prevent gettext from thinking --holdver is an option
|
|
error "$(gettext "\\0--holdver and --forcever cannot both be specified" )"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$CLEANCACHE" = "1" ]; then
|
|
#fix flyspray feature request #5223
|
|
if [ -n "$SRCDEST" -a "$SRCDEST" != "$startdir" ]; then
|
|
msg "$(gettext "Cleaning up ALL files from %s.")" "$SRCDEST"
|
|
echo -n "$(gettext " Are you sure you wish to do this? [Y/n] ")"
|
|
read answer
|
|
answer=$(echo $answer | tr [:upper:] [:lower:])
|
|
if [ "$answer" = "yes" -o "$answer" = "y" ]; then
|
|
rm "$SRCDEST"/*
|
|
if [ $? -ne 0 ]; then
|
|
error "$(gettext "Problem removing files; you may not have correct permissions in %s")" "$SRCDEST"
|
|
exit 1
|
|
else
|
|
# removal worked
|
|
msg "$(gettext "Source cache cleaned.")"
|
|
exit 0
|
|
fi
|
|
else
|
|
# answer = no
|
|
msg "$(gettext "No files have been removed.")"
|
|
exit 0
|
|
fi
|
|
else
|
|
# $SRCDEST is $startdir, two possibilities
|
|
error "$(gettext "Source destination must be defined in makepkg.conf.")"
|
|
plain "$(gettext "In addition, please run makepkg -C outside of your cache directory.")"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [ -z $BUILDSCRIPT ]; then
|
|
error "$(gettext "BUILDSCRIPT is undefined! Ensure you have updated %s.")" "$confdir/makepkg.conf"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$INFAKEROOT" = "0" ]; then
|
|
if [ $EUID -eq 0 -a "$ASROOT" = "0" ]; then
|
|
# Warn those who like to live dangerously.
|
|
error "$(gettext "Running makepkg as root is a BAD idea and can cause")"
|
|
plain "$(gettext "permanent, catastrophic damage to your system. If you")"
|
|
plain "$(gettext "wish to run as root, please use the --asroot option.")"
|
|
exit 1 # $E_USER_ABORT
|
|
elif [ $EUID -gt 0 -a "$ASROOT" = "1" ]; then
|
|
# Warn those who try to use the --asroot option when they are not root
|
|
error "$(gettext "The --asroot option is meant for the root user only.")"
|
|
plain "$(gettext "Please rerun makepkg without the --asroot flag.")"
|
|
exit 1 # $E_USER_ABORT
|
|
elif [ "$(check_buildenv fakeroot)" = "y" -a $EUID -gt 0 ]; then
|
|
if [ ! $(type -p fakeroot) ]; then
|
|
error "$(gettext "Fakeroot must be installed if using the 'fakeroot' option")"
|
|
plain "$(gettext "in the BUILDENV array in %s.")" "$confdir/makepkg.conf"
|
|
exit 1
|
|
fi
|
|
elif [ $EUID -gt 0 ]; then
|
|
warning "$(gettext "Running makepkg as an unprivileged user will result in non-root")"
|
|
plain "$(gettext "ownership of the packaged files. Try using the fakeroot environment by")"
|
|
plain "$(gettext "placing 'fakeroot' in the BUILDENV array in makepkg.conf.")"
|
|
sleep 1
|
|
fi
|
|
else
|
|
if [ "$FAKEROOTKEY" = "" ]; then
|
|
error "$(gettext "Do not use the '-F' option. This option is only for use by makepkg.")"
|
|
exit 1 # TODO: error code
|
|
fi
|
|
fi
|
|
|
|
# check for sudo if we will need it during makepkg execution
|
|
if [ "$ASROOT" = "0" -a \( "$DEP_BIN" = "1" \
|
|
-o "$RMDEPS" = "1" -o "$INSTALL" = "1" \) ]; then
|
|
if [ ! "$(type -p sudo)" ]; then
|
|
error "$(gettext "Cannot find the sudo binary! Is sudo installed?")"
|
|
plain "$(gettext "Missing dependencies cannot be installed or removed as a normal user")"
|
|
plain "$(gettext "without sudo; install and configure sudo to auto-resolve dependencies.")"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
unset pkgname pkgver pkgrel pkgdesc url license groups provides md5sums
|
|
unset replaces depends conflicts backup source install build makedepends
|
|
unset optdepends options noextract
|
|
|
|
if [ ! -f "$BUILDSCRIPT" ]; then
|
|
error "$(gettext "%s does not exist.")" "$BUILDSCRIPT"
|
|
exit 1
|
|
fi
|
|
|
|
source "$BUILDSCRIPT"
|
|
|
|
if [ "$GENINTEG" = "1" ]; then
|
|
mkdir -p "$srcdir"
|
|
cd "$srcdir"
|
|
download_sources
|
|
generate_checksums
|
|
exit 0 # $E_OK
|
|
fi
|
|
|
|
# check for no-no's in the build script
|
|
if [ -z "$pkgname" ]; then
|
|
error "$(gettext "%s is not allowed to be empty.")" "pkgname"
|
|
exit 1
|
|
fi
|
|
if [ -z "$pkgver" ]; then
|
|
error "$(gettext "%s is not allowed to be empty.")" "pkgver"
|
|
exit 1
|
|
fi
|
|
if [ -z "$pkgrel" ]; then
|
|
error "$(gettext "%s is not allowed to be empty.")" "pkgrel"
|
|
exit 1
|
|
fi
|
|
if [ $(echo "$pkgver" | grep '-') ]; then
|
|
error "$(gettext "%s is not allowed to contain hyphens.")" "pkgver"
|
|
exit 1
|
|
fi
|
|
if [ $(echo "$pkgrel" | grep '-') ]; then
|
|
error "$(gettext "%s is not allowed to contain hyphens.")" "pkgrel"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$arch" = 'any' ]; then
|
|
CARCH='any'
|
|
fi
|
|
|
|
if ! in_array $CARCH ${arch[@]}; then
|
|
if [ "$IGNOREARCH" = "0" ]; then
|
|
error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgname" "$CARCH"
|
|
plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
|
|
plain "$(gettext "such as arch=('%s').")" "$CARCH"
|
|
exit 1
|
|
else
|
|
warning "$(gettext "%s is not available for the '%s' architecture.")" "$pkgname" "$CARCH"
|
|
plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT"
|
|
plain "$(gettext "such as arch=('%s').")" "$CARCH"
|
|
fi
|
|
fi
|
|
|
|
if [ "$install" -a ! -f "$install" ]; then
|
|
error "$(gettext "Install scriptlet (%s) does not exist.")" "$install"
|
|
exit 1
|
|
fi
|
|
|
|
valid_options=1
|
|
for opt in ${options[@]}; do
|
|
known=0
|
|
# check if option matches a known option or its inverse
|
|
for kopt in ${known_options[@]}; do
|
|
if [ "${opt}" = "${kopt}" -o "${opt}" = "!${kopt}" ]; then
|
|
known=1
|
|
fi
|
|
done
|
|
if [ $known -eq 0 ]; then
|
|
error "$(gettext "options array contains unknown option '%s'")" "$opt"
|
|
valid_options=0
|
|
fi
|
|
done
|
|
if [ $valid_options -eq 0 ]; then
|
|
exit 1
|
|
fi
|
|
unset valid_options opt known kopt
|
|
|
|
# We need to run devel_update regardless of whether we are in the fakeroot
|
|
# build process so that if the user runs makepkg --forcever manually, we
|
|
# 1) output the correct pkgver, and 2) use the correct filename when
|
|
# checking if the package file already exists - fixes FS #9194
|
|
devel_check
|
|
devel_update
|
|
|
|
if [ -f "$PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" \
|
|
-a "$FORCE" = "0" -a "$SOURCEONLY" = "0" -a "$NOBUILD" = "0" ]; then
|
|
if [ "$INSTALL" = "1" ]; then
|
|
warning "$(gettext "A package has already been built, installing existing package...")"
|
|
install_package
|
|
exit $?
|
|
else
|
|
error "$(gettext "A package has already been built. (use -f to overwrite)")"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Run the bare minimum in fakeroot
|
|
# fix flyspray bug 6208 -- using makepkg with fakeroot gives an error
|
|
if [ "$INFAKEROOT" = "1" ]; then
|
|
if [ "$REPKG" = "1" ]; then
|
|
warning "$(gettext "Skipping build.")"
|
|
else
|
|
run_build
|
|
tidy_install
|
|
fi
|
|
|
|
create_package
|
|
|
|
msg "$(gettext "Leaving fakeroot environment.")"
|
|
exit 0 # $E_OK
|
|
fi
|
|
|
|
msg "$(gettext "Making package: %s")" "$pkgname $pkgver-$pkgrel $CARCH ($(date))"
|
|
|
|
if [ $EUID -eq 0 ]; then
|
|
warning "$(gettext "Running makepkg as root...")"
|
|
fi
|
|
|
|
# if we are creating a source-only package, go no further
|
|
if [ "$SOURCEONLY" != "0" ]; then
|
|
if [ -f "$PKGDEST/${pkgname}-${pkgver}-${pkgrel}${SRCEXT}" \
|
|
-a "$FORCE" = "0" ]; then
|
|
error "$(gettext "A package has already been built. (use -f to overwrite)")"
|
|
exit 1
|
|
fi
|
|
create_srcpackage
|
|
msg "$(gettext "Source package created: %s")" "$pkgname ($(date))"
|
|
exit 0
|
|
fi
|
|
|
|
# fix flyspray bug #5973
|
|
if [ "$NODEPS" = "1" -o "$NOBUILD" = "1" -o "$REPKG" = "1" ]; then
|
|
if [ "$NODEPS" = "1" ]; then
|
|
warning "$(gettext "Skipping dependency checks.")"
|
|
fi
|
|
# skip printing a warning message for the others: nobuild, repkg
|
|
elif [ $(type -p pacman) ]; then
|
|
unset pkgdeps # Set by resolve_deps() and used by remove_deps()
|
|
deperr=0
|
|
|
|
msg "$(gettext "Checking Runtime Dependencies...")"
|
|
resolve_deps ${depends[@]} || deperr=1
|
|
|
|
msg "$(gettext "Checking Buildtime Dependencies...")"
|
|
resolve_deps ${makedepends[@]} || deperr=1
|
|
|
|
if [ $deperr -eq 1 ]; then
|
|
error "$(gettext "Could not resolve all dependencies.")"
|
|
exit 1
|
|
fi
|
|
else
|
|
warning "$(gettext "pacman was not found in PATH; skipping dependency checks.")"
|
|
fi
|
|
|
|
# ensure we have a sane umask set
|
|
umask 0022
|
|
|
|
# get back to our src directory so we can begin with sources
|
|
mkdir -p "$srcdir"
|
|
cd "$srcdir"
|
|
|
|
if [ "$NOEXTRACT" = "1" -o "$REPKG" = "1" ]; then
|
|
warning "$(gettext "Skipping source retrieval -- using existing src/ tree")"
|
|
warning "$(gettext "Skipping source integrity checks -- using existing src/ tree")"
|
|
warning "$(gettext "Skipping source extraction -- using existing src/ tree")"
|
|
|
|
if [ "$NOEXTRACT" = "1" -a "$(ls "$srcdir" 2>/dev/null)" = "" ]; then
|
|
error "$(gettext "The source directory is empty, there is nothing to build!")"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
elif [ "$REPKG" = "1" -a \( ! -d "$pkgdir" -o "$(ls "$pkgdir" 2>/dev/null)" = "" \) ]; then
|
|
error "$(gettext "The package directory is empty, there is nothing to repackage!")"
|
|
plain "$(gettext "Aborting...")"
|
|
exit 1
|
|
fi
|
|
else
|
|
download_sources
|
|
check_checksums
|
|
extract_sources
|
|
fi
|
|
|
|
if [ "$NOBUILD" = "1" ]; then
|
|
msg "$(gettext "Sources are ready.")"
|
|
exit 0 #E_OK
|
|
else
|
|
# check for existing pkg directory; don't remove if we are repackaging
|
|
if [ -d "$pkgdir" -a "$REPKG" = "0" ]; then
|
|
msg "$(gettext "Removing existing pkg/ directory...")"
|
|
rm -rf "$pkgdir"
|
|
fi
|
|
mkdir -p "$pkgdir"
|
|
cd "$startdir"
|
|
|
|
if [ "$(check_buildenv fakeroot)" != "y" -o $EUID -eq 0 ]; then
|
|
# if we are root or if fakeroot is not enabled, then we don't use it
|
|
if [ "$REPKG" = "1" ]; then
|
|
warning "$(gettext "Skipping build.")"
|
|
else
|
|
devel_update
|
|
run_build
|
|
tidy_install
|
|
fi
|
|
|
|
create_package
|
|
else
|
|
msg "$(gettext "Entering fakeroot environment...")"
|
|
|
|
if [ "$newpkgver" != "" ]; then
|
|
fakeroot -- $0 --forcever $newpkgver -F $ARGLIST || exit $?
|
|
else
|
|
fakeroot -- $0 -F $ARGLIST || exit $?
|
|
fi
|
|
fi
|
|
|
|
create_xdelta "$PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}"
|
|
fi
|
|
|
|
msg "$(gettext "Finished making: %s")" "$pkgname $pkgver-$pkgrel $CARCH ($(date))"
|
|
|
|
install_package
|
|
|
|
exit 0 #E_OK
|
|
|
|
# vim: set ts=2 sw=2 noet:
|