在 Ubuntu 20.04 上,我需要使用 libc++,因为默认的 libstdc++ 缺少必需的支持。为了不必发布 libc++,我需要针对 libc++ 进行静态链接。
我有一个可用的静态版本的 libc++,它是使用以下一系列命令在本地创建的(根据 https://libcxx.llvm.org/BuildingLibcxx.html):
git clone --single-branch --branch release/15.x --depth 1 https://github.com/llvm/llvm-project.git
mkdir /llvm-project/build
cmake -G "Ninja" -S /llvm-project/runtimes -B /llvm-project/build \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
-DLIBCXX_INCLUDE_BENCHMARKS=OFF \
-DLIBCXX_INCLUDE_TESTS=OFF \
-DLIBCXX_ENABLE_SHARED=ON \
-DLIBCXX_ENABLE_STATIC=ON \
-DLIBCXXABI_ENABLE_SHARED=ON \
-DLIBCXXABI_ENABLE_STATIC=ON \
-DLIBCXX_CXX_ABI=libcxxabi \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE=Release
ninja -C /llvm-project/build cxx cxx-abi unwind
ninja -C /llvm-project/build install-cxx install-cxxabi install-unwind
我没能使它达到不对 libc++ 有任何运行时依赖的预期结果。
尝试编译以下简单示例:
#include <iostream>
int main(int, const char**) {
std::cout << "Clang " << __clang_version__ << '\n';
#ifdef _LIBCPP_VERSION
std::cout << " Using libc++ " << _LIBCPP_VERSION << '\n';
#endif
return 0;
}
使用 clang++ test.cpp -std=c++20 -static-libstdc++ -static-libgcc
将不会导致不需要的运行时依赖(仅 linux-vdso、libm、libc、ld-linux ),但是它使用的是 stdlibc++,它不适用于实际代码。
使用 clang++ test.cpp -stdlib=libc++ -std=c++20 -static-libstdc++ -static-libgcc
会导致大量关于缺少标准内容的链接器错误。
使用 clang++ test.cpp -stdlib=libc++ -std=c++20 -static-libstdc++ -static-libgcc -lc++abi
后跟 ldd a.out
将显示它依赖于 libc++abi.so 和 libgcc_s.so.1,这两者都是不需要的,前者比后者更重要。
(为什么我必须显式链接 c++abi,它不应该像在 c++ 中那样自己完成吗?)
尝试不让讨厌的运行时依赖性执行 clang++ test.cpp -stdlib=libc++ -std=c++20 -static-libstdc++ -static-libgcc -lc++abi -static
将导致
ld: error: duplicate symbol: __lll_lock_wait_private
>>> defined at libc-lowlevellock.o:(__lll_lock_wait_private) in archive /lib/x86_64-linux-gnu/libc.a
>>> defined at lowlevellock.c:27
>>> lowlevellock.o:(.text+0x0) in archive /lib/x86_64-linux-gnu/libpthread.a
不知道为什么它突然决定在那里安装 pthread,因为我从未指定过它,并且在示例代码中似乎不需要它,但无论如何。
如何说服 clang 真正静态链接 libc++(和 libc++abi),没有错误,这样它就不会有非标准的运行时依赖性?
最佳答案
整个 C++ 标准库(libc++/libstdc++ 等)都依赖于标准 C 库和 pthreads 等。
C++ 标准库在 Linux 上 只是围绕 C 语言提供的基础结构的一个小外壳,它是真正的主力军。
std::thread 基本上只是 pthreads 之上的语法糖。这是大多数 C++ 开发人员难以接受的残酷现实。
查看示例:
关于c++ - Clang 静态链接 libc++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75258346/