web-dev-qa-db-ja.com

Android Studio CMake-共有ライブラリにlibc ++ _ shared.soがありません?CMakeにこれをバンドルできますか?

Android Studio 2.2が正式にリリースされたので、AS内でCMakeを使用して試すために、古いndk-buildプロセスから移行しています。社内に複数のコードベースを組み込んでいるため(私は編集できません)C++ 11コード(恐ろしいstd :: to_string()メソッドを含む)を多用しているため、コンパイルできる唯一の方法は、選択したいくつかの構成オプションを使用することです。 ndk-buildで作業を開始します(以下を参照)。

したがって、すべてが再びコンパイルされ、APKに組み込まれます-そして、出力共有ライブラリがAPKに存在することを100%確認しますが、System.loadLibrary('mylibrary')を正常に使用できません-これは、依存関係が原因ですlibc ++ _ shared.soがありません。

のように、私は次のエラーを受け取ります:

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

私の古いndk-buildプロセスでは、2つのライブラリ(mylibrary.soおよびlibc + + _shared.so)出力フォルダーにあります。これにより、アプリにバンドルされます。 CMakeツールチェーンがバンドルされていないようですlibc ++ _ shared.so(実際、APKにはありません)。

私はこれに頭を6時間叩いてきました。どういうわけか、CMakeツールチェーンにこの不足しているライブラリをバンドルさせることができますか?手がかりはありますか?

私の設定:

Gradle.build:

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

そして、私のCMakeLists.txt(簡潔にするためにファイル名を省略しています):

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)
10
Mete

STLファイルをパッケージ化する必要があるCMake構成を作成しました: https://github.com/jomof/ndk-stl/blob/master/ndk-stl-config.cmake

このファイルを_CMakeLists.txt_の横と_CMakeLists.txt_の内部にコピーします。

include(ndk-stl-config.cmake)

問題がある場合はお知らせください

8
Jomo Fisher

このスクリプトをmoudleのbuild.gradleに追加するだけです。

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

「libc ++ _ shared.so」をapkファイルにパッケージ化します

6
debugger

Gerryが指摘したように、audio-echoサンプルプロジェクト( 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
Mete

これをbuild.gradle (Module: app)に追加します

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

含めるだけ

APP_STL := c++_shared

あなたのApplication.mkで

0