Table of Contents
- Background
- My setup
- UPDATE
- Lexicon
- The issue
- Cause
- Solution
- Java
- Debugging Ant’s build.xml
- Android NDK
- Android SDK Manager
- Hack
- Re-compile Lime
- Done!
Background
Google unwrapped a new app store policy this holiday season: https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html
In summary, in late 2018 new apps and updates to existing apps will need to target Android API version 26
or newer. In addition in 2019 64-bit
native libraries will be mandatory.
I started developing Peasant Knight years ago so it uses HaxeFlixel/OpenFL/lime versions which are quite old and don’t run with newer Android APIs out of the box. It took me many frustrating hours to update from Android API 16
to 26
, and I hope this write-up will save others from the same pain.
I haven’t tried compiling to other architectures yet (Lime compiles to 32-bit
ARMv7
by default). That will remain an article for another day.
Lime logo by underscorediscovery. The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.
My setup
- Haxe
3.2.0
- HaxeFlixel
3.3.11
- OpenFL
3.1.4
- Lime
2.5.0
- hxcpp
3.3.49
- Those are very old versions of course but in my case they’re not worth updating
UPDATE
Here’s another working setup kindly contributed by a friend:
- Haxe
4.3.3
- HaxeFlixel
4.3.0
- latest as of January 2018 - OpenFL
3.6.1
- Lime
2.9.1
- hxcpp
3.4.64
Lexicon
Most of the frustration stems from the fact that there’s no unified documentation for all the tools involved in a Lime Android build, and there’s quite a few. You just kind of get it after messing around and going through endless GitHub issues and forum posts. Hence the title. I won’t go into detail here but I’ll at least list all the Android-specific tools involved:
32/64 bit
: There’s overwhelming odds that your operating system supports 64-bit. Download only the 64-bit versions of everything. A mismatch could prevent the Android build process from executing correctly.Java JDK/JRE
: Java comes mainly in two flavors: the Java development kit which notably includes the Java compiler, and the Java runtime environment which is for end-users. The Android build process only requires the JDK.Android SDK Manager
: This is a now obsolete package which includes many tools (like Ant) that run during the build process. It’s also a download manager for Android tools and SDKs.Android SDK Tools
: Replaces the obsolete SDK Manager. They’re essentially equivalent, but old versions of Lime may or may not work with the new replacement.Android NDK
: Native Android toolkit for C/C++. Our C++ translated Haxe code is compiled and linked using this toolkit.Ant
: Invokes all the other tools during a build process. It’s like a very powerful batch file or shell script.build-tools
: A collection of tools used during the build process.Target Android SDK/API/platform
: Java libraries and more that are included in the build. The Android OS also treats applications differently depending on the API they are targeting.Lime ndll libraries
: A regular Lime installation provides pre-compiled lime dynamic libraries. These have been compiled using some specific Android NDK and API for a specific set of CPU architectures. Depending on the desired usage they may need to be re-compiled using a different NDK/API or for other CPU architectures.
The issue
I was able to compile with target-sdk 26
, but I was getting the following error on launch: java.lang.UnsatisfiedLinkError: dlopen failed: library "/home/joshua/Development/Android/android-ndk-r8b/platforms/android-9/arch-arm/usr/lib/libc.so" not found
.
You can find more info about it in this GitHub hxcpp issue and in this OpenFL forum post.
Cause
This happens because Android’s dynamic linker underwent a breaking change in API 23
. Old OpenFL/Lime versions were compiled with Android NDK version r8b
which is incompatible with this new dynamic linker.
Solution
Make sure to use Android NDK r9d
or later, and re-compile the Lime libraries with that newer NDK. Be careful with using r14
or later, as header files and some other files have been moved and/or renamed.
Java
- Remove all installed Java versions
- Install
Java JDK 1.8 64-bit
(I usedjdk1.8.0_151
) 64-bit, AND DO NOT INSTALL THE JRE WHEN PROMPTED - Set the
JAVA_HOME
environment variable to your JDK installation directory - The Android build process is often confused about which Java version to use. This can cause it to use different Java versions at different steps and run into version conflicts down the line. Be safe.
Debugging Ant’s build.xml
If you want to see precisely which Java executables are used during the build process, or similar details, you can ask Ant to produce a log file. You would need to add the following line to the <Android SDK Manager>/tools/ant/build.xml
file:
<record name="C:/Users/<Username>/Desktop/build.log" loglevel="debug" action="start" />
Android NDK
- Download
Android NDK
versionr9d
64-bit - Make sure Lime is pointed to its path
Android SDK Manager
- Download
Android SDK Manager
version22.0.5
- Make sure Lime is pointed to its path
Hack
- Download
Android SDK Tools
version26.0.1
- Using
Android SDK Tools
runsdkmanager platforms;android-26
- Copy
<Android SDK Tools path>/platforms/android-26
over to<Android SDK Manager path>/platforms
- Using
Android SDK Tools
runsdkmanager build-tools;26.0.3
- Copy
<Android SDK Tools path>/build-tools/26.0.3
over to<Android SDK Manager path>/build-tools
- This is necessary because
Android SDK Manager
is obsolete and incapable of downloading these packages but can still use them if we simply move them to the correct locations.
Re-compile Lime
- Run
openfl rebuild hxcpp android -clean
git clone
Lime into<Haxe libs path>/lime
(haxelib releases of Lime can’t be recompiled)- Checkout the tag containing your version of Lime (
2.5.0
in my case) - Update the submodules
- Rename your current Lime directory, and give its previous name to the cloned one
- Run
haxelib install format
- Run
lime rebuild android -Dlegacy
- Run
lime rebuild tools
- The resulting Lime libraries will work with the new dynamic linker
Done!
- Set
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="26" />
in yourAndroidManifest.xml
- Set
<android target-sdk-version="26" />
in yourProject.xml
- Run
lime build android -release
and test