Reputation: 11
For my diploma project, I'm trying to use Android Studio to port my c++ project to android. My c++ project includes my own code and library which was developed before me. Firstly I was tried to compile the source code of this library to a shared android library. I successfully did it. But when I am compiling the code which uses this library, cmake tells me that my library is incompatible for x86 architecture (I think for others will be too). When I was compiling the library I use this code for different ABI includes:
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()
I don't know how to fix that. It looks like I need to link any ABI dependent library, but I don't know how I can understand which library I need. "My" library has many files and it would be hard to just trace all dependencies. So how I can fix that (sure after building "my" library I have *.so for all ABIs and I am linking they to main code using ${ANDROID_ABI})?
I have 2 modules in my Android Studio project: library and application. The library builds well, but I can't link it to the application because cmake tells me that library is an incompatible target. After changing cmakes I got rid of ABI cmake block, but the library still doesn't want to link.
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 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 other 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}")
Upvotes: 0
Views: 809
Reputation: 11
I finally did it! After I had rewritten cmakes files I was close to correct decision. I miss ABI dependence. I have a little corrected my 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 (I remove MSVC block just because of it useless for android build):
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()
Upvotes: 1
Reputation: 10519
You don't need to add that block of CMake manually (it's also far from complete). Follow the docs on using CMake with the NDK and it'll handle handle the details for you: https://developer.android.com/studio/projects/add-native-code
Upvotes: 0