summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2017-12-29 17:12:55 +0100
committerMax Kellermann <max@musicpd.org>2018-10-14 23:41:38 +0200
commit94592c14062d5afc9482d11baa401648082022c0 (patch)
tree8723d462737f883181fb1aaa3f91ee3d0add9721 /android
parent13ce142df137f346526de2a31a7ccbd59a903cdd (diff)
build with Meson instead of autotools
So long, autotools! This is my last MPD related project to migrate away from it. It has its strengths, but also very obvious weaknesses and weirdnesses. Today, many of its quirks are not needed anymore, and are cumbersome and slow. Now welcome our new Meson overlords!
Diffstat (limited to 'android')
-rwxr-xr-xandroid/apk/make-unsigned-apk.sh21
-rw-r--r--android/apk/meson.build59
-rwxr-xr-xandroid/build.py50
-rwxr-xr-xandroid/make-resources-apk.sh24
-rw-r--r--android/meson.build140
-rwxr-xr-xandroid/run-aidl.sh12
-rwxr-xr-xandroid/run-javac.sh22
7 files changed, 298 insertions, 30 deletions
diff --git a/android/apk/make-unsigned-apk.sh b/android/apk/make-unsigned-apk.sh
new file mode 100755
index 000000000..f6a2e9739
--- /dev/null
+++ b/android/apk/make-unsigned-apk.sh
@@ -0,0 +1,21 @@
+#!/bin/sh -e
+
+S=`dirname "$0"`
+ANDROID_ABI=$1
+STRIP=$2
+ZIP=$3
+UNSIGNED_APK=$4
+LIBMPD_SO=$5
+CLASSES_DEX=$6
+RESOURCES_APK=$7
+D=`dirname "$UNSIGNED_APK"`
+
+rm -rf "$D/apk"
+mkdir -p "$D/apk/lib/$ANDROID_ABI"
+
+"$STRIP" "$LIBMPD_SO" -o "$D/apk/lib/$ANDROID_ABI/`basename $LIBMPD_SO`"
+cp "$CLASSES_DEX" "$D/apk/"
+cp "$RESOURCES_APK" "$UNSIGNED_APK"
+
+cd "$D/apk"
+exec zip -q -r "../`basename $UNSIGNED_APK`" .
diff --git a/android/apk/meson.build b/android/apk/meson.build
new file mode 100644
index 000000000..fc9c81737
--- /dev/null
+++ b/android/apk/meson.build
@@ -0,0 +1,59 @@
+unsigned_apk = custom_target(
+ 'mpd-unsigned.apk',
+ output: 'mpd-unsigned.apk',
+ input: [mpd, classes_dex, resources_apk[0]],
+ command: [
+ join_paths(meson.current_source_dir(), 'make-unsigned-apk.sh'),
+ android_abi,
+ get_option('android_strip'),
+ zip,
+ '@OUTPUT0@',
+ '@INPUT@',
+ ],
+)
+
+if get_option('android_debug_keystore') != ''
+ debug_apk = custom_target(
+ 'mpd-debug.apk',
+ output: 'mpd-debug.apk',
+ input: unsigned_apk,
+ command: [
+ jarsigner,
+ '-keystore', get_option('android_debug_keystore'),
+ '-storepass', 'android',
+ '-signedjar', '@OUTPUT@',
+ '@INPUT@',
+ 'androiddebugkey',
+ ],
+ build_by_default: true
+ )
+endif
+
+if get_option('android_keystore') != '' and get_option('android_keyalias') != '' and get_option('android_keypass') != ''
+ unaligned_apk = custom_target(
+ 'mpd-unaligned.apk',
+ output: 'mpd-unaligned.apk',
+ input: unsigned_apk,
+ command: [
+ jarsigner,
+ '-digestalg', 'SHA1', '-sigalg', 'MD5withRSA',
+ '-keystore', get_option('android_keystore'),
+ '-storepass', get_option('android_keypass'),
+ '-signedjar', '@OUTPUT@',
+ '@INPUT@',
+ get_option('android_keyalias'),
+ ],
+ )
+
+ apk = custom_target(
+ 'mpd.apk',
+ output: 'mpd.apk',
+ input: unaligned_apk,
+ command: [
+ android_zipalign,
+ '-f', '4',
+ '@INPUT@', '@OUTPUT@',
+ ],
+ build_by_default: true
+ )
+endif
diff --git a/android/build.py b/android/build.py
index caf85f06c..dd8b74d23 100755
--- a/android/build.py
+++ b/android/build.py
@@ -57,6 +57,7 @@ sys.path[0] = os.path.join(mpd_path, 'python')
# output directories
from build.dirs import lib_path, tarball_path, src_path
+from build.meson import configure as run_meson
arch_path = os.path.join(lib_path, arch)
build_path = os.path.join(arch_path, 'build')
@@ -144,7 +145,15 @@ class AndroidNdkToolchain:
# redirect pkg-config to use our root directory instead of the
# default one on the build host
- self.env['PKG_CONFIG_LIBDIR'] = os.path.join(install_prefix, 'lib/pkgconfig')
+ import shutil
+ bin_dir = os.path.join(install_prefix, 'bin')
+ try:
+ os.makedirs(bin_dir)
+ except:
+ pass
+ self.pkg_config = shutil.copy(os.path.join(mpd_path, 'build', 'pkg-config.sh'),
+ os.path.join(bin_dir, 'pkg-config'))
+ self.env['PKG_CONFIG'] = self.pkg_config
# a list of third-party libraries to be used by MPD on Android
from build.libs import *
@@ -173,32 +182,13 @@ for x in thirdparty_libs:
toolchain = AndroidNdkToolchain(tarball_path, src_path, build_path,
use_cxx=True)
-configure = [
- os.path.join(mpd_path, 'configure'),
- 'CC=' + toolchain.cc,
- 'CXX=' + toolchain.cxx,
- 'CFLAGS=' + toolchain.cflags,
- 'CXXFLAGS=' + toolchain.cxxflags,
- 'CPPFLAGS=' + toolchain.cppflags,
- 'LDFLAGS=' + toolchain.ldflags,
- 'LIBS=' + toolchain.libs,
- 'AR=' + toolchain.ar,
- 'RANLIB=' + toolchain.ranlib,
- 'STRIP=' + toolchain.strip,
- '--host=' + toolchain.arch,
- '--prefix=' + toolchain.install_prefix,
- '--with-sysroot=' + toolchain.sysroot,
- '--with-android-sdk=' + sdk_path,
-
- '--enable-silent-rules',
-
- '--disable-icu',
-
-] + configure_args
-
-from build.cmdline import concatenate_cmdline_variables
-configure = concatenate_cmdline_variables(configure,
- set(('CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS', 'LIBS')))
-
-subprocess.check_call(configure, env=toolchain.env)
-subprocess.check_call(['/usr/bin/make', '--quiet', '-j12'], env=toolchain.env)
+configure_args += [
+ '-Dandroid_sdk=' + sdk_path,
+ '-Dandroid_ndk=' + ndk_path,
+ '-Dandroid_abi=' + android_abi,
+ '-Dandroid_strip=' + toolchain.strip,
+]
+
+from build.meson import configure as run_meson
+run_meson(toolchain, mpd_path, '.', configure_args)
+subprocess.check_call(['/usr/bin/ninja'], env=toolchain.env)
diff --git a/android/make-resources-apk.sh b/android/make-resources-apk.sh
new file mode 100755
index 000000000..bee1f4c81
--- /dev/null
+++ b/android/make-resources-apk.sh
@@ -0,0 +1,24 @@
+#!/bin/sh -e
+
+S=`dirname "$0"`
+AAPT=$1
+BASE_JAR=$2
+JAVA_PKG=$3
+JAVA_PKG_PATH=$4
+APK_FILE="$5"
+D=`dirname "$APK_FILE"`
+
+rm -rf "$D/res"
+mkdir -p "$D/res/drawable" "$D/src"
+cp "$D/icon.png" "$D/notification_icon.png" "$D/res/drawable/"
+
+"$AAPT" package -f -m --auto-add-overlay \
+ --custom-package "$JAVA_PKG" \
+ -M "$S/AndroidManifest.xml" \
+ -S "$D/res" \
+ -S "$S/res" \
+ -J "$D/src" \
+ -I "$BASE_JAR" \
+ -F "$D/resources.apk"
+
+cp "$D/src/$JAVA_PKG_PATH/R.java" "$D/"
diff --git a/android/meson.build b/android/meson.build
new file mode 100644
index 000000000..ddd3f030c
--- /dev/null
+++ b/android/meson.build
@@ -0,0 +1,140 @@
+android_package = 'org.musicpd'
+android_package_path = join_paths(android_package.split('.'))
+
+android_ndk = get_option('android_ndk')
+android_sdk = get_option('android_sdk')
+android_abi = get_option('android_abi')
+
+android_sdk_build_tools_version = '27.0.0'
+android_sdk_platform = 'android-21'
+
+android_build_tools_dir = join_paths(android_sdk, 'build-tools', android_sdk_build_tools_version)
+android_sdk_platform_dir = join_paths(android_sdk, 'platforms', android_sdk_platform)
+
+android_aidl = join_paths(android_build_tools_dir, 'aidl')
+android_aapt = join_paths(android_build_tools_dir, 'aapt')
+android_dx = join_paths(android_build_tools_dir, 'dx')
+android_zipalign = join_paths(android_build_tools_dir, 'zipalign')
+
+javac = find_program('javac')
+jarsigner = find_program('jarsigner')
+rsvg_convert = find_program('rsvg-convert')
+convert = find_program('convert')
+zip = find_program('zip')
+
+common_cppflags += '-I' + join_paths(meson.current_build_dir(), 'include')
+
+#
+# AIDL
+#
+
+IMainCallback_java = custom_target(
+ 'IMainCallback.java',
+ output: 'IMainCallback.java',
+ input: join_paths(meson.current_source_dir(), 'src', 'IMainCallback.aidl'),
+ command: [
+ join_paths(meson.current_source_dir(), 'run-aidl.sh'),
+ android_aidl,
+ '@INPUT@',
+ '@OUTPUT@',
+ join_paths(meson.current_build_dir(), 'src'),
+ android_package_path,
+ ],
+)
+
+IMain_java = custom_target(
+ 'IMain.java',
+ output: 'IMain.java',
+ input: join_paths(meson.current_source_dir(), 'src', 'IMain.aidl'),
+ depends: IMainCallback_java,
+ command: [
+ join_paths(meson.current_source_dir(), 'run-aidl.sh'),
+ android_aidl,
+ '@INPUT@',
+ '@OUTPUT@',
+ join_paths(meson.current_build_dir(), 'src'),
+ android_package_path,
+ ],
+)
+
+#
+# Resources
+#
+
+android_icon = custom_target(
+ 'Android icon',
+ output: 'icon.png',
+ input: '../mpd.svg',
+ command: [
+ rsvg_convert, '--width=48', '--height=48', '@INPUT@', '-o', '@OUTPUT@',
+ ],
+)
+
+android_notification_icon = custom_target(
+ 'Android notification icon',
+ output: 'notification_icon.png',
+ input: android_icon,
+ command: [
+ convert, '@INPUT@', '-colorspace', 'Gray', '-gamma', '2.2', '@OUTPUT@',
+ ],
+)
+
+resources_apk = custom_target(
+ 'resources.apk',
+ output: ['resources.apk', 'R.java'],
+ input: [
+ 'res/layout/custom_notification_gb.xml',
+ 'res/layout/log_item.xml',
+ 'res/layout/settings.xml',
+ 'res/values/strings.xml',
+ android_icon,
+ android_notification_icon,
+ ],
+ command: [
+ join_paths(meson.current_source_dir(), 'make-resources-apk.sh'),
+ android_aapt,
+ join_paths(android_sdk_platform_dir, 'android.jar'),
+ android_package,
+ android_package_path,
+ '@OUTPUT0@',
+ ],
+)
+
+#
+# Compile Java
+#
+
+classes_jar = custom_target(
+ 'classes.jar',
+ output: 'classes.jar',
+ input: [
+ 'src/Bridge.java',
+ 'src/Loader.java',
+ 'src/Main.java',
+ 'src/Receiver.java',
+ 'src/Settings.java',
+ IMain_java,
+ IMainCallback_java,
+ resources_apk[1],
+ ],
+ command: [
+ join_paths(meson.current_source_dir(), 'run-javac.sh'),
+ javac,
+ join_paths(android_sdk_platform_dir, 'android.jar'),
+ android_package_path,
+ zip,
+ '@OUTPUT@',
+ '@INPUT@',
+ ],
+)
+
+classes_dex = custom_target(
+ 'classes.dex',
+ output: 'classes.dex',
+ input: classes_jar,
+ command: [
+ android_dx,
+ '--dex', '--output', '@OUTPUT@',
+ '@INPUT@',
+ ],
+)
diff --git a/android/run-aidl.sh b/android/run-aidl.sh
new file mode 100755
index 000000000..986d75878
--- /dev/null
+++ b/android/run-aidl.sh
@@ -0,0 +1,12 @@
+#!/bin/sh -e
+
+AIDL=$1
+SRC=$2
+DST=$3
+GENSRC=$4
+JAVA_PKG_PATH=$5
+
+mkdir -p "$GENSRC/$JAVA_PKG_PATH"
+cp "$SRC" "$GENSRC/$JAVA_PKG_PATH/"
+"$AIDL" -I"$GENSRC" -o"$GENSRC" "$GENSRC/$JAVA_PKG_PATH/`basename $SRC`"
+exec cp "$GENSRC/$JAVA_PKG_PATH/`basename $DST`" "$DST"
diff --git a/android/run-javac.sh b/android/run-javac.sh
new file mode 100755
index 000000000..5cda96fe0
--- /dev/null
+++ b/android/run-javac.sh
@@ -0,0 +1,22 @@
+#!/bin/sh -e
+
+JAVAC=$1
+CLASSPATH=$2
+JAVA_PKG_PATH=$3
+ZIP=$4
+JARFILE=`realpath "$5"`
+shift 5
+
+D=`dirname "$JARFILE"`
+GENSRC="$D/src"
+GENCLASS="$D/classes"
+GENINCLUDE="$D/include"
+
+mkdir -p "$GENSRC/$JAVA_PKG_PATH"
+"$JAVAC" -source 1.6 -target 1.6 -Xlint:-options \
+ -cp "$CLASSPATH" \
+ -h "$GENINCLUDE" \
+ -d "$GENCLASS" \
+ "$@"
+cd "$GENCLASS"
+zip -q -r "$JARFILE" .