clang 相关的若干事
感谢 llvmlinux 项目多年的努力, clang 可以无补丁的编译 linux kernel 4.14, 现在在搞 lld 和其它的一些支持 https://github.com/ClangBuiltLinux/linux (有时候会想错成 clangbuiltkernel, 特此纠正). 只支持 x86-64 和 arm64/aarch64 (其他 arch 有行的也有不行的). 如果有小问题可以跟着错误信息找 patch 解决, 或者关闭某些模块.
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- HOSTCC=clang CC="clang -target aarch64-none-linux-gnu" 写成 make.sh 的脚本可以是这样的 (target 根据 binutils 来写): make ARCH=$ARCH CROSS_COMPILE=$TARGET- HOSTCC=clang CC="clang -target $TARGET" LD=ld.gold $@ 如有需要可以在 install / module_install 时追加 INSTALL_MOD_PATH=blah INSTALL_PATH=blah/boot 对 rpi3 来说可能需要先 make bcmrpi3_defconfig. 追记: lld-8 可以链接 aarch64 内核了, 需要几个内核补丁.
这里可以插播三件事情.
第一个问题是装哪个版本的 clang? 第一答案是选 chromium 的, mac 和 linux 通用 (windows 也有). 方法如下
mkdir -p src/tools/clang/scripts && cd src/tools/clang/scripts curl "https://chromium.googlesource.com/chromium/src/tools/clang/+/master/scripts/update.py?format=TEXT" | base64 -d > update-clang.py python2 update-clang.py cd ../../../.. cp -s $PWD/src/third_party/llvm-build/Release+Asserts/bin/* /usr/local/bin/
比较有趣的是 GNU 的 cp 比 ln 可能更好用, -s 都是符号链接的意思.
但是如果要考虑到跨体系结构的统一(有混非 x86 机器), 去 llvm 官方下也可以, 那一般就依赖 glibc 了.
---
其次需要注意的是 clang 本身就是 cross-compiler, 只要指定的 -target 在支持范围内 (以前叫 -ccc-host-triple 或者 -ccc-target-triple).
最上面编译内核用的 make 需要先准备好对应的 binutils, 各发行版不同不提. 据称 --enable-targets=all --enable-64-bit-bfd --enable-install-libbfd 就能搞出全部的 arch, 需要多少编译时间就不知道了.
从某种意义上来说, 只要坚持用 glibc + clang, 关心编译器怎么自举是一件很没必要的事情, 有某家对编译器做反复的测试, 不用这个现成的干啥? 最坏情况也不过是 /lib64/ld-linux-x86-64.so.2 --library-path "/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu" --inhibit-rpath "" EXEC.
llvm 应该有一个目标是构建统一支持全平台的 assembler, linker, compiler. LLD 链接 linux kernel 的尝试起于一年前, 现在如何尚不得而知... ref: http://lists.llvm.org/pipermail/llvm-dev/2017-January/109288.html 里面能够看到 HOSTCC=clang HOSTLD=ld.lld CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm (其实还应该有 llvm-ranlib) clang 不包括 llvm-nm / ranlib, chromium clang 没提供 llvm, 还要继续用 binutils 版.
binutils 应该短时间内不会失去历史地位, 比如 objcopy 和 strip 就换不了. (追记: 后来都有了, 叫 llvm-objdump / llvm-strip, 后者其实是依赖于前者代码, 是个 wrapper). objcopy --only-keep-debug / --strip-debug / --add-gnu-debuglink 很有用, 这里记一笔.
---
最后是 distcc 和 distcc-pump, 首先必要条件就是在高配机器上准备 distccd. (配置方法略, 也可以用 ssh 法, distccd 本身是不安全的, 必须保证网络私有才能使用). 追记: distcc 3.3 左右引入了原生 clang 支持, target 是自动生成的, 非常方便 (当然尽量用新版).
传统玩法是 (ccache) distcc machine-vendor-operatingsystem-gcc/g++. 注意不能用 -march=native 和 -mtune=native. 后来有了 distcc-pump, 可以把预编译也让远程机器做. 但是这时候要写成 distcc-pump make 而且不能用 ccache. 把这些事情合起来...
-
志诚 赞了这篇日记 2018-02-03 22:47:15
-
River 赞了这篇日记 2018-02-03 17:41:00
-
咚touch her 赞了这篇日记 2018-02-03 15:47:39