Android Studio CMake - 缺少libc ++ _ shared.so的共享库? CMake能捆绑吗?

时间:2016-09-21 15:27:45

标签: android c++11 android-ndk cmake std

现在Android Studio 2.2正式发布,我从旧的ndk-build流程迁移到尝试在AS中使用CMake。由于我在公司内部(我无法编辑)合并了大量使用C ++ 11代码(包括可怕的std :: to_string()方法)的代码库,这是我唯一的方法可以编译的是选择的几个配置选项 - 我在开始使用ndk-build时发现的所有这些选项。 (见下文)

所以一切都会再次编译并构建到APK中 - 我100%验证我的输出共享库是否存在于APK中,但我无法成功使用<img src="@($"{Model.CdnUrl}/images/myImage.svg")" /> - 事实证明这是因为缺少依赖 libc ++ _ shared.so

如同,我收到以下错误:

System.loadLibrary('mylibrary')

在我原来的ndk-build过程中,我总是在输出文件夹中找到2个库( mylibrary.so libc ++ _ shared.so ),从而捆绑在一起的应用程序。似乎CMake工具链并没有捆绑 libc ++ _ shared.so (实际上,它没有在APK中找到)。

我已经在这上面打了6个小时。我可以以某种方式获取CMake工具链来捆绑这个丢失的库吗?有线索吗?

我的设置:

在gradle.build中:

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

我的CMakeLists.txt(文件名为了简洁起见):

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

6 个答案:

答案 0 :(得分:6)

我写了一个应该封装STL文件的CMake配置: https://github.com/jomof/ndk-stl/blob/master/ndk-stl-config.cmake

将此文件复制到CMakeLists.txt旁边和CMakeLists.txt内

包括(NDK-STL-config.cmake)

如果您有问题,请告诉我

答案 1 :(得分:2)

正如Gerry指出的那样,音频回声示例项目(https://github.com/googlesamples/android-ndk/pull/298)的最新变化包括对我有用的变化。我将它添加到我的CMakeLists.txt文件的底部。

# 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's 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's 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()

我想这是一种解决方法,我们可以在没有某天的情况下完成...请注意,您必须更改行add_custom_command(TARGET mylibrary PRE_BUILD并将mylibrary替换为您的目标名称。

答案 2 :(得分:0)

将此添加到您的app.gradle

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

答案 3 :(得分:0)

我只是将此脚本添加到moudle的build.gradle中:

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

它将'libc ++ _ shared.so'打包到apk文件中

答案 4 :(得分:0)

在 Application.mk 中添加以下行

APP_STL := c++_shared

答案 5 :(得分:-1)

请加入

APP_STL := c++_shared
你的Application.mk中的