This recipe discusses how to port a command-line executable to Android with an NDK build system. We will use the open source Fugenschnitzer program (fusch
) as
an example.
You should read the Porting a library as a static library with an Android NDK build system recipe in Chapter 8, Porting and Using Existing Libraries with Android NDK, before going through this one.
The following steps describe how to port the fusch
program to Android with an NDK build system:
cookbook.chapter9.portingexecutable
. Refer to the Loading native libraries and registering native methods recipe in Chapter 2, Java Native Interface, if you want more detailed instructions.jni
folder of the project.fusch
library and command-line application from http://fugenschnitzer.sourceforge.net/main_en.html. Extract the archive files and put them into the jni/fusch
and jni/fusch_lib
folders respectively.libpng 1.2.50
from http://sourceforge.net/projects/libpng/files/libpng12/1.2.50/ and extract the files to the jni/libpng-1.2.50
folder. The latest version of libpng
won't work because the interface is different.Android.mk
file under the jni/libpng-1.2.50
folder to build libpng
as a static library module. The file has the following content:LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS := LOCAL_MODULE := libpng LOCAL_SRC_FILES := png.c pngerror.c pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c pngrutil.c pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c LOCAL_LDLIBS := -lz LOCAL_EXPORT_LDLIBS := -lz LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) include $(BUILD_STATIC_LIBRARY)
Android.mk
file under the jni/fusch_lib
folder to build libseamcarv
as a static library module. The file content is as follows:LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libseamcarv LOCAL_SRC_FILES := sc_core.c sc_carve.c sc_color.c sc_shift.c sc_mgmnt.c seamcarv.c LOCAL_CFLAGS := -std=c99 LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) include $(BUILD_STATIC_LIBRARY)
Android.mk
file under the jni/fusch
folder to build the fusch
executable, which uses the two static libraries built in the two folders libpng-1.2.50
and fusch_lib
.LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := fusch LOCAL_SRC_FILES := fusch.c LOCAL_CFLAGS := -std=c99 LOCAL_STATIC_LIBRARIES := libpng libseamcarv include $(BUILD_EXECUTABLE)
Android.mk
file under the jni
folder to include the Android.mk
files under its subfolders.LOCAL_PATH := $(call my-dir) include $(call all-subdir-makefiles)
fusch
, under the libs/armeabi
folder. We can put this binary into a rooted Android device or an emulator with the following command:$ adb push fusch /data/data/
$ adb shell # cd /data/data # chmod 755 fusch # ./fusch
This will print out the help message of the program.
cookbook_ch9_test.png
(available under the assets
folder of the sample project's source code) to the testing device or emulator with the following command:$ adb push cookbook_ch9_test.png /data/data/
fusch
program again with the following command:# ./fusch cookbook_ch9_test.png 1.png h-200
$ adb pull /data/data/1.png .
The sample project demonstrates how to port the fusch
program as a command-line executable to Android. We describe the sources to the Android
NDK build system in the Android.mk
file and the NDK build system handles the rest.
The steps to port a command-line executable are as follows:
fusch
depends on libseamcarv
(in the fusch_lib
folder) and libpng
, and libpng
subsequently depends on zlib
.libseamcarv
and libpng
in our sample application. But as zlib
is available on Android, we simply need to link to it.We have covered most of the Android.mk
variables and macros in Chapter 8, Porting and Using Existing Libraries with Android NDK. We will introduce two more predefined variables here. You can also refer to the Android NDK file docs/ANDROID-MK.html
for information on more macros and variables.
LOCAL_CFLAGS
: A module description variable. This allows us to specify additional compiler options or macro definitions for building C and C++ source files. Another variable that serves a similar purpose is LOCAL_CPPFLAGS
, but for C++ source files only. In our sample project, we passed -std=c99
to the compiler when building libseamcarv
and fusch
. This asks the compiler to accept ISO C99 C language standard syntax. Failing to specify the flag will result in compilation errors at the time of building.BUILD_EXECUTABLE
: A GNU make variable. It points to a build script that collects all information about the executable that we want to build and determines how to build it. It is similar to BUILD_SHARED_LIBRARY
and BUILD_STATIC_LIBRARY
except that it is for executables. It is used when building fusch
in our sample project.include $(BUILD_EXECUTABLE)
With this explanation and the knowledge we acquired in Chapter 8, Porting and Using Existing Libraries with Android NDK, it is now fairly easy to understand the four Android.mk
files used in our sample application. We ported libpng
and libseamcarv
as two static library modules. We
export the dependent libraries (with LOCAL_EXPORT_LDLIBS
) and header files (with LOCAL_EXPORT_C_INCLUDES
), so they are automatically included when using the module. When porting libpng
, we also link to the zlib
library (with LOCAL_LDLIBS
) available on the Android system. Finally, we port the fusch
program by referring to the two library modules (with LOCAL_STATIC_LIBRARIES
).