I have the latest version of the 64bit NDK (r10c), and the latest version of Android Studio I can download (0.8.14).
I am making a number of JNI calls to use String, Vector, Atomic, etc. But I can not figure out how to use thread and mutex.
Both of them give me the same error
Error:(92, 5) error: 'thread' is not a member of 'std'
Error:(93, 5) error: 'mutex' is not a member of 'std'
I'm sure that the NDK is using 4.9 of the gnu-libstdc++. If I put in a #error in the file I see my error and compilation stops. It appears that I'm not missing any defines since I can put the #error inside the class and see it.
Here is the ndk config in my build.gradle
ndk {
moduleName "myLib"
ldLibs "log"
stl "gnustl_shared"
cFlags "-std=c++11 -frtti -fexceptions -pthread"
}
The -frtti and -pthread seem to make no difference. I have also tried stl of gnustl_shared as well as gnustl_static, no difference.
By default, NDK still uses GCC 4.6 which has crippled support for C++11. You need the grade equivalent for setting NDK_TOOLCHAIN_VERSION:=4.9 in Application.mk. You can find some answers here: how to specify NDK_TOOLCHAIN_VERSION in gradle file for android ndk build, but unfortunately the bottom line is that today you have to disable automatic ndk-build call by setting jni.srcDirs to empty and use the Android.mk and Application.mk files the old way.
So, if in your jni directory, there are files file1.cpp and file2.cpp, you will need the following Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myLib
LOCAL_SRC_FILES := file1.cpp file2.cpp
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS := -std=c++11 -frtti -fexceptions -pthread
... and Application.mk
APP_ABI := armeabi-v7a
APP_STL := gnustl_shared
NDK_TOOLCHAIN_VERSION := 4.9
Related
I'm trying to build a static library using a standalone toolchain for a project that has its own build process, which I then wrap with a C++ library and expose to Android (compiled with ndk-build). However, on the ndk-build step I receive the following error:
➜ jni /Users/chrisfosterelli/Library/Android/sdk/ndk-bundle/ndk-build
[arm64-v8a] Compile++ : wrapper <= wrapper.cpp
In file included from /Users/chrisfosterelli/workspace/android/jni/wrapper.cpp:9:
In file included from ../prebuild/include/valhalla/meili/universal_cost.h:7:
In file included from ../prebuild/include/valhalla/sif/dynamiccost.h:4:
In file included from ../prebuild/include/valhalla/baldr/directededge.h:5:
../prebuild/include/valhalla/baldr/graphconstants.h:432:11: warning: 21 enumeration values not handled in switch: 'kRoad', 'kRamp', 'kTurnChannel'... [-Wswitch]
switch (use) {
^
1 warning generated.
[arm64-v8a] SharedLibrary : libwrapper.so
/Users/chrisfosterelli/Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin/ld: /Users/chrisfosterelli/workspace/android/jni/../prebuild/libvalhalla_meili.a(libvalhalla_meili_la-map_matcher_factory.o): Relocations in generic ELF (EM: 62)
[...above message repeated many times...]
/Users/chrisfosterelli/workspace/android/jni/../prebuild/libvalhalla_meili.a: error adding symbols: File in wrong format
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [/Users/chrisfosterelli/workspace/android/obj/local/arm64-v8a/libwrapper.so] Error 1
➜ jni ls /Users/chrisfosterelli/Library/Android/sdk/ndk-bundle/
This error indicates, as far as I can tell, that I'm trying to mix and match binaries compiled for different architectures. However, from what I can tell the library is the correct architecture:
root#eacbdb1c0e46:/meili/meili2/newtest# ar x libvalhalla_meili.a
root#eacbdb1c0e46:/meili/meili2/newtest# file libvalhalla_meili_la-map_matcher_factory.o
libvalhalla_meili_la-map_matcher_factory.o: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), not stripped
root#eacbdb1c0e46:/meili/meili2/newtest#
FWIW, these are my current Application.mk,
APP_STL := c++_static
APP_CPPFLAGS := -frtti -std=gnu++11 -D_GLIBCXX_USE_C99
APP_CPPFLAGS += -fexceptions
NDK_TOOLCHAIN_VERSION := clang
APP_LDFLAGS := -latomic
APP_PLATFORM := android-21
APP_ABI := arm64-v8a
and Android.mk,
LOCAL_PATH := $(call my-dir)
# static library info
include $(CLEAR_VARS)
LOCAL_MODULE := libvalhalla_meili
LOCAL_SRC_FILES := ../prebuild/libvalhalla_meili.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include
include $(PREBUILT_STATIC_LIBRARY)
# wrapper info
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += ../prebuild/include
LOCAL_MODULE := wrapper
LOCAL_SRC_FILES := wrapper.cpp
LOCAL_STATIC_LIBRARIES := libvalhalla_meili
include $(BUILD_SHARED_LIBRARY)
Any ideas how to resolve this? I've tried a number of things but all of them lead to more (more obscure) errors, so I'm hoping someone here can point me in the correct direction!
I discovered the problem, but I wish I had a more insightful answer. Apparently the build process had created two library files. The one that I inspected was, of course, ARM64. However the one that I actually copied to the Android device was x86.
So, the error message was correct and so was the library file, but there was more than one file involved. If you're running into the same problem and pretty sure your library is ARM64, double check that's actually the same file that is being compiled into the ndk build!
I'm using Android NDK r10d. My application.mk is setup like so:
APP_CFLAGS := -DANDROID -DBUILD_OGLES2
APP_CPPFLAGS := $(APP_CFLAGS) -fexceptions -frtti -std=c++14
APP_STL := gnustl_static
APP_ABI := armeabi-v7a
APP_PLATFORM := android-15
NDK_TOOLCHAIN_VERSION := clang
I am using std::make_unique in my code and it isn't compiling (says it isn't found). This feature should be available in STL starting with C++14. I did some poking around and it seems that clang isn't using GNU STL 4.9 in the NDK. If it were, it would be available since I see it inside <memory> header.
What am I missing here? Is there a way to use 4.9 GNU STL with clang?
make_unique isn't available through gnustl from clang. You can try using LLVM libc++ instead. Set this inside your Application.mk:
APP_STL := c++_static
NDK_TOOLCHAIN_VERSION := clang
edit:
Forcing the use of GNU STL 4.9 (by changing TOOLCHAIN_VERSION inside android-ndk-r10d/toolchains/*toolchain_name*-clang3.5/setup.mk) makes the build crash:
clang++: /s/ndk-toolchain/src/llvm-3.5/llvm/tools/clang/lib/AST/DeclBase.cpp:1293: clang::DeclContext::lookup_result clang::DeclContext::lookup(clang::DeclarationName): Assertion 'DeclKind != Decl::LinkageSpec && "Should not perform lookups into linkage specs!"' failed.
I've set up a makefile for my game in SDL. The template of the Application.mk file included in SDL has three architectures:
APP_ABI := armeabi armeabi-v7a x86
Everything compiles just fine for armeabi, but for armeabi-v7a it fails. To me, it looks like compilation completes, but the linker has all obj files of two certain folders twice. While this does not happen for armeabi. The linker (ld) gives me an error of this kind:
/path/to/bin/ld: error: /path/to/myObjFile.obj: multiple definition of 'foo(int, int)'
/path/to/bin/ld: /path/to/myObjFile.obj: previous definition here
The path is exactly the same, so this makes me assume that the linker uses every file twice. A full example of such an error is here:
/Users/martijncourteaux/Development/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: error: /Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Box2D/Collision/b2Distance.o: multiple definition of 'b2Distance(b2DistanceOutput*, b2SimplexCache*, b2DistanceInput const*)'
/Users/martijncourteaux/Development/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: /Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Box2D/Collision/b2Distance.o: previous definition here
However, the object files that are linked double also generate this warning when I launch ndk-build:
/Users/martijncourteaux/Development/android-ndk-r10c/build/core/build-binary.mk:449: warning: ignoring old commands for target `/Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Collision/b2Distance.o'
/Users/martijncourteaux/Development/android-ndk-r10c/build/core/build-binary.mk:449: warning: overriding commands for target `/Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Collision/b2Distance.o'
Note that I have the impression that all these obj-files that have these multiple definition errors generate also generate this warning.
This is my Application.mk:
APP_STL := gnustl_static
APP_ABI := armeabi armeabi-v7a x86
NDK_TOOLCHAIN_VERSION := clang
APP_CPPFLAGS += -std=c++11
APP_PLATFORM := android-10
And here is my Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
SDL_PATH := ../SDL
THIRD_PARTY_FOLDER := $(LOCAL_PATH)/../ThirdParty
LOCAL_CPPFLAGS += -frtti
LOCAL_CPPFLAGS += -fexceptions
LOCAL_CPPFLAGS += -funwind-tables
PCH_FILE := $(LOCAL_PATH)/Gump/Gump-Prefix.pch
#PCH_FILE := Gump/Gump-Prefix.pch
LOCAL_CPPFLAGS += -include $(PCH_FILE)
#LOCAL_PCH := $(PCH_FILE)
#LOCAL_CPPFLAGS += -DPCH
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include \
$(LOCAL_PATH)/$(SDL_PATH)_mixer/ \
$(LOCAL_PATH)/$(SDL_PATH)_image/ \
$(LOCAL_PATH)/$(SDL_PATH)_net/ \
$(LOCAL_PATH)/../ThirdParty/ \
$(LOCAL_PATH)/Gump/
# Add your application source files here...
GUMP_SRC_FILES := $(wildcard $(LOCAL_PATH)/Gump/*.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/tinyxml2/tinyxml2.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/Box2D/*/*.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/Box2D/*/*/*.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/poly2tri/**/*.cc)
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c $(THIRD_PARTY_SRC_FILES) $(GUMP_SRC_FILES)
LOCAL_SHARED_LIBRARIES := SDL2_image SDL2_mixer SDL2_net SDL2
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
include $(BUILD_SHARED_LIBRARY)
My Guess (turns out false):
After writing this question and looking closely to provide you guys the most accurate information as possible about my problem, I noticed that the obj-files that are giving errors are those were I've used a wildcard on folder level as well. Eg: $(ROOT)/*/*.cpp. While these wildcards give no problem: $(ROOT)/Gump/*.cpp. I don't know for sure, but I guess that the wildcards work different on when linking for these different architectures...
Update:
I've tested it again not using wildcards for folders, and the same error about multiple definition appears.
Your list of files is appended every time a new ABI is being built. LOCAL_SRC_FILES is erased through include $(CLEAR_VARS); GUMP_SRC_FILES is redefined each time. But THIRD_PARTY_SRC_FILES only grows longer and longer. This has nothing to do with the wildcards, as you noticed. Simply add line
THIRD_PARTY_SRC_FILES :=
after include $(CLEAR_VARS), and your build will be fine.
Running ndk-build V=1 shows the build commands executed during the process. There I could see the .o files being linked twice. I'm not sure what the reason for that is. I guess it might have been due to the fact that the android makefile in the src/ folder used sources from his parent directory: ../ThirdParty/[morehere].
I fixed it by creating extra makefiles for these third party libraries, so now every library creates a shared library in a .so file. Which gets linked at compile-time. I think this is neater, because changing a makefile requires only that subproject to be recompiled.
Am trying to build an android ndk app using clang instead of gcc, for know i have tried this
in the Android.mk
NDK_TOOLCHAIN_VERSION := clang
LOCAL_CLANG :=true
LOCAL_LDLIBS := -lc++_static
LOCAL_CFLAGS := -std=c++11
and in the Application.mk
APP_PLATFORM := android-9
APP_STL := libc++_static
APP_CPPFLAGS := -fexceptions -frtti
APP_ABI := armeabi-v7a
but it always give me link errors with the std library.
Any help is appreciated !
There are several mistakes in your *.mk files:
libc++_static isn't a proper value for APP_STL, it should be c++_static here.
NDK_TOOLCHAIN_VERSION has no effect when set inside Android.mk, it should be set inside Application.mk
LOCAL_CLANG is a variable used inside system modules from AOSP, not when using the NDK.
Since you're setting APP_STL as c++_static, the NDK toolchain will correctly tell the linker what lib to use, you shouldn't add LOCAL_LDLIBS := -lc++_static.
Also, you set APP_ABI to only armeabi-v7a, is it on purpose ? Android runs on other architectures as well and you'll get better performance on these if you also compile your libraries accordingly. You can either set APP_ABI to all or to a list of architectures armeabi-v7a x86...
In summary:
Android.mk
LOCAL_CFLAGS := -std=c++11
Application.mk
NDK_TOOLCHAIN_VERSION := clang
APP_PLATFORM := android-9
APP_STL := c++_static
APP_CPPFLAGS := -fexceptions -frtti
APP_ABI := all
If you continue having some troubles compiling your code, please show the exact errors you're getting.
The building settings are correct,
mostly this is happens because you are linking with library that use gcc instead of clang. check if all your linked library using clang !
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