Post Written By: David Wingrove
Golden Hammer Software took a trip earlier this year to New York to attend the Intel Android CodeFest. We updated Big Mountain Snowboarding, Trick Shot Bowling, and Scribble Worm to run natively on Intel Android devices during that weekend. All three of these games use C++ through the NDK.
Java-based apps don't require any extra work for Intel devices. C++ apps compiled for ARM will run on Intel devices thanks to a run-time interpreter. C++ apps that are more processor intensive would benefit from cross-compiling for ARM and x86. The native x86 code should be faster and more efficient on an x86 device. This article shows the steps involved in setting up an NDK project to compile for multiple target platforms.
Compiling C++ for Multiple Architectures
The first step is to edit the Application.mk file to add additional platforms under the APP_ABI flag. It’s possible to put “all” here in order to create a .so file for every architecture supported by Android, but compile times would get very long. Unless you are using special armv7 api calls, x86 and armeabi should be enough. This will create two .so files. Unfortunately, it also doubles the compile time.
APP_ABI := x86 armeabi
Linking the .so Files with the Java Project
The two .so files will be created in [ndk project dir]\libs\armabi and [ndk project dir]\libs\x86. They need to be copied into separate directories under your Android java project.
We use a simple bat file to copy the files for us every time we compile. This file lives in our NDK\[Project]\jni folder.
CMD /C ..\..\..\..\..\..\contrib\android-ndk-r9c\ndk-build
copy ..\libs\armeabi\libGHBowling.so ..\..\..\GHBowling\libs\armeabi\libGHBowling.so
copy ..\libs\x86\libGHBowling.so ..\..\..\GHBowling\libs\x86\libGHBowling.so
Supporting Multiple C++ Libraries
Our games use multiple C++ libraries. We have our game-independent code in one library and our game code in a second library. The game library needs to link with the game-independent library. We were able to add a concrete relative path from one project to another when supporting only ARM, but the Android.mk file has to be updated when dealing with multiple targets. The flag $(TARGET_ARCH_ABI) will grab the appropriate library during each compile pass.
LOCAL_MODULE := libGHEngine
LOCAL_SRC_FILES := ../../GHEngine/obj/local/$(TARGET_ARCH_ABI)/libGHEngine.a
I highly recommend testing on an actual Intel Android device. There are subtle compiler differences. We had a null pointer crash that wasn't exposed until we compiled for x86. It was a real bug that existed on all platforms, but somehow the other compilers managed to create code that would function while touching out of bounds memory. When we ran the x86 Android code on a Samsung Intel Android tablet, the game crashed on startup until we found and fixed the bug.
Intel has created a series of tools to make Android development easier that can be found at /content/www/us/en/develop/android.html/tools. These include an emulator, a graphics profiler, a cross-platform library, and a full game engine. We have also benefitted from Intel® Developer Zone programs like the Intel Android Showcase.
Supporting Intel Android in your C++ app is a fairly easy process. ARM C++ libraries are likely to work without modification, but a couple simple makefile changes will make them run more efficiently. Java apps don't require any changes to support the new hardware.
David Wingrove has four years of experience making Android applications and 14 years of experience making games. He is the co-founder of Golden Hammer Software, and has released games for Android, Wii, PC, iOS, Blackberry, and other platforms.
Related Articles and Resources:
Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice.
Notice revision #20110804