简体   繁体   中英

Clang linking .so library libc++_shared.so

I'm having an Error in my Native C++ Code in Android NDK Application

My main.cpp

#include <stdio.h>

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

The main.c is exactly the same. If i run

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

then

adb push a.out /data/local/tmp

and

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

all works fine. But if i run

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

then

adb push a.out /data/local/tmp

and

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

The error message is:

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

Then i tried to run

/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

to link the library, but it doesn't work anyway.

The error message is:

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

That's the expected behavior. Unlike the standard C library (to which your program is linking when building with simple *-clang ), C++ is not a system library. You have to make it available on the device just like any other third party library.

Quoted from official documentation :

Note: libc++ is not a system library. If you use libc++_shared.so , it must be included in your APK. If you're building your application with Gradle this is handled automatically.

And:

If you're using clang directly in your own build system, clang++ will use c++_shared by default. To use the static variant, add -static-libstdc++ to your linker flags.

So either link with C++ statically by passing -static-libstdc++ to compiler. Or copy the libc++_shared.so (from <NDK>/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/ in your case) and run like:

adb push a.out libc++_shared.so /data/local/tmp/
adb shell
cd /data/local/tmp/
LD_LIBRARY_PATH=. ./a.out

Other than the LLVM's Standard C++ library discussed above, there's also a limited system C++ runtime ( /system/lib(64)/libstdc++.so ) which "provides support for the basic C++ Runtime ABI" . But "The system STL will be removed in a future NDK release."

I compiled the same "hello world" code in a .c and .cpp file and didn't have the same issue when I pushed the application to my device. I assume you're having the same issue as in this topic: Application can't find libc++_shared.so The issue may come from your toolchain or toolchain parameters as you are calling clang manually.

I created a simple project that you can run and test: 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
        )

In generated cmake script, I can see the following definition for cpp compiler:

 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

I write a new Answer for the Solution because i cannot edit my question. The Solution is the following command for android devices with armv7:

/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

For aarch64 armv8 the command is:

/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

A CMakeLists.txt file should look as:

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

Then can the app build with

cmake

make

adb push Test /data/local/tmp

adb shell /data/local/tmp/Test

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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