i want to load shared library dynamically from external files directory.
I create library and test it on linux, it works.
Compile: gcc -fPIC -shared -static-libstdc++ -static-libgcc test_lib.cpp constructor.cpp -o test.so
But when i use this in android ndk, i get runtime error:
dlopen failed: library "libc.so.6" not found.
How i can solve it? I'm use emulator
You can't use libraries built for normal linux on android - it's still linking to the shared libc.so.6 which isn't available on Android. (You can't statically link a shared library, see e.g. https://stackoverflow.com/a/6637842/3115956.)
You need to build the library using the NDK compiler against the Android C runtime library.
If you're adventurous, you could try forcing it to link the C runtime statically into your library though, by making it link libc.a instead of libc.so, but I'm not sure if this causes other issues. (One can run executables built for normal linux on android, assuming they're built with -static, but I'm not sure how well that works for shared libraries.)
Related
We are trying to build capicxx-core-runtime for an ARM based platform running Android Pie. It's an open source IPC framework which is part of the GENIVI initiative by major automotive OEM's. Our AIM is to bring the IPC framework into our Android system.
The git repo is placed here https://github.com/GENIVI/capicxx-core-runtime.git
I am using the Android NDK version r17b and building using the following command to configure the cmake based build.
cmake -DCMAKE_TOOLCHAIN_FILE=/home/hp/downloads/android-ndk-r17b/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_NATIVE_API_LEVEL=27 ../
When I compile using 'make', I see the individual cpp files are compiled, but I am getting following errors during linking as shown in the link below.What is the configuration that I may be missing.
Linker error log
the capicxx-core-runtime is building a shared library, so you need to resolve all of it's internal symbols, including the c++ runtime.
To quickly test this: edit the capicxx-core-runtime CMakeLists.txt to link the c++_shared runtime, line 130:
target_link_libraries(CommonAPI PRIVATE ${DL_LIBRARY} ${DLT_LIBRARIES})
becomes
target_link_libraries(CommonAPI PRIVATE ${DL_LIBRARY} ${DLT_LIBRARIES} c++_shared)
and rerun your cmake command and make command.
It seems that capicxx-core-runtime can be buildable now for Android (both NDK and AOSP) out the box, please see corresponding pull requests: https://github.com/GENIVI/capicxx-core-runtime/pulls?q=author%3Ankh-lab+
Also here is simple example for AndroidStudio how it could be used with vSOME/IP transport: https://github.com/nkh-lab/ndk-capi-hello-world
I am attempting to use GRPC with Unity. I'm stuck compiling a libgrpc_csharp_ext.so file which will successfully work with the arm-v7a Android archetecture. I expected the following command to work from the GRPC repository root:
arm-linux-androideabi-gcc -I. -I./include -fPIC -o libgrpc_csharp_ext.o -c src/csharp/ext/grpc_csharp_ext.c
arm-linux-androideabi-gcc -I. -I./include -shared libgrpc_csharp_ext.o -o libgrpc_csharp_ext.so
I cobbled this together from this question. It compiles successfully and Unity recognizes the file when placed in /Plugins/Android as a arvm7 library:
but when GRPC attempts to DllImport("grpc_csharp_ext") on an actual Android device, I get an error:
Unable to load library
'/data/app/PACKAGE/lib/arm/libgrpc_csharp_ext.so',
native render plugin support disabled: java.lang.UnsatisfiedLinkError:
dlopen failed: cannot locate symbol "grpc_slice_from_copied_buffer"
referenced by
"/data/app/PACKAGE/lib/arm/libgrpc_csharp_ext.so"...
Followed by:
Unable to find grpc_csharp_ext
I know this is possible because this open-source project has successfully cross-compiled the necessary files. When I download the .so file from their project and drop it into mine it successfully loads, except it was compiled with a very old version of GRPC and I therefore do not wish to use it. Furthermore, I've already successfully created an .a file for iOS which works well with a similar strategy. When I check my file with file libgrpc_csharp_ext.so I see that it is ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, with debug_info, not stripped. This matches the type of the file obtained from the open-source repository.
It seems like the appropriate symbols are not included in the resulting .so, based upon the error message above and also that the .so is ~36kb, but the "correct" .so from the open-source project is >5mb. I guess I'm compiling a dynamic library that doesn't include all the necessary symbols, but I'm not enough of a compiler guru to find the correct options.
Thanks to the help of the GRPC team, I have a working solution; see my comment in the issue here: https://github.com/grpc/grpc/issues/14402#issuecomment-369942250
I'm working with them to hopefully get this integrated into master. In the mean time, I will try to keep this blog post up to date with the instructions for each platform (not just Android): http://examinedself.com/cross-compile-grpc-unity/
I am compiling C++ library code in Android Studio 2.2. I follow the new guide, where I add all the files to my project and compile it using CMake (and CMakeLists.txt) like this. I want to use C++14 features, and stuff like atomic, stoi etc. but the building is failing with errors.
error: no type named 'condition_variable' in namespace 'std'
error: no member named 'stoi' in namespace 'std'
This is what my CMakeLists looks like (other lines set source files and other stuff):
find_library(GLES GLESv2)
include_directories(${COMMON_PATH} /usr/local/include)
set(ANDROID_STL "c++_shared")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -latomic")
add_library(native-lib SHARED ${COMMON_SRC})
target_link_libraries(native-lib ${GLES})
I found this article on the android page (here), but I don't know how and if I can do this when using CMakeLists and not ndk-build. I see other question that solve it using the c++_static runtime but only with ndk-build.
This documentation would be more useful for cmake case:
arguments "-DANDROID_STL=c++_shared
Gradle also packs libc++_shared.so into APK when using c++_shared; bypassing Gradle might cause trouble for your app on early version of Android OS.
at the time of this question, Android Studio might have trouble; at the time now Android Studio 3.1.3, it should be ok
The cross-compilation process used to generate the native libraries for Android uses the c++ dependencies from the NDK libraries. The NDK provided by Google is good and it has lots of things, but the C++11 and C++14 support is not complete.
If you want to use C++14 features, you can use other NDK like CrystaX NDK for example. With CrystaX you have also C++17 support.
I've been working on an Android project which has several native C++ libraries. Compiling and debugging using Eclipse with ADT plugin works well. Obviously Android NDK uses arm-linux-gnueabi-gcc of some version to compile the native libraries.
Since I've been using NEON intrinsics heavily, I would like to try to compile the native libraries with ARM's official compiler armcc. I read everywhere that armcc is supposed to give better optimized code when using intrinsics. So I downloaded the trial version of DS-5 from ARM website, just to try and see whether there's really any speed difference.
The DS-5 seems to be just a modified version of Eclipse that uses the ARMCC toolchain, so I installed the ADT plugin. But when I compile using DS-5, it seems that the code is still generated using gcc rather than armcc.
Do you have any idea how to force DS-5 or Eclipse to build the Android native code using armcc? Or is it possible (and how) to build the static NDK libraries from command line and then replace the libraries in my project, so they get deployed to the testing phone?
ARM DS-5 Community Edition doesn't include ARM compiler (armcc).
If you could get hold of armcc best would be to separate your processing heavy algorithms to individual compilation units (separate C files), build them with armcc as you would do for any compilation unit. When you get the object files, convert them into an archive then use that in Android.mk as LOCAL_STATIC_LIBRARIES += <your_archive>.
You can't use armcc plainly to build Android compatible libraries mostly because of Bionic dependencies, I think.
You can use armcc to build Android compatible static libraries even though Android has a different C library (bionic). The key is the --library_interface flag for armcc. According to the documentation:
Use an option of the form --library_interface=aeabi_* when linking with an ABI-compliant C library. Options of the form --library_interface=aeabi_* ensure that the compiler does not generate calls to any optimized functions provided by the ARM C library.
In addition, there are a few more flags to ensure compatibility with the Android EABI resulting in the following command for an Android armeabi-v7a target:
armcc --library_interface=aeabi_clib --wchar32 --enum_is_int --no_hide_all --cpu=7-A --fpu=softvfp+vfpv3 -c -o libfunc.o libfunc.c
You can then use armar --create libfunc.a libfunc.o to create a static library that can be linked with the Android NDK as LOCAL_STATIC_LIBRARIES.
I have successfully tested this with Android NDK r10d on Android KitKat 4.4.2.
I had some experience of android but know almost nothing of GCC Makefile. Here is what I need,
working on mac osx or linux, using android ndk toolchain, build an android shared library .so (a jni lib), linking in a prebuilt static library (already built for android). In static lib, I need logcat functions and C funcs such as sprintf. So no "ndk-build" in the process. The reason I have to do this, when linking in the static lib, a special linker is required to replace the standard arm-eabi-gcc, and the standard linker will be rolled back later.
I know that I need to set following environment variables such as:
ANDROID_NDK,
PATH=$PATH:"$ANDROID_NDK/build/prebuilt/darwin-x86/toolchain/arm-eabi-4.4.0/bin"
MACHINE=armv7l
SYSTEM=android
ARCH=arm
CROSS_COMPILE="arm-eabi-"
ANDROID_DEV="$ANDROID_NDK/platforms/android-8/arch-arm/usr"
HOSTCC=gcc
All I need is a sample Makefile, so that I can run "make" to build a .so by linking in a .a, and other necessary android and c libs.
Thanks
Try running ndk_build V=1 and recording the commands it issues in verbose mode. Then issue comparable commands to your custom linker.
Beware the commands might change for a different ndk version.