缺少aarch64 Android的标准库交叉编译



在我的主机系统(Ubuntu, 64Bit)上,我使用gcc/g++编译器为我的Android应用程序(arm64-v8a)交叉编译我的库。在从我的应用程序调用函数时,我收到的消息是无法找到libc.so.6libstdc++.so.6等库。

在我的/usr目录中,我有一个aarch64-linux-gnu文件夹,包含bin,includelib文件夹。

CMakeLists.txt:

cmake_minimum_required(VERSION 3.6.0)
set(CMAKE_TOOLCHAIN_FILE android.toolchain.cmake)
project(testlibrary)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STYANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# find header & source
file(GLOB_RECURSE SOURCE_CPP "src/*.cpp")
file(GLOB_RECURSE HEADER "src/*.h")
add_library(${PROJECT_NAME}  SHARED
${SOURCE_CPP}
${HEADER}
)
source_group("Header include" FILES ${HEADER})
source_group("Source src"     FILES ${SOURCE_CPP})

android.toolchain.cmake:

cmake_minimum_required(VERSION 3.6.0)
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc")
set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++")
set(CMAKE_ANDROID_NDK /home/ubuntu/Android/Sdk/ndk/21.4.7075529)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

错误信息如下:

dlopen failed: library "libc.so.6" not found: needed by /my/lib/path/testlib.so in namespace classloader-namespace

dlopen failed: library "libstdc++.so.6" not found: needed by /my/lib/path/testlib.so in namespace classloader-namespace

我是否必须设置Sysroot或其他路径,以便在我的工具链文件中找到我的库,我使用哪个路径?

EDIT1:aarch64-linux-gnu文件夹添加到我的构建目录并显式地包括

target_link_libraries($PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/aarch64-linux-gnu/lib/libstdc++.so.6)
# also any other lib, e.g. libstdc++.so, libc.so and libc.so.6 don't work

仍然导致上述错误消息。

我使用下面的.cpp.hpp文件做了一个最小的错误示例,这导致了libc.so.6 not found的这种情况。删除malloc行也会删除错误消息。调用testFunc也返回正确的值到我的应用程序,我可以显示。src_file.cpp

#include "header_file.hpp"
#include <stdlib.h> // for malloc
int testFunc_(){
char* buffer;
buffer = (char *) malloc (10);
return 42;
}

header_file.hpp

extern "C" int testFunc_();

我还将以下行添加到我的android.toolchain.cmake文件(我将文件夹从/usr/aarch64/linux-gnu/复制到我的构建目录)

set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
set(LDFLAGS="-Wl,-rpath,../aarch64-linux-gnu/lib")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LDFLAGS}" CACHE INTERNAL "" FORCE)
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} ${LDFLAGS}" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LDFLAGS}" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} ${LDFLAGS}" CACHE INTERNAL "" FORCE)

EDIT2:在运行readelf -d 'path/to/lib'时,我得到以下(我认为是必要的)条目

Tag         Type            Name/Value
0x000...1   (NEEDED)        Shared library: [libc.so.6]
0x000..1d   (RUNPATH)       Library runpath: [/home/username/Desktop/projectfolder/aarch64-linux-gnu/lib]

将以下行添加到我的CMakeLists.txt(从我的工具链文件中删除RPATH相关的东西或将它们也更改为./)应该允许我在构建文件夹(arm64-v8a)中添加库旁边的library.so

set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-Wl,-rpath,./")

没有RPATH标签。RUNPATH条目是我从/usr/aarch64-linux-gnu文件夹复制的.so.6.so文件的位置。我认为我的主要问题是在我的应用程序中正确捆绑必要的库,正如David Grayson所暗示的那样。

EDIT3:运行file libc.so.6还显示它是一个与ARM aarch64架构动态链接的ELF 64位LSB共享对象,用于GNU/Linux 3.7.0,解释器/lib/ld- Linux -aarch64.so。1,剥夺了

标:在我的app/build.gradle中,我有以下行

if(isNewArchitectureEnabled()) {
externalNativeBuild {
ndkBuild {
arguments "APP_PLATFORM=android-12",
"APP_STL=c_++shared",
"NDK_TOOLCHAIN_VERSION=gcc", // was clang before
"GENERATED_SRC_DIR=$buildDir/generated/source",
"PROJECT_BUILD_DIR=$buildDir",
"REACT_ANDROID_DIR=${reactNativeRoot}/ReactAndroid",
"REACT_ANDROID_BUILD_DIR=${reactNativeRoot}/ReactAndroid/build",
"NODE_MODULES_DIR=$rootDir/../node_modules"
cflags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
cppFlags "-std=c++17", //maybe 11 here(?) tried out both my App and .so to 11 but also no success
targets "myapp_appmodules"
}
}
}

packagingOptions {
pickFirst 'lib/arm64-v8a/libc++_shared.so'
pickFirst 'lib/arm64-v8a/libm.so'
pickFirst 'lib/arm64-v8a/libm.so.6'
pickFirst 'lib/arm64-v8a/libstdc++.so'
pickFirst 'lib/arm64-v8a/libstdc++.so.6'
pickFirst 'lib/arm64-v8a/libc.so'
pickFirst 'lib/arm64-v8a/libc.so.6'
}

我可能使用了一个错误的编译器/给我的ndk文件夹内的独立工具链一个尝试!

您要么需要将这些库静态地链接到您的可执行文件中(链接时-static可能有效),要么需要将它们与可执行文件一起发布,并将它们放在可执行文件可以找到的地方,例如在同一目录中。

我对Android不是很熟悉,但也可能有一种方法可以让目标Android系统在运行时提供这些库,因为它们非常常见并且被广泛使用。

我解决了它改变我的编译器(CMAKE_C_COMPILERCMAKE_CXX_COMPILER)在工具链文件和离开我的CMakeLists.txt和一开始一样。

cmake_minimum_required(VERSION 3.6.0)
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_C_COMPILER /home/username/path/to/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang)
set(CMAKE_CXX_COMPILER /home/username/path/to/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++)
set(CMAKE_ANDROID_NDK /home/username/path/to/ndk)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

使用Android API level 21.

最新更新