Android Studio问题与链接不同ABI的共享库

时间:2018-10-15 20:15:59

标签: android-studio cmake android-ndk abi

对于我的文凭项目,我正在尝试使用Android Studio将我的c ++项目移植到android。我的c ++项目包括我自己开发的代码和库。 首先,我试图将该库的源代码编译为共享的android库。我成功做到了。但是,当我编译使用该库的代码时,cmake告诉我我的库与x86架构不兼容(我认为其他库也将不兼容)。 在编译库时,我将此代码用于不同的ABI,包括:

if (${ANDROID_ABI} STREQUAL "armeabi-v7a")
    include_directories(${ANDROID_SYSROOT}/usr/include/arm-linux-androideabi)
elseif (${ANDROID_ABI} STREQUAL "x86_64")
    include_directories(${ANDROID_SYSROOT}/usr/include/x86_64-linux-android)
elseif (${ANDROID_ABI} STREQUAL "x86")
    include_directories(${ANDROID_SYSROOT}/usr/include/i686-linux-android)
elseif (${ANDROID_ABI} STREQUAL "arm64-v8a")
    include_directories(${ANDROID_SYSROOT}/usr/include/aarch64-linux-android)
endif()

我不知道该如何解决。看来我需要链接任何依赖于ABI的库,但是我不知道如何理解所需的库。 “我的”库有许多文件,很难仅跟踪所有依赖项。那么,我该如何解决(在建立“我的”库之后,我对所有ABI都拥有* .so,并且正在使用$ {ANDROID_ABI}将它们链接至主代码)?

我的Android Studio项目中有2个模块:库和应用程序。该库构建良好,但是我无法将其链接到应用程序,因为cmake告诉我该库是不兼容的目标。更改cmake之后,我摆脱了ABI cmake块,但是该库仍然不想链接。

应用cmake:

cmake_minimum_required(VERSION 3.4.1)

add_library(native-lib
            SHARED
            src/main/cpp/native-lib.cpp )

find_library(log-lib
             log )

add_library( libacheron SHARED IMPORTED )
set(lib_src_DIR ${CMAKE_CURRENT_LIST_DIR}/../acheron_lib/build/Debug/acheron)

set_target_properties(libacheron
                      PROPERTIES IMPORTED_LOCATION
                      ${lib_src_DIR}/libacheron.so)
include_directories(${CMAKE_CURRENT_LIST_DIR}/../acheron_lib/temp/include)

target_link_libraries( native-lib
                       libacheron
                       ${log-lib})

lib main cmake:

cmake_minimum_required(VERSION 3.3)

set(ACHERON_GLOBAL_ROOT ${CMAKE_CURRENT_LIST_DIR})
set(ACHERON_GLOBAL_BUILD_DIRECTORY "${ACHERON_GLOBAL_ROOT}/build")

function(acheron_add_subprojects proj_dir_list)
    foreach(proj_dir ${proj_dir_list})
        add_subdirectory(${proj_dir})
    endforeach()
endfunction()

acheron_add_subprojects("${ACHERON_GLOBAL_ROOT}/src/main/acheron")

释放其他cmake:

cmake_minimum_required(VERSION 3.3)

project(acheron)

set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})

macro(acheron_set_build_directory build_dir)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${build_dir})
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${build_dir})
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${build_dir})
    if(MSVC)
        set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${build_dir})
        set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${build_dir})
        set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${build_dir})
        set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${build_dir})
        set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${build_dir})
        set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${build_dir})
    endif(MSVC)
endmacro()

acheron_set_build_directory(${ACHERON_GLOBAL_BUILD_DIRECTORY}/${CMAKE_BUILD_TYPE}/${PROJECT_NAME})

function(acheron_get_files_from_list out_file_list in_list)
    set(file_list "")
    foreach(in_item ${in_list})
        if(NOT IS_DIRECTORY ${in_item})
            list(APPEND file_list ${in_item})
        endif()
    endforeach()
    set(${out_file_list} ${file_list} PARENT_SCOPE)
endfunction()
function(acheron_get_all_files_recursively out_file_list folder)
    file(GLOB_RECURSE all_list ${folder}/*)
    acheron_get_files_from_list(file_list "${all_list}")
    set(${out_file_list} ${file_list} PARENT_SCOPE)
endfunction()

acheron_get_all_files_recursively(acheron_files ${CMAKE_CURRENT_SOURCE_DIR})

function(acheron_get_src_regex_pattern out_pattern)
    set(${out_pattern} ".*\\.(((C|c)(P|p)(P|p)))$" PARENT_SCOPE)
endfunction()

acheron_get_src_regex_pattern(src_pattern)

function(acheron_get_filtered out_list regex_pattern in_list)
    set(temp_list "")
    foreach(in_item ${in_list})
        if(${in_item} MATCHES ${regex_pattern})
            list(APPEND temp_list ${in_item})
        endif()
    endforeach()
    set(${out_list} ${temp_list} PARENT_SCOPE)
endfunction()

acheron_get_filtered(acheron_files ${src_pattern} "${acheron_files}")

function(acheron_add_source_groups root_dir src_list)
    foreach(src_file ${src_list})
        get_filename_component(src_name ${src_file} NAME)
        string(REPLACE ${root_dir}/ "" group_name ${src_file})
        string(REPLACE /${src_name} "" group_name ${group_name})
        string(REPLACE "/" "\\" group_name ${group_name})
        if(NOT ${group_name} STREQUAL ${src_name})
            source_group(${group_name} FILES ${src_file})
        endif()
    endforeach()
endfunction()

acheron_add_source_groups(${CMAKE_CURRENT_SOURCE_DIR} "${acheron_files}")


add_library(${PROJECT_NAME} SHARED "${acheron_files}")

2 个答案:

答案 0 :(得分:0)

您不需要手动添加该CMake块(距离完成还很遥远)。按照有关在NDK上使用CMake的文档进行操作,它将为您处理详细信息:https://developer.android.com/studio/projects/add-native-code

答案 1 :(得分:0)

我终于做到了!在重写cmakes文件之后,我接近正确的决定。我想念ABI的依赖。我已经纠正了一些问题:

应用cmake:

set(lib_src_DIR ${CMAKE_CURRENT_LIST_DIR}/../acheron_lib/build/${CMAKE_BUILD_TYPE}/acheron)

set_target_properties(libacheron
                      PROPERTIES IMPORTED_LOCATION
                      ${lib_src_DIR}/${ANDROID_ABI}/libacheron.so)

lib other cmake (我之所以删除MSVC块,只是因为它对Android构建无效):

macro(acheron_set_build_directory build_dir)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${build_dir}/${ANDROID_ABI})
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${build_dir}/${ANDROID_ABI})
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${build_dir}/${ANDROID_ABI})
endmacro()