I have tried to get following sample code working to know whether asynchronous programming is working in Android NDK. Though NDK has the STL <future> which gets recognized as a header, the std::async is not getting recognized are not getting recognized. The code I tried to use was the following:
#include <future>
#include <iostream>
struct Foo
{
Foo() : data(0) {}
void sum(int i) { data +=i;}
int data;
};
int main()
{
Foo foo;
auto f = std::async(&Foo::sum, &foo, 42);
f.get();
std::cout << foo.data << "\n";
}
Also all the include paths have been set to the specified folder under Properties->Paths and Symbols
Errors
Description Resource Path Location Type
invalid use of incomplete type 'std::__async_sfinae_helper<void (Foo::*)(int), void (Foo::*)(int), Foo*, int>::type {aka struct std::future<void>}' Sample.cpp /Project12/jni line 50 C/C++ Problem
Description Resource Path Location Type
declaration of 'std::__async_sfinae_helper<void (Foo::*)(int), void (Foo::*)(int), Foo*, int>::type {aka struct std::future<void>}' Project12 line 111, external location: D:\android-ndk-r8e-windows-x86_64\android-ndk-r8e\sources\cxx-stl\gnu-libstdc++\4.6\include\future C/C++ Problem
Curently Android NDK does not incorporate all of the C++11 features. Clang 3.3 compiler from NDK r9b is C++11-feature complete, however, STL and stdlib on Android are not.
To use the most recent C++11 feature set in Android use Clang 3.3 compiler from Android NDK r9b. Put this line into your Application.mk file:
NDK_TOOLCHAIN_VERSION := clang
Also, add -std=c++11 switch to the LOCAL_CPPFLAGS variable:
LOCAL_CPPFLAGS += -std=c++11
Related
I try to build a cpp file as below to an executable on the Android platform. Therefore, by calling dumping_callstack(), I can get call stack of my executable in run time. But there are some errors。
cpp file:mycallstack.cpp
#include <utils/CallStack.h>
extern "C" void dumping_callstack()
{
CallStack stack("haha");
}
mycallstack.h
void dumping_callstack();
test.c
#include <mycallstack.h>
main()
{
dumping_callstack();
}
android.mk
LOCAL_SRC_FILES += mycallstack.cpp
LOCAL_SHARED_LIBRARIES := libc libcutils liblog libutils
then compile.
error: undefined reference to 'android::CallStack::CallStack(char const*,int)'
error: undefined reference to 'android::CallStack::~CallStack()'
In android 9.0, you should use libutilscallstack.
Look "android/system/core/libutils/Android.bp" for more details.
The implementation of CallStack::CallStack and CallStack::~CallStack isn't provided to the compiler/linker.
You might forgot to link it to the corresponding object file/library, I suggest you to read the documentation, there might be some information about linking. Sometimes it can help to just compile it with the -static switch, this makes the executable almost standalone, some libraries even require to be linked staticly.
It might also be the case, that the implementation is not available for release builds, I think the CallStack-class could only be available for debugging.
I start getting funny errors with NDK with fairly complex program:
#include <stdio.h>
#include <iostream>
int main( int argc, char **argv ) {
return 0;
}
>call c:\android-ndk-r9\ndk-build.cmd
"Compile++ thumb : test <= test.cpp
In file included from C:/workspace/c++11_test//jni/test.cpp:11:
In file included from c:/android-ndk-r9/sources/cxx-stl/stlport/stlport\iostream:43:
In file included from c:/android-ndk-r9/sources/cxx-stl/stlport/stlport\stl/_istream.h:31:
In file included from c:/android-ndk-r9/sources/cxx-stl/stlport/stlport\stl/_ostream.h:380:
In file included from c:/android-ndk-r9/sources/cxx-stl/stlport/stlport\stl/_ostream.c:26:
In file included from c:/android-ndk-r9/sources/cxx-stl/stlport/stlport\stl/_num_put.h:180:
In file included from c:/android-ndk-r9/sources/cxx-stl/stlport/stlport\stl/_num_put.c:26:
c:/android-ndk-r9/sources/cxx-stl/stlport/stlport\stl/_limits.h:217:48: error: non-type template argument evaluates to -2147483648, which cannot be narrowed to type 'wchar_t'
[-Wc++11-narrowing]
: public _STLP_PRIV _Integer_limits<wchar_t, WCHAR_MIN, WCHAR_MAX, -1, true>
^
c:/android-ndk-r9/platforms/android-14/arch-arm/usr/include\../include/wchar.h:76:22: note: expanded from macro 'WCHAR_MIN'
#define WCHAR_MIN INT_MIN
^
c:/android-ndk-r9/platforms/android-14/arch-arm/usr/include\sys/limits.h:69:18: note: expanded from macro 'INT_MIN'
#define INT_MIN (-0x7fffffff-1) /* min value for an int */
^
1 error generated.
make: * [C:/workspace/c++11_test//obj/local/armeabi/objs/test/test.o] Error 1
It's ndk-r9. 4.8 complie it just fine, only clang stumbles on it.
Do I need to define something to make clang work?
I've tried to Google errors, but got nothing relevant...
Obviously, I can turn it off with -Wno-c++11-narrowing, but I don't want disable narrowing checks.
And it's only shows with stlport_static, there is NO error with gnustl_static
You appear to have enabled C++11, since you are getting this warning.
STLport support for C++11 is not very good. I suspect this is the reason for your woes.
A fix requires changes to STLport, or removing the "-std=c++11" switch from the clang command-line.
IMHO, I would recommend switching to the gnustl (aka. libstdc++), unless there are other reasons that prevent you from doing so (licensing: libstdc++ is GPL3 with some significant exceptions that may or may not be valid for clang - you should determine that for yourself), legacy support, size etc.). I have had very good experiences with that.
Here is simple binarization function
void binarize(void *output, const void *input, int begin, int end, uint8_t threshold) {
#ifdef __ARM_NEON__
uint8x16_t thresholdVector = vdupq_n_u8(threshold);
uint8x16_t highValueVector = vdupq_n_u8(255);
uint8x16_t* __restrict inputVector = (uint8x16_t*)input;
uint8x16_t* __restrict outputVector = (uint8x16_t*)output;
for ( ; begin < end; begin += 16, ++inputVector, ++outputVector) {
*outputVector = (*inputVector > thresholdVector) & highValueVector;
}
#endif
}
It works fine on iOS. However when I'm compiling it for Android it gives me an error:
error: invalid operands of types 'uint8x16_t {aka __vector(16)
__builtin_neon_uqi}' and 'uint8x16_t {aka __vector(16) __builtin_neon_uqi}' to binary 'operator>'
I use this flag in Android.mk to enable NEON:
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_ARM_NEON := true
endif
The difference comes because of different compilers. For iOS you are compiling with Clang but for Android you are building the code with GCC (unless you override the defaults).
GCC is much more stupid about vector types and could not use them with C/C++ operators like > or &. So you have two basic options:
Try to compile with Clang from the latest Android NDK r8c
Put NDK_TOOLCHAIN_VERSION=clang3.1 to your Application.mk for this.
Rewrite your code explicitly using vld1q_u8 for load, vst1q_u8 for store, vcgtq_u8 for operator > and vandq_u8 for operator &
I am using open-ssl source given at https://github.com/eighthave/openssl-android
to build a library which can be used in android project.
As per instructions given at README.txt, I am able to compile it for the the Android platform version 2.2 (level -8)
But my app requires it to be 2.1 (level -7) compatible.
I tried following options with the default.properties file ( https://github.com/eighthave/openssl-android/blob/master/default.properties )
1) set target=android-7
2) set target=android-5
But when I compile it using command ndk-build, it gives following error
Compile thumb : crypto <= dsa_vrf.c
Compile thumb : crypto <= dso_dl.c
Compile thumb : crypto <= dso_dlfcn.c
/Crypto/openssl-android/crypto/dso/dso_dlfcn.c: In function 'dlfcn_pathbyaddr':
/Crypto/openssl-android/crypto/dso/dso_dlfcn.c:445: error: 'Dl_info' undeclared (first use in this function)
/Crypto/openssl-android/crypto/dso/dso_dlfcn.c:445: error: (Each undeclared identifier is reported only once
/Crypto/openssl-android/crypto/dso/dso_dlfcn.c:445: error: for each function it appears in.)
/Crypto/openssl-android/crypto/dso/dso_dlfcn.c:445: error: expected ';' before 'dli'
/Crypto/openssl-android/crypto/dso/dso_dlfcn.c:455: error: 'dli' undeclared (first use in this function)
make: *** [obj/local/armeabi/objs/crypto/dso/dso_dlfcn.o] Error 1
As per error message- Dl_info is not defined. but if we go to file dso_dlfcn.c , the definition for the structure is already provided. (https://github.com/eighthave/openssl-android/blob/master/crypto/dso/dso_dlfcn.c)
And this code compiled for target=android-8 in default properties file, but not for android-7 or android-5.
Request you to help me to resolve this error. and let me know what all changes needs to be done in order to compile it for android 2.1 platform.
Thanks in advance.
Try to include the following piece of code into dso_dlfcn.c:
typedef struct {
const char *dli_fname; /* Pathname of shared object that
contains address */
void *dli_fbase; /* Address at which shared object
is loaded */
const char *dli_sname; /* Name of nearest symbol with address
lower than addr */
void *dli_saddr; /* Exact address of symbol named
in dli_sname */
} Dl_info;
int dladdr(const void *addr, Dl_info *info) { return 0; }
Before:
#ifdef __linux
# ifndef _GNU_SOURCE
# define _GNU_SOURCE /* make sure dladdr is declared */
# endif
#endif
After that in my case the library is built.
Try to install with latest NDK version and update Application.mk file appropriately.
LOCAL_PATH := $(call my-dir)
APP_PLATFORM := android-19
NDK_TOOLCHAIN_VERSION := clang
APP_ABI := armeabi-v7a
APP_STL := gnustl_static
APP_CPPFLAGS += -frtti
APP_CPPFLAGS += -fexceptions
APP_CPPFLAGS += -DANDROID
APP_PROJECT_PATH := $(shell pwd)
APP_BUILD_SCRIPT := $(LOCAL_PATH)/../Android.mk
The above 2 problems will be solved.
I had one issue with #Yuri's solution and had to improve it alittle. My APP_ABI is set to all in Application.mk. In my case it meant that among armeabi and armeabi-v7a I'm building also for x86 and mips. I have also android-9 target installed in android sdk to use in other projects. x86 and mips are supported by ndk starting from android-9. As written in the docs, when ndk-build will start building these targets, it will switch to android-9 target automatically. And what? - Yes, it will fail to compile :-). Here is my solution:
In crypto/Android.mk find the line local_c_flags :=
-DNO_WINDOWS_BRAINDEATH. After the line write this http://pastebin.com/7euUVD7A.
Yuri's code has to be inserted into if defined: http://pastebin.com/V58gTSBU
By the way, I've inserted Yuri's block after #include <openssl/dso.h> but not before #ifdef __linux
I am playing with android ndk. I am using Window Vista with cygwin (latest version). I compiled and launched the hello world jni sample on my phone. It is working. The code is (is a .cpp file):
#include <string.h>
#include <jni.h>
extern "C" {
JNIEXPORT jstring JNICALL Java_org_android_helloworld_HelloworldActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis);
};
jstring Java_org_android_helloworld_HelloworldActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis)
{
return env->NewStringUTF("Hello from native code!");
}
I wanted to add some modifications, just to play with it a bit:
#include <algorithm>
and then, in the function above, i added:
int a;
a=std::min<int>(10, 5);
but the compiler says that it cannot find the file 'algorithm' and that min() is not part of std.
After a bit of searching, i have found that the android ndk has a gnu-libstdc++ directory with all the std files needed. Reading the NDK docs, i have learned that usint std::* should work without any modification to the code (if one include the proper header files). But it seems that gcc on cygwin is not able to find the needed files.
What are the steps to do in order to be able to use std and stl within a .cpp file in an android ndk app?
From NDK r5's docs/CPLUSPLUS-SUPPORT.html:
By default, the headers and libraries for the minimal C++ runtime system
library (/system/lib/libstdc++.so) are used when building C++ sources.
You can however select a different implementation by setting the variable
APP_STL to something else in your Application.mk, for example:
APP_STL := stlport_static
To select the static STLport implementation provided with this NDK.
Value APP_STL values are the following:
system -> Use the default minimal C++ runtime library.
stlport_static -> Use STLport built as a static library.
stlport_shared -> Use STLport built as a shared library.
gnustl_static -> Use GNU libstdc++ as a static library.
Which NDK are you using? Have you tried compiling one of the sample applications that utilize the STL such as test-libstdc++?