Do not think I did not search, my Android project (on Eclipse) refuses to recognize std::chrono library. The include is OK in my header file :
#include <chrono>
But when I want use it :
using namespace std::chrono;
I have a : Symbol 'chrono' could not be resolved, and all the functions of chrono are unavailables.
So I use NDK r10e, I add some lines in my Application.mk, which now looks like this :
APP_PLATFORM := android-22
APP_STL := gnustl_static
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.8
And in my Android.mk, I add :
LOCAL_CFLAGS += -std=gnu++11
It did not solve my problem. Any ideas ? Bad Eclipse configuration ?
After modifications in mk files, I have build and re-build my project.
This is known problem of GNU libstdc++ in Android NDK. It's built on top of very limited libc (Google's Bionic) and thus can't provide full C++ Standard Library functionality. In particular, std::chrono is almost completely disabled at build time, but not only std::chrono. There are many other classes and functions being disabled, so Google's NDK just don't support C++ fully.
You can switch to LLVM libc++ (APP_STL := c++_static), but it has experimental status in Google's Android NDK and is actually unstable (i.e. it cause crashes in the application even for completely standard C++ code). This instability is caused by the same reason as for GNU libstdc++ - i.e. because it's built on top of very limited libc.
I'd recommend switch to CrystaX NDK - alternative fork of Google's Android NDK, which I've started mainly to solve Google's NDK problems such as non-standard implementations of libc, libc++, etc. CrystaX NDK is developed to work as a drop-in replacement for Google's NDK (except for the fact that it provides fully standard-conforming low-level libraries). In CrystaX NDK, both GNU libstdc++ and LLVM libc++ are much more stable and fully conforming to C++ standard, at least at the same level as they conform to it on GNU/Linux. In particular, std::chrono is fully implemented there and works just fine. Also, in CrystaX NDK, you can use more recent compilers such as gcc-5.3 and clang-3.7, with better support of C++11 and C++14. I'd be happy if it helps you.
Related
I have developed an application and a native library for Android. The native library uses openSL ES for audio processing.
In my Android.mk file I have the following statement:
LOCAL_LDLIBS := -lOpenSLES
So I'm guessing that this means that the application will dynamically link in the openSLES library from the device's system/lib folder at the time when the application is loaded/executed on the device?
The problem I'm facing is that the libraries on the device are buggy and I have 3 updated libraries which contain the bug fix. If possible, how do I make sure that my native library is using the 3 libraries I have:
Libwilhelm.so
libOpenMAXAL.so
libOpenSLES.so
Do I just replace
LOCAL_LDLIBS := -lOpenSLES
with
LOCAL_SHARED_LIBRARIES := -lOpenSLES -lOpenMAXAL -lwilhelm
As long as you target a specific device or a very limited set of devices, the proposed solution is good enough. But if your aim is a public app, which will be installed on different platforms, including future 'N' version of Android, and customized ROMs, including e.g. Samsung, you should be careful with the system dependencies of these libraries.
While OpenSLES and OpenMAXAL are innocent (they only depend on liblog and libwilhelm), the latter requires more care.
Looking at its Android.mk, libwilhelm depends on liblog libutils libmedia libbinder libstagefright libstagefright_foundation libcutils libgui libdl libeffects and libstagefright_http_support.
Only liblog and libdl are "official" (i.e., part of NDK). The others depend on platform, and their exported functions may be incompatible for different devices running same platform level.
To be on the safe side, I would only introduce the fixes, and keep using the system version of libwilhelm when possible. I hope you can reduce your system dependencies this way.
I'm compiling Qt/C++ project with android NDK standalone toolchain. I’ve created standalone toolchain with make-standalone-toolchain.sh --arch=arm --toolchain=arm-linux-androideabi-4.9 --platform=android-21 command. NDK version is android-ndk-r10e. Target project uses some functions from pthread library. At compile time, I get the following error:
error: 'pthread_getaffinity_np' was not declared in this scope
const int err = pthread_getaffinity_np(_pthreadId, sizeof(cpu_set_t), &cpuSetMask);
compilation terminated due to -Wfatal-errors.
I've checked the header of pthread included in ndk toolchain and I did not find the declaration of pthread_getaffinity_np function.
Is pthread functionality for Android limited? How to use pthread with Android NDK properly?
Is pthread functionality for Android limited?
AFAIK, Yes.
http://mobilepearls.com/labs/native-android-api/#pthreads
https://web.archive.org/web/20180602101341/http://mobilepearls.com/labs/native-android-api/#pthreads
POSIX threads (pthreads)
The android libc, bionic, provides built-in support for pthreads, so no
additional linking (-lpthreads) is necessary. It does not implement full
POSIX threads functionality and leaves out support for read/write locks,
pthread_cancel(), process-shared mutexes and condition variables as well as
other more advanced features. Read the bionic OVERVIEW.txt for more
information.
TLS, thread-local storage, is limited to 59 pthread_key_t slots available
to applications, lower than the posix minimum of 128.
See https://android.googlesource.com/platform/bionic/+/master/docs/status.md for our official docs about what is in which Android version.
you can also look at the <pthread.h> header in the NDK (current version here) and see for example entries like:
pid_t pthread_gettid_np(pthread_t __pthread) __INTRODUCED_IN(21);
this shows that we do have the non-POSIX/non-portable (_np) function pthread_gettid_np, but that it was introduced in API level 21, so if your code needs to run on older releases you can't use it.
basically the headers are the canonical source of truth for "which functions are available in which API levels?".
for the specific case of pthread_getaffinity_np, no, we don't support that. you can combine pthread_gettid_np from <pthread.h> and sched_getaffinity from <sched.h> though.
POSIX threads (pthreads) seems to be not provided for -host build modules.
at least here is the error for the libcrypto-host module build:
out/host/linux-x86/obj/SHARED_LIBRARIES/libcrypto-host_intermediates/src/crypto/thread_pthread.o:
In function `thread_local_init':
/media/compilation/projects/android/beagle2/external/boringssl/src/crypto/thread_pthread.c:112:
undefined reference to `pthread_key_create'
and the only way to fix it so far is to add -lpthread inside
external/boringssl/Android.mk before directive:
include $(BUILD_HOST_SHARED_LIBRARY)
example:
# Host shared library
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libcrypto-host
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_MULTILIB := both
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
LOCAL_CFLAGS += -DOPENSSL_NO_ASM
LOCAL_LDLIBS += -lpthread
include $(LOCAL_PATH)/crypto-sources.mk
include $(BUILD_HOST_SHARED_LIBRARY)
I'm trying to compile a native Android library using the Intel c++ compiler.
The library compiles without problems using gcc 4.8 (I'm using some c++11 code) but when I set NDK_TOOLCHAIN := x86-icc, it tries to include the stl headers from gcc-4.6
I've read the intel compiler documentation, but I can't find a way to change the include path on the command line. Also setting NDK_TOOLCHAIN_VERSION to 4.8 or specifying a compiler with -gcc-name has no effect.
Is the path hardcoded into the compiler?
Open the file {ndk}/toolchains/x86-icc/setup.mk and change the variable GCC_TOOLCHAIN_VERSION from 4.6 to 4.8.
At least for my small code sample it worked.
The problem:
I have a native Android application that is compiled for x86 and arm, armv7a.
The app also links to a pre-shared library.
That pre-shared library is also compiled for x86, arm, and armv7a. So there are 3 lib.so files.
What must I do in the Android.mk/Application.mk to link to the appropriate *.so file given the architecture it is being compiled for?
That is, when the build system is compiling for arm, it should link to the libs/armeabi/lib.so.
Likewise, when the Build system is compiling for x86, it should use the libs/x86/lib.so file.
I believe the alternative might be a more complex build script but I'm shooting for the simple solution first, if it exists.
Thanks!
The answer
Unfortunately my query skills were not very good and shortly after posting, I found the question and answer already on SO:
How can i Link prebuilt shared Library to Android NDK project?
To summarize:
Prebuilt shared libraries, compiled for different platforms, should all be named the same and go under the jni/${ARCH}/ directory.
That is, the structure should appear as so:
jni/x86/libtest.so
jni/armeabi/libtest.so
jni/armeabi-v7a/libtest.so
You should use the $(TARGET_ARCH_ABI) flag, for example:
include $(CLEAR_VARS)
LOCAL_MODULE := mylib-prebuilt
LOCAL_SRC_FILES := ../path_to_prebuilt_folder/libs/$(TARGET_ARCH_ABI)/libmylib.so
include $(PREBUILT_SHARED_LIBRARY)
I've downloaded a custom toolchain (linaro) to build ARM based Android apps. How do I tell the NDK to use it? Can I define or set something in Android.mk and Application.mk that would allow me to do that? Is there another way?
The NDK makefile system is quite extensible and you can indeed define a different toolchain. You'll need some understanding of how Make works.
Toolchains are discovered and initialized in build/core/init.mk line 261 (in NDKr6, the line # may change in future versions). The initialization code looks for files named config.mk under $(NDK_ROOT)/toolchains/*. So you'll need to add your toolchain in a subdirectory under the NDK toolchains directory, and add a config.mk and setup.mk to that subdirectory. Look at toolchains/x86-4.4.3 and toolchains/arm-linux-androideabi-4.4.3 for examples. You should be able to cut and paste the ARM toolchain config.mk and setup.mk if your toolchain has a standard layout.
Once you've defined a toolchain in the toolchain directory, you can switch to it by setting the NDK_TOOLCHAIN variable inside your Application.mk file.
As the other answer mentions, toolchains are discovered by ndk-build makefile system in $(NDK_ROOT)/toolchains/ and you can mirror ideas you see there. But there are a few extra concepts for supporting non-Android target platforms that are interesting although they may be soon outdated as ndk-build starts to explicitly support other platforms, such as mingw targeting win32 (or other gcc compilers targeting plain 'ol linux).
In config.mk:
TOOLCHAIN_ABIS := (list of ABIs that the toolchain supports)
This is an important definition, because you can use this name in your Application.mk to build using the toolchain for a particular ABI. One of the benefits of corrupting the usage of this definition, is that ndk-build can simultaneously build for multiple ABIs. It always assumes that the platform is Android, but if you want to target win32 using a mingw based toolchain, you can define an "ABI" as x86-win32, and then use this ABI in your Application.mk to select it as an additional target via APP_ABI:= x86-win32 Then in your Android.mk files you can use the TARGET_ARCH_ABI definition to select win32 specific sources and include paths, for example:
ifeq ($(TARGET_ARCH_ABI),x86-win32)
LOCAL_SRC_FILES += my_win32_file.c
LOCAL_CFLAGS += -DSOME_WIN32_SPECIFIC
endif
The final piece is that in setup.mk for your toolchain, it may be insufficient to look at other toolchains as examples, because what setup.mk for a particular toolchain really does is override build settings in default-build-commands.mk, so what you want to do is inspect that file, and redefine things in it that you don't like.
Following the previous example, mingw does not support the noexec flag in the binaries, and you can get rid of this feature by adding the following lines in your setup.mk:
# These flags are used to enforce the NX (no execute) security feature in the
# generated machine code. This adds a special section to the generated shared
# libraries that instruct the Linux kernel to disable code execution from
# the stack and the heap.
TARGET_NO_EXECUTE_CFLAGS := # our platform doesn't support this flag!
TARGET_NO_EXECUTE_LDFLAGS := # our platform doesn't support this flag!
# These flags disable the above security feature
TARGET_DISABLE_NO_EXECUTE_CFLAGS := # our platform doesn't support this flag!
TARGET_DISABLE_NO_EXECUTE_LDFLAGS := # our platform doesn't support this flag!
This is just one example of the many features in default-build-commands.mk that may need to be overridden, and of course it's important to provide TOOLCHAIN_NAME so that the toolchain can be selected via NDK_TOOLCHAIN variable inside your Application.mk file in addition to the ABI methodology I mention above.
well,you can simply add "NDK_TOOLCHAIN_VERSION = 4.9" in your Application.mk