我正在尝试使用Android NDK 23(23.1.7779620)构建一个简单的C++库,但是我感到非常困惑。我正在使用CMake,这是一个非常简单的程序:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(mf)
add_library(mf lib.cpp)
// lib.hpp
#pragma once
#include <string>
std::string foo(std::string);
// lib.cpp
#include "lib.hpp"
std::string foo(std::string str) {
return std::string{"test"} + str;
}
这是构建命令行代码:
这是构建的命令行代码:
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DANDROID_STL=c++_shared -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-29 -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake ..
cmake --build . -v
- 首先遇到的问题是,我原本期望链接到的是
libc++.so
而不是libc++_shared.so
。它们之间有什么区别?我阅读了这篇文章,但还是没有解释libc++
和libc++_shared
之间的区别。 - 第二个问题更糟糕,似乎我正在使用libstdc++!
- 第三点,我以为clang的C++实现在命名空间
std::__1
下,但我找不到类似的东西。
我知道使用了libc++_shared
是因为这个命令:
$ readelf -d libmf.so
Dynamic section at offset 0x76e0 contains 26 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libm.so]
0x0000000000000001 (NEEDED) Shared library: [libc++_shared.so]
0x0000000000000001 (NEEDED) Shared library: [libdl.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x000000000000000e (SONAME) Library soname: [libmf.so]
运行 nm 命令后,我发现我正在使用来自 libstdc++
库的符号:
$ nm -gDC libmf.so | grep '__ndk1'
0000000000003af0 T foo(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >)
U std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >::append(char const*, unsigned long)
$ nm -gDC libmf.so | grep '__1'
$
更新
本文解释了libc++.so
和libc++_shared.so
之间的区别。
libc++_shared.so
。您有建议吗? (2) 不清楚您为什么认为正在使用libstdc++
。这个符号模式不是libstdc++
的特征。__1
也不一定存在于所有的libc++
安装中。__1
中的1
是_LIBCPP_ABI_VERSION
扩展的内容,但它可以配置为扩展为任何内容。 - n. m.libstdc++
中有一个ABI命名空间叫做__cxx11
,但它是(1)硬编码的,并且(2)并不适用于所有符号,特别是不适用于allocator
或char_traits
。 - n. m.libc++.so
和libc++_shared.so
之间有什么区别呢?为什么 Android ndk 不允许“轻松地”“只是”使用libc++.so
呢? - Elvis Dukaj