mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-12-23 03:11:30 +00:00
Move build script to python (#1184)
This commit is contained in:
parent
88535ed16f
commit
988bbb0893
5 changed files with 139 additions and 131 deletions
11
README.md
11
README.md
|
@ -27,18 +27,9 @@ Make sure you clone the project with
|
||||||
`git clone https://github.com/syncthing/syncthing-android.git --recursive`. Alternatively, run
|
`git clone https://github.com/syncthing/syncthing-android.git --recursive`. Alternatively, run
|
||||||
`git submodule init && git submodule update` in the project folder.
|
`git submodule init && git submodule update` in the project folder.
|
||||||
|
|
||||||
Build Syncthing using `./syncthing/build-syncthing.bash`. Then use `./gradlew assembleDebug` or
|
Build Syncthing using `./gradlew buildNative`. Then use `./gradlew assembleDebug` or
|
||||||
Android Studio to build the apk.
|
Android Studio to build the apk.
|
||||||
|
|
||||||
### Building on Windows
|
|
||||||
|
|
||||||
To build the Syncthing app on Windows we need to have cygwin installed.
|
|
||||||
|
|
||||||
From a cygwin shell in the project directory, build Syncthing using `./syncthing/build-syncthing.bash`
|
|
||||||
|
|
||||||
Lastly, use `./gradlew assembleDebug` in the project directory to compile the APK, or use Android
|
|
||||||
Studio to build/deploy the APK.
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
The project is licensed under the [MPLv2](LICENSE).
|
The project is licensed under the [MPLv2](LICENSE).
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
for ARCH in arm x86 arm64; do
|
for ARCH in arm x86 arm64; do
|
||||||
GOARCH=${ARCH}
|
GOARCH=${ARCH}
|
||||||
SDK=14
|
SDK=16
|
||||||
case ${ARCH} in
|
case ${ARCH} in
|
||||||
arm)
|
arm)
|
||||||
GCC="arm-linux-androideabi-clang"
|
GCC="arm-linux-androideabi-clang"
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ -z "${ANDROID_NDK_HOME}" ]; then
|
|
||||||
echo "Please set ANDROID_NDK_HOME environment variable"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
MODULE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
||||||
PROJECT_DIR="${MODULE_DIR}/.."
|
|
||||||
MIN_SDK=$(grep "minSdkVersion" "${PROJECT_DIR}/app/build.gradle" -m 1 | awk '{print $2}')
|
|
||||||
# Use seperate build dir so standalone ndk isn't deleted by `gradle clean`
|
|
||||||
BUILD_DIR="${MODULE_DIR}/gobuild"
|
|
||||||
GO_BUILD_DIR="${BUILD_DIR}/go-packages"
|
|
||||||
export GOPATH="${MODULE_DIR}/"
|
|
||||||
|
|
||||||
if [ "${OSTYPE}" = "cygwin" ]; then
|
|
||||||
export GOPATH=`cygpath -w ${GOPATH}`
|
|
||||||
GO_BUILD_DIR=`cygpath -w ${GO_BUILD_DIR}`
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "${MODULE_DIR}/src/github.com/syncthing/syncthing"
|
|
||||||
|
|
||||||
# Make sure all tags are available for git describe
|
|
||||||
# https://github.com/syncthing/syncthing-android/issues/872
|
|
||||||
git fetch --tags
|
|
||||||
|
|
||||||
for ANDROID_ARCH in arm x86 arm64; do
|
|
||||||
echo -e "Starting build for ${ANDROID_ARCH}\n"
|
|
||||||
case ${ANDROID_ARCH} in
|
|
||||||
arm)
|
|
||||||
GOARCH=arm
|
|
||||||
JNI_DIR="armeabi"
|
|
||||||
GCC="arm-linux-androideabi-clang"
|
|
||||||
;;
|
|
||||||
arm64)
|
|
||||||
GOARCH=arm64
|
|
||||||
JNI_DIR="arm64-v8a"
|
|
||||||
GCC="aarch64-linux-android-clang"
|
|
||||||
# arm64 requires at least API 21.
|
|
||||||
MIN_SDK=21
|
|
||||||
;;
|
|
||||||
x86)
|
|
||||||
GOARCH=386
|
|
||||||
JNI_DIR="x86"
|
|
||||||
GCC="i686-linux-android-clang"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid architecture"
|
|
||||||
exit 1
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -z "${SYNCTHING_ANDROID_PREBUILT}" ]; then
|
|
||||||
# Build standalone NDK toolchain if it doesn't exist.
|
|
||||||
# https://developer.android.com/ndk/guides/standalone_toolchain.html
|
|
||||||
STANDALONE_NDK_DIR="${BUILD_DIR}/standalone-ndk/android-${MIN_SDK}-${GOARCH}"
|
|
||||||
PKG_ARGUMENT="-pkgdir ${GO_BUILD_DIR}"
|
|
||||||
else
|
|
||||||
# The environment variable indicates the SDK and stdlib was prebuilt, set a custom paths.
|
|
||||||
STANDALONE_NDK_DIR="${ANDROID_NDK_HOME}/standalone-ndk/android-${MIN_SDK}-${GOARCH}"
|
|
||||||
PKG_ARGUMENT=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d "$STANDALONE_NDK_DIR" ]; then
|
|
||||||
if ! which python &>/dev/null; then
|
|
||||||
echo "Could not find python"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# We can't build the NDK with Cygwin/MinGW provided python, check that python is reporting a sensible host system.
|
|
||||||
# Also, strip \r as that is returned by Windows python.
|
|
||||||
HOST_PLATFORM=`python -c 'import platform; print platform.system()' | tr -d '\r'`
|
|
||||||
|
|
||||||
case ${HOST_PLATFORM} in
|
|
||||||
Windows|Linux|Darwin)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Cannot build NDK with Python provided by an unsupported system: ${HOST_PLATFORM}"
|
|
||||||
echo "Please make sure that python that is available on the path is native to your host platform (Windows/Linux/Darwin)"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ "${OSTYPE}" = "cygwin" ]; then
|
|
||||||
STANDALONE_NDK_DIR=`cygpath -w ${STANDALONE_NDK_DIR}`
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "Building standalone NDK\n"
|
|
||||||
${ANDROID_NDK_HOME}/build/tools/make-standalone-toolchain.sh \
|
|
||||||
--platform=android-${MIN_SDK} --arch=${ANDROID_ARCH} \
|
|
||||||
--install-dir=${STANDALONE_NDK_DIR}
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "Building Syncthing\n"
|
|
||||||
CGO_ENABLED=1 CC="${STANDALONE_NDK_DIR}/bin/${GCC}" \
|
|
||||||
go run build.go -goos android -goarch ${GOARCH} $PKG_ARGUMENT -no-upgrade build
|
|
||||||
|
|
||||||
# Copy compiled binary to jniLibs folder
|
|
||||||
TARGET_DIR="${PROJECT_DIR}/app/src/main/jniLibs/${JNI_DIR}"
|
|
||||||
mkdir -p ${TARGET_DIR}
|
|
||||||
mv syncthing ${TARGET_DIR}/libsyncthing.so
|
|
||||||
|
|
||||||
echo -e "Finished build for ${ANDROID_ARCH}\n"
|
|
||||||
|
|
||||||
done
|
|
||||||
|
|
||||||
echo -e "All builds finished"
|
|
132
syncthing/build-syncthing.py
Normal file
132
syncthing/build-syncthing.py
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import platform
|
||||||
|
|
||||||
|
SUPPORTED_PYTHON_PLATFORMS = ['Windows', 'Linux', 'Darwin']
|
||||||
|
|
||||||
|
BUILD_TARGETS = [
|
||||||
|
{
|
||||||
|
'arch': 'arm',
|
||||||
|
'goarch': 'arm',
|
||||||
|
'jni_dir': 'armeabi',
|
||||||
|
'cc': 'arm-linux-androideabi-clang',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'arch': 'arm64',
|
||||||
|
'goarch': 'arm64',
|
||||||
|
'jni_dir': 'arm64-v8a',
|
||||||
|
'cc': 'aarch64-linux-android-clang',
|
||||||
|
'min_sdk': 21,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'arch': 'x86',
|
||||||
|
'goarch': '386',
|
||||||
|
'jni_dir': 'x86',
|
||||||
|
'cc': 'i686-linux-android-clang',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def fail(message, *args, **kwargs):
|
||||||
|
print((message % args).format(**kwargs))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def get_min_sdk(project_dir):
|
||||||
|
with open(os.path.join(project_dir, 'app', 'build.gradle')) as file_handle:
|
||||||
|
for line in file_handle:
|
||||||
|
tokens = list(filter(None, line.split()))
|
||||||
|
if len(tokens) == 2 and tokens[0] == 'minSdkVersion':
|
||||||
|
return int(tokens[1])
|
||||||
|
|
||||||
|
fail('Failed to find minSdkVersion')
|
||||||
|
|
||||||
|
|
||||||
|
def get_ndk_home():
|
||||||
|
if not os.environ.get('ANDROID_NDK_HOME', ''):
|
||||||
|
fail('ANDROID_NDK_HOME environment variable not defined')
|
||||||
|
return os.environ['ANDROID_NDK_HOME']
|
||||||
|
|
||||||
|
|
||||||
|
if platform.system() not in SUPPORTED_PYTHON_PLATFORMS:
|
||||||
|
fail('Unsupported python platform %s. Supported platforms: %s', platform.system(),
|
||||||
|
', '.join(SUPPORTED_PYTHON_PLATFORMS))
|
||||||
|
|
||||||
|
module_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
project_dir = os.path.realpath(os.path.join(module_dir, '..'))
|
||||||
|
# Use seperate build dir so standalone ndk isn't deleted by `gradle clean`
|
||||||
|
build_dir = os.path.join(module_dir, 'gobuild')
|
||||||
|
go_build_dir = os.path.join(build_dir, 'go-packages')
|
||||||
|
syncthing_dir = os.path.join(module_dir, 'src', 'github.com', 'syncthing', 'syncthing')
|
||||||
|
min_sdk = get_min_sdk(project_dir)
|
||||||
|
|
||||||
|
# Make sure all tags are available for git describe
|
||||||
|
# https://github.com/syncthing/syncthing-android/issues/872
|
||||||
|
subprocess.check_call([
|
||||||
|
'git',
|
||||||
|
'-C',
|
||||||
|
syncthing_dir,
|
||||||
|
'fetch',
|
||||||
|
'--tags'
|
||||||
|
])
|
||||||
|
|
||||||
|
for target in BUILD_TARGETS:
|
||||||
|
target_min_sdk = str(target.get('min_sdk', min_sdk))
|
||||||
|
print('Building for', target['arch'])
|
||||||
|
|
||||||
|
if os.environ.get('SYNCTHING_ANDROID_PREBUILT', ''):
|
||||||
|
# The environment variable indicates the SDK and stdlib was prebuilt, set a custom paths.
|
||||||
|
standalone_ndk_dir = '%s/standalone-ndk/android-%s-%s' % (
|
||||||
|
get_ndk_home(), target_min_sdk, target['goarch']
|
||||||
|
)
|
||||||
|
pkg_argument = []
|
||||||
|
else:
|
||||||
|
# Build standalone NDK toolchain if it doesn't exist.
|
||||||
|
# https://developer.android.com/ndk/guides/standalone_toolchain.html
|
||||||
|
standalone_ndk_dir = '%s/standalone-ndk/android-%s-%s' % (
|
||||||
|
build_dir, target_min_sdk, target['goarch']
|
||||||
|
)
|
||||||
|
pkg_argument = ['-pkgdir', os.path.join(go_build_dir, target['goarch'])]
|
||||||
|
|
||||||
|
if not os.path.isdir(standalone_ndk_dir):
|
||||||
|
print('Building standalone NDK for', target['arch'], 'API level', target_min_sdk, 'to', standalone_ndk_dir)
|
||||||
|
subprocess.check_call([
|
||||||
|
sys.executable,
|
||||||
|
os.path.join(get_ndk_home(), 'build', 'tools', 'make_standalone_toolchain.py'),
|
||||||
|
'--arch',
|
||||||
|
target['arch'],
|
||||||
|
'--api',
|
||||||
|
target_min_sdk,
|
||||||
|
'--install-dir',
|
||||||
|
standalone_ndk_dir,
|
||||||
|
'-v'
|
||||||
|
])
|
||||||
|
|
||||||
|
print('Building syncthing')
|
||||||
|
|
||||||
|
environ = os.environ.copy()
|
||||||
|
environ.update({
|
||||||
|
'GOPATH': module_dir,
|
||||||
|
'CGO_ENABLED': '1',
|
||||||
|
'CC': os.path.join(standalone_ndk_dir, 'bin', target['cc'])
|
||||||
|
})
|
||||||
|
|
||||||
|
subprocess.check_call([
|
||||||
|
'go', 'run', 'build.go', '-goos', 'android', '-goarch', target['goarch'],
|
||||||
|
] + pkg_argument + ['-no-upgrade', 'build'], env=environ, cwd=syncthing_dir)
|
||||||
|
|
||||||
|
# Copy compiled binary to jniLibs folder
|
||||||
|
target_dir = os.path.join(project_dir, 'app', 'src', 'main', 'jniLibs', target['jni_dir'])
|
||||||
|
if not os.path.isdir(target_dir):
|
||||||
|
os.makedirs(target_dir)
|
||||||
|
target_artifact = os.path.join(target_dir, 'libsyncthing.so')
|
||||||
|
if os.path.exists(target_artifact):
|
||||||
|
os.unlink(target_artifact)
|
||||||
|
os.rename(os.path.join(syncthing_dir, 'syncthing'), target_artifact)
|
||||||
|
|
||||||
|
print('Finished build for', target['arch'])
|
||||||
|
|
||||||
|
print('All builds finished')
|
|
@ -1,21 +1,14 @@
|
||||||
import org.gradle.internal.os.OperatingSystem
|
|
||||||
|
|
||||||
task buildNative(type: Exec) {
|
task buildNative(type: Exec) {
|
||||||
outputs.upToDateWhen { false }
|
inputs.dir("$projectDir/src/")
|
||||||
if (OperatingSystem.current().isWindows()) {
|
outputs.dir("$projectDir/../app/src/main/jniLibs/")
|
||||||
if (!file("../app/src/main/jniLibs").exists()) {
|
executable = 'python'
|
||||||
throw new GradleException('Please run ./build-syncthing.bash via cygwin/MinGW manually')
|
args = ['-u', './build-syncthing.py']
|
||||||
}
|
|
||||||
executable = 'rundll32' // Does nothing
|
|
||||||
} else {
|
|
||||||
executable = './build-syncthing.bash'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use separate task instead of standard clean(), so these folders aren't deleted by `gradle clean`.
|
* Use separate task instead of standard clean(), so these folders aren't deleted by `gradle clean`.
|
||||||
*/
|
*/
|
||||||
task cleanNative(type: Delete) {
|
task cleanNative(type: Delete) {
|
||||||
delete "../app/src/main/jniLibs/"
|
delete "$projectDir/../app/src/main/jniLibs/"
|
||||||
delete "gobuild"
|
delete "gobuild"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue