diff --git a/.gitignore b/.gitignore index 9fb3bd8ed6..8b4c93be31 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ scripts/.vagrant/ # Built *.deb files. /debs/ +/output/ # Preinstalled build tools. /build-tools/ diff --git a/build-all.sh b/build-all.sh index bd5f2f8221..78f0a8de18 100755 --- a/build-all.sh +++ b/build-all.sh @@ -31,7 +31,7 @@ case "$option" in a) TERMUX_ARCH="$OPTARG";; d) TERMUX_DEBUG_BUILD='-d';; i) TERMUX_INSTALL_DEPS='-i';; - o) TERMUX_DEBDIR="$(realpath -m "$OPTARG")";; + o) TERMUX_OUTPUT_DIR="$(realpath -m "$OPTARG")";; h) _show_usage;; *) _show_usage >&2 ;; esac @@ -73,7 +73,7 @@ while read -r PKG PKG_DIR; do echo -n "Building $PKG... " BUILD_START=$(date "+%s") bash -x "$BUILDSCRIPT" -a "$TERMUX_ARCH" $TERMUX_DEBUG_BUILD \ - ${TERMUX_DEBDIR+-o $TERMUX_DEBDIR} $TERMUX_INSTALL_DEPS "$PKG_DIR" \ + ${TERMUX_OUTPUT_DIR+-o $TERMUX_OUTPUT_DIR} $TERMUX_INSTALL_DEPS "$PKG_DIR" \ > "$BUILDALL_DIR"/"${PKG}".out 2> "$BUILDALL_DIR"/"${PKG}".err BUILD_END=$(date "+%s") BUILD_SECONDS=$(( BUILD_END - BUILD_START )) diff --git a/build-package.sh b/build-package.sh index 0bbf608343..f6f9620f43 100755 --- a/build-package.sh +++ b/build-package.sh @@ -219,8 +219,12 @@ termux_step_create_subpkg_debscripts() { } # Create all subpackages. Run from termux_step_massage -# shellcheck source=scripts/build/termux_create_subpackages.sh -source "$TERMUX_SCRIPTDIR/scripts/build/termux_create_subpackages.sh" +# shellcheck source=scripts/build/termux_create_debian_subpackages.sh +source "$TERMUX_SCRIPTDIR/scripts/build/termux_create_debian_subpackages.sh" + +# Create all subpackages. Run from termux_step_massage +# shellcheck source=scripts/build/termux_create_pacman_subpackages.sh +source "$TERMUX_SCRIPTDIR/scripts/build/termux_create_pacman_subpackages.sh" # Function to run various cleanup/fixes # shellcheck source=scripts/build/termux_step_massage.sh @@ -231,18 +235,23 @@ termux_step_post_massage() { return } -# Create data.tar.gz with files to package. Not to be overridden by package scripts. -# shellcheck source=scripts/build/termux_step_create_datatar.sh -source "$TERMUX_SCRIPTDIR/scripts/build/termux_step_create_datatar.sh" - # Hook function to create {pre,post}install, {pre,post}rm-scripts and similar termux_step_create_debscripts() { return } +# Convert Debian maintainer scripts into pacman-compatible installation hooks. +# This is used only when creating pacman packages. +# shellcheck source=scripts/build/termux_step_create_pacman_install_hook.sh +source "$TERMUX_SCRIPTDIR/scripts/build/termux_step_create_pacman_install_hook.sh" + # Create the build deb file. Not to be overridden by package scripts. -# shellcheck source=scripts/build/termux_step_create_debfile.sh -source "$TERMUX_SCRIPTDIR/scripts/build/termux_step_create_debfile.sh" +# shellcheck source=scripts/build/termux_step_create_debian_package.sh +source "$TERMUX_SCRIPTDIR/scripts/build/termux_step_create_debian_package.sh" + +# Create the build .pkg.tar.xz file. Not to be overridden by package scripts. +# shellcheck source=scripts/build/termux_step_create_pacman_package.sh +source "$TERMUX_SCRIPTDIR/scripts/build/termux_step_create_pacman_package.sh" # Finish the build. Not to be overridden by package scripts. # shellcheck source=scripts/build/termux_step_finish_build.sh @@ -280,41 +289,78 @@ _show_usage() { echo " -I Download and extract dependencies instead of building them, keep existing $TERMUX_BASE_DIR files." echo " -q Quiet build." echo " -s Skip dependency check." - echo " -o Specify deb directory. Default: debs/." + echo " -o Specify directory where to put built packages. Default: output/." + echo " --format Specify package output format (debian, pacman)." exit 1 } -while getopts :a:hdDfiIqso:c option; do - case "$option" in - a) - if [ "$TERMUX_ON_DEVICE_BUILD" = "true" ]; then - termux_error_exit "./build-package.sh: option '-a' is not available for on-device builds" +declare -a PACKAGE_LIST=() + +if [ "$#" -lt 1 ]; then _show_usage; fi +while (($# >= 1)); do + case "$1" in + --) shift 1; break;; + -h|--help) _show_usage;; + --format) + if [ $# -ge 2 ]; then + shift 1 + if [ -z "$1" ]; then + termux_error_exit "./build-package.sh: argument to '--format' should not be empty" + fi + + case "$1" in + debian|pacman) TERMUX_PACKAGE_FORMAT="$1";; + *) termux_error_exit "./build-package.sh: only 'debian' and 'pacman' formats are supported";; + esac else - export TERMUX_ARCH="$OPTARG" + termux_error_exit "./build-package.sh: option '--format' requires an argument" fi ;; - h) _show_usage;; - d) export TERMUX_DEBUG_BUILD=true;; - D) TERMUX_IS_DISABLED=true;; - f) TERMUX_FORCE_BUILD=true;; - i) + -a) + if [ $# -ge 2 ]; then + shift 1 + if [ -z "$1" ]; then + termux_error_exit "Argument to '-a' should not be empty." + fi + if [ "$TERMUX_ON_DEVICE_BUILD" = "true" ]; then + termux_error_exit "./build-package.sh: option '-a' is not available for on-device builds" + else + export TERMUX_ARCH="$1" + fi + else + termux_error_exit "./build-package.sh: option '-a' requires an argument" + fi + ;; + -d) export TERMUX_DEBUG_BUILD=true;; + -D) TERMUX_IS_DISABLED=true;; + -f) TERMUX_FORCE_BUILD=true;; + -i) if [ "$TERMUX_ON_DEVICE_BUILD" = "true" ]; then termux_error_exit "./build-package.sh: option '-i' is not available for on-device builds" else export TERMUX_INSTALL_DEPS=true fi ;; - I) export TERMUX_INSTALL_DEPS=true && export TERMUX_NO_CLEAN=true;; - q) export TERMUX_QUIET_BUILD=true;; - s) export TERMUX_SKIP_DEPCHECK=true;; - o) TERMUX_DEBDIR=$(realpath -m "$OPTARG");; - c) TERMUX_CONTINUE_BUILD="true";; - ?) termux_error_exit "./build-package.sh: illegal option -$OPTARG";; + -I) export TERMUX_INSTALL_DEPS=true && export TERMUX_NO_CLEAN=true;; + -q) export TERMUX_QUIET_BUILD=true;; + -s) export TERMUX_SKIP_DEPCHECK=true;; + -o) + if [ $# -ge 2 ]; then + shift 1 + if [ -z "$1" ]; then + termux_error_exit "./build-package.sh: argument to '-o' should not be empty" + fi + TERMUX_OUTPUT_DIR=$(realpath -m "$1") + else + termux_error_exit "./build-package.sh: option '-o' requires an argument" + fi + ;; + -c) TERMUX_CONTINUE_BUILD=true;; + -*) termux_error_exit "./build-package.sh: illegal option '$1'";; + *) PACKAGE_LIST+=("$1");; esac + shift 1 done -shift $((OPTIND-1)) - -if [ "$#" -lt 1 ]; then _show_usage; fi unset -f _show_usage if [ "${TERMUX_INSTALL_DEPS-false}" = "true" ]; then @@ -338,7 +384,7 @@ if [ "${TERMUX_INSTALL_DEPS-false}" = "true" ]; then } fi -while (($# > 0)); do +for ((i=0; i<${#PACKAGE_LIST[@]}; i++)); do # Following commands must be executed under lock to prevent running # multiple instances of "./build-package.sh". # @@ -354,18 +400,19 @@ while (($# > 0)); do for arch in 'aarch64' 'arm' 'i686' 'x86_64'; do env TERMUX_ARCH="$arch" TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh \ ${TERMUX_FORCE_BUILD+-f} ${TERMUX_INSTALL_DEPS+-i} ${TERMUX_IS_DISABLED+-D} \ - ${TERMUX_DEBUG_BUILD+-d} ${TERMUX_DEBDIR+-o $TERMUX_DEBDIR} "$1" + ${TERMUX_DEBUG_BUILD+-d} ${TERMUX_OUTPUT_DIR+-o $TERMUX_OUTPUT_DIR} \ + --format ${TERMUX_PACKAGE_FORMAT} "${PACKAGE_LIST[i]}" done exit fi # Check the package to build: - TERMUX_PKG_NAME=$(basename "$1") - if [[ $1 == *"/"* ]]; then + TERMUX_PKG_NAME=$(basename "${PACKAGE_LIST[i]}") + if [[ ${PACKAGE_LIST[i]} == *"/"* ]]; then # Path to directory which may be outside this repo: - if [ ! -d "$1" ]; then termux_error_exit "'$1' seems to be a path but is not a directory"; fi + if [ ! -d "${PACKAGE_LIST[i]}" ]; then termux_error_exit "'${PACKAGE_LIST[i]}' seems to be a path but is not a directory"; fi export TERMUX_PKG_BUILDER_DIR - TERMUX_PKG_BUILDER_DIR=$(realpath "$1") + TERMUX_PKG_BUILDER_DIR=$(realpath "${PACKAGE_LIST[i]}") else # Package name: if [ -n "${TERMUX_IS_DISABLED=""}" ]; then @@ -434,10 +481,13 @@ while (($# > 0)); do cd "$TERMUX_PKG_MASSAGEDIR/$TERMUX_PREFIX" termux_step_post_massage cd "$TERMUX_PKG_MASSAGEDIR" - termux_step_create_datatar - termux_step_create_debfile + if [ "$TERMUX_PACKAGE_FORMAT" = "debian" ]; then + termux_step_create_debian_package + elif [ "$TERMUX_PACKAGE_FORMAT" = "pacman" ]; then + termux_step_create_pacman_package + else + termux_error_exit "Unknown packaging format '$TERMUX_PACKAGE_FORMAT'." + fi termux_step_finish_build ) 5< "$TERMUX_BUILD_LOCK_FILE" - - shift 1 done diff --git a/scripts/build/termux_create_subpackages.sh b/scripts/build/termux_create_debian_subpackages.sh similarity index 96% rename from scripts/build/termux_create_subpackages.sh rename to scripts/build/termux_create_debian_subpackages.sh index 17b3cea950..14e9f09487 100644 --- a/scripts/build/termux_create_subpackages.sh +++ b/scripts/build/termux_create_debian_subpackages.sh @@ -1,4 +1,4 @@ -termux_create_subpackages() { +termux_create_debian_subpackages() { # Sub packages: if [ "$TERMUX_PKG_NO_STATICSPLIT" = "false" ] && [[ -n $(shopt -s globstar; shopt -s nullglob; echo lib/**/*.a) ]]; then # Add virtual -static sub package if there are include files: @@ -91,7 +91,7 @@ termux_create_subpackages() { tar -cJf "$SUB_PKG_PACKAGE_DIR/control.tar.xz" -H gnu . # Create the actual .deb file: - TERMUX_SUBPKG_DEBFILE=$TERMUX_DEBDIR/${SUB_PKG_NAME}${DEBUG}_${TERMUX_PKG_FULLVERSION}_${SUB_PKG_ARCH}.deb + TERMUX_SUBPKG_DEBFILE=$TERMUX_OUTPUT_DIR/${SUB_PKG_NAME}${DEBUG}_${TERMUX_PKG_FULLVERSION}_${SUB_PKG_ARCH}.deb test ! -f "$TERMUX_COMMON_CACHEDIR/debian-binary" && echo "2.0" > "$TERMUX_COMMON_CACHEDIR/debian-binary" ar cr "$TERMUX_SUBPKG_DEBFILE" \ "$TERMUX_COMMON_CACHEDIR/debian-binary" \ diff --git a/scripts/build/termux_create_pacman_subpackages.sh b/scripts/build/termux_create_pacman_subpackages.sh new file mode 100644 index 0000000000..a03d8f973a --- /dev/null +++ b/scripts/build/termux_create_pacman_subpackages.sh @@ -0,0 +1,169 @@ +termux_create_pacman_subpackages() { + # Sub packages: + if [ "$TERMUX_PKG_NO_STATICSPLIT" = "false" ] && [[ -n $(shopt -s globstar; shopt -s nullglob; echo lib/**/*.a) ]]; then + # Add virtual -static sub package if there are include files: + local _STATIC_SUBPACKAGE_FILE=$TERMUX_PKG_TMPDIR/${TERMUX_PKG_NAME}-static.subpackage.sh + echo TERMUX_SUBPKG_INCLUDE=\"lib/**/*.a lib/**/*.la\" > "$_STATIC_SUBPACKAGE_FILE" + echo "TERMUX_SUBPKG_DESCRIPTION=\"Static libraries for ${TERMUX_PKG_NAME}\"" >> "$_STATIC_SUBPACKAGE_FILE" + fi + + # Now build all sub packages + rm -Rf "$TERMUX_TOPDIR/$TERMUX_PKG_NAME/subpackages" + for subpackage in $TERMUX_PKG_BUILDER_DIR/*.subpackage.sh $TERMUX_PKG_TMPDIR/*subpackage.sh; do + test ! -f "$subpackage" && continue + local SUB_PKG_NAME + SUB_PKG_NAME=$(basename "$subpackage" .subpackage.sh) + # Default value is same as main package, but sub package may override: + local TERMUX_SUBPKG_PLATFORM_INDEPENDENT=$TERMUX_PKG_PLATFORM_INDEPENDENT + local SUB_PKG_DIR=$TERMUX_TOPDIR/$TERMUX_PKG_NAME/subpackages/$SUB_PKG_NAME + local TERMUX_SUBPKG_ESSENTIAL=false + local TERMUX_SUBPKG_BREAKS="" + local TERMUX_SUBPKG_DEPENDS="" + local TERMUX_SUBPKG_CONFLICTS="" + local TERMUX_SUBPKG_REPLACES="" + local TERMUX_SUBPKG_CONFFILES="" + local TERMUX_SUBPKG_DEPEND_ON_PARENT="" + local SUB_PKG_MASSAGE_DIR=$SUB_PKG_DIR/massage/$TERMUX_PREFIX + local SUB_PKG_PACKAGE_DIR=$SUB_PKG_DIR/package + mkdir -p "$SUB_PKG_MASSAGE_DIR" "$SUB_PKG_PACKAGE_DIR" + + # shellcheck source=/dev/null + source "$subpackage" + + # Allow globstar (i.e. './**/') patterns. + shopt -s globstar + for includeset in $TERMUX_SUBPKG_INCLUDE; do + local _INCLUDE_DIRSET + _INCLUDE_DIRSET=$(dirname "$includeset") + test "$_INCLUDE_DIRSET" = "." && _INCLUDE_DIRSET="" + + if [ -e "$includeset" ] || [ -L "$includeset" ]; then + # Add the -L clause to handle relative symbolic links: + mkdir -p "$SUB_PKG_MASSAGE_DIR/$_INCLUDE_DIRSET" + mv "$includeset" "$SUB_PKG_MASSAGE_DIR/$_INCLUDE_DIRSET" + fi + done + shopt -u globstar + + local SUB_PKG_ARCH=$TERMUX_ARCH + [ "$TERMUX_SUBPKG_PLATFORM_INDEPENDENT" = "true" ] && SUB_PKG_ARCH=any + + cd "$SUB_PKG_DIR/massage" + local SUB_PKG_INSTALLSIZE + SUB_PKG_INSTALLSIZE=$(du -bs . | cut -f 1) + + local BUILD_DATE + BUILD_DATE=$(date +%s) + + local PKG_DEPS_SPC=" ${TERMUX_PKG_DEPENDS//,/} " + if [ -z "$TERMUX_SUBPKG_DEPEND_ON_PARENT" ] && [ "${PKG_DEPS_SPC/ $SUB_PKG_NAME /}" = "$PKG_DEPS_SPC" ]; then + # Does pacman supports versioned dependencies? + #TERMUX_SUBPKG_DEPENDS+=", $TERMUX_PKG_NAME (= $TERMUX_PKG_FULLVERSION)" + TERMUX_SUBPKG_DEPENDS+=", $TERMUX_PKG_NAME" + elif [ "$TERMUX_SUBPKG_DEPEND_ON_PARENT" = unversioned ]; then + TERMUX_SUBPKG_DEPENDS+=", $TERMUX_PKG_NAME" + elif [ "$TERMUX_SUBPKG_DEPEND_ON_PARENT" = deps ]; then + TERMUX_SUBPKG_DEPENDS+=", $TERMUX_PKG_DEPENDS" + fi + + # Package metadata. + { + echo "pkgname = $SUB_PKG_NAME" + echo "pkgbase = $TERMUX_PKG_NAME" + if [ -n "$TERMUX_PKG_REVISION" ]; then + echo "pkgver = $TERMUX_PKG_VERSION-${TERMUX_PKG_REVISION}" + else + echo "pkgver = $TERMUX_PKG_VERSION-0" + fi + echo "pkgdesc = $(echo "$TERMUX_SUBPKG_DESCRIPTION" | tr '\n' ' ')" + echo "url = $TERMUX_PKG_HOMEPAGE" + echo "builddate = $BUILD_DATE" + echo "packager = $TERMUX_PKG_MAINTAINER" + echo "size = $SUB_PKG_INSTALLSIZE" + echo "arch = $SUB_PKG_ARCH" + + if [ -n "$TERMUX_SUBPKG_REPLACES" ]; then + tr ',' '\n' <<< "$TERMUX_SUBPKG_REPLACES" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "replaces = %s\n", $1 }' + fi + + if [ -n "$TERMUX_SUBPKG_CONFLICTS" ]; then + tr ',' '\n' <<< "$TERMUX_SUBPKG_CONFLICTS" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "conflict = %s\n", $1 }' + fi + + if [ -n "$TERMUX_SUBPKG_BREAKS" ]; then + tr ',' '\n' <<< "$TERMUX_SUBPKG_BREAKS" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "conflict = %s\n", $1 }' + fi + + if [ -n "$TERMUX_SUBPKG_DEPENDS" ]; then + tr ',' '\n' <<< "${TERMUX_SUBPKG_DEPENDS/#, /}" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "depend = %s\n", $1 }' + fi + + if [ -n "$TERMUX_SUBPKG_CONFFILES" ]; then + tr ',' '\n' <<< "$TERMUX_SUBPKG_CONFFILES" | awk '{ printf "backup = '"${TERMUX_PREFIX:1}"'/%s\n", $1 }' + fi + } > .PKGINFO + + # Build metadata. + { + echo "format = 2" + echo "pkgname = $SUB_PKG_NAME" + echo "pkgbase = $TERMUX_PKG_NAME" + if [ -n "$TERMUX_PKG_REVISION" ]; then + echo "pkgver = $TERMUX_PKG_VERSION-${TERMUX_PKG_REVISION}" + else + echo "pkgver = $TERMUX_PKG_VERSION-0" + fi + echo "pkgarch = $SUB_PKG_ARCH" + echo "packager = $TERMUX_PKG_MAINTAINER" + echo "builddate = $BUILD_DATE" + } > .BUILDINFO + + # Write package installation hooks. + termux_step_create_subpkg_debscripts + termux_step_create_pacman_install_hook + + # Configuring the selection of a copress for a batch. + local COMPRESS + local PKG_FORMAT + case $TERMUX_PACMAN_PACKAGE_COMPRESSION in + "gzip") + COMPRESS=(gzip -c -f -n) + PKG_FORMAT="gz";; + "bzip2") + COMPRESS=(bzip2 -c -f) + PKG_FORMAT="bz2";; + "zstd") + COMPRESS=(zstd -c -z -q -) + PKG_FORMAT="zst";; + "lrzip") + COMPRESS=(lrzip -q) + PKG_FORMAT="lrz";; + "lzop") + COMPRESS=(lzop -q) + PKG_FORMAT="lzop";; + "lz4") + COMPRESS=(lz4 -q) + PKG_FORMAT="lz4";; + "lzip") + COMPRESS=(lzip -c -f) + PKG_FORMAT="lz";; + "xz" | *) + COMPRESS=(xz -c -z -) + PKG_FORMAT="xz";; + esac + + # Create the actual .pkg file: + local TERMUX_SUBPKG_PACMAN_FILE=$TERMUX_OUTPUT_DIR/${SUB_PKG_NAME}${DEBUG}-${TERMUX_PKG_FULLVERSION}-${SUB_PKG_ARCH}.pkg.tar.${PKG_FORMAT} + shopt -s dotglob globstar + printf '%s\0' **/* | bsdtar -cnf - --format=mtree \ + --options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link' \ + --null --files-from - --exclude .MTREE | \ + gzip -c -f -n > .MTREE + printf '%s\0' **/* | bsdtar --no-fflags -cnf - --null --files-from - | \ + $COMPRESS > "$TERMUX_SUBPKG_PACMAN_FILE" + shopt -u dotglob globstar + + # Go back to main package: + cd "$TERMUX_PKG_MASSAGEDIR/$TERMUX_PREFIX" + done +} diff --git a/scripts/build/termux_step_create_datatar.sh b/scripts/build/termux_step_create_datatar.sh deleted file mode 100644 index 2f0386087a..0000000000 --- a/scripts/build/termux_step_create_datatar.sh +++ /dev/null @@ -1,8 +0,0 @@ -termux_step_create_datatar() { - if [ "$TERMUX_PKG_METAPACKAGE" = "true" ]; then - # Metapackage doesn't have data inside. - rm -rf data - fi - - tar -cJf "$TERMUX_PKG_PACKAGEDIR/data.tar.xz" -H gnu . -} diff --git a/scripts/build/termux_step_create_debfile.sh b/scripts/build/termux_step_create_debian_package.sh similarity index 87% rename from scripts/build/termux_step_create_debfile.sh rename to scripts/build/termux_step_create_debian_package.sh index b5253d3dec..d8e6163b79 100644 --- a/scripts/build/termux_step_create_debfile.sh +++ b/scripts/build/termux_step_create_debian_package.sh @@ -1,4 +1,10 @@ -termux_step_create_debfile() { +termux_step_create_debian_package() { + if [ "$TERMUX_PKG_METAPACKAGE" = "true" ]; then + # Metapackage doesn't have data inside. + rm -rf data + fi + tar -cJf "$TERMUX_PKG_PACKAGEDIR/data.tar.xz" -H gnu . + # Get install size. This will be written as the "Installed-Size" deb field so is measured in 1024-byte blocks: local TERMUX_PKG_INSTALLSIZE TERMUX_PKG_INSTALLSIZE=$(du -sk . | cut -f 1) @@ -38,7 +44,7 @@ termux_step_create_debfile() { tar -cJf "$TERMUX_PKG_PACKAGEDIR/control.tar.xz" -H gnu . test ! -f "$TERMUX_COMMON_CACHEDIR/debian-binary" && echo "2.0" > "$TERMUX_COMMON_CACHEDIR/debian-binary" - TERMUX_PKG_DEBFILE=$TERMUX_DEBDIR/${TERMUX_PKG_NAME}${DEBUG}_${TERMUX_PKG_FULLVERSION}_${TERMUX_ARCH}.deb + TERMUX_PKG_DEBFILE=$TERMUX_OUTPUT_DIR/${TERMUX_PKG_NAME}${DEBUG}_${TERMUX_PKG_FULLVERSION}_${TERMUX_ARCH}.deb # Create the actual .deb file: ar cr "$TERMUX_PKG_DEBFILE" \ "$TERMUX_COMMON_CACHEDIR/debian-binary" \ diff --git a/scripts/build/termux_step_create_pacman_install_hook.sh b/scripts/build/termux_step_create_pacman_install_hook.sh new file mode 100644 index 0000000000..a80d5cd25a --- /dev/null +++ b/scripts/build/termux_step_create_pacman_install_hook.sh @@ -0,0 +1,32 @@ +termux_step_create_pacman_install_hook() { + # Unlike dpkg, pacman doesn't use separate scripts for package installation + # hooks. Instead it uses a single script with functions. + if [ -f "./preinst" ]; then + echo "pre_install() {" >> .INSTALL + cat preinst | grep -v '^#' >> .INSTALL + echo "}" >> .INSTALL + rm -f preinst + fi + if [ -f "./postinst" ]; then + echo "post_install() {" >> .INSTALL + cat postinst | grep -v '^#' >> .INSTALL + echo "}" >> .INSTALL + rm -f postinst + fi + if [ -f "./prerm" ]; then + echo "pre_remove() {" >> .INSTALL + cat prerm | grep -v '^#' >> .INSTALL + echo "}" >> .INSTALL + rm -f prerm + fi + if [ -f "./postrm" ]; then + echo "post_remove() {" >> .INSTALL + cat postrm | grep -v '^#' >> .INSTALL + echo "}" >> .INSTALL + rm -f postrm + fi + + # Conversion from dpkg triggers to libalpm hooks is not supported + # currently. Delete unneeded triggers file. + rm -f triggers +} diff --git a/scripts/build/termux_step_create_pacman_package.sh b/scripts/build/termux_step_create_pacman_package.sh new file mode 100644 index 0000000000..5115a18a48 --- /dev/null +++ b/scripts/build/termux_step_create_pacman_package.sh @@ -0,0 +1,128 @@ +termux_step_create_pacman_package() { + local TERMUX_PKG_INSTALLSIZE + TERMUX_PKG_INSTALLSIZE=$(du -bs . | cut -f 1) + + # From here on TERMUX_ARCH is set to "all" if TERMUX_PKG_PLATFORM_INDEPENDENT is set by the package + [ "$TERMUX_PKG_PLATFORM_INDEPENDENT" = "true" ] && TERMUX_ARCH=any + + # Configuring the selection of a copress for a batch. + local COMPRESS + local PKG_FORMAT + case $TERMUX_PACMAN_PACKAGE_COMPRESSION in + "gzip") + COMPRESS=(gzip -c -f -n) + PKG_FORMAT="gz";; + "bzip2") + COMPRESS=(bzip2 -c -f) + PKG_FORMAT="bz2";; + "zstd") + COMPRESS=(zstd -c -z -q -) + PKG_FORMAT="zst";; + "lrzip") + COMPRESS=(lrzip -q) + PKG_FORMAT="lrz";; + "lzop") + COMPRESS=(lzop -q) + PKG_FORMAT="lzop";; + "lz4") + COMPRESS=(lz4 -q) + PKG_FORMAT="lz4";; + "lzip") + COMPRESS=(lzip -c -f) + PKG_FORMAT="lz";; + "xz" | *) + COMPRESS=(xz -c -z -) + PKG_FORMAT="xz";; + esac + + local PACMAN_FILE=$TERMUX_OUTPUT_DIR/${TERMUX_PKG_NAME}${DEBUG}-${TERMUX_PKG_FULLVERSION}-${TERMUX_ARCH}.pkg.tar.${PKG_FORMAT} + + local BUILD_DATE + BUILD_DATE=$(date +%s) + + # Package metadata. + { + echo "pkgname = $TERMUX_PKG_NAME" + echo "pkgbase = $TERMUX_PKG_NAME" + if [ -n "$TERMUX_PKG_REVISION" ]; then + echo "pkgver = $TERMUX_PKG_VERSION-${TERMUX_PKG_REVISION}" + else + echo "pkgver = $TERMUX_PKG_VERSION-0" + fi + echo "pkgdesc = $(echo "$TERMUX_PKG_DESCRIPTION" | tr '\n' ' ')" + echo "url = $TERMUX_PKG_HOMEPAGE" + echo "builddate = $BUILD_DATE" + echo "packager = $TERMUX_PKG_MAINTAINER" + echo "size = $TERMUX_PKG_INSTALLSIZE" + echo "arch = $TERMUX_ARCH" + + if [ -n "$TERMUX_PKG_LICENSE" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_LICENSE" | awk '{ printf "license = %s\n", $0 }' + fi + + if [ -n "$TERMUX_PKG_REPLACES" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_REPLACES" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "replaces = %s\n", $1 }' + fi + + if [ -n "$TERMUX_PKG_CONFLICTS" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_CONFLICTS" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "conflict = %s\n", $1 }' + fi + + if [ -n "$TERMUX_PKG_BREAKS" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_BREAKS" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "conflict = %s\n", $1 }' + fi + + if [ -n "$TERMUX_PKG_PROVIDES" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_PROVIDES" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "provides = %s\n", $1 }' + fi + + if [ -n "$TERMUX_PKG_DEPENDS" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_DEPENDS" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "depend = %s\n", $1 }' + fi + + if [ -n "$TERMUX_PKG_RECOMMENDS" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_RECOMMENDS" | awk '{ printf "optdepend = %s\n", $1 }' + fi + + if [ -n "$TERMUX_PKG_SUGGESTS" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_SUGGESTS" | awk '{ printf "optdepend = %s\n", $1 }' + fi + + if [ -n "$TERMUX_PKG_BUILD_DEPENDS" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_BUILD_DEPENDS" | sed 's|(||g; s|)||g; s| ||g; s|>>|>|g; s|<<|<|g' | awk '{ printf "makedepend = %s\n", $1 }' + fi + + if [ -n "$TERMUX_PKG_CONFFILES" ]; then + tr ',' '\n' <<< "$TERMUX_PKG_CONFFILES" | awk '{ printf "backup = '"${TERMUX_PREFIX:1}"'/%s\n", $1 }' + fi + } > .PKGINFO + + # Build metadata. + { + echo "format = 2" + echo "pkgname = $TERMUX_PKG_NAME" + echo "pkgbase = $TERMUX_PKG_NAME" + if [ -n "$TERMUX_PKG_REVISION" ]; then + echo "pkgver = $TERMUX_PKG_VERSION-${TERMUX_PKG_REVISION}" + else + echo "pkgver = $TERMUX_PKG_VERSION-0" + fi + echo "pkgarch = $TERMUX_ARCH" + echo "packager = $TERMUX_PKG_MAINTAINER" + echo "builddate = $BUILD_DATE" + } > .BUILDINFO + + # Write installation hooks. + termux_step_create_debscripts + termux_step_create_pacman_install_hook + + # Create package + shopt -s dotglob globstar + printf '%s\0' **/* | bsdtar -cnf - --format=mtree \ + --options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link' \ + --null --files-from - --exclude .MTREE | \ + gzip -c -f -n > .MTREE + printf '%s\0' **/* | bsdtar --no-fflags -cnf - --null --files-from - | \ + $COMPRESS > "$PACMAN_FILE" + shopt -u dotglob globstar +} diff --git a/scripts/build/termux_step_get_dependencies.sh b/scripts/build/termux_step_get_dependencies.sh index 51e5d53261..707b93ad42 100644 --- a/scripts/build/termux_step_get_dependencies.sh +++ b/scripts/build/termux_step_get_dependencies.sh @@ -29,7 +29,7 @@ termux_step_get_dependencies() { if ! termux_download_deb $PKG $DEP_ARCH $DEP_VERSION; then echo "Download of $PKG@$DEP_VERSION from $TERMUX_REPO_URL failed, building instead" - TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh -I "${PKG_DIR}" + TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh -I --format $TERMUX_PACKAGE_FORMAT "${PKG_DIR}" continue fi if [ "$TERMUX_ON_DEVICE_BUILD" = "false" ]; then @@ -62,8 +62,8 @@ termux_step_get_dependencies() { termux_error_exit "Obtaining buildorder failed" fi echo "Building dependency $PKG if necessary..." - # Built dependencies are put in the default TERMUX_DEBDIR instead of the specified one - TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh -s "${PKG_DIR}" + # Built dependencies are put in the default TERMUX_OUTPUT_DIR instead of the specified one + TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh -s --format $TERMUX_PACKAGE_FORMAT "${PKG_DIR}" done<<<$(./scripts/buildorder.py "$TERMUX_PKG_BUILDER_DIR" $TERMUX_PACKAGES_DIRECTORIES || echo "ERROR") fi } diff --git a/scripts/build/termux_step_massage.sh b/scripts/build/termux_step_massage.sh index b391c665be..422e17f383 100644 --- a/scripts/build/termux_step_massage.sh +++ b/scripts/build/termux_step_massage.sh @@ -79,7 +79,11 @@ termux_step_massage() { termux_error_exit "Package contains hard links: $HARDLINKS" fi - termux_create_subpackages + if [ "$TERMUX_PACKAGE_FORMAT" = "debian" ]; then + termux_create_debian_subpackages + elif [ "$TERMUX_PACKAGE_FORMAT" = "pacman" ]; then + termux_create_pacman_subpackages + fi # .. remove empty directories (NOTE: keep this last): find . -type d -empty -delete diff --git a/scripts/build/termux_step_setup_build_folders.sh b/scripts/build/termux_step_setup_build_folders.sh index 84b4b3c0b7..e418e595bb 100644 --- a/scripts/build/termux_step_setup_build_folders.sh +++ b/scripts/build/termux_step_setup_build_folders.sh @@ -29,7 +29,7 @@ termux_step_setup_build_folders() { mkdir -p "$TERMUX_COMMON_CACHEDIR" \ "$TERMUX_COMMON_CACHEDIR-$TERMUX_ARCH" \ "$TERMUX_COMMON_CACHEDIR-all" \ - "$TERMUX_DEBDIR" \ + "$TERMUX_OUTPUT_DIR" \ "$TERMUX_PKG_BUILDDIR" \ "$TERMUX_PKG_PACKAGEDIR" \ "$TERMUX_PKG_TMPDIR" \ diff --git a/scripts/build/termux_step_setup_variables.sh b/scripts/build/termux_step_setup_variables.sh index 04d16cb5e8..5bcc002b64 100644 --- a/scripts/build/termux_step_setup_variables.sh +++ b/scripts/build/termux_step_setup_variables.sh @@ -1,6 +1,7 @@ termux_step_setup_variables() { + : "${TERMUX_PACKAGE_FORMAT:="debian"}" # debian, pacman : "${TERMUX_ARCH:="aarch64"}" # arm, aarch64, i686 or x86_64. - : "${TERMUX_DEBDIR:="${TERMUX_SCRIPTDIR}/debs"}" + : "${TERMUX_OUTPUT_DIR:="${TERMUX_SCRIPTDIR}/output"}" : "${TERMUX_DEBUG_BUILD:="false"}" : "${TERMUX_FORCE_BUILD:="false"}" : "${TERMUX_INSTALL_DEPS:="false"}" @@ -12,6 +13,7 @@ termux_step_setup_variables() { : "${TERMUX_QUIET_BUILD:="false"}" : "${TERMUX_SKIP_DEPCHECK:="false"}" : "${TERMUX_TOPDIR:="$HOME/.termux-build"}" + : "${TERMUX_PACMAN_PACKAGE_COMPRESSION:="xz"}" if [ "$TERMUX_ON_DEVICE_BUILD" = "true" ]; then # For on-device builds cross-compiling is not supported so we can