【发布时间】:2022-01-07 00:19:37
【问题描述】:
尝试使用 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。它们之间有什么区别?我读了this article。但是仍然没有解释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之间的区别
【问题讨论】:
-
(1) 不清楚您为什么认为
libc++_shared.so被使用。你有建议它的构建日志吗? (2) 不清楚你为什么认为你在使用libstdc++。此符号模式不是libstdc++的特征。__1也不一定存在于libc++的所有安装中。1in__1是what _LIBCPP_ABI_VERSION扩展为,但可以配置为扩展为任何内容。 -
感谢您的反馈,我更新了我的问题
-
这些绝对不是来自 libstdc++ 的符号。在
libstdc++中有一个名为__cxx11的 ABI 命名空间,但它 (1) 是硬编码的,并且 (2) 不适用于所有符号,尤其不适用于allocator或char_traits。 -
那么
libc++.so和libc++_shared.so有什么区别,为什么Android ndk不允许“轻松”“只”使用libc++.so? -
这个我不知道。
标签: c++ android-ndk libc++