From 94592c14062d5afc9482d11baa401648082022c0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 29 Dec 2017 17:12:55 +0100 Subject: 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! --- android/apk/make-unsigned-apk.sh | 21 ++++++ android/apk/meson.build | 59 +++++++++++++++++ android/build.py | 50 ++++++-------- android/make-resources-apk.sh | 24 +++++++ android/meson.build | 140 +++++++++++++++++++++++++++++++++++++++ android/run-aidl.sh | 12 ++++ android/run-javac.sh | 22 ++++++ 7 files changed, 298 insertions(+), 30 deletions(-) create mode 100755 android/apk/make-unsigned-apk.sh create mode 100644 android/apk/meson.build create mode 100755 android/make-resources-apk.sh create mode 100644 android/meson.build create mode 100755 android/run-aidl.sh create mode 100755 android/run-javac.sh (limited to 'android') 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" . -- cgit v1.2.3