392 lines
13 KiB
Bash
Executable file
392 lines
13 KiB
Bash
Executable file
#!/bin/sh
|
|
set -e
|
|
|
|
make_dir_path_absolute() {
|
|
(cd "$1" && pwd)
|
|
}
|
|
|
|
has_command() {
|
|
which "$1" > /dev/null
|
|
}
|
|
|
|
# Determine what's supposed to happen.
|
|
OPERATION=build
|
|
if [ 1 -le $# ]; then OPERATION="$1"; fi
|
|
case "$OPERATION" in
|
|
download|extract|build) ;;
|
|
*) echo "$0: error: Invalid operation: $OPERATION" >&2
|
|
exit 1
|
|
esac
|
|
|
|
# Detect if the environment isn't set up properly.
|
|
if [ -z "$HOST" ]; then
|
|
echo "$0: error: You need to set \$HOST" >&2
|
|
exit 1
|
|
elif [ -z "$SYSROOT" ]; then
|
|
echo "$0: error: You need to set \$SYSROOT" >&2
|
|
exit 1
|
|
elif [ -z "$SORTIX_PORTS_DIR" ]; then
|
|
echo "$0: error: You need to set \$SORTIX_PORTS_DIR" >&2
|
|
exit 1
|
|
elif [ -z "$SORTIX_MIRROR_DIR" ]; then
|
|
echo "$0: error: You need to set \$SORTIX_MIRROR_DIR" >&2
|
|
exit 1
|
|
elif [ -z "$SORTIX_REPOSITORY_DIR" ]; then
|
|
echo "$0: error: You need to set \$SORTIX_REPOSITORY_DIR" >&2
|
|
exit 1
|
|
elif ! [ -d "$SORTIX_PORTS_DIR" ]; then
|
|
echo "Warning: No ports directory found, third party software will not be built"
|
|
exit 0
|
|
elif [ "$OPERATION" != build ]; then
|
|
: # tix isn't required for downloading and extracting
|
|
elif ! has_command tix-collection ||
|
|
! has_command tix-build ||
|
|
! has_command tix-install; then
|
|
echo "$0: error: You need to have installed Tix locally to compile ports." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Load the ports sets.
|
|
. "$(dirname -- "$0")/ports.conf"
|
|
|
|
# Create the mirror directory for downloaded archives.
|
|
mkdir -p "$SORTIX_MIRROR_DIR"
|
|
|
|
# Add the platform triplet to the binary repository path.
|
|
SORTIX_REPOSITORY_DIR="$SORTIX_REPOSITORY_DIR/$HOST"
|
|
mkdir -p "$SORTIX_REPOSITORY_DIR"
|
|
|
|
# Make paths absolute for later use.
|
|
SYSROOT=$(make_dir_path_absolute "$SYSROOT")
|
|
SORTIX_MIRROR_DIR=$(make_dir_path_absolute "$SORTIX_MIRROR_DIR")
|
|
SORTIX_PORTS_DIR=$(make_dir_path_absolute "$SORTIX_PORTS_DIR")
|
|
SORTIX_REPOSITORY_DIR=$(make_dir_path_absolute "$SORTIX_REPOSITORY_DIR")
|
|
|
|
# Decide the optimization options with which the ports will be built.
|
|
if [ -z "${OPTLEVEL+x}" ]; then OPTLEVEL="-Os -s"; fi
|
|
if [ -z "${PORTS_OPTLEVEL+x}" ]; then PORTS_OPTLEVEL="$OPTLEVEL"; fi
|
|
if [ -z "${PORTS_CFLAGS+x}" ]; then PORTS_CFLAGS="$PORTS_OPTLEVEL"; fi
|
|
if [ -z "${PORTS_CXXFLAGS+x}" ]; then PORTS_CXXFLAGS="$PORTS_OPTLEVEL"; fi
|
|
if [ -z "${CFLAGS+x}" ]; then CFLAGS="$PORTS_CFLAGS"; fi
|
|
if [ -z "${CXXFLAGS+x}" ]; then CXXFLAGS="$PORTS_CXXFLAGS"; fi
|
|
CFLAGS="$CFLAGS -Werror=format -Wno-error=format-contains-nul -Werror=implicit-function-declaration"
|
|
CXXFLAGS="$CXXFLAGS -Werror=format -Wno-error=format-contains-nul"
|
|
export CFLAGS
|
|
export CXXFLAGS
|
|
|
|
# Create the system root if absent.
|
|
mkdir -p "$SYSROOT"
|
|
|
|
# Initialize Tix package management in the system root if absent.
|
|
[ -e "$SYSROOT/tix/collection.conf" ] ||
|
|
tix-collection "$SYSROOT" create --platform=$HOST --prefix= --generation=2
|
|
|
|
# Detect all packages.
|
|
get_all_packages() {
|
|
for PACKAGE in $(ls "$SORTIX_PORTS_DIR"); do
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.info" ]; then
|
|
echo $PACKAGE
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Detect which packages are available if not specified.
|
|
if [ -z "${PACKAGES+x}" ]; then
|
|
PACKAGES=$(get_all_packages)
|
|
fi
|
|
|
|
# Simply stop if there is no packages available.
|
|
if [ -z "$PACKAGES" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Detect the build-time dependencies for a package.
|
|
get_package_dependencies_raw() {(
|
|
PACKAGE_DIR=$(echo $1 | grep -Eo '^[^\.]*')
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE_DIR/$PACKAGE_DIR.info" ]; then
|
|
(BUILD_LIBRARIES= &&
|
|
. $SORTIX_PORTS_DIR/$PACKAGE_DIR/$PACKAGE_DIR.info &&
|
|
echo "$BUILD_LIBRARIES")
|
|
else
|
|
for set in $sets; do
|
|
if [ $set = $1 ]; then
|
|
echo $(eval echo \$set_$set)
|
|
fi
|
|
done
|
|
fi
|
|
)}
|
|
|
|
# Include the recursive dependencies if requested.
|
|
# TODO: This algorithm scales extremely poorly.
|
|
get_package_dependencies_recursive() {
|
|
for DEPENDENCY in $(get_package_dependencies_raw $1); do
|
|
WANT=false
|
|
if [ "$2" = "!!" ]; then
|
|
WANT=true
|
|
else
|
|
case "$DEPENDENCY" in
|
|
*"?") ;;
|
|
*) WANT=true ;;
|
|
esac
|
|
fi
|
|
if $WANT; then
|
|
DEPENDENCY=$(echo "$DEPENDENCY" | tr -d '?')
|
|
PACKAGE_DIR=$(echo "$DEPENDENCY" | grep -Eo '^[^\.]*')
|
|
# Optional dependencies might not exist yet.
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE_DIR/$PACKAGE_DIR.info" ]; then
|
|
echo "$DEPENDENCY"
|
|
get_package_dependencies_recursive "$DEPENDENCY" "$2"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
PACKAGES=$(for PACKAGE in $PACKAGES; do
|
|
RECURSION=$(echo "$PACKAGE" | grep -Eo '!*$')
|
|
PACKAGE=$(echo "$PACKAGE" | grep -Eo '^[^!]*')
|
|
# TODO: Better way of detecting a port is a set.
|
|
PACKAGE_DIR=$(echo "$PACKAGE" | grep -Eo '^[^\.]*')
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE_DIR/$PACKAGE_DIR.info" ]; then
|
|
echo "$PACKAGE"
|
|
fi
|
|
if [ -n "$RECURSION" ]; then
|
|
get_package_dependencies_recursive "$PACKAGE" "$RECURSION"
|
|
fi
|
|
done | sort -u | tr '\n' ' ')
|
|
|
|
# Detect the build-time dependencies for a package with missing optional
|
|
# dependencies removed.
|
|
get_package_dependencies() {(
|
|
PRINTED_ANY=false
|
|
for DEPENDENCY in $(get_package_dependencies_raw $1); do
|
|
if [ "$DEPENDENCY" != "${DEPENDENCY%\?}" ]; then
|
|
DEPENDENCY="${DEPENDENCY%\?}"
|
|
FOUND=false
|
|
for PACKAGE in $PACKAGES; do
|
|
if [ "$PACKAGE" = "$DEPENDENCY" ]; then
|
|
FOUND=true
|
|
break
|
|
fi
|
|
done
|
|
if ! $FOUND; then
|
|
continue
|
|
fi
|
|
fi
|
|
if $PRINTED_ANY; then printf ' '; fi
|
|
printf "%s" "$DEPENDENCY"
|
|
PRINTED_ANY=true
|
|
done
|
|
if $PRINTED_ANY; then echo; fi
|
|
)}
|
|
|
|
# Decide the order the packages are built in according to their dependencies.
|
|
PACKAGES="$(echo "$PACKAGES" | tr ' ' '\n' | sort -R)"
|
|
DEPENDENCY_MAKEFILE=$(mktemp)
|
|
(for PACKAGE in $PACKAGES; do
|
|
echo "$PACKAGE: $(get_package_dependencies $PACKAGE)"
|
|
echo " @echo $PACKAGE"
|
|
done;
|
|
printf ".PHONY:"
|
|
for PACKAGE in $PACKAGES; do
|
|
printf " $PACKAGE"
|
|
done;
|
|
echo) > "$DEPENDENCY_MAKEFILE"
|
|
|
|
BUILD_LIST=$(unset MAKE;
|
|
unset MFLAGS;
|
|
unset MAKEFLAGS;
|
|
make -Bs -f "$DEPENDENCY_MAKEFILE" $PACKAGES)
|
|
rm -f "$DEPENDENCY_MAKEFILE"
|
|
PACKAGES="$BUILD_LIST"
|
|
|
|
# TODO: This adds another decompression and compression to the build time, this
|
|
# should be done as a tix post installation step. Also this might miss
|
|
# programs in unusual locations, so need a thorough search and strip.
|
|
strip_tix() {
|
|
DIR=$(mktemp -d)
|
|
tar -C "$DIR" -xf "$1"
|
|
$HOST-strip -d "$DIR/data/bin/"* 2>/dev/null || true
|
|
$HOST-strip -d "$DIR/data/lib/"* 2>/dev/null || true
|
|
$HOST-strip -d "$DIR/data/libexec"* 2>/dev/null || true
|
|
$HOST-strip -d "$DIR/data/libexec/git-core/"* 2>/dev/null || true
|
|
$HOST-strip -d "$DIR/data/sbin/"* 2>/dev/null || true
|
|
(cd "$DIR" && tar --numeric-owner --owner=0 --group=0 -cJf port.tar.tix.xz tix data)
|
|
cp "$DIR/port.tar.tix.xz" "$1"
|
|
rm -rf "$DIR"
|
|
}
|
|
|
|
announce() {
|
|
cat << EOF
|
|
================================================================================
|
|
==== $1
|
|
================================================================================
|
|
EOF
|
|
}
|
|
|
|
download_archive_from_url() {(
|
|
PACKAGE="$1"
|
|
ARCHIVE="$2"
|
|
URL="$3"
|
|
SHA256SUM="$4"
|
|
mkdir -p "$SORTIX_MIRROR_DIR/$PACKAGE"
|
|
if [ ! -e "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.sha256sum" ]; then
|
|
announce "Downloading $1: $ARCHIVE"
|
|
(if echo "$URL" | grep -Eq '^[a-z][a-z0-9.+-]*://'; then
|
|
if ! wget -O "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.untrusted" -- "$URL"; then
|
|
echo "warning: Failed to download $ARCHIVE from $URL" >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
if ! cp -- "$URL" "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.untrusted"; then
|
|
echo "warning: Failed to copy $ARCHIVE from $URL" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
if ! echo "$SHA256SUM $SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.untrusted" | sha256sum -c; then
|
|
echo "warning: Wrong sha256sum after downloading $ARCHIVE from $URL" >&2
|
|
exit 1
|
|
fi
|
|
mv "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.untrusted" "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE"
|
|
echo "$URL" > "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.url"
|
|
echo "$SHA256SUM $ARCHIVE" > "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.sha256sum.new"
|
|
mv "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.sha256sum.new" \
|
|
"$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.sha256sum"
|
|
) || (
|
|
rm -f "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.untrusted"
|
|
rm -f "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.url"
|
|
rm -f "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.sha56sum.new"
|
|
rm -f "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE.sha56sum"
|
|
exit 1
|
|
)
|
|
fi
|
|
)}
|
|
|
|
download_archive() {(
|
|
PACKAGE="$1"
|
|
ARCHIVE="$2"
|
|
UPSTREAM_SITE="$3"
|
|
UPSTREAM_ARCHIVE="$4"
|
|
SHA256SUM="$5"
|
|
if ! ([ -n "$SORTIX_PORTS_MIRROR" ] &&
|
|
download_archive_from_url "$PACKAGE" "$ARCHIVE" "$SORTIX_PORTS_MIRROR/$PACKAGE/$ARCHIVE" "$SHA256SUM") &&
|
|
! download_archive_from_url "$PACKAGE" "$ARCHIVE" "$UPSTREAM_SITE/$UPSTREAM_ARCHIVE" "$SHA256SUM"; then
|
|
echo "error: Failed to download $ARCHIVE with sha256sum $SHA256SUM" >&2
|
|
false
|
|
fi
|
|
)}
|
|
|
|
download_package() {(
|
|
PACKAGE="$1"
|
|
unset ARCHIVE
|
|
unset ARCHIVE_2
|
|
. "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.info"
|
|
if [ -n "$ARCHIVE" ]; then
|
|
download_archive "$PACKAGE" "$ARCHIVE" "$UPSTREAM_SITE" "$UPSTREAM_ARCHIVE" "$SHA256SUM"
|
|
if [ -n "$ARCHIVE_2" ]; then
|
|
download_archive "$PACKAGE" "$ARCHIVE_2" "$UPSTREAM_SITE_2" "$UPSTREAM_ARCHIVE_2" "$SHA256SUM_2"
|
|
fi
|
|
fi
|
|
)}
|
|
|
|
desired_version() {(
|
|
#unset ARCHIVE
|
|
#unset ARCHIVE_2
|
|
#. "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.info"
|
|
VERSION_STAMP="$NAME"
|
|
if [ -n "$ARCHIVE" ]; then
|
|
VERSION_STAMP="$VERSION_STAMP.$VERSION.$SHA256SUM"
|
|
if [ -n "$ARCHIVE_2" ]; then
|
|
VERSION_STAMP="$VERSION_STAMP.$VERSION_2.$SHA256SUM_2"
|
|
fi
|
|
fi
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.patch" ]; then
|
|
VERSION_STAMP="$VERSION_STAMP.$(cat "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.patch" | sha256sum | grep -Eo '^[^ ]*')"
|
|
fi
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.execpatch" ]; then
|
|
VERSION_STAMP="$VERSION_STAMP.$(cat "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.execpatch" | sha256sum | grep -Eo '^[^ ]*')"
|
|
fi
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.normalize" ]; then
|
|
VERSION_STAMP="$VERSION_STAMP.$(cat "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.normalize" | sha256sum | grep -Eo '^[^ ]*')"
|
|
fi
|
|
echo "$VERSION_STAMP"
|
|
)}
|
|
|
|
extract_package() {(
|
|
PACKAGE="$1"
|
|
VERSION_STAMP="$2"
|
|
unset ARCHIVE
|
|
unset ARCHIVE_2
|
|
unset NEED_WRITABLE
|
|
. "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.info"
|
|
VERSION_STAMP="$(desired_version)"
|
|
if [ ! -e "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.version" ] ||
|
|
[ "$(cat "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.version")" != "$VERSION_STAMP" ] ||
|
|
[ ! -e "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.version" ]; then
|
|
echo "$VERSION_STAMP" > "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.version.new"
|
|
rm -rf "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE"
|
|
mkdir "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE"
|
|
if [ -n "$ARCHIVE" ]; then
|
|
announce "Extracting $1: $ARCHIVE"
|
|
tar -C "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE" -xf "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE" --strip-components=1
|
|
if [ -n "$ARCHIVE_2" ]; then
|
|
announce "Extracting $1: $ARCHIVE_2"
|
|
tar -C "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE" -xf "$SORTIX_MIRROR_DIR/$PACKAGE/$ARCHIVE_2" --strip-components=1
|
|
fi
|
|
fi
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.patch" ]; then
|
|
patch -d "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE" -p1 < "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.patch"
|
|
fi
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.execpatch" ]; then
|
|
tix-execpatch --directory "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE" "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.execpatch"
|
|
fi
|
|
if [ -f "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.normalize" ]; then
|
|
tix-rmpatch --directory "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE" "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.normalize"
|
|
fi
|
|
if [ "$NEED_WRITABLE" != true ]; then
|
|
find "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE" '!' -type d -exec chmod -w '{}' +
|
|
fi
|
|
mv "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.version.new" "$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.version"
|
|
fi
|
|
)}
|
|
|
|
# Build all the packages (if needed) and otherwise install them.
|
|
for PACKAGE in $PACKAGES; do
|
|
SOURCE_PACKAGE=$( (SOURCE_PACKAGE= &&
|
|
. $SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE.info &&
|
|
echo "$SOURCE_PACKAGE") )
|
|
# TODO: clean support.
|
|
|
|
if [ ! -f "$SORTIX_REPOSITORY_DIR/$PACKAGE.tix.tar.xz" ] ||
|
|
[ "$OPERATION" != build ] ; then
|
|
|
|
# download
|
|
if [ -n "$SOURCE_PACKAGE" ]; then
|
|
download_package "$SOURCE_PACKAGE"
|
|
fi
|
|
download_package "$PACKAGE"
|
|
if [ "$OPERATION" = download ]; then continue; fi
|
|
|
|
# extract
|
|
if [ -n "$SOURCE_PACKAGE" ]; then
|
|
extract_package "$SOURCE_PACKAGE"
|
|
fi
|
|
extract_package "$PACKAGE"
|
|
if [ "$OPERATION" = extract ]; then continue; fi
|
|
|
|
# build
|
|
announce "Building $PACKAGE"
|
|
tix-build \
|
|
--sysroot="$SYSROOT" \
|
|
--host=$HOST \
|
|
--prefix= \
|
|
--destination="$SORTIX_REPOSITORY_DIR" \
|
|
--generation=2 \
|
|
${SOURCE_PACKAGE:+--source-package "$SORTIX_PORTS_DIR/$SOURCE_PACKAGE/$SOURCE_PACKAGE"} \
|
|
"$SORTIX_PORTS_DIR/$PACKAGE/$PACKAGE"
|
|
strip_tix "$SORTIX_REPOSITORY_DIR/$PACKAGE.tix.tar.xz"
|
|
fi
|
|
announce "Installing $PACKAGE"
|
|
tix-install \
|
|
--collection="$SYSROOT" \
|
|
--reinstall \
|
|
"$SORTIX_REPOSITORY_DIR/$PACKAGE.tix.tar.xz"
|
|
done
|