openwrt/scripts/ipkg-build
Jo-Philipp Wich d157a76c67 script: ipkg-build: honour $SOURCE_DATE_EPOCH
When the SOURCE_DATE_EPOCH environment variable is set, use it to
override the timestamps of .ipk archive contents.

This ensures that .ipk archives built in environments without SCM
metadata (mainly the SDK) are reproducible between different runs.

Ref: https://github.com/openwrt/packages/issues/6954
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-11-08 11:52:33 +01:00

167 lines
3.9 KiB
Bash
Executable File

#!/bin/sh
# ipkg-build -- construct a .ipk from a directory
# Carl Worth <cworth@east.isi.edu>
# based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
# 2003-04-25 rea@sr.unh.edu
# Updated to work on Familiar Pre0.7rc1, with busybox tar.
# Note it Requires: binutils-ar (since the busybox ar can't create)
# For UID debugging it needs a better "find".
set -e
version=1.0
FIND="$(which find)"
FIND="${FIND:-$(which gfind)}"
TAR="${TAR:-$(which tar)}"
GZIP="$(which gzip)"
# try to use fixed source epoch
if [ -n "$SOURCE_DATE_EPOCH" ]; then
TIMESTAMP=$(date --date="@$SOURCE_DATE_EPOCH")
# look up date of last commit
elif [ -d "$TOPDIR/.git" ]; then
GIT="$(which git)"
TIMESTAMP=$(cd $TOPDIR; $GIT log -1 -s --format=%ci)
elif [ -d "$TOPDIR/.svn" ]; then
SVN="$(which svn)"
TIMESTAMP=$($SVN info "$TOPDIR" | sed -n "s/^Last Changed Date: \(.*\)/\1/p")
else
TIMESTAMP=$(date)
fi
ipkg_extract_value() {
sed -e "s/^[^:]*:[[:space:]]*//"
}
required_field() {
field=$1
grep "^$field:" < $CONTROL/control | ipkg_extract_value
}
pkg_appears_sane() {
local pkg_dir=$1
local owd=$PWD
cd $pkg_dir
PKG_ERROR=0
pkg=`required_field Package`
version=`required_field Version | sed 's/Version://; s/^.://g;'`
arch=`required_field Architecture`
if echo $pkg | grep '[^a-zA-Z0-9_.+-]'; then
echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
PKG_ERROR=1;
fi
if [ -f $CONTROL/conffiles ]; then
rm -f $CONTROL/conffiles.resolved
for cf in `$FIND $(sed -e "s!^/!$pkg_dir/!" $CONTROL/conffiles) -type f`; do
echo "${cf#$pkg_dir}" >> $CONTROL/conffiles.resolved
done
rm $CONTROL/conffiles
if [ -f $CONTROL/conffiles.resolved ]; then
mv $CONTROL/conffiles.resolved $CONTROL/conffiles
chmod 0644 $CONTROL/conffiles
fi
fi
cd $owd
return $PKG_ERROR
}
###
# ipkg-build "main"
###
ogargs=""
noclean=0
usage="Usage: $0 [-c] [-C] [-o owner] [-g group] <pkg_directory> [<destination_directory>]"
while getopts "cg:ho:v" opt; do
case $opt in
o ) owner=$OPTARG
ogargs="--owner=$owner"
;;
g ) group=$OPTARG
ogargs="$ogargs --group=$group"
;;
c ) ;;
C ) noclean=1;;
v ) echo $version
exit 0
;;
h ) echo $usage >&2 ;;
\? ) echo $usage >&2
esac
done
shift $(($OPTIND - 1))
# continue on to process additional arguments
case $# in
1)
dest_dir=$PWD
;;
2)
dest_dir=$2
if [ "$dest_dir" = "." -o "$dest_dir" = "./" ] ; then
dest_dir=$PWD
fi
;;
*)
echo $usage >&2
exit 1
;;
esac
pkg_dir=$1
if [ ! -d $pkg_dir ]; then
echo "*** Error: Directory $pkg_dir does not exist" >&2
exit 1
fi
# CONTROL is second so that it takes precedence
CONTROL=
[ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
if [ -z "$CONTROL" ]; then
echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
exit 1
fi
if ! pkg_appears_sane $pkg_dir; then
echo >&2
echo "ipkg-build: Please fix the above errors and try again." >&2
exit 1
fi
tmp_dir=$dest_dir/IPKG_BUILD.$$
mkdir $tmp_dir
echo $CONTROL > $tmp_dir/tarX
# Preserve permissions (-p) when creating data.tar.gz as non-root user
( cd $pkg_dir && $TAR $ogargs -X $tmp_dir/tarX --format=gnu --sort=name -cpf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/data.tar.gz )
installed_size=`stat -c "%s" $tmp_dir/data.tar.gz`
sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \
$pkg_dir/$CONTROL/control
( cd $pkg_dir/$CONTROL && $TAR $ogargs --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/control.tar.gz )
rm $tmp_dir/tarX
echo "2.0" > $tmp_dir/debian-binary
pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
rm -f $pkg_file
( cd $tmp_dir && $TAR $ogargs --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" ./debian-binary ./data.tar.gz ./control.tar.gz | $GZIP -n - > $pkg_file )
rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
rmdir $tmp_dir
echo "Packaged contents of $pkg_dir into $pkg_file"