Android NDK - Use of APP_STL in Application.mk - android

I have the latest android ndk installed. I am using Eclipse along with Sequoyah.
I am trying to use various things that should be found in stlport or gnustl libraries, but I keep getting errors that they cannot be found.
In JNI/Application.mk I only have
APP_STL := stlport_shared
I have tried stlport_static and the gnustl_static/shared and all get the same result.
In my Android.mk I have
LIB_TEST_DIR := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PATH := $(LIB_TEST_DIR)
LOCAL_MODULE := testmod
LOCAL_MODULE_FILENAME := libtestmod
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libtest2/
LOCAL_CFLAGS := -DHAVE_CONFIG_H
LOCAL_SRC_FILES := test.cc
include $(BUILD_SHARED_LIBRARY)
In a header file that test.cc includes, I have
#include <cassert>
#include <algorithm>
#include <iosfwd>
But, when I build, it cannot find any of these. Any idea what I am doing wrong?
When I do a clean, I see this:
Clean: addiJNI [armeabi]
Clean: stlport_shared [armeabi]
Clean: stlport_static [armeabi]
So, it seems like it knew I wanted stlport. Similar thing happens if I use the gnu libs instead. But when I build even the simplest example, I get something like...
jni/test.cpp:4:19: error: cassert: No such file or directory
jni/test.cpp:6:21: error: algorithm: No such file or directory
jni/test.cpp:7:18: error: iosfwd: No such file or directory
make: *** [obj/local/armeabi/objs/addiJNI/addiJNI.o] Error 1

This was the problem, not sure why.
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
It didn't like the .cxx at the beginning.

Related

ANDROID: How to properly link against static libraries while creating shared libraries with dependencies on the static ones

I have to use some c++ code in my android application. This code was used successfully in an iOS project.
The code depends on 2 external libraries: zero-mq and protocol buffers.
I compiled the zmq library as an static library like explained here. I added the static (.a) library and the .jar to my project.
I created the protobuf library with the following configurations:
./configure --host=arm-eabi --with-sysroot=x/android-ndk-r10d/platforms/android-21/arch-arm CC="x/android-ndk-r10d/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot x/android-ndk-r10d/platforms/android-21/arch-arm" --enable-cross-compile --with-protoc=protoc LIBS=-lc
make
I changed the real directories to x to make them shorter.
In my Android Project(IDE: Android Studio) I prepared everything which is necessary. I created a JNI Folder and deactivated the auto-creation of the makefiles.
Application.mk:
APP_MODULE := proxy
APP_STL := gnustl_shared
APP_CPPFLAGS := -frtti -fexceptions --std=c++11
APP_ABI := armeabi-v7a ##all later
NDK_TOOLCHAIN_VERSION := 4.9
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := zmq_static
LOCAL_SRC_FILES := zmq/libzmq.a
include $(PREBUILD_STATIC_LIBRARY)
LOCAL_MODULE := protobuf_static1
LOCAL_SRC_FILES := protobuf/libprotobuf.a
LOCAL_EXPORT_C_INCLUDES := google/protobuf protobuf/
include $(PREBUILD_STATIC_LIBRARY)
LOCAL_MODULE := protobuf_static2
LOCAL_SRC_FILES := protobuf/libprotobuf-lite.a
LOCAL_EXPORT_C_INCLUDES := google/protobuf protobuf/
include $(PREBUILD_STATIC_LIBRARY)
LOCAL_MODULE := protobuf_static3
LOCAL_SRC_FILES := protobuf/libprotoc.a
LOCAL_EXPORT_C_INCLUDES := google/protobuf protobuf/
include $(PREBUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := proxy
LOCAL_CFLAGS := -I/include -pthread -lpthread -D__GXX_EXPERIMENTAL_CXX0X__ - frtti
LOCAL_CPPFLAGS := -I/include -pthread -lpthread -D__GXX_EXPERIMENTAL_CXX0X__ -frtti
LOCAL_CPP_FEATURES += exceptions
LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := \
usersession.cpp\
## LOCAL_ALLOW_UNDEFINED_SYMBOLS := true will compile the code but shutdown on runtime
LOCAL_C_INCLUDES += C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\main\jni
LOCAL_C_INCLUDES += C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\arm\jni
LOCAL_C_INCLUDES += C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\debug\jni
LOCAL_C_INCLUDES += C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\armDebug\jni
LOCAL_C_INCLUDES += \zmq
LOCAL_C_INCLUDES += \protobuf
LOCAL_STATIC_LIBRARIES := zmq_static protobuf_static1 protobuf_static2 protobuf_static3
LOCAL_WHOLE_STATIC_LIBRARIES := zmq_static protobuf_static1 protobuf_static2 protobuf_static3
include $(BUILD_SHARED_LIBRARY)
The zmq library is in the subdirectory zmq and the protobuf library is in the subfolder protobuf.
Now the linking of the Objects still does not work. The Error Output when I execute ndk-build:
C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\main\jni>ndk-build
[armeabi-v7a] SharedLibrary : libproxy.so
C:/Users/M/Documents/ndk/sources/cxx-stl/gnu- libstdc++/4.9/include/ext/new_allocator.h:127: error: undefined reference to 'ControlledInstance::ControlledInstan (std::shared_ptr<protogen::Application>, std:
:shared_ptr<protogen::Role>, std::shared_ptr<protogen::User>)'
C:/Users/M/Documents/ndk/sources/cxx-stl/gnu- libstdc++/4.9/include/bits/shared_ptr_base.h:511: error: undefined reference to 'protogen::User::User()'
C:/Users/M/Documents/ndk/sources/cxx-stl/gnu- libstdc++/4.9/include/bits/shared_ptr_base.h:914: error: undefined reference to 'google::protobuf::internal::empty tring_'
C:/Users/M/Dropbox/Workspace/ndk_swig_test/app/src/main//jni/controlledinstance.h :23: error: undefined reference to 'protogen::MetaGraph::~MetaGraph()'
collect2.exe: error: ld returned 1 exit status
make.exe: *** [C:/Users/M/Dropbox/Workspace/ndk_swig_test/app/src/main//obj/local/armeabi- v7a/libproxy.so] Error 1
I tried many versions of the Android.mk and recreated the library more than once with different options which I found all over the internet.
I also looked at dozens of threads on stackoverflow which did not help me.(I'm not allowed to link them because of low reputation)
Additionally i read most of the doc files from the ndk e.g. PREBUILTS.
I added some other directories to my JNI directory e.g. the directory with the original files and directories (compiler, io, stubs...). I think this directory should offer the export of the necessary methods if the prebuild library was successfully linked to my shared library - which is not the case.
I tried far more than I can explain in few minutes and I think it would be overkill if i added everything I've tried because nothing helped.
Because this is my first question I dont have the reputation to include more than 2 links. Sorry for that.
There may probably be other issues as well, but you at least have got a typo - it should be include $(PREBUILT_STATIC_LIBRARY), as in, BUILT, not BUILD.

WARNING: .../Android.mk: non-system libraries in linker flags

I'm getting this warning while running $ANDROID_NDK_ROOT/ndk-build. The Android.mk is below.
$ $ANDROID_NDK_ROOT/ndk-build
WARNING:/Users/jwalton/Android-CryptoPP/jni/Android.mk:prng:
non-system libraries in linker flags: -lcryptopp -lstlport_shared
This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
current module
...
However, when I follow the instructions and remove -lcryptopp -lstlport_shared from LOCAL_LDLIBS, then I get link errors related to symbols from libstlport_shared.so. A sample of the errors are shown below after the Android.mk file.
How, exactly, does ndk-build want Android.mk set up?
Why do I have to add $(STLPORT_INCL) to LOCAL_C_INCLUDES, and $(STLPORT_LIB) to LOCAL_LDFLAGS? Why does APP_STL := stlport_shared not setup the STL correctly out of the box?
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
TARGET_ARCH_ABI := armeabi
TARGET_ABI := android-9-armeabi
CRYPTOPP_INCL := /usr/local/cryptopp-android-9/include
CRYPTOPP_LIB := /usr/local/cryptopp-android-9/lib
STLPORT_INCL := /opt/android-ndk-r9/sources/cxx-stl/stlport/stlport
STLPORT_LIB := /opt/android-ndk-r9/sources/cxx-stl/stlport/libs/armeabi
APP_STL := stlport_shared
APP_MODULES := stlport_shared cryptopp
LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_C_INCLUDES := $(CRYPTOPP_INCL) $(CRYPTOPP_INCL)/cryptopp $(STLPORT_INCL)
LOCAL_LDFLAGS := -L $(CRYPTOPP_LIB) -L $(STLPORT_LIB)
LOCAL_LDLIBS := -lcryptopp -lstlport_shared -llog -landroid
# LOCAL_LDLIBS := -llog -landroid
# LOCAL_SHARED_LIBRARIES := -lcryptopp -lstlport_shared
LOCAL_MODULE := prng
LOCAL_SRC_FILES := libprng.cpp
include $(BUILD_SHARED_LIBRARY)
Here is a sample of the error when trying to follow the advice by removing my local libraries from LOCAL_LDLIBS:
$ $ANDROID_NDK_ROOT/ndk-build
Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 9 in /Users/jwalton/Android-CryptoPP/AndroidManifest.xml
Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
Compile++ thumb : prng <= libprng.cpp
SharedLibrary : libprng.so
/opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: /Users/jwalton/Android-CryptoPP/obj/local/armeabi/objs-debug/prng/libprng.o: in function std::__node_alloc::allocate(unsigned int&):/opt/android-ndk-r9/sources/cxx-stl/stlport/stlport/stl/_alloc.h:158: error: undefined reference to 'std::__node_alloc::_M_allocate(unsigned int&)'
/opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: /Users/jwalton/Android-CryptoPP/obj/local/armeabi/objs-debug/prng/libprng.o: in function std::__node_alloc::deallocate(void*, unsigned int):/opt/android-ndk-r9/sources/cxx-stl/stlport/stlport/stl/_alloc.h:161: error: undefined reference to 'std::__node_alloc::_M_deallocate(void*, unsigned int)'
/opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: /Users/jwalton/Android-CryptoPP/obj/local/armeabi/objs-debug/prng/libprng.o: in function std::ios_base::_M_check_exception_mask():/opt/android-ndk-r9/sources/cxx-stl/stlport/stlport/stl/_ios_base.h:193: error: undefined reference to 'std::ios_base::_M_throw_failure()'
...
I interpret the "non-system libraries in linker flags" message as a warning that you're not using the default system libraries (in usr/lib) which may be perfectly fine, but which could also lead to errors (incompatibility between different libraries versions). Whether this warning bugs you is completely up to you.
Then, about the way you tried to solve it, I think you're using wrongly the LOCAL_SHARED_LIBRARIES variable of the NDK.
I paste here a sample from one of my Android.mk file which uses Assimp
#------------------------------------------------------------------ Assimp
include $(CLEAR_VARS)
LOCAL_MODULE := Assimp
LOCAL_EXPORT_C_INCLUDES := $(GENERATED_INCLUDE_PATH)/assimp/include
LOCAL_SRC_FILES := $(GENERATED_PATH)/assimp/lib/libassimp.a
include $(PREBUILT_STATIC_LIBRARY)
...
LOCAL_STATIC_LIBRARIES := \
Assimp \
<Your other libs here>
As you can see, I declare a LOCAL_MODULE with a custom name, set up a few variables and then include the PREBUILT_STATIC_LIBRARY script which tells the NDK to use this lib.
Then in LOCAL_STATIC_LIBRARIES I list the libraries I use with their module name, not as if this was a linker flag like you're doing here.
In your case, I believe you should do the following, for example for the stl
include $(CLEAR_VARS)
LOCAL_MODULE := STLPortShared
LOCAL_EXPORT_C_INCLUDES := <path to stlport includes>
LOCAL_SRC_FILES := <path to stlport library>
include $(PREBUILT_SHARED_LIBRARY)
...
#Notice the name, identical to the one specified for LOCAL_MODULE
LOCAL_SHARED_LIBRARIES = STLPortShared
I think this should do it. Of course, repeat the process for each libs that causes trouble, and don't forget the include(CLEAR_VARS) between each lib specification.

Compiling code with OpenCV dependency Android NDK

I am trying to compile C++ code dependent on OpenCV on the Android NDK.
I have looked into several answers (mainly this) but apparently the NDK still cannot see the directory I'm giving it in the LOCAL_C_INCLUDES variable.
This is my Application.mk:
APP_ABI :=armeabi armeabi-v7a
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_PLATFORM :=android-14
NDK_TOOLCHAIN_VERSION=4.7
This is my Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= swt
LOAL_CPP_EXTENSIO:=.cpp
LOCAL_C_INCLUDES := /usr/include:/usr/include/i386-linux-gnu:/usr/include/i386-linux-gnu/bits:/usr/include/i386-linux-gnu/sys:/usr/include/i386-linux-gnu/gnu:/usr/include/i386-linux-gnu/asm:/home/hamdy/Downloads/android-ndk-r8e/sources:/usr/local/include/opencv:/usr/local/include/opencv2/core
LOCAL_CFLAFS := -x c++ -lopencv_core -lopencv_highgui -lopencv_imgproc
LOCAL_SRC_FILES := TextDetection.cpp FeaturesMain.cpp
include $(BUILD_SHARED_LIBRARY)
This is the error I'm getting [cv.h is the file included in my .cpp so it can apparently see that in the /usr/local/include/opencv directory but cannot get past the includes in it]:
/usr/local/include/opencv/cv.h:63:33: fatal error: opencv2/core/core_c.h: No such file or directory
compilation terminated.
I don't know why but when I've compiled the same under Linux everything compiled fine. Under Windows there were errors. So I've switched to Linux

Eclipse can't include opencv2 header files

I've created an Android Application Project in Eclipse Juno, and after I've added native support to this project (Android Tools -> Add Native Support). So Eclipse has added in the project automatically a jni directory, within which a .cpp file and the file Android.mk.
Then I've build the project, without errors.
In order to use opencv for android libraries (2.4.5), I've added the path to the 'include' directory of these libraries in the project (Properties -> C/C++ General -> Path And Symbols -> Include Diretories). I've also set in the Eclipse Preferences -> NDK the correct path to the ndk directory in my pc, to make possible to execute ndk-build when I build the projects.
But, if i try to include in the .cpp file:
#include <opencv2/opencv.hpp>
The console show me this result:
12:24:25 **** Build of configuration Default for project ProvaVideoCapture ****
"C:\\Users\\Micaela\\Desktop\\Android\\android-ndk-r8e\\ndk-build.cmd" all
"Compile++ thumb : jniVideoCapture <= jniVideoCapture.cpp
jni/jniVideoCapture.cpp:4:30: fatal error: opencv2/opencv.hpp: No such file or directory
compilation terminated.
make: *** [obj/local/armeabi-v7a/objs/jniVideoCapture/jniVideoCapture.o] Error 1
12:24:26 Build Finished (took 282ms)
My Android.mk file is:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jniVideoCapture
LOCAL_SRC_FILES := jniVideoCapture.cpp
include $(BUILD_SHARED_LIBRARY)
The Application.mk file that I've added manually (it has not been automatically added by Eclipse) is:
APP_ABI := all
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_PLATFORM := android-9
I don't know how to solve this problem, or what I've done wrong.
Could you help me?
Add path like below to your Android.mk file and check
include E:/OpenCV-2.3.1/share/OpenCV/OpenCV.mk
Sample Android.mk for reference
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE:=STATIC
OPENCV_INSTALL_MODULES:=on
include E:/OpenCV-2.3.1/share/OpenCV/OpenCV.mk
include $(OPENCV_MK_PATH)
LOCAL_MODULE := firstcv
LOCAL_SRC_FILES := first.cpp
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)

Headers with Android NDK

I'm trying to compilate my own library with the Android NDK But I've got some problems.
Here is my Android.mk file:
# Define vars for library that will be build statically.
include $(CLEAR_VARS)
LOCAL_MODULE := MyLib
LOCAL_SRC_FILES := ../../../src/mylib/utils/Timer.cpp
LOCAL_C_INCLUDES := ../../../src/mylib/
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_LDLIBS := -llog
LOCAL_CPPFLAGS := -std=c++0x
include $(BUILD_SHARED_LIBRARY)
When I build my project with "ndk-build" I've got the following error :
Clean: mylib [armeabi]
Clean: stlport_shared [armeabi]
Clean: stlport_static [armeabi]
Compile++ thumb : mylib <= Timer.cpp
jni/../../../src/mylib/utils/Timer.cpp:1:34: fatal error: mylib/utils/Timer.hpp: No such file or directory
compilation terminated.
For information, I'm including the .hpp like that :
#include <mylib/utils/Timer.hpp>
I don't know why headers aren't found, my library working in Xcode and eclipse.
Thanks for your time!
Edit: Here is my project's architecture to understand my problem: http://i.imgur.com/aiah6zH.jpg
I'm trying to indicate where is located my ".hpp" files in the Android.mk file.
Your LOCAL_C_INCLUDES should include the ../../../src/ or ../../../inc directory in order for you to use #include <mylib/utils/Timer.hpp> i.e:
LOCAL_C_INCLUDES := ../../../src/
Why don't you put your C and C++ headers and source files inside the jni/ directory of the Android project, near the Android.mk file?
See: What is the difference between #include <filename> and #include "filename"?
Also this is incorrect, because the second LOCAL_LDLIBS overrides the previous LOCAL_LDLIBS directive in the current module :
LOCAL_LDLIBS = -lz -lm
LOCAL_LDLIBS := -llog
If you want to append to a make directive use:
LOCAL_LDLIBS := -lz -lm
LOCAL_LDLIBS += -llog
or LOCAL_LDLIBS := -lz -lm -llog
EDIT:
Using the following Android.mk it seems to work if you run ndk-build from the Android/jni directory.
LOCAL_PATH := $(call my-dir)
# first lib, which will be built statically
#
include $(CLEAR_VARS)
LOCAL_MODULE := MyLib
LOCAL_C_INCLUDES := ../../../inc/
LOCAL_SRC_FILES := ../../../src/mylib/utils/Timer.cpp
include $(BUILD_STATIC_LIBRARY)
# second lib, which will depend on and include the first one
#
include $(CLEAR_VARS)
LOCAL_MODULE := MyNativeFinalSharedLib
LOCAL_LDLIBS := -lz -lm -llog
LOCAL_CPPFLAGS := -std=c++0x
LOCAL_STATIC_LIBRARIES := MyLib
include $(BUILD_SHARED_LIBRARY)
Also you forgot to put LOCAL_PATH := (call my-dir) on the first line and some other missing make directives.
An Android.mk file must begin with the definition of the LOCAL_PATH
variable. It is used to locate source files in the development tree.
In this example, the macro function 'my-dir', provided by the build
system, is used to return the path of the current directory (i.e. the
directory containing the Android.mk file itself).
(from android-ndk-r8d/docs/ANDROID-MK.html)
It's highly recommended to have your Android.mk file define $(LOCAL_PATH). In your case, the best choice would probably be
LOCAL_PATH := $(call my-dir)/../../../../src
Now you can simply write
LOCAL_SRC_FILES := mylib/utils/Timer.cpp
But for the includes, the path should be defined as relative from current, i.e. MyProject/build/Android directory. In your case, it seems, the correct path would be
LOCAL_C_INCLUDES := ../../../inc
This when you specify mylib in the #include statement:
#include <mylib/utils/Timer.hpp>

Categories

Resources