Проблема Android Studio со связыванием разделяемой библиотеки для разных ABI - PullRequest
0 голосов
/ 15 октября 2018

В своем дипломном проекте я пытаюсь использовать 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 библиотеку, но я не знаю, как понять, какая библиотека мне нужна.В «моей» библиотеке много файлов, и было бы сложно просто проследить все зависимости.Итак, как я могу это исправить (конечно, после создания "моей" библиотеки у меня есть * .so для всех ABI, и я связываю их с основным кодом, используя $ {ANDROID_ABI})?

У меня есть 2 модуля в моем AndroidСтудийный проект: библиотека и приложение.Библиотека хорошо собирается, но я не могу связать ее с приложением, потому что cmake говорит мне, что библиотека является несовместимой целью.После смены cmakes я избавился от блока ABI cmake, но библиотека по-прежнему не хочет ссылаться.

App 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основной 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")

lib другой 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 голосов
/ 16 октября 2018

Я наконец сделал это!После того, как я переписал файлы cmakes, я был близок к правильному решению.Я скучаю по зависимости ABI.Я немного исправил свои cmakes:

app 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()
0 голосов
/ 16 октября 2018

Вам не нужно добавлять этот блок CMake вручную (он также далек от завершения).Следуйте документации по использованию CMake с NDK, и он обработает детали для вас: https://developer.android.com/studio/projects/add-native-code

...