在Linux上,一般情况下都会使用GCC
和libstdc++
,因为他们之间有特殊优化,如果使用Clang
编译,性能不会比GCC
高,因为默认情况下Clang
编译出来的程序也是链接的libstdc++
,而Clang
的正统在libc++
上
运行环境
docker run -it --rm ubuntu bash
apt update && apt install -y clang make cmake ninja libc++-dev libc++abi-dev llvm-dev
使用VSCode附加到容器
-
创建test文件夹,在VSCode中打开
-
Ctrl+Shift+P
选择CMake: Quick Start
-
输入项目名称
test
-
VSCode中选择编译器为Clang
编译生成
- 默认
clang
会使用libstdc++.so
作为C++
的运行时库,libstdc++.so
是属于GNU
的,GCC
同属于GNU
组织
cmake_minimum_required(VERSION 3.5.0)
project(test VERSION 0.1.0 LANGUAGES C CXX)
add_executable(test main.cpp)
root@49d525b221f5:~/test/build# ldd test
linux-vdso.so.1 (0x00007ffd5bdd8000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fdf8c330000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdf8c247000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fdf8c21a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdf8c008000)
/lib64/ld-linux-x86-64.so.2 (0x00007fdf8c5b8000)
Clang
属于LLVM
,如果想在Linux上使用libc++.so
,需要手动指定,Clang
和libc++.so
都是属于LLVM
cmake_minimum_required(VERSION 3.5.0)
project(test VERSION 0.1.0 LANGUAGES C CXX)
add_executable(test main.cpp)
target_compile_options(test PUBLIC -stdlib=libc++)
target_link_libraries(test PUBLIC c++ -rtlib=compiler-rt -unwindlib=libunwind -stdlib=libc++)
# 一定要加 -rtlib=compiler-rt -unwindlib=libunwind -stdlib=libc++ 否则会同时链接libc++和libstdc++
root@49d525b221f5:~/test/build# ldd test
linux-vdso.so.1 (0x00007ffcf736a000)
libc++.so.1 => /lib/x86_64-linux-gnu/libc++.so.1 (0x00007fee9680f000)
libc++abi.so.1 => /lib/x86_64-linux-gnu/libc++abi.so.1 (0x00007fee967d3000)
libunwind.so.1 => /lib/x86_64-linux-gnu/libunwind.so.1 (0x00007fee967c5000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fee966dc000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fee964ca000)
/lib64/ld-linux-x86-64.so.2 (0x00007fee96918000)
如果要静态链接运行时,在target_link_libraries
中加入-static
即可。
使用MUSL的libc库
上面编译出来的程序,始终都链接了系统的glibc
,如果想要完全去除GNU
相关的东西,最简单的办法就是使用Alpine
系统
FROM alpine:edge
RUN sed -i 's#https\?://dl-cdn.alpinelinux.org/alpine#https://mirrors.tuna.tsinghua.edu.cn/alpine#g' /etc/apk/repositories
RUN apk add --no-cache cmake ninja clang musl-dev llvm-dev libc++-dev llvm-libunwind-dev lld libc-dev compiler-rt libc++-static llvm-libunwind-static linux-headers lldb
系统需要使用alpine:edge
,alpine
最新版本的libc++
已经不依赖libgcc
了,3.20版本的libc++
库还是会依赖libgcc
cmake文件
cmake_minimum_required(VERSION 3.5.0)
project(test VERSION 0.1.0 LANGUAGES C CXX)
add_executable(test main.cpp)
target_compile_definitions(test PUBLIC _LARGEFILE64_SOURCE)
target_compile_options(test PUBLIC --stdlib=libc++)
target_link_libraries(test PUBLIC --rtlib=compiler-rt --unwindlib=libunwind --stdlib=libc++ -fuse-ld=lld c++ c++abi)
# 需要静态链接 后面加 -static
编译器选择clang
root@f7f43530e56b:~/test/build# ldd test
/lib/ld-musl-x86_64.so.1 (0x7fa9fb884000)
libc++.so.1 => /usr/lib/libc++.so.1 (0x7fa9fb6fb000)
libc++abi.so.1 => /usr/lib/libc++abi.so.1 (0x7fa9fb6c4000)
libunwind.so.1 => /usr/lib/libunwind.so.1 (0x7fa9fb6b5000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7fa9fb884000)
-
TODO 参考alpine的编译脚本编译llvm+clang
参考:
Assembling a Complete Toolchain — Clang 20.0.0git documentation (llvm.org)