Skip to content

Commit

Permalink
ANDROID: Add support for Android platform
Browse files Browse the repository at this point in the history
All official architectures are supported (arm, aarch64, x86, x86_64)
Two toolchains are provided for stable and master ScummVM.
Changes will come to simplify generation though
  • Loading branch information
lephilousophe committed Apr 8, 2020
1 parent d60d6df commit da62f82
Show file tree
Hide file tree
Showing 19 changed files with 1,178 additions and 0 deletions.
89 changes: 89 additions & 0 deletions master/platforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,95 @@ def _3ds():
platforms.append(platform)
_3ds()

def android(suffix, scummvm_target, ndk_target, cxx_target, abi_version,
android_master_root = "/opt/android/master",
android_stable_root = "/opt/android/stable"):
android_master_toolchain = "{0}/ndk/toolchains/llvm/prebuilt/linux-x86_64".format(
android_master_root)
android_stable_toolchain = "{0}/toolchain".format(android_stable_root)
platform = Platform("android_{0}".format(suffix))
platform.workerimage = "android"
platform.compatibleBuilds = (builds.ScummVMBuild, )
platform.buildenv = {
builds.ScummVMBuild: {
"ANDROID_NDK_ROOT": "{0}/ndk".format(android_master_root),
# configure script will find everything from this
"ANDROID_TOOLCHAIN": "{0}".format(android_master_toolchain),
# We keep SDK and gradle dynamic and outside the container
# Their versions can change without the need to regenerate the image
# Android build system can be shared across all versions so we don't specialize
# the directory in /data/bshomes
"ANDROID_SDK_ROOT": "/data/bshomes/android/sdk",
"ANDROID_SDK_HOME": "/data/bshomes/android/sdk-home",
"GRADLE_USER_HOME": "/data/bshomes/android/gradle",
"CXX": "ccache {0}/bin/{1}{2}-clang++".format(
android_master_toolchain, cxx_target, abi_version),
# Worker has all libraries installed in the NDK sysroot
"PKG_CONFIG_LIBDIR": "{0}/sysroot/usr/lib/{1}/{2}/pkgconfig".format(
android_master_toolchain, ndk_target, abi_version),
},
builds.ScummVMStableBuild: {
"ANDROID_NDK": "{0}/ndk".format(android_stable_root),
"ANDROID_SDK": "{0}/sdk".format(android_stable_root),
"ANDROID_SDK_HOME": "/data/bshomes/android/sdk-home",
"AR": "{0}/bin/{1}-ar".format(
android_stable_toolchain, ndk_target),
"AS": "{0}/bin/{1}-as".format(
android_stable_toolchain, ndk_target),
"RANLIB": "{0}/bin/{1}-ranlib".format(
android_stable_toolchain, ndk_target),
"STRIP": "{0}/bin/{1}-strip".format(
android_stable_toolchain, ndk_target),
"STRINGS": "{0}/bin/{1}-strings".format(
android_stable_toolchain, ndk_target),
"CXX": "ccache {0}/bin/{1}-clang++".format(
android_stable_toolchain, ndk_target),
"CC": "ccache {0}/bin/{1}-clang".format(
android_stable_toolchain, ndk_target),
# Worker has all libraries installed in the toolchain
"PKG_CONFIG_LIBDIR": "{0}/sysroot/usr/lib/{1}/pkgconfig".format(
android_stable_toolchain, ndk_target),
}
}
platform.configureargs.append("--host=android-{0}".format(scummvm_target))
platform.buildconfigureargs = {
builds.ScummVMBuild: [ "--enable-debug",
# libcurl is detected using curl-config. Instead of modifying PATH just provide path to it to configure.
"--with-libcurl-prefix={0}/sysroot/usr/bin/{1}/{2}".format(android_master_toolchain, ndk_target, abi_version)],
builds.ScummVMStableBuild: [ "--enable-debug",
# libcurl is detected using curl-config. Instead of modifying PATH just provide path to it to configure.
"--with-libcurl-prefix={0}/sysroot/usr/bin/{1}".format(android_stable_toolchain, ndk_target)],
}
platform.packaging_cmd = "androiddistdebug"
platform.built_files = {
builds.ScummVMBuild: [ "debug" ],
}
platform.archiveext = "zip"
platform.testable = False
platform.run_tests = False
platforms.append(platform)

android(suffix="arm",
scummvm_target="arm-v7a",
ndk_target="arm-linux-androideabi",
cxx_target="armv7a-linux-androideabi",
abi_version=16)
android(suffix="arm64",
scummvm_target="arm64-v8a",
ndk_target="aarch64-linux-android",
cxx_target="aarch64-linux-android",
abi_version=21)
android(suffix="x86",
scummvm_target="x86",
ndk_target="i686-linux-android",
cxx_target="i686-linux-android",
abi_version=16)
android(suffix="x86_64",
scummvm_target="x86_64",
ndk_target="x86_64-linux-android",
cxx_target="x86_64-linux-android",
abi_version=21)

def debian_x86_64():
platform = Platform("debian-x86_64")
platform.env["CXX"] = "ccache g++"
Expand Down
175 changes: 175 additions & 0 deletions toolchains/android/Dockerfile.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# This toolchain is made of two sub-toolchains one for stable ScummVM and one for master one
# Two sub-toolchains are used to avoid invalidating one when updating the other
# The merging process, being only copies, is faster

FROM toolchains/common AS helpers

m4_include(`paths.m4')m4_dnl

# Don't import packages.m4 as it clashes with functions defined here

m4_define(`local_sdk_package', COPY packages/$1 lib-helpers/packages/$1/
RUN $3 lib-helpers/packages/$1/build.sh $2)
m4_define(`local_package', COPY packages/$1 lib-helpers/packages/$1/
RUN $3 lib-helpers/multi-build.sh lib-helpers/packages/$1/build.sh $2)
m4_define(`helpers_package', COPY --from=helpers /lib-helpers/packages/$1 lib-helpers/packages/$1/
RUN $3 lib-helpers/multi-build.sh lib-helpers/packages/$1/build.sh $2)

##### master toolchain : NDK 21.0.6113669 + SDK licenses only / SDK and tools are download by Gradle #####
FROM debian:stable-slim AS toolchain-master
USER root

WORKDIR /usr/src

# Copy and execute each step separately to avoid invalidating cache
COPY --from=helpers /lib-helpers/prepare.sh lib-helpers/
RUN lib-helpers/prepare.sh

COPY --from=helpers /lib-helpers/functions.sh lib-helpers/

COPY functions-platform.sh lib-helpers/
COPY functions-sdk.sh lib-helpers/
COPY multi-build.sh lib-helpers/

# nasm is used for x86 ScummVM
# Create man directories to please openjdk which expects them
# cf. https://github.com/debuerreotype/debuerreotype/issues/10
RUN for i in $(seq 1 8); do mkdir -p "/usr/share/man/man${i}"; done && \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
default-jre-headless \
golang-go \
nasm && \
rm -rf /var/lib/apt/lists/*

# API is the API versions for which we will compile packages
# This variable can also be :
# - all which means all API versions of all possible targets
# - lowest the lowest API version for each target
# - version[:version...] which will search for the specified versions (or most approaching) in all targets
#
# API and ANDROID_NDK_VERSION must be kept in sync with ScummVM source tree
# If multiple NDKs must be installed (for stable and master),
# we should duplicate all instructions from this point
#
# API is synchronized with ScummVM minSdkVersion
# As we follow same rules as Android, we should
# always get the same API versions as expected by Android

ENV ANDROID_ROOT=/opt/android/master

ENV ANDROID_NDK_ROOT=${ANDROID_ROOT}/ndk \
ANDROID_NDK_VERSION=21.0.6113669 \
API=16 \
HOST_TAG=linux-x86_64

# Install NDK using settings above
local_sdk_package(ndk)

# Include the packaging instructions
m4_include(`packages_list.m4')

# Only install licenses on this version as everything will be installed by gradle
# It's installed last to avoid rebuilding everything if we just want to update licenses

ENV ANDROID_SDK_ROOT=${ANDROID_ROOT}/sdk
# Install SDK using settings above
local_sdk_package(sdk)

##### stable toolchain : NDK r14b and SDK 25 #####
FROM debian:stable-slim AS toolchain-stable
USER root

WORKDIR /usr/src

# Copy and execute each step separately to avoid invalidating cache
COPY --from=helpers /lib-helpers/prepare.sh lib-helpers/
RUN lib-helpers/prepare.sh

COPY --from=helpers /lib-helpers/functions.sh lib-helpers/

COPY functions-platform.sh lib-helpers/
# We don't need these functions for older SDK but that let's image reuse possible
COPY functions-sdk.sh lib-helpers/
COPY multi-build.sh lib-helpers/

# nasm is used for x86 ScummVM
# JDK is needed instead of JRE to patch Android SDK for OpenJDK 11
# Create man directories to please openjdk which expects them
# cf. https://github.com/debuerreotype/debuerreotype/issues/10
RUN for i in $(seq 1 8); do mkdir -p "/usr/share/man/man${i}"; done && \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
default-jdk-headless \
golang-go \
nasm && \
rm -rf /var/lib/apt/lists/*

# Unlike the newer toolchain, this one is quite static because it shouldn't evolve in time
# and many tricks may depend on the NDK version

ENV ANDROID_ROOT=/opt/android/stable

# Old toolchains need python to create toolchains and old ncurses
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
libncurses5 \
python && \
rm -rf /var/lib/apt/lists/*

# ABIS is for ndk-old package and determine how the unified toolchain will be composed
# API is none because we don't have new style folder hierarchy
ENV ANDROID_NDK_ROOT=${ANDROID_ROOT}/ndk \
TOOLCHAIN=${ANDROID_ROOT}/toolchain \
ABIS="arm/9 arm64/21 x86/9 x86_64/21" \
API="none" \
HOST_TAG=linux-x86_64

# Install NDK using settings above
local_sdk_package(ndk-old)

# Include the packaging instructions
m4_include(`packages_list.m4')

# Install an old (unsupported) SDK because build process depends on android project command

ENV ANDROID_SDK_ROOT=${ANDROID_ROOT}/sdk
local_sdk_package(sdk-old)

##### Resulting toolchain #####
FROM debian:stable-slim
USER root

WORKDIR /usr/src

# Copy and execute each step separately to avoid invalidating cache
COPY --from=helpers /lib-helpers/prepare.sh lib-helpers/
RUN lib-helpers/prepare.sh

COPY --from=helpers /lib-helpers/functions.sh lib-helpers/

COPY functions-platform.sh lib-helpers/
COPY functions-sdk.sh lib-helpers/
COPY multi-build.sh lib-helpers/

# Create man directories to please openjdk which expects them
# cf. https://github.com/debuerreotype/debuerreotype/issues/10
# ant is used by ScummVM build system
# file is used ndk-build in NDK 14
# libncurses5 is used by binaries in NDK 14
# nasm is used for x86 ScummVM
RUN for i in $(seq 1 8); do mkdir -p "/usr/share/man/man${i}"; done && \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ant \
default-jre-headless \
file \
libncurses5 \
nasm && \
rm -rf /var/lib/apt/lists/*

ENV ANDROID_ROOT=/opt/android

# Toolchains are not (yet?) relocatable, so we must not change their path once they are compiled
COPY --from=toolchain-master ${ANDROID_ROOT}/master/ ${ANDROID_ROOT}/master/
COPY --from=toolchain-stable ${ANDROID_ROOT}/stable/ ${ANDROID_ROOT}/stable/
37 changes: 37 additions & 0 deletions toolchains/android/functions-platform.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Paths are not standard in Android toolchain, adapt them
__do_configure_android () {
if [ "${API}" = "." ]; then
__do_configure --libdir=${PREFIX}/lib/${TARGET} --bindir=${PREFIX}/bin/${TARGET} "$@"
else
__do_configure --libdir=${PREFIX}/lib/${TARGET}/${API} \
--bindir=${PREFIX}/bin/${TARGET}/${API} "$@"
fi
}

__do_cmake_android () {
local cmake_target cmake_args orig_api
orig_api=${API}
if [ "${API}" = "." ]; then
API=$(sed -ne 's/^.*-D__ANDROID_API__=\([0-9]\+\) .*$/\1/p' "$CC")
cmake_args="-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang"
fi
case $TARGET in
arm-linux-androideabi) cmake_target=armeabi-v7a ;;
aarch64-linux-android) cmake_target=arm64-v8a ;;
i686-linux-android) cmake_target=x86 ;;
x86_64-linux-android) cmake_target=x86_64 ;;
*) error "Unknown target ${TARGET}" ;;
esac
__do_cmake -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=${cmake_target} \
-DANDROID_NATIVE_API_LEVEL=${API} \
-DCMAKE_INSTALL_LIBDIR=${PREFIX}/lib/${TARGET}/${orig_api} \
-DCMAKE_INSTALL_BINDIR=${PREFIX}/bin/${TARGET}/${orig_api} \
$cmake_args \
"$@"
}

for f in do_configure do_cmake; do
unset -f $f
eval "$f () { __${f}_android \"\$@\"; }"
done
37 changes: 37 additions & 0 deletions toolchains/android/functions-sdk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
CMDLINE_TOOLS_VERSION=6200805
CMDLINE_TOOLS_CHECKSUM="sha256:f10f9d5bca53cc27e2d210be2cbc7c0f1ee906ad9b868748d74d62e10f2c8275"

# Disable HTTPS to allow caching in optional proxy

do_install_sdk_tools () {
do_http_fetch tools "https://dl.google.com/android/repository/commandlinetools-${HOST_TAG%%-*}-${CMDLINE_TOOLS_VERSION}_latest.zip" 'unzip' \
"${CMDLINE_TOOLS_CHECKSUM}"

# Don't stay in tools subdirectory
cd ..

ANDROID_TEMP_SDK_DIR="$(pwd)"
export ANDROID_SDK_HOME="$(pwd)"

# Make sure we have the last version
yes | "${ANDROID_TEMP_SDK_DIR}/tools/bin/sdkmanager" --sdk_root="${ANDROID_TEMP_SDK_DIR}" --no_https --install "cmdline-tools;latest"
}

do_sdk_accept_licenses () {
local dst=$1
if [ -z "$dst" ]; then
dst=${ANDROID_TEMP_SDK_DIR}
fi

yes | "${ANDROID_TEMP_SDK_DIR}/tools/bin/sdkmanager" --sdk_root="$dst" --no_https --licenses >/dev/null
}

do_sdk_install () {
local pkg=$1 dst=$2
if [ -z "$dst" ]; then
dst=${ANDROID_TEMP_SDK_DIR}
fi

# Install requested NDK
yes | "${ANDROID_TEMP_SDK_DIR}/tools/bin/sdkmanager" --sdk_root="$dst" --no_https --install "$pkg"
}
Loading

0 comments on commit da62f82

Please sign in to comment.