Build and use static library in Android NDK

Carlos Bautista picture Carlos Bautista · Feb 20, 2013 · Viewed 8.2k times · Source

I'm trying to build a library for my NativeActivity app and use it, but it is giving me an error:

Having these files:

-jni/
--android.mk
--application.mk
--main.cpp
--png/
---android.mk
---lodepng.c
---lodepng.h

The android.mk in jni/png/ is this:

LOCAL_PATH  := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := lodepng
LOCAL_SRC_FILES := lodepng.c
# LOCAL_C_INCLUDES  := $(LOCAL_PATH)
LOCAL_CFLAGS    := -DLODEPNG_NO_COMPILE_ENCODER -DLODEPNG_NO_COMPILE_DISK -DLODEPNG_NO_COMPILE_ANCILLARY_CHUNKS -DLODEPNG_NO_COMPILE_CPP

include $(BUILD_STATIC_LIBRARY)

And the android.mk in jni/ is this:

LOCAL_PATH  := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := myapp
LOCAL_SRC_FILES := main.cpp
# LOCAL_C_INCLUDES  := $(LOCAL_PATH)/png
LOCAL_CFLAGS    := -DANDROID
LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES  := lodepng android_native_app_glue

include $(BUILD_SHARED_LIBRARY)

include $(LOCAL_PATH)/png/android.mk

$(call import-module,android/native_app_glue)

(I have commented the C_INCLUDES as I'm not sure I need them. Using them or not has no difference in the result).

The error I get when I try to compile it, is this one:

C:\workspace\myapp> C:\cygwin\bin\bash --login -c "ndk-build -C ."
Compile++ thumb  : myapp <= main.cpp
Compile thumb  : lodepng <= lodepng.c
StaticLibrary  : liblodepng.a
SharedLibrary  : libmyapp.so
C:/android-ndk-r8d/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/..
/lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe:
 ./obj/local/armeabi/objs/myapp/main.o: in function init():jni/main.cpp:194:
 error: undefined reference to 'lodepng_decode32(unsigned char**, unsigned int*,
 unsigned int*, unsigned char const*, unsigned int)'
C:/android-ndk-r8d/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/..
/lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe:
 ./obj/local/armeabi/objs/myapp/main.o: in function init():jni/main.cpp:196:
 error: undefined reference to 'lodepng_error_text(unsigned int)'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/libmyapp.so] Error 1

In resume, it is like if the code could't find the header, of this lib. Nevertheless, It does compile, so that is not the problem...

What should I edit so I can make use of it?

Answer

Mārtiņš Možeiko picture Mārtiņš Možeiko · Feb 21, 2013

I'm guessing C++ name mangling is problem here. Your lodepng.c file provides _lodepng_decode32 symbol (as it is compiled as C code), but your main.cpp file expects something like _lodepng_decode32$asdaASd symbol (because it is compiled as C++ code).

You should rename lodepng.c to lodepng.cpp.

Or you need to put #include "lodepng.h" in your main.cpp file inside extern "C" { ... } block.