Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

How to Set Up an NDK Project to Compile for Multiple Target Platforms

5.00/5 (2 votes)
14 Aug 2014CPOL3 min read 12.8K  
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.

This article is for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers

Introduction

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.

Application.mk

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.

Android.mk

include $(CLEAR_VARS)

LOCAL_MODULE := libGHEngine

LOCAL_SRC_FILES := ../../GHEngine/obj/local/$(TARGET_ARCH_ABI)/libGHEngine.a

include $(PREBUILT_STATIC_LIBRARY)

Compiler Differences

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.

Final Thoughts

Intel has created a series of tools to make Android development easier that can be found at https://software.intel.com/en-us/android/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.

Related Articles and Resources

Author Bio

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)