繁体   English   中英

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

[英]Clang linking .so library libc++_shared.so

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

我的主.cpp

#include <stdio.h>

int main() 
{
  printf("Hello, world\n");
  return 0;
}

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

/home/rip/Music/android-ndk-r19b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang -pie main.c

然后

adb push a.out /data/local/tmp

adb shell /data/local/tmp/a.out

一切正常。 但如果我跑

/home/rip/Music/android-ndk-r19b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang++ -pie main.cpp

然后

adb push a.out /data/local/tmp

 adb shell /data/local/tmp/a.out

错误信息是:

CANNOT LINK EXECUTABLE "/data/local/tmp/a.out": library "libc++_shared.so" not found

然后我试着跑

/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

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

错误信息是:

 CANNOT LINK EXECUTABLE "/data/local/tmp/a.out": library "libc++_shared.so" not found

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

引用自官方文档

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

和:

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

因此,要么通过将-static-libstdc++传递给编译器来静态链接 C++。 或者复制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

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

我在 .c 和 .cpp 文件中编译了相同的“hello world”代码,当我将应用程序推送到我的设备时没有出现相同的问题。 我假设您遇到了与本主题相同的问题: Application can't find libc++_shared.so当您手动调用 clang 时,该问题可能来自您的工具链或工具链参数。

我创建了一个可以运行和测试的简单项目: android-ndk-example

add_executable( # Sets the name of the library.
    ndk_example_c

    # Provides a relative path to your source file(s).
    main.c
    )


add_executable( # Sets the name of the library.
        ndk_example_cpp

        # Provides a relative path to your source file(s).
        main2.cpp
        )

在生成的 cmake 脚本中,我可以看到 cpp 编译器的以下定义:

 rule CXX_COMPILER__ndk_example_cpp
  depfile = $DEP_FILE
  deps = gcc
  command = D:\Users\$USER\AppData\Local\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe  --target=armv7-none-linux-androideabi19 --gcc-toolchain=D:/Users/$USER/AppData/Local/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=D:/Users/$USER/AppData/Local/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot  $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $IN_ABS
  description = Building CXX object $out

我为解决方案写了一个新的答案,因为我无法编辑我的问题。 对于带有 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

对于 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

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

然后可以构建应用程序

cmake

make

adb push Test /data/local/tmp

adb shell /data/local/tmp/Test

暂无
暂无

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

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