scripts(build-package.sh): fix on device compilation of packages when force building and revert `-f` flag behaviour

- Reverted behviour of `-f` flag changed in b9b5987 and only force build current package instead of dependencies.
- Added a  new `-F` flag to force build current package and dependencies as well.
- If both `-I` and `-F` flags are passed and dependencies cannot be compiled on device, i.e `$TERMUX_PKG_ON_DEVICE_BUILD_NOT_SUPPORTED` is set to `true` in `build.sh` of package, then they will be downloaded instead.
- If only `-F` flag is passed without the `-I` flag, and building on device is not supported, then building with fail with error.
- The `$TERMUX_BUILD_PACKAGE_CALL_DEPTH` variable will be used to track depth of recursive calls to `build-package.sh`.
- The file at `$TERMUX_BUILD_PACKAGE_CALL_BUILT_PACKAGES_LIST_FILE_PATH` will be used to track list of packages and their dependencies that have been compiled at any instant by recursive calls to `build-package.sh`.
- Added `scripts/utils/package/package.sh` to store package utils. The `pacakge__is_package_version_built()` method can be used to check if a certain package version has been built. In future this should include `$TERMUX_APP_PACKAGE` as well.

Co-authored-by: agnostic-apollo <agnosticapollo@gmail.com>
Co-authored-by: Maxython <mixython@gmail.com>
This commit is contained in:
Maxython 2023-01-03 19:57:00 +05:00 committed by agnostic-apollo
parent ab7793e03c
commit d502e7489d
5 changed files with 148 additions and 26 deletions

View File

@ -1,6 +1,21 @@
#!/bin/bash
# shellcheck disable=SC1117
# Setting the TMPDIR variable
: "${TMPDIR:=/tmp}"
export TMPDIR
# Set the build-package.sh call depth
# If its the root call, then create a file to store the list of packages and their dependencies
# that have been compiled at any instant by recursive calls to build-package.sh
if [[ ! "$TERMUX_BUILD_PACKAGE_CALL_DEPTH" =~ ^[0-9]+$ ]]; then
export TERMUX_BUILD_PACKAGE_CALL_DEPTH=0
export TERMUX_BUILD_PACKAGE_CALL_BUILT_PACKAGES_LIST_FILE_PATH="${TMPDIR}/build-package-call-built-packages-list-$(date +"%Y-%m-%d-%H.%M.%S.")$((RANDOM%1000))"
echo -n " " > "$TERMUX_BUILD_PACKAGE_CALL_BUILT_PACKAGES_LIST_FILE_PATH"
else
export TERMUX_BUILD_PACKAGE_CALL_DEPTH=$((TERMUX_BUILD_PACKAGE_CALL_DEPTH+1))
fi
set -e -o pipefail -u
cd "$(realpath "$(dirname "$0")")"
@ -10,13 +25,12 @@ export TERMUX_SCRIPTDIR
# Store pid of current process in a file for docker__run_docker_exec_trap
source "$TERMUX_SCRIPTDIR/scripts/utils/docker/docker.sh"; docker__create_docker_exec_pid_file
# Functions for working with packages
source "$TERMUX_SCRIPTDIR/scripts/utils/package/package.sh"
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct 2>/dev/null || date "+%s")
export SOURCE_DATE_EPOCH
: "${TMPDIR:=/tmp}"
export TMPDIR
if [ "$(uname -o)" = "Android" ] || [ -e "/system/bin/app_process" ]; then
if [ "$(id -u)" = "0" ]; then
echo "On-device execution of this script as root is disabled."
@ -348,6 +362,20 @@ if [ "$TERMUX_ON_DEVICE_BUILD" = "true" ]; then
export TERMUX_ARCH
fi
# Check if the package is in the compiled list
termux_check_package_in_built_packages_list() {
[ ! -f "$TERMUX_BUILD_PACKAGE_CALL_BUILT_PACKAGES_LIST_FILE_PATH" ] && termux_error_exit "ERROR: file '$TERMUX_BUILD_PACKAGE_CALL_BUILT_PACKAGES_LIST_FILE_PATH' not found."
cat "$TERMUX_BUILD_PACKAGE_CALL_BUILT_PACKAGES_LIST_FILE_PATH" | grep -q " $1 "
return $?
}
# Adds a package to the list of built packages if it is not in the list
termux_add_package_to_built_packages_list() {
if ! termux_check_package_in_built_packages_list "$1"; then
echo -n "$1 " >> $TERMUX_BUILD_PACKAGE_CALL_BUILT_PACKAGES_LIST_FILE_PATH
fi
}
# Special hook to prevent use of "sudo" inside package build scripts.
# build-package.sh shouldn't perform any privileged operations.
sudo() {
@ -364,6 +392,7 @@ _show_usage() {
echo " -d Build with debug symbols."
echo " -D Build a disabled package in disabled-packages/."
echo " -f Force build even if package has already been built."
echo " -F Force build even if package and its dependencies have already been built."
[ "$TERMUX_ON_DEVICE_BUILD" = "false" ] && echo " -i Download and extract dependencies instead of building them."
echo " -I Download and extract dependencies instead of building them, keep existing $TERMUX_BASE_DIR files."
echo " -q Quiet build."
@ -409,6 +438,7 @@ while (($# >= 1)); do
-d) export TERMUX_DEBUG_BUILD=true;;
-D) TERMUX_IS_DISABLED=true;;
-f) TERMUX_FORCE_BUILD=true;;
-F) TERMUX_FORCE_BUILD_DEPENDENCIES=true && 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"
@ -577,6 +607,13 @@ for ((i=0; i<${#PACKAGE_LIST[@]}; i++)); do
else
termux_error_exit "Unknown packaging format '$TERMUX_PACKAGE_FORMAT'."
fi
# Saving a list of compiled packages for further work with it
termux_add_package_to_built_packages_list "$TERMUX_PKG_NAME"
termux_step_finish_build
) 5< "$TERMUX_BUILD_LOCK_FILE"
done
# Removing a file to store a list of compiled packages
if [ "$TERMUX_BUILD_PACKAGE_CALL_DEPTH" = "0" ]; then
rm "$TERMUX_BUILD_PACKAGE_CALL_BUILT_PACKAGES_LIST_FILE_PATH"
fi

View File

@ -1,5 +1,9 @@
termux_step_get_dependencies() {
if [ "$TERMUX_SKIP_DEPCHECK" = false ] && [ "$TERMUX_INSTALL_DEPS" = true ] && [ "$TERMUX_PKG_METAPACKAGE" = "false" ]; then
if [ "$TERMUX_SKIP_DEPCHECK" = true ] || [ "$TERMUX_PKG_METAPACKAGE" = true ]; then
return 0
fi
if [ "$TERMUX_INSTALL_DEPS" = true ]; then
# Download repo files
termux_get_repo_files
@ -10,8 +14,6 @@ termux_step_get_dependencies() {
"pacman") pacman -Sy;;
esac
fi
# Download dependencies
while read PKG PKG_DIR; do
if [ -z $PKG ]; then
continue
@ -21,29 +23,39 @@ termux_step_get_dependencies() {
# llvm doesn't build if ndk-sysroot is installed:
if [ "$PKG" = "ndk-sysroot" ]; then continue; fi
read DEP_ARCH DEP_VERSION DEP_VERSION_PAC <<< $(termux_extract_dep_info $PKG "${PKG_DIR}")
if [ ! "$TERMUX_QUIET_BUILD" = true ]; then
echo "Downloading dependency $PKG@$DEP_VERSION if necessary..."
[ ! "$TERMUX_QUIET_BUILD" = true ] && echo "Downloading dependency $PKG@$DEP_VERSION if necessary..."
local force_build_dependency="$TERMUX_FORCE_BUILD_DEPENDENCIES"
if [ "$TERMUX_FORCE_BUILD_DEPENDENCIES" = "true" ] && [ "$TERMUX_ON_DEVICE_BUILD" = "true" ] && ! pacakge__is_package_on_device_build_supported "$PKG_DIR"; then
echo "Building dependency $PKG on device is not supported. It will be downloaded..."
force_build_dependency="false"
fi
if [ -e "$TERMUX_BUILT_PACKAGES_DIRECTORY/$PKG" ]; then
if [ "$(cat "$TERMUX_BUILT_PACKAGES_DIRECTORY/$PKG")" = "$DEP_VERSION" ]; then
if [ ! "$TERMUX_QUIET_BUILD" = true ]; then
echo "Skipping already built dependency $PKG@$DEP_VERSION"
fi
local build_dependency=false
if [ "$force_build_dependency" = "true" ]; then
[ ! "$TERMUX_QUIET_BUILD" = true ] && echo "Force building dependency $PKG instead of downloading due to -I flag..."
termux_force_check_package_dependency && continue
build_dependency=true
else
if pacakge__is_package_version_built "$PKG" "$DEP_VERSION"; then
[ ! "$TERMUX_QUIET_BUILD" = true ] && echo "Skipping already built dependency $PKG@$DEP_VERSION"
continue
fi
if ! termux_download_deb_pac $PKG $DEP_ARCH $DEP_VERSION $DEP_VERSION_PAC; then
if [ "$TERMUX_FORCE_BUILD_DEPENDENCIES" = "true" ] && [ "$TERMUX_ON_DEVICE_BUILD" = "true" ]; then
echo "Download of $PKG@$DEP_VERSION from $TERMUX_REPO_URL failed"
return 1
else
echo "Download of $PKG@$DEP_VERSION from $TERMUX_REPO_URL failed, building instead"
build_dependency=true
fi
fi
fi
if ! termux_download_deb_pac $PKG $DEP_ARCH $DEP_VERSION $DEP_VERSION_PAC; then
echo "Download of $PKG@$DEP_VERSION from $TERMUX_REPO_URL failed, building instead"
TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh $(test "${TERMUX_FORCE_BUILD}" = "true" && echo "-f" || true) -I --format $TERMUX_PACKAGE_FORMAT "${PKG_DIR}"
if $build_dependency; then
TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh -I $(test "${TERMUX_FORCE_BUILD_DEPENDENCIES}" = "true" && echo "-F" || true) --format $TERMUX_PACKAGE_FORMAT "${PKG_DIR}"
continue
fi
termux_add_package_to_built_packages_list "$PKG"
if [ "$TERMUX_ON_DEVICE_BUILD" = "false" ]; then
if [ ! "$TERMUX_QUIET_BUILD" = true ]; then
echo "extracting $PKG to $TERMUX_COMMON_CACHEDIR-$DEP_ARCH..."
fi
[ ! "$TERMUX_QUIET_BUILD" = true ] && echo "extracting $PKG to $TERMUX_COMMON_CACHEDIR-$DEP_ARCH..."
(
cd $TERMUX_COMMON_CACHEDIR-$DEP_ARCH
ar x ${PKG}_${DEP_VERSION}_${DEP_ARCH}.deb data.tar.xz
@ -57,11 +69,10 @@ termux_step_get_dependencies() {
fi
)
fi
mkdir -p $TERMUX_BUILT_PACKAGES_DIRECTORY
echo "$DEP_VERSION" > "$TERMUX_BUILT_PACKAGES_DIRECTORY/$PKG"
done<<<$(./scripts/buildorder.py -i "$TERMUX_PKG_BUILDER_DIR" $TERMUX_PACKAGES_DIRECTORIES || echo "ERROR")
elif [ "$TERMUX_SKIP_DEPCHECK" = false ] && [ "$TERMUX_INSTALL_DEPS" = false ] && [ "$TERMUX_PKG_METAPACKAGE" = "false" ]; then
else
# Build dependencies
while read PKG PKG_DIR; do
if [ -z $PKG ]; then
@ -69,9 +80,27 @@ termux_step_get_dependencies() {
elif [ "$PKG" = "ERROR" ]; then
termux_error_exit "Obtaining buildorder failed"
fi
echo "Building dependency $PKG if necessary..."
# Built dependencies are put in the default TERMUX_OUTPUT_DIR instead of the specified one
TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh $(test "${TERMUX_FORCE_BUILD}" = "true" && echo "-f" || true) -s --format $TERMUX_PACKAGE_FORMAT "${PKG_DIR}"
if [ "$TERMUX_FORCE_BUILD_DEPENDENCIES" = "true" ]; then
[ ! "$TERMUX_QUIET_BUILD" = true ] && echo "Force building dependency $PKG..."
if [ "$TERMUX_ON_DEVICE_BUILD" = "true" ] && ! pacakge__is_package_on_device_build_supported "$PKG_DIR"; then
echo "Building $PKG on device is not supported. Consider passing -I flag to download it instead"
return 1
fi
read DEP_ARCH DEP_VERSION DEP_VERSION_PAC <<< $(termux_extract_dep_info $PKG "${PKG_DIR}")
termux_force_check_package_dependency && continue
else
[ ! "$TERMUX_QUIET_BUILD" = true ] && echo "Building dependency $PKG if necessary..."
fi
TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh -s $(test "${TERMUX_FORCE_BUILD_DEPENDENCIES}" = "true" && echo "-F" || true) --format $TERMUX_PACKAGE_FORMAT "${PKG_DIR}"
done<<<$(./scripts/buildorder.py "$TERMUX_PKG_BUILDER_DIR" $TERMUX_PACKAGES_DIRECTORIES || echo "ERROR")
fi
}
termux_force_check_package_dependency() {
if termux_check_package_in_built_packages_list "$PKG" && pacakge__is_package_version_built "$PKG" "$DEP_VERSION"; then
[ ! "$TERMUX_QUIET_BUILD" = true ] && echo "Skipping already built dependency $PKG@$DEP_VERSION"
return 0
fi
return 1
}

View File

@ -3,6 +3,7 @@ termux_step_setup_variables() {
: "${TERMUX_OUTPUT_DIR:="${TERMUX_SCRIPTDIR}/output"}"
: "${TERMUX_DEBUG_BUILD:="false"}"
: "${TERMUX_FORCE_BUILD:="false"}"
: "${TERMUX_FORCE_BUILD_DEPENDENCIES:="false"}"
: "${TERMUX_INSTALL_DEPS:="false"}"
: "${TERMUX_MAKE_PROCESSES:="$(nproc)"}"
: "${TERMUX_NO_CLEAN:="false"}"
@ -124,6 +125,7 @@ termux_step_setup_variables() {
TERMUX_PKG_GROUPS="" # https://wiki.archlinux.org/title/Pacman#Installing_package_groups
TERMUX_PKG_NO_SHEBANG_FIX=false # if true, skip fixing shebang accordingly to TERMUX_PREFIX
TERMUX_PKG_IS_HASKELL_LIB=true # by default assume haskell package is lib package as most of them will always be libs.
TERMUX_PKG_ON_DEVICE_BUILD_NOT_SUPPORTED=false # if the package does not support compilation on a device, then this package should not be compiled on devices
unset CFLAGS CPPFLAGS LDFLAGS CXXFLAGS
}

View File

@ -78,6 +78,11 @@ termux_step_start_build() {
# a continued build
return
fi
if [ "$TERMUX_ON_DEVICE_BUILD" = "true" ] && [ "$TERMUX_PKG_ON_DEVICE_BUILD_NOT_SUPPORTED" = "true" ]; then
termux_error_exit "Package '$TERMUX_PKG_NAME' is not available for on-device builds."
fi
if [ "$TERMUX_ON_DEVICE_BUILD" = "true" ]; then
case "$TERMUX_APP_PACKAGE_MANAGER" in
"apt") apt install -y termux-elf-cleaner;;

View File

@ -0,0 +1,49 @@
# shellcheck shell=sh
# shellcheck disable=SC2039,SC2059
# Title: package
# Description: A library for package utils.
##
# Check if package on device builds are supported by checking
# `$TERMUX_PKG_ON_DEVICE_BUILD_NOT_SUPPORTED` value in its `build.sh`
# file.
# .
# .
# **Parameters:**
# `package_dir` - The directory path for the package `build.sh` file.
# .
# **Returns:**
# Returns `0` if supported, otherwise `1`.
# .
# .
# pacakge__is_package_on_device_build_supported `package_dir`
##
pacakge__is_package_on_device_build_supported() {
[ $(. "${1}/build.sh"; echo "$TERMUX_PKG_ON_DEVICE_BUILD_NOT_SUPPORTED") != "true" ]
return $?
}
##
# Check if a specific version of a package has been built by checking
# the `$TERMUX_BUILT_PACKAGES_DIRECTORY/<package_name>` file.
# .
# .
# **Parameters:**
# `package_name` - The package name for the package.
# `package_version` - The package version for the package to check.
# .
# **Returns:**
# Returns `0` if built, otherwise `1`.
# .
# .
# pacakge__is_package_version_built `package_name` `package_version`
##
pacakge__is_package_version_built() {
[ -e "$TERMUX_BUILT_PACKAGES_DIRECTORY/$1" ] && [ "$(cat "$TERMUX_BUILT_PACKAGES_DIRECTORY/$1")" = "$2" ]
return $?
}