Clang 链接 .so 库 libc++_shared.so

Joh*_*ith 5 c++ android clang android-ndk

我在 Android NDK 应用程序中的本机 C++ 代码中遇到错误

我的主.cpp

#include <stdio.h>

int main() 
{
  printf("Hello, world\n");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

main.c 是完全一样的。如果我跑

/home/rip/Music/android-ndk-r19b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang -pie main.c
Run Code Online (Sandbox Code Playgroud)

然后

adb push a.out /data/local/tmp
Run Code Online (Sandbox Code Playgroud)

adb shell /data/local/tmp/a.out
Run Code Online (Sandbox Code Playgroud)

一切正常。但如果我跑

/home/rip/Music/android-ndk-r19b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang++ -pie main.cpp
Run Code Online (Sandbox Code Playgroud)

然后

adb push a.out /data/local/tmp
Run Code Online (Sandbox Code Playgroud)

 adb shell /data/local/tmp/a.out
Run Code Online (Sandbox Code Playgroud)

错误信息是:

CANNOT LINK EXECUTABLE "/data/local/tmp/a.out": library "libc++_shared.so" not found
Run Code Online (Sandbox Code Playgroud)

然后我试着跑

/home/rip/Music/android-ndk-r19b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang++ -pie hello1.cpp  /home/rip/Music/android-ndk-r19b/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so
Run Code Online (Sandbox Code Playgroud)

链接库,但无论如何它都不起作用。

Irf*_*tif 9

错误信息是:

CANNOT LINK EXECUTABLE "/data/local/tmp/a.out": library "libc++_shared.so" not found
Run Code Online (Sandbox Code Playgroud)

这是预期的行为。与标准 C 库(您的程序在使用 simple 构建时链接到该库*-clang)不同,C++ 不是系统库。您必须像任何其他第三方库一样在设备上提供它。

引用自官方文档

注意: libc++ 不是系统库。如果您使用libc++_shared.so,则它必须包含在您的 APK 中。如果您使用 Gradle 构建应用程序,则会自动处理。

和:

如果您直接在自己的构建系统中使用 clang,则c++_shared默认情况下将使用 clang++。要使用静态变体,请添加-static-libstdc++到链接器标志中。

因此,要么通过传递给编译器来静态链接 C++ -static-libstdc++。或者复制libc++_shared.so(来自<NDK>/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/您的情况)并运行如下:

adb push a.out libc++_shared.so /data/local/tmp/
adb shell
cd /data/local/tmp/
LD_LIBRARY_PATH=. ./a.out
Run Code Online (Sandbox Code Playgroud)

除了上面讨论的 LLVM 标准 C++ 库之外,还有一个有限的系统 C++ 运行时 ( /system/lib(64)/libstdc++.so),它“提供对基本 C++ 运行时 ABI 的支持”。但“系统 STL 将在未来的 NDK 版本中被删除。”


Joh*_*ith 0

我为解决方案编写了一个新答案,因为我无法编辑我的问题。对于带有armv7的android设备,解决方案是以下命令:

/home/tony/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=armv7-none-linux-androideabi19 --gcc-toolchain=/home/tony/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=/home/tony/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot main.cpp
Run Code Online (Sandbox Code Playgroud)

对于 aarch64 armv8,命令是:

/home/tony/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=aarch64-none-linux-android21 --gcc-toolchain=/home/tony/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=/home/tony/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot main.cpp
Run Code Online (Sandbox Code Playgroud)

CMakeLists.txt 文件应如下所示:

cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_COMPILER /home/tony/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++)

project(Test CXX)

set(CMAKE_CXX_FLAGS "--target=aarch64-none-linux-android21 --gcc-toolchain=/home/tony/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=/home/tony/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot")

set(SOURCES
        main.cpp
        )

add_executable(Test ${SOURCES})
Run Code Online (Sandbox Code Playgroud)

然后可以使用以下命令构建应用程序

cmake

make

adb push Test /data/local/tmp

adb shell /data/local/tmp/Test
Run Code Online (Sandbox Code Playgroud)

  • 您永远不需要手动配置这些东西。如果您使用 NDK 的 CMake 工具链文件,所有这些都已为您处理。如果您需要这样做,那么您就错误地调用了 CMake。 (2认同)