Para mi proyecto de diploma, estoy tratando de usar Android Studio para portar mi proyecto de C ++ a Android. Mi proyecto de C ++ incluye mi propio código y biblioteca que fue desarrollado antes que yo. En primer lugar, intenté compilar el código fuente de esta biblioteca en una biblioteca compartida de Android. Lo hice con éxito. Pero cuando estoy compilando el código que usa esta biblioteca, cmake me dice que mi biblioteca es incompatible para la arquitectura x86 (creo que para otros también lo será). Cuando estaba compilando la biblioteca, uso este código para diferentes ABI incluye:

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()

No sé cómo arreglar eso. Parece que necesito vincular cualquier biblioteca dependiente de ABI, pero no sé cómo puedo entender qué biblioteca necesito. "Mi" biblioteca tiene muchos archivos y sería difícil rastrear todas las dependencias. Entonces, ¿cómo puedo solucionar eso (seguro que después de construir "mi" biblioteca tengo * .so para todas las ABI y las estoy vinculando al código principal usando $ {ANDROID_ABI})?

Tengo 2 módulos en mi proyecto de Android Studio: biblioteca y aplicación. La biblioteca se compila bien, pero no puedo vincularla a la aplicación porque cmake me dice que la biblioteca es un objetivo incompatible. Después de cambiar cmakes, me deshice del bloque ABI cmake, pero la biblioteca aún no quiere vincular.

Creación de aplicaciones:

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")

lib otra 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}")
0
tw1nkle 15 oct. 2018 a las 23:15

2 respuestas

La mejor respuesta

¡Finalmente lo hice! Después de haber reescrito los archivos de cmakes, estaba cerca de tomar la decisión correcta. Extraño la dependencia de ABI. He corregido un poco mis cmakes:

creación de aplicaciones:

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 (elimino el bloque MSVC solo porque es inútil para la compilación de 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
tw1nkle 16 oct. 2018 a las 18:27

No es necesario que agregue ese bloque de CMake manualmente (también está lejos de estar completo). Siga los documentos sobre el uso de CMake con el NDK y manejará los detalles por usted: https://developer.android.com/studio/projects/add-native-code

0
Dan Albert 15 oct. 2018 a las 23:21