Skip to content

Commit

Permalink
enable on-device builds
Browse files Browse the repository at this point in the history
Partial compatibility for on-device builds.

There is no guarantee that it will be possible to build all available
packages and built packages will have same reliability that cross-compiled
but should solve "self-hosting" problems as much as possible.
  • Loading branch information
Leonid Plyushch committed Aug 8, 2019
1 parent 3ac6f52 commit 8014bd0
Show file tree
Hide file tree
Showing 20 changed files with 340 additions and 145 deletions.
5 changes: 5 additions & 0 deletions build-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

set -e -u -o pipefail

if [ "$(uname -o)" = "Android" ] || [ -e "/system/bin/app_process" ]; then
echo "On-device execution of this script is not supported."
exit 1
fi

# Read settings from .termuxrc if existing
test -f $HOME/.termuxrc && . $HOME/.termuxrc
: ${TERMUX_TOPDIR:="$HOME/.termux-build"}
Expand Down
57 changes: 42 additions & 15 deletions build-package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@

set -e -o pipefail -u

# Utility function to log an error message and exit with an error code.
source scripts/build/termux_error_exit.sh

if [ "$(uname -o)" = Android ]; then
termux_error_exit "On-device builds are not supported - see README.md"
: "${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."
exit 1
fi

# This variable tells all parts of build system that build
# is performed on device.
export TERMUX_ON_DEVICE_BUILD=true
else
export TERMUX_ON_DEVICE_BUILD=
fi

# Lock file to prevent parallel running in the same environment.
TERMUX_BUILD_LOCK_FILE="/tmp/.termux-build.lck"
TERMUX_BUILD_LOCK_FILE="${TMPDIR}/.termux-build.lck"
if [ ! -e "$TERMUX_BUILD_LOCK_FILE" ]; then
touch "$TERMUX_BUILD_LOCK_FILE"
fi
Expand All @@ -20,6 +29,9 @@ fi
# lock file.
: "${TERMUX_BUILD_IGNORE_LOCK:=false}"

# Utility function to log an error message and exit with an error code.
source scripts/build/termux_error_exit.sh

# Utility function to download a resource with an expected checksum.
source scripts/build/termux_download.sh

Expand Down Expand Up @@ -151,13 +163,16 @@ source scripts/build/termux_step_finish_build.sh
################################################################################

_show_usage() {
echo "Usage: ./build-package.sh [-a ARCH] [-d] [-D] [-f] [-i] [-I] [-q] [-s] [-o DIR] PACKAGE_1 PACKAGE_2 ..."
echo "Usage: ./build-package.sh [options] PACKAGE_1 PACKAGE_2 ..."
echo
echo "Build a package by creating a .deb file in the debs/ folder."
echo " -a The architecture to build for: aarch64(default), arm, i686, x86_64 or all."
echo
echo "Available options:"
[ -z "$TERMUX_ON_DEVICE_BUILD" ] && echo " -a The architecture to build for: aarch64(default), arm, i686, x86_64 or all."
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 " -i Download and extract dependencies instead of building them."
[ -z "$TERMUX_ON_DEVICE_BUILD" ] && echo " -i Download and extract dependencies instead of building them."
echo " -I Download and extract dependencies instead of building them, keep existing /data/data/com.termux files."
echo " -q Quiet build."
echo " -s Skip dependency check."
Expand All @@ -167,12 +182,24 @@ _show_usage() {

while getopts :a:hdDfiIqso: option; do
case "$option" in
a) TERMUX_ARCH="$OPTARG";;
a)
if [ -n "$TERMUX_ON_DEVICE_BUILD" ]; then
termux_error_exit "./build-package.sh: option '-a' is not available for on-device builds"
else
export TERMUX_ARCH="$OPTARG"
fi
;;
h) _show_usage;;
d) export TERMUX_DEBUG=true;;
D) local TERMUX_IS_DISABLED=true;;
f) TERMUX_FORCE_BUILD=true;;
i) export TERMUX_INSTALL_DEPS=true;;
i)
if [ -n "$TERMUX_ON_DEVICE_BUILD" ]; 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;;
Expand All @@ -197,11 +224,11 @@ while (($# > 0)); do
fi

# Handle 'all' arch:
if [ -n "${TERMUX_ARCH+x}" ] && [ "${TERMUX_ARCH}" = 'all' ]; then
if [ -z "$TERMUX_ON_DEVICE_BUILD" ] && [ -n "${TERMUX_ARCH+x}" ] && [ "${TERMUX_ARCH}" = 'all' ]; then
for arch in 'aarch64' 'arm' 'i686' 'x86_64'; do
TERMUX_BUILD_IGNORE_LOCK=true ./build-package.sh ${TERMUX_FORCE_BUILD+-f} \
-a $arch ${TERMUX_INSTALL_DEPS+-i} ${TERMUX_IS_DISABLED+-D} ${TERMUX_DEBUG+-d} \
${TERMUX_DEBDIR+-o $TERMUX_DEBDIR} "$1"
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+-d} ${TERMUX_DEBDIR+-o $TERMUX_DEBDIR} "$1"
done
exit
fi
Expand Down
31 changes: 25 additions & 6 deletions clean.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,26 @@
# clean.sh - clean everything.
set -e -u

# Read settings from .termuxrc if existing
test -f $HOME/.termuxrc && . $HOME/.termuxrc
: ${TERMUX_TOPDIR:="$HOME/.termux-build"}
# Checking if script is running on Android with 2 different methods.
# Needed for safety to prevent execution of potentially dangerous
# operations such as 'rm -rf /data/*' on Android device.
if [ "$(uname -o)" = "Android" ] || [ -e "/system/bin/app_process" ]; then
export TERMUX_ON_DEVICE_BUILD=true
fi

if [ "$(id -u)" = "0" ] && [ -n "$TERMUX_ON_DEVICE_BUILD" ]; then
echo "On-device execution of this script as root is disabled."
exit 1
fi

# Read settings from .termuxrc if existing
test -f "$HOME/.termuxrc" && . "$HOME/.termuxrc"
: "${TERMUX_TOPDIR:="$HOME/.termux-build"}"
: "${TMPDIR:=/tmp}"
export TMPDIR

# Lock file. Same as used in build-package.sh.
TERMUX_BUILD_LOCK_FILE="/tmp/.termux-build.lck"
TERMUX_BUILD_LOCK_FILE="${TMPDIR}/.termux-build.lck"
if [ ! -e "$TERMUX_BUILD_LOCK_FILE" ]; then
touch "$TERMUX_BUILD_LOCK_FILE"
fi
Expand All @@ -20,7 +33,13 @@ fi
fi

if [ -d "$TERMUX_TOPDIR" ]; then
chmod +w -R $TERMUX_TOPDIR
chmod +w -R "$TERMUX_TOPDIR"
fi

if [ -n "$TERMUX_ON_DEVICE_BUILD" ]; then
# For on-device build cleanup /data shouldn't be erased.
rm -Rf "$TERMUX_TOPDIR"
else
rm -Rf /data/* "$TERMUX_TOPDIR"
fi
rm -Rf /data/* $TERMUX_TOPDIR
} 5< "$TERMUX_BUILD_LOCK_FILE"
14 changes: 8 additions & 6 deletions scripts/build/configure/termux_step_configure_autotools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ termux_step_configure_autotools() {
QUIET_BUILD="--enable-silent-rules --silent --quiet"
fi

# Some packages provides a $PKG-config script which some configure scripts pickup instead of pkg-config:
mkdir "$TERMUX_PKG_TMPDIR/config-scripts"
for f in $TERMUX_PREFIX/bin/*config; do
test -f "$f" && cp "$f" "$TERMUX_PKG_TMPDIR/config-scripts"
done
export PATH=$TERMUX_PKG_TMPDIR/config-scripts:$PATH
if [ -z "$TERMUX_ON_DEVICE_BUILD" ]; then
# Some packages provides a $PKG-config script which some configure scripts pickup instead of pkg-config:
mkdir "$TERMUX_PKG_TMPDIR/config-scripts"
for f in $TERMUX_PREFIX/bin/*config; do
test -f "$f" && cp "$f" "$TERMUX_PKG_TMPDIR/config-scripts"
done
export PATH=$TERMUX_PKG_TMPDIR/config-scripts:$PATH
fi

# Avoid gnulib wrapping of functions when cross compiling. See
# http://wiki.osdev.org/Cross-Porting_Software#Gnulib
Expand Down
33 changes: 22 additions & 11 deletions scripts/build/configure/termux_step_configure_cmake.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
termux_step_configure_cmake() {
termux_setup_cmake

local TOOLCHAIN_ARGS="-DCMAKE_ANDROID_STANDALONE_TOOLCHAIN=$TERMUX_STANDALONE_TOOLCHAIN"
local BUILD_TYPE=MinSizeRel
test -n "$TERMUX_DEBUG" && BUILD_TYPE=Debug

Expand All @@ -14,33 +13,45 @@ termux_step_configure_cmake() {
else
MAKE_PROGRAM_PATH=$(which make)
fi
CFLAGS+=" --target=$CCTERMUX_HOST_PLATFORM -fno-addrsig"
CXXFLAGS+=" --target=$CCTERMUX_HOST_PLATFORM -fno-addrsig"
LDFLAGS+=" --target=$CCTERMUX_HOST_PLATFORM"

CXXFLAGS+=" -fno-addrsig"
CFLAGS+=" -fno-addrsig"

local CMAKE_ADDITIONAL_ARGS=()
if [ -z "$TERMUX_ON_DEVICE_BUILD" ]; then
CXXFLAGS+=" --target=$CCTERMUX_HOST_PLATFORM"
CFLAGS+=" --target=$CCTERMUX_HOST_PLATFORM"
LDFLAGS+=" --target=$CCTERMUX_HOST_PLATFORM"

CMAKE_ADDITIONAL_ARGS+=("-DCMAKE_CROSSCOMPILING=True")
CMAKE_ADDITIONAL_ARGS+=("-DCMAKE_LINKER=$TERMUX_STANDALONE_TOOLCHAIN/bin/$LD $LDFLAGS")
CMAKE_ADDITIONAL_ARGS+=("-DCMAKE_SYSTEM_NAME=Android")
CMAKE_ADDITIONAL_ARGS+=("-DCMAKE_SYSTEM_VERSION=$TERMUX_PKG_API_LEVEL")
CMAKE_ADDITIONAL_ARGS+=("-DCMAKE_SYSTEM_PROCESSOR=$CMAKE_PROC")
CMAKE_ADDITIONAL_ARGS+=("-DCMAKE_ANDROID_STANDALONE_TOOLCHAIN=$TERMUX_STANDALONE_TOOLCHAIN")
else
CMAKE_ADDITIONAL_ARGS+=("-DCMAKE_LINKER=$(which $LD) $LDFLAGS")
fi

# XXX: CMAKE_{AR,RANLIB} needed for at least jsoncpp build to not
# pick up cross compiled binutils tool in $PREFIX/bin:
# pick up cross compiled binutils tool in $TERMUX_PREFIX/bin:
cmake -G "$TERMUX_CMAKE_BUILD" "$TERMUX_PKG_SRCDIR" \
-DCMAKE_AR="$(which $AR)" \
-DCMAKE_UNAME="$(which uname)" \
-DCMAKE_RANLIB="$(which $RANLIB)" \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DCMAKE_CROSSCOMPILING=True \
-DCMAKE_C_FLAGS="$CFLAGS $CPPFLAGS" \
-DCMAKE_CXX_FLAGS="$CXXFLAGS $CPPFLAGS" \
-DCMAKE_LINKER="$TERMUX_STANDALONE_TOOLCHAIN/bin/$LD $LDFLAGS" \
-DCMAKE_FIND_ROOT_PATH=$TERMUX_PREFIX \
-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
-DCMAKE_INSTALL_PREFIX=$TERMUX_PREFIX \
-DCMAKE_MAKE_PROGRAM=$MAKE_PROGRAM_PATH \
-DCMAKE_SYSTEM_PROCESSOR=$CMAKE_PROC \
-DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_SYSTEM_VERSION=$TERMUX_PKG_API_LEVEL \
-DCMAKE_SKIP_INSTALL_RPATH=ON \
-DCMAKE_USE_SYSTEM_LIBRARIES=True \
-DDOXYGEN_EXECUTABLE= \
-DBUILD_TESTING=OFF \
$TERMUX_PKG_EXTRA_CONFIGURE_ARGS $TOOLCHAIN_ARGS
"${CMAKE_ADDITIONAL_ARGS[@]}" \
$TERMUX_PKG_EXTRA_CONFIGURE_ARGS
}
25 changes: 18 additions & 7 deletions scripts/build/setup/termux_setup_cmake.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,26 @@ termux_setup_cmake() {
local TERMUX_CMAKE_TARNAME=cmake-${TERMUX_CMAKE_VERSION}-Linux-x86_64.tar.gz
local TERMUX_CMAKE_TARFILE=$TERMUX_PKG_TMPDIR/$TERMUX_CMAKE_TARNAME
local TERMUX_CMAKE_FOLDER=$TERMUX_COMMON_CACHEDIR/cmake-$TERMUX_CMAKE_VERSION
if [ ! -d "$TERMUX_CMAKE_FOLDER" ]; then
termux_download https://cmake.org/files/v$TERMUX_CMAKE_MAJORVESION/$TERMUX_CMAKE_TARNAME \

if [ -z "$TERMUX_ON_DEVICE_BUILD" ]; then
if [ ! -d "$TERMUX_CMAKE_FOLDER" ]; then
termux_download https://cmake.org/files/v$TERMUX_CMAKE_MAJORVESION/$TERMUX_CMAKE_TARNAME \
"$TERMUX_CMAKE_TARFILE" \
757e7ddd29d11422334a60d7cd9c19b7af20349a03cb15aa3c879f1b54193c95
rm -Rf "$TERMUX_PKG_TMPDIR/cmake-${TERMUX_CMAKE_VERSION}-Linux-x86_64"
tar xf "$TERMUX_CMAKE_TARFILE" -C "$TERMUX_PKG_TMPDIR"
mv "$TERMUX_PKG_TMPDIR/cmake-${TERMUX_CMAKE_VERSION}-Linux-x86_64" \
"$TERMUX_CMAKE_FOLDER"
rm -Rf "$TERMUX_PKG_TMPDIR/cmake-${TERMUX_CMAKE_VERSION}-Linux-x86_64"
tar xf "$TERMUX_CMAKE_TARFILE" -C "$TERMUX_PKG_TMPDIR"
mv "$TERMUX_PKG_TMPDIR/cmake-${TERMUX_CMAKE_VERSION}-Linux-x86_64" \
"$TERMUX_CMAKE_FOLDER"
fi

export PATH=$TERMUX_CMAKE_FOLDER/bin:$PATH
else
if [ "$(dpkg-query -W -f '${db:Status-Status}\n' cmake 2>/dev/null)" != "installed" ]; then
echo "Package 'cmake' is not installed."
echo "Install it with command 'pkg install cmake'."
exit 1
fi
fi
export PATH=$TERMUX_CMAKE_FOLDER/bin:$PATH

export CMAKE_INSTALL_ALWAYS=1
}
32 changes: 20 additions & 12 deletions scripts/build/setup/termux_setup_golang.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,28 @@ termux_setup_golang() {
termux_error_exit "Unsupported arch: $TERMUX_ARCH"
fi

local TERMUX_GO_VERSION=go1.12.7
local TERMUX_GO_PLATFORM=linux-amd64
if [ -z "$TERMUX_ON_DEVICE_BUILD" ]; then
local TERMUX_GO_VERSION=go1.12.7
local TERMUX_GO_PLATFORM=linux-amd64

local TERMUX_BUILDGO_FOLDER=$TERMUX_COMMON_CACHEDIR/${TERMUX_GO_VERSION}
export GOROOT=$TERMUX_BUILDGO_FOLDER
export PATH=$GOROOT/bin:$PATH
local TERMUX_BUILDGO_FOLDER=$TERMUX_COMMON_CACHEDIR/${TERMUX_GO_VERSION}
export GOROOT=$TERMUX_BUILDGO_FOLDER
export PATH=$GOROOT/bin:$PATH

if [ -d "$TERMUX_BUILDGO_FOLDER" ]; then return; fi
if [ -d "$TERMUX_BUILDGO_FOLDER" ]; then return; fi

local TERMUX_BUILDGO_TAR=$TERMUX_COMMON_CACHEDIR/${TERMUX_GO_VERSION}.${TERMUX_GO_PLATFORM}.tar.gz
rm -Rf "$TERMUX_COMMON_CACHEDIR/go" "$TERMUX_BUILDGO_FOLDER"
termux_download https://storage.googleapis.com/golang/${TERMUX_GO_VERSION}.${TERMUX_GO_PLATFORM}.tar.gz \
"$TERMUX_BUILDGO_TAR" \
66d83bfb5a9ede000e33c6579a91a29e6b101829ad41fffb5c5bb6c900e109d9
local TERMUX_BUILDGO_TAR=$TERMUX_COMMON_CACHEDIR/${TERMUX_GO_VERSION}.${TERMUX_GO_PLATFORM}.tar.gz
rm -Rf "$TERMUX_COMMON_CACHEDIR/go" "$TERMUX_BUILDGO_FOLDER"
termux_download https://storage.googleapis.com/golang/${TERMUX_GO_VERSION}.${TERMUX_GO_PLATFORM}.tar.gz \
"$TERMUX_BUILDGO_TAR" \
66d83bfb5a9ede000e33c6579a91a29e6b101829ad41fffb5c5bb6c900e109d9

( cd "$TERMUX_COMMON_CACHEDIR"; tar xf "$TERMUX_BUILDGO_TAR"; mv go "$TERMUX_BUILDGO_FOLDER"; rm "$TERMUX_BUILDGO_TAR" )
( cd "$TERMUX_COMMON_CACHEDIR"; tar xf "$TERMUX_BUILDGO_TAR"; mv go "$TERMUX_BUILDGO_FOLDER"; rm "$TERMUX_BUILDGO_TAR" )
else
if [ "$(dpkg-query -W -f '${db:Status-Status}\n' golang 2>/dev/null)" != "installed" ]; then
echo "Package 'golang' is not installed."
echo "Install it with command 'pkg install golang'."
exit 1
fi
fi
}
27 changes: 18 additions & 9 deletions scripts/build/setup/termux_setup_ninja.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
termux_setup_ninja() {
local NINJA_VERSION=1.9.0
local NINJA_FOLDER=$TERMUX_COMMON_CACHEDIR/ninja-$NINJA_VERSION
if [ ! -x "$NINJA_FOLDER/ninja" ]; then
mkdir -p "$NINJA_FOLDER"
local NINJA_ZIP_FILE=$TERMUX_PKG_TMPDIR/ninja-$NINJA_VERSION.zip
termux_download https://github.com/ninja-build/ninja/releases/download/v$NINJA_VERSION/ninja-linux.zip \
"$NINJA_ZIP_FILE" \
1b1235f2b0b4df55ac6d80bbe681ea3639c9d2c505c7ff2159a3daf63d196305
unzip "$NINJA_ZIP_FILE" -d "$NINJA_FOLDER"
chmod 755 $NINJA_FOLDER/ninja

if [ -z "$TERMUX_ON_DEVICE_BUILD" ]; then
if [ ! -x "$NINJA_FOLDER/ninja" ]; then
mkdir -p "$NINJA_FOLDER"
local NINJA_ZIP_FILE=$TERMUX_PKG_TMPDIR/ninja-$NINJA_VERSION.zip
termux_download https://github.com/ninja-build/ninja/releases/download/v$NINJA_VERSION/ninja-linux.zip \
"$NINJA_ZIP_FILE" \
1b1235f2b0b4df55ac6d80bbe681ea3639c9d2c505c7ff2159a3daf63d196305
unzip "$NINJA_ZIP_FILE" -d "$NINJA_FOLDER"
chmod 755 $NINJA_FOLDER/ninja
fi
export PATH=$NINJA_FOLDER:$PATH
else
if [ "$(dpkg-query -W -f '${db:Status-Status}\n' ninja 2>/dev/null)" != "installed" ]; then
echo "Package 'ninja' is not installed."
echo "Install it with command 'pkg install ninja'."
exit 1
fi
fi
export PATH=$NINJA_FOLDER:$PATH
}
24 changes: 16 additions & 8 deletions scripts/build/setup/termux_setup_protobuf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,25 @@ termux_setup_protobuf() {
local _PROTOBUF_ZIP=protoc-$_PROTOBUF_VERSION-linux-x86_64.zip
local _PROTOBUF_FOLDER=$TERMUX_COMMON_CACHEDIR/protobuf-$_PROTOBUF_VERSION

if [ ! -d "$_PROTOBUF_FOLDER" ]; then
termux_download \
if [ -z "$TERMUX_ON_DEVICE_BUILD" ]; then
if [ ! -d "$_PROTOBUF_FOLDER" ]; then
termux_download \
https://github.com/protocolbuffers/protobuf/releases/download/v$_PROTOBUF_VERSION/$_PROTOBUF_ZIP \
$TERMUX_PKG_TMPDIR/$_PROTOBUF_ZIP \
15e395b648a1a6dda8fd66868824a396e9d3e89bc2c8648e3b9ab9801bea5d55

rm -Rf "$TERMUX_PKG_TMPDIR/protoc-$_PROTOBUF_VERSION-linux-x86_64"
unzip $TERMUX_PKG_TMPDIR/$_PROTOBUF_ZIP -d $TERMUX_PKG_TMPDIR/protobuf-$_PROTOBUF_VERSION
mv "$TERMUX_PKG_TMPDIR/protobuf-$_PROTOBUF_VERSION" \
$_PROTOBUF_FOLDER
fi
rm -Rf "$TERMUX_PKG_TMPDIR/protoc-$_PROTOBUF_VERSION-linux-x86_64"
unzip $TERMUX_PKG_TMPDIR/$_PROTOBUF_ZIP -d $TERMUX_PKG_TMPDIR/protobuf-$_PROTOBUF_VERSION
mv "$TERMUX_PKG_TMPDIR/protobuf-$_PROTOBUF_VERSION" \
$_PROTOBUF_FOLDER
fi

export PATH=$_PROTOBUF_FOLDER/bin/:$PATH
export PATH=$_PROTOBUF_FOLDER/bin/:$PATH
else
if [ "$(dpkg-query -W -f '${db:Status-Status}\n' protobuf 2>/dev/null)" != "installed" ]; then
echo "Package 'protobuf' is not installed."
echo "Install it with command 'pkg install protobuf'."
exit 1
fi
fi
}
Loading

0 comments on commit 8014bd0

Please sign in to comment.