Clang
Clang 是一个基于 LLVM 的 C/C++/Objective C/CUDA 编译器。最新版本在 “Apache 2.0 License with LLVM exceptions” 协议下分发。
安装
使用 Clang 构建软件包
通用设置
要更改构建软件包的默认编译器,请 编辑
/etc/makepkg.conf
... export CC=clang export CXX=clang++
若要使用 libc++ 作为 C++ 标准库 而非 GCC 的 libstdc++:请安装 libc++ 软件包,然后在 /etc/makepkg.conf 的 CXXFLAGS 中添加 -stdlib=libc++。
若要支持 LTO:请 安装 lld 软件包,然后在 /etc/makepkg.conf 的 LDFLAGS 中添加 -fuse-ld=lld。
如果您使用 debug 构建,还需要从 DEBUG_CFLAGS 和 DEBUG_CXXFLAGS 中删除 -fvar-tracking-assignments,因为 Clang 不支持该选项。
makepkg.conf 中注释掉 Clang 相关的行。Qt 软件包
Qt 软件包可能需要额外设置。Qt 有预定义的构建配置,称为 mkspecs,在 Linux 上默认使用 GCC。
在某些情况下,mkspec 会根据 CC/CXX 变量自动设置为 linux-clang。但在其他情况下(例如直接调用 qmake 的软件包),则不会自动设置,因此我们可以显式地进行设置
/etc/makepkg.conf
export QMAKESPEC=linux-clang
Rust 软件包
每当 clang 被设置为系统默认编译器时,需要配置 Rust 使用 clang 作为 C 代码的链接器,因为 C 代码经常作为构建 Rust 应用程序过程的一部分而被编译。
为此,需要在 /etc/makepkg.conf.d/rust.conf 中指定 clang(以及可选的 lld)。
例如,要使用 clang 和 lld
/etc/makepkg.conf.d/rust.conf
RUSTFLAGS="-Cforce-frame-pointers=yes -Clinker=clang -Clink-arg=-fuse-ld=lld"
使用静态分析器
要分析项目,只需在构建命令前加上 scan-build。例如
$ scan-build make
如果您的项目已经编译过,scan-build 将不会重新构建也不会进行分析。要强制重新编译并分析,请使用 -B 开关
$ scan-build make -B
也可以分析特定文件
$ scan-build gcc -c t1.c t2.c
技巧与提示
Bash 补全
为了启用 Bash 补全,请安装 bash-completion。
故障排除
栈保护
clang 软件包默认启用 -fstack-protector-strong。这一做法在编译大多数程序时不会产生任何问题,且能以极小的代价提高整体的安全性和鲁棒性。然而,在某些情况下,TLS 中的栈保护金丝雀(canary)未初始化(例如,当您自己实现 _start 函数时)。在这种情况下,使用 -fstack-protector-strong 编译可能会导致分段错误或其他意外错误。用户应意识到 clang 软件包与上游版本之间的差异。