I am trying to compile a NDK only app (command line app).
I was using C++11 for many things, and I recently added threads:
#include <thread>
Now my compilation is not working, even though it works for map/deque/vector/....
With the following error:
jni/common.h:24:10: fatal error: 'thread' file not found
#include <thread>
^
1 error generated.
This is my Application.mk:
APP_PLATFORM := android-18
APP_CPPFLAGS := -Wall -frtti -fexceptions -fpermissive
APP_ABI := armeabi-v7a
APP_STL:=stlport_static
NDK_TOOLCHAIN_VERSION := clang
APP_OPTIM := release
This is my Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := XXXX
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/XXXXX
LOCAL_SRC_FILES := ....
LOCAL_C_FLAGS := -O3 -std=c++11
LOCAL_CXX_FLAGS := -O3 -std=c++11
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
I am using NDK 10d.
Ok, I'll answer myself :)
Seems that APP_STL:=stlport_static does not support C++ threads. Changing to the APP_STL:=gnustl_static solves the problem.
Related
I tried to link my existing NDK C code with the new Android Studio 2.2.1 from the relevant Link C++ Project with Gradle menu but I'm getting the following error:
Error:Cannot get property 'soFolder' on null object
I really have no idea what is causing this error as my native code used to work fine in previous Android Studio versions.
Currently my app-specific gradle file looks like this
In addition here are my mk files:
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/android-config.mk
LOCAL_CFLAGS := -DNO_WINDOWS_BRAINDEATH -DOPENSSL_BN_ASM_MONT -DSHA1_AS
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS :=$(LOCAL_CFLAGS) -march=armv6
LOCAL_SRC_FILES := sha/sha1-armv4-large.S
endif
ifeq ($(TARGET_ARCH),x86)
LOCAL_CFLAGS :=$(LOCAL_CFLAGS) -msse2 -m32 -march=i686 -mtune=atom
LOCAL_SRC_FILES := sha/sha1-586.S
endif
ifeq ($(TARGET_ARCH),mips)
LOCAL_CFLAGS :=$(LOCAL_CFLAGS) -march=mips1
LOCAL_SRC_FILES := sha/sha1-mips.S
endif
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
sha/sha1dgst.c \
nativecalc.c \
LOCAL_C_INCLUDES := $(LOCAL_PATH)/includeLocal
LOCAL_LDLIBS := -llog
LOCAL_MODULE:= nativecalc
include $(BUILD_SHARED_LIBRARY)
android-config.mk
LOCAL_CFLAGS += -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN #-DTERMIO
# From DEPFLAG=
LOCAL_CFLAGS += -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_CAST -DOPENSSL_NO_CMS -DOPENSSL_NO_GMP -DOPENSSL_NO_IDEA -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_SHA0 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SEED -DOPENSSL_NO_STORE -DOPENSSL_NO_WHIRLPOOL
# Extra
LOCAL_CFLAGS += -DOPENSSL_NO_HW -DOPENSSL_NO_ENGINE -DZLIB
# Debug
# LOCAL_CFLAGS += -DCIPHER_DEBUG
Application.mk
APP_ABI := armeabi x86 mips
APP_PLATFORM := android-9
Any ideas how can I fix this in order for my native code to compile successfully?
I've compiled a 3rd party library on Linux using a standalone toolchain, and I'm now trying to load that library in my app.
Problem is I'm getting java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_Znwj" referenced by "libmxnet_predict.so"
I've tried adding CFLAGS and LDFLAGS, both APP & LOCAL, but to no avail.
Before you ask, I'm developing with ADT because I have to.
This is my Application.mk:
APP_STL := gnustl_shared
APP_CFLAGS += -std=c++11
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-19
My (simplified) Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE:=SHARED
OPENCV_CAMERA_MODULES:=off
OPENCV_INSTALL_MODULES:=on
NDK_TOOLCHAIN_VERSION=4.9
include $(CLEAR_VARS)
include $(PREBUILT_SHARED_LIBRARIES)
include C:/OpenCV-2.4.8-android-sdk/sdk/native/jni/OpenCV.mk
LOCAL_MODULE := FreshubML
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_SRC_FILES := Mldevlib.cpp \
Tablet.cpp \
Interface.cpp \
LOCAL_LDLIBS += -llog -ldl -landroid -lm -ljnigraphics -lstdc++
C:\KitchenVision\Workspaces\MLDevWorkspace\MLDev\assets\share
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libmxnet_predict
LOCAL_SRC_FILES := lib/armeabi-v7a/libmxnet_predict.so
include $(PREBUILT_SHARED_LIBRARY)
Searching the standalone toolchain I saw that the symbol was referenced in libgnust_shared.so which I added to my project via APP_STL and in libstdc++.so but still, same error.
How do I get this to work?
I have successfully compiled multiple static libraries with the ndk toolchain and linked them into my own project. I have to use many cpp files and they need protocol buffers and a ZeroMQ, as a library, to compile successfully. Linking against protocol buffers works great, however, when I link against the ZeroMQ I get the following error:
C:/Users/x/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/windows- x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux- androideabi/bin/ld.exe: error: ./zmq/lib/libzmq.a(libzmq
_la-zmq.o): incompatible target
collect2.exe: error: ld returned 1 exit status
make.exe: *** [C:/Users/x/Workspace/y/app/src/main//obj/local/armeabi- v7a/libZ.so] Error 1
I have replaced personal information with x, y, z for a clear reason.
I'm using Windows 8.1 with Android Studio 1.1 RC1 and NDK10d. I compiled the libraries on a Ubuntu and a Debian system (tried different ones). Both use the same arm toolchain.
To compile ZeroMQ I followed the steps from the official page. I tried zeromq3-x and zeromq4-x. I tried the mentioned ndk8 and the new ndk10d.
My Application.mk:
APP_STL := gnustl_static #tried: c++_static/shared stlport_static/shared
APP_PLATFORM := android-21
APP_USE_CPP0X := true #tried to omit
APP_CXXFLAGS := -std=gnu++11
APP_CPPFLAGS := -frtti -fexceptions --std=c++11
APP_ABI := armeabi-v7a #tried different like armeabi, all, x86 - obviously only arm should work
NDK_TOOLCHAIN_VERSION := 4.9
Android.mk without important files to compile because it will crash on the first need of zmq:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ../jni/protobuf
LOCAL_SRC_FILES := ../jni/protobuf/libprotobuf.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include
LOCAL_EXPORT_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf- 2.6.0\build\include\google
LOCAL_EXPORT_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf- 2.6.0\build\include\google\proto
LOCAL_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf- 2.6.0\build\include
LOCAL_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include\google
LOCAL_C_INCLUDES := C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include\google\protobuf
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_MODULE := zmq
LOCAL_SRC_FILES := zmq/lib/libzmq.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDES := C:\Users\x\Android\ZMQ\ARM-FINAL\include
LOCAL_EXPORT_C_INCLUDES := zmq/include
LOCAL_C_INCLUDES := C:\Users\x\Android\ZMQ\ARM-FINAL\include
LOCAL_C_INCLUDES := zmq/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Z
LOCAL_CFLAGS := -I/zmq -std=c++11
LOCAL_CPPFLAGS := -I/zmq -std=c++11
LOCAL_CPP_FEATURES += exceptions
LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog
LOCAL_CPP_EXTENSION := .cxx .cpp .cc .h
LOCAL_DISABLE_FORMAT_STRING_CHECKS := true
LOCAL_SRC_FILES := \
../jni/protogen/applications.pb.cc \ # this will work
common/bytearray.cpp \ # this will fail
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
LOCAL_C_INCLUDES += C:\Users\x\Android-MasterUI\app\src\main\jni
LOCAL_C_INCLUDES += ../jni/protogen
LOCAL_C_INCLUDES += common
LOCAL_C_INCLUDES += C:\Users\x\Android\ZMQ\ARM-FINAL\include
LOCAL_C_INCLUDES += C:\Users\x\Workspace\\app\src\main\jni\protobuf
LOCAL_C_INCLUDES += C:\Users\x\Workspace\Android- MasterUI\app\src\main\jni\protobuf\include
LOCAL_C_INCLUDES += C:\Users\x\Android- MasterUI\app\src\main\jni\protobuf\include\google
LOCAL_C_INCLUDES += C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include
LOCAL_C_INCLUDES += C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf- 2.6.0\build\include\google
LOCAL_C_INCLUDES += C:\Users\x\Android\Proto\.lib arm 5 2.6\protobuf-2.6.0\build\include\google\protobuf
LOCAL_STATIC_LIBRARIES := zmq protobuf
include $(BUILD_SHARED_LIBRARY)
The objdump from the static library looks like this
libzmq_la-address.o: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
I will omit the further ones because they are all the same. There was a better way to dump all the pieces of information with more details about the architecture, but I can not find it anymore.
If you know a better way you may tell me and I will add more information.
Any idea is welcome and appreciated...
Environment
android-ndk-r10c
VisualGDB
Windows x64
Use-case 1
ADB Cmdline executable ( no Java / APK ) is consist of several C++ files
Executable is compiled having "APP_STL := gnustl_static" at Application.mk
Executable is successfully compiled and running
Use-case 2
The ADB tool of Use-case 1 is split into two separate projects
A static library encapsulating general purpose functionality
The ADB Tool minus the functionality moved out to the static lib
Executable & static Lib are compiled having "APP_STL := gnustl_static" at Application.mk
ADB Exe is compiled having LOCAL_LDLIBS := -L$(PATH_TO_STATIC_LIB) -lstaticlib
Compilation fail with "undefined reference to `std::terminate()'" Linker error
Problem at hand
When compiling all CPP files as one project all goes fine, no linker error.
When spiting the logic into a thin executable and a staticlib (that the executable is linked against ) I get an "undefined reference to `std::terminate()'" Linker error.
It seems to me as if "gnustl_static" is not linked with the executable although "APP_STL := gnustl_static" is specified...
What am I missing here? Is there any way to force 'gnustl_static' to link ?
The make files for reference:
Makefile where all files are part of the same executable (WORKING)
Application.mk
APP_STL := gnustl_static
APP_ABI := all
APP_CFLAGS := -std=gnu++11
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.9
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ScreenCapSvc
LOCAL_SRC_FILES := ScreenCapSvc.cpp SnapshotController.cpp SimpleTCPStream.cpp SocketsServer.cpp uuids.cpp
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS :=
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_EXECUTABLE)
Makefiles where files are split into a static lib and executable that links against the lib
(NOT WORKING)
Executable Application.mk
APP_STL := gnustl_static
APP_ABI := all
APP_CFLAGS := -std=gnu++11
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.9
Executable Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ScreenCapSvc
LOCAL_SRC_FILES := ScreenCapSvc.cpp SnapshotController.cpp
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_LDLIBS := -llog -L$(PATH_TO_STATIC_LIB) -lCollections_statis
LOCAL_CFLAGS :=
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_EXECUTABLE)
Static Lib Application.mk
APP_STL := gnustl_static
APP_ABI := all
APP_CFLAGS := -std=gnu++11
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.9
APP_MODULES := Collections-static Collections-shared
Static Lib Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Collections-shared
LOCAL_SRC_FILES := SimpleTCPStream.cpp SocketsServer.cpp uuids.cpp
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS :=
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Collections-static
LOCAL_SRC_FILES := $(COMMON_SRC_FILES)
include $(BUILD_STATIC_LIBRARY)
This isn't a bug in the NDK build system, but it is an issue with how you are using it.
If you run ndk-build V=1, you see the actual commands that it tries to execute, and you'd see that it already tries to link in gnustl_static, but it links it in before linking in your own static library. The linker only tries libraries in the order they are specified on the linker command line, which means that it won't try to use the earlier specified gnustl_static library to resolve undefined references from a later library.
The correct solution here is to not use LOCAL_LDLIBS for forcing linking to a static library, but use the NDK provided infrastructure for linking to static libraries. That is, change your executable Android.mk like this:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ScreenCapSvc
LOCAL_SRC_FILES := ScreenCapSvc.cpp SnapshotController.cpp
LOCAL_STATIC_LIBRARIES := Collections_static
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE := Collections_static
LOCAL_SRC_FILES := $(PATH_TO_STATIC_LIB)/libCollections_static.a
include $(PREBUILT_STATIC_LIBRARY)
This way, you include the static library into the build of the executable in the same way regardless if the static library is built as part of the same build, or is a prebuilt library.
This syntax also allows you to add LOCAL_EXPORT_C_INCLUDES in the section for the static library, to add the right include path when building the executable, without having to manually add it to section for the executable.
It appears that indeed although "APP_STL := gnustl_static" is strictly specified at Application.mk of the Executable it is not really linked, to force gnustl_static to link I have added the following to LOCAL_LDLIBS of Android.mk
LOCAL_LDLIBS += -L$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/$(TARGET_ARCH_ABI) -lgnustl_static
Seems to me like a bug in the NDK build system...
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_CFLAGS := -Wall
LOCAL_SRC_FILES := test.c
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
include $(BUILD_SHARED_LIBRARY)
I run....
ndk-build NDK_PROJECT_PATH=./ APP_BUILD_SCRIPT=./Android.mk
and I get....
Compile thumb : test <= test.c
./test.c:8:29: fatal error: GLES/gl.h: No such file or directory
compilation terminated.
make: * [obj/local/armeabi/objs/test/test.o] Error 1
Now I am guessing adding a cflag of -I/include or a C_Include in the Android.mk will work but shouldn't that be handled by the -lGLESv1_CM.
Making an Application.mk file worked for me....
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-8