Android Studio CMake - no shared library lib ++ _ shared.so? Can CMake talk about this?

Now that Android Studio 2.2 is officially released, I am moving from my old ndk-build process to try using CMake inside AS. Since I include several codebases inside my company (which I cannot edit) that heavily use C ++ 11 code (including the awful std :: to_string () method), the only way I can compile is to use several configuration options - all this I discovered earlier when I started working with ndk-build. (see below)

So, everything is compiled and embedded in the APK again - and I will 100% verify that my shared partition library exists in the APK, but I can not successfully use System.loadLibrary('mylibrary') - and it turns out that this is due to the fact that the dependency lib ++ _ shared.so is missing.

As in, I get the following error:

 java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found 

In my old ndk-build process, I always ended up in two libraries (mylibrary.so and lib ++ _ shared.so) in my output folder, which thus got together in the application. It seems that the CMake toolchain does not bind lib ++ _ shared.so at all (indeed, it was not found in the APK).

I hit my head about it for 6 hours. Can I somehow get the CMake toolchain to merge this missing library? Any clues?

.

.

My settings:

In gradle.build:

 externalNativeBuild { cmake { arguments '-DANDROID_STL=c++_shared', '-DANDROID_TOOLCHAIN=gcc', '-DANDROID_PLATFORM=android-16' } } 

And my CMakeLists.txt (file names are cut out for brevity):

 cmake_minimum_required(VERSION 3.4.1) set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=gnu++11") include_directories(.) include_directories(./other) set(my_SRCS jniInterface.cpp etc.cpp) add_library(mylibrary SHARED ${my_SRCS}) target_link_libraries(mylibrary atomic log) 
+8
source share
5 answers

I wrote a CMake configuration that should pack STL files: https://github.com/jomof/ndk-stl/blob/master/ndk-stl-config.cmake

Copy this file next to your CMakeLists.txt and inside CMakeLists.txt do

include (ndk-stl-config.cmake)

Let me know if you have a problem.

+6
source

As Jerry noted, recent changes to the draft audio echo sample ( https://github.com/googlesamples/android-ndk/pull/298 ) include the changes that worked for me. I added this to the end of my CMakeLists.txt file.

 # Android Studio CMake does not pack stl shared libraries, so app needs to pack # the right shared lib into APK. The following code find right stl type and copy # the needed shared lib into app app/src/main/jniLibs, android studio assembles # it into the final APK # Helper function to retrieve shared stl path and name in NDK # stl_path: the path to the NDK shared lib path; empty if not using shared stl function(get_stl_info stl_path stl_name) # assume app not uses shared stl lib set(${stl_path} "" PARENT_SCOPE) if(NOT ${ANDROID_STL} MATCHES "_shared") return() endif() # using shared lib, config lib name and path if("${ANDROID_STL}" MATCHES "c\\\+\\\+_") # app uses c++_shared for stl type set(stlPath "llvm-libc++/libs/${ANDROID_ABI}") set(stlName "libc++_shared.so") elseif(${ANDROID_STL} MATCHES "gnustl_") set(stlPath "gnu-libstdc++/4.9/libs/${ANDROID_ABI}") set(stlName "libgnustl_shared.so") else() # this sample not supporting other stl types message(FATAL_ERROR "Not Suppored STL type: ${ANDROID_STL}") return() endif() set(${stl_path} ${ANDROID_NDK}/sources/cxx-stl/${stlPath} PARENT_SCOPE) set(${stl_name} ${stlName} PARENT_SCOPE) endfunction() # force copying needed shared stl lib into ${project}/app/src/main/jniLibs # so it will be packed into APK get_stl_info(ndk_stl_path ndk_stl_name) if(NOT ${ndk_stl_path} STREQUAL "") set(jniLibs_dir "${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs") add_custom_command(TARGET mylibrary PRE_BUILD COMMAND "${CMAKE_COMMAND}" -E copy ${ndk_stl_path}/${ndk_stl_name} "${jniLibs_dir}/${ANDROID_ABI}/${ndk_stl_name}" COMMENT "Copying Shared library to the packing directory") endif() 

I think this is a workaround that we can do without any day ... Please note that you need to change the add_custom_command(TARGET mylibrary PRE_BUILD line add_custom_command(TARGET mylibrary PRE_BUILD and replace mylibrary with the target name.

+2
source

add this to your app.gradle

 externalNativeBuild { cmake { cppFlags "-std=c++14 -fexceptions -frtti" arguments "-DANDROID_ARM_NEON=TRUE",'-DANDROID_STL=c++_shared' } } 
0
source

I just add this script to moudle build.gradle:

 externalNativeBuild { cmake { cppFlags "" arguments "-DANDROID_STL=c++_shared" } } 

it will pack lib ++ _ shared.so in apk file

0
source

Just turn it on

 APP_STL := c++_shared 

in your application.mk application

-1
source

All Articles