mirror of
https://github.com/openwrt/openwrt.git
synced 2026-06-17 12:40:16 +04:00
e36c2946b7
Previously PKG_SOURCE_DATE_EPOCH came from a git log on the OpenWrt package directory. That fails in shallow feed clones and in the SDK (no .git), collapsing to the script's mtime and breaking .apk reproducibility across SDK rebuilds and between buildbot and SDK. With this comment, PKG_UNPACK generates a version.date file, later used to determine a reproducible SOURCE_DATE_EPOCH. Since unpack happens after download, the evaluation of SOURCE_DATE_EPOCH is now lazy, invoking the `get_source_date_epoch.sh` script on every use. While at it, drop export of PKG_SOURCE_DATE_EPOCH and clean it from the ipkg-build script. Link: https://github.com/openwrt/openwrt/issues/21579 Link: https://github.com/openwrt/openwrt/pull/21587 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Link: https://github.com/openwrt/openwrt/pull/23576 Signed-off-by: Paul Spooren <mail@aparcar.org>
199 lines
4.5 KiB
Bash
Executable File
199 lines
4.5 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="$(command -v find)"
|
|
FIND="${FIND:-$(command -v gfind)}"
|
|
TAR="${TAR:-$(command -v tar)}"
|
|
|
|
# try to use fixed source epoch
|
|
if [ -n "$SOURCE_DATE_EPOCH" ]; then
|
|
TIMESTAMP=$(date --date="@$SOURCE_DATE_EPOCH")
|
|
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 '$pkg' 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
|
|
LC_ALL=C sort -o "$CONTROL"/conffiles "$CONTROL"/conffiles.resolved
|
|
rm "$CONTROL"/conffiles.resolved
|
|
chmod 0644 "$CONTROL"/conffiles
|
|
fi
|
|
fi
|
|
|
|
cd "$owd"
|
|
return $PKG_ERROR
|
|
}
|
|
|
|
resolve_file_mode_id() {
|
|
local var=$1 type=$2 name=$3 id
|
|
|
|
case "$name" in
|
|
root)
|
|
id=0
|
|
;;
|
|
*[!0-9]*)
|
|
id=$(sed -ne "s#^$type $name \\([0-9]\\+\\)\\b.*\$#\\1#p" "$TOPDIR/tmp/.packageusergroup" 2>/dev/null)
|
|
;;
|
|
*)
|
|
id=$name
|
|
;;
|
|
esac
|
|
|
|
export "$var=$id"
|
|
|
|
[ -n "$id" ]
|
|
}
|
|
|
|
###
|
|
# ipkg-build "main"
|
|
###
|
|
file_modes=""
|
|
usage="Usage: $0 [-v] [-h] [-m] <pkg_directory> [<destination_directory>]"
|
|
while getopts "hvm:" opt; do
|
|
case $opt in
|
|
v ) echo "$version"
|
|
exit 0
|
|
;;
|
|
h ) echo "$usage" >&2 ;;
|
|
m ) file_modes=$OPTARG ;;
|
|
\? ) 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" = "." ] || [ "$dest_dir" = "./" ] ; then
|
|
dest_dir=$PWD
|
|
fi
|
|
;;
|
|
*)
|
|
echo "$usage" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
pkg_dir="$(realpath "$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
|
|
cd "$pkg_dir"
|
|
for file_mode in $file_modes; do
|
|
case $file_mode in
|
|
/*:*:*:*)
|
|
;;
|
|
*)
|
|
echo "ERROR: file modes must use absolute path and contain user:group:mode"
|
|
echo "$file_mode"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
mode=${file_mode##*:}; path=${file_mode%:*}
|
|
group=${path##*:}; path=${path%:*}
|
|
user=${path##*:}; path=${path%:*}
|
|
|
|
if ! resolve_file_mode_id uid user "$user"; then
|
|
echo "ERROR: unable to resolve uid of $user" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! resolve_file_mode_id gid group "$group"; then
|
|
echo "ERROR: unable to resolve gid of $group" >&2
|
|
exit 1
|
|
fi
|
|
|
|
chown "$uid:$gid" "$pkg_dir/$path"
|
|
chmod "$mode" "$pkg_dir/$path"
|
|
done
|
|
$TAR -X "$tmp_dir"/tarX --format=gnu --numeric-owner --sort=name -cpf - --mtime="$TIMESTAMP" . | gzip -n - > "$tmp_dir"/data.tar.gz
|
|
|
|
installed_size=$(zcat < "$tmp_dir"/data.tar.gz | wc -c)
|
|
sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \
|
|
"$pkg_dir"/$CONTROL/control
|
|
|
|
( cd "$pkg_dir"/$CONTROL && $TAR --format=gnu --numeric-owner --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 --format=gnu --numeric-owner --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"
|