繁体   English   中英

aarch64 缺少标准库交叉编译 Android

[英]Missing Standard Library Crosscompiling for aarch64 Android

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

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

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 还会将正确的值返回到我可以显示的应用程序。 源文件.cpp

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

头文件.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还显示其 ELF 64 位 LSB 共享 object 与 ARM aarch64 架构动态链接 GNU/Linux 3.7.0,解释器/lib/ld-linux-aarch64.so.1,剥离

EDIT4:在我的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 21 级。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM