|
| 1 | +.. SPDX-License-Identifier: GPL-2.0 |
| 2 | +
|
| 3 | +.. include:: ../disclaimer-zh_CN.rst |
| 4 | + |
| 5 | +:Original: Documentation/kbuild/llvm.rst |
| 6 | +:Translator: 慕冬亮 Dongliang Mu <dzm91@hust.edu.cn> |
| 7 | + |
| 8 | +========================== |
| 9 | +使用 Clang/LLVM 构建 Linux |
| 10 | +========================== |
| 11 | + |
| 12 | +本文档介绍如何使用 Clang 和 LLVM 工具构建 Linux 内核。 |
| 13 | + |
| 14 | +关于 |
| 15 | +---- |
| 16 | + |
| 17 | +Linux 内核传统上一直使用 GNU 工具链(如 GCC 和 binutils)进行编译。持续的工作使得 |
| 18 | +`Clang <https://clang.llvm.org/>`_ 和 `LLVM <https://llvm.org/>`_ 工具可 |
| 19 | +作为可行的替代品。一些发行版,如 `Android <https://www.android.com/>`_、 |
| 20 | +`ChromeOS <https://www.chromium.org/chromium-os>`_、`OpenMandriva |
| 21 | +<https://www.openmandriva.org/>`_ 和 `Chimera Linux |
| 22 | +<https://chimera-linux.org/>`_ 使用 Clang 编译的内核。谷歌和 Meta 的数据中心 |
| 23 | +集群也运行由 Clang 编译的内核。 |
| 24 | + |
| 25 | +`LLVM 是由 C++ 对象实现的工具链组件集合 <https://www.aosabook.org/en/llvm.html>`_。 |
| 26 | +Clang 是 LLVM 的前端,支持 C 语言和内核所需的 GNU C 扩展,其发音为 "klang",而非 |
| 27 | +"see-lang"。 |
| 28 | + |
| 29 | +使用 LLVM 构建 |
| 30 | +-------------- |
| 31 | + |
| 32 | +通过以下命令调用 ``make``:: |
| 33 | + |
| 34 | + make LLVM=1 |
| 35 | + |
| 36 | +为主机目标进行编译。对于交叉编译:: |
| 37 | + |
| 38 | + make LLVM=1 ARCH=arm64 |
| 39 | + |
| 40 | +LLVM= 参数 |
| 41 | +---------- |
| 42 | + |
| 43 | +LLVM 有 GNU binutils 工具的替代品。这些工具可以单独启用。以下是支持的 make 变量 |
| 44 | +完整列表:: |
| 45 | + |
| 46 | + make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip \ |
| 47 | + OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump READELF=llvm-readelf \ |
| 48 | + HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld |
| 49 | + |
| 50 | +``LLVM=1`` 扩展为上述命令。 |
| 51 | + |
| 52 | +如果你的 LLVM 工具不在 PATH 中,你可以使用以斜杠结尾的 LLVM 变量提供它们的位置:: |
| 53 | + |
| 54 | + make LLVM=/path/to/llvm/ |
| 55 | + |
| 56 | +这将使用 ``/path/to/llvm/clang``、``/path/to/llvm/ld.lld`` 等工具。也可以 |
| 57 | +使用以下命令:: |
| 58 | + |
| 59 | + PATH=/path/to/llvm:$PATH make LLVM=1 |
| 60 | + |
| 61 | +如果你的 LLVM 工具带有版本后缀,并且你希望测试该特定版本而非无后缀的可执行文件, |
| 62 | +类似于 ``LLVM=1``,你可以使用 ``LLVM`` 变量传递该后缀:: |
| 63 | + |
| 64 | + make LLVM=-14 |
| 65 | + |
| 66 | +这将使用 ``clang-14``、``ld.lld-14`` 等工具。为了支持带有版本后缀的树外路径组合, |
| 67 | +我们建议:: |
| 68 | + |
| 69 | + PATH=/path/to/llvm/:$PATH make LLVM=-14 |
| 70 | + |
| 71 | +``LLVM=0`` 与省略 ``LLVM`` 完全不同,它将表现得像 ``LLVM=1``。如果你只希望使用 |
| 72 | +某些 LLVM 工具,请使用它们各自的 make 变量。 |
| 73 | + |
| 74 | +在通过不同命令配置和构建时,应为每次调用 ``make`` 设置相同的 ``LLVM=`` 值。如果 |
| 75 | +运行的脚本最终会调用 ``make``,则还应将 ``LLVM=`` 设置为环境变量。 |
| 76 | + |
| 77 | +交叉编译 |
| 78 | +-------- |
| 79 | + |
| 80 | +单个 Clang 编译器二进制文件(及其对应的 LLVM 工具)通常会包含所有支持的后端,这可以 |
| 81 | +简化交叉编译,尤其是使用 ``LLVM=1`` 时。如果仅使用 LLVM 工具,``CROSS_COMPILE`` |
| 82 | +或目标三元组前缀就变得不必要。示例:: |
| 83 | + |
| 84 | + make LLVM=1 ARCH=arm64 |
| 85 | + |
| 86 | +作为混合 LLVM 和 GNU 工具的示例,对于像 ``ARCH=s390`` 这样目前尚不支持 |
| 87 | +``ld.lld`` 或 ``llvm-objcopy`` 的目标,你可以通过以下方式调用 ``make``:: |
| 88 | + |
| 89 | + make LLVM=1 ARCH=s390 LD=s390x-linux-gnu-ld.bfd \ |
| 90 | + OBJCOPY=s390x-linux-gnu-objcopy |
| 91 | + |
| 92 | +此示例将调用 ``s390x-linux-gnu-ld.bfd`` 作为链接器和 |
| 93 | +``s390x-linux-gnu-objcopy``,因此请确保它们在你的 ``$PATH`` 中。 |
| 94 | + |
| 95 | +当 ``LLVM=1`` 未设置时,``CROSS_COMPILE`` 不会用于给 Clang 编译器二进制文件 |
| 96 | +(或相应的 LLVM 工具)添加前缀,而 GNU 工具则需要这样做。 |
| 97 | + |
| 98 | +LLVM_IAS= 参数 |
| 99 | +-------------- |
| 100 | + |
| 101 | +Clang 可以编译汇编代码。你可以传递 ``LLVM_IAS=0`` 禁用此行为,使 Clang 调用 |
| 102 | +相应的非集成汇编器。示例:: |
| 103 | + |
| 104 | + make LLVM=1 LLVM_IAS=0 |
| 105 | + |
| 106 | +在交叉编译时,你需要使用 ``CROSS_COMPILE`` 与 ``LLVM_IAS=0``,从而设置 |
| 107 | +``--prefix=`` 使得编译器可以对应的非集成汇编器(通常,在面向另一种架构时, |
| 108 | +你不想使用系统汇编器)。例如:: |
| 109 | + |
| 110 | + make LLVM=1 ARCH=arm LLVM_IAS=0 CROSS_COMPILE=arm-linux-gnueabi- |
| 111 | + |
| 112 | +Ccache |
| 113 | +------ |
| 114 | + |
| 115 | +``ccache`` 可以与 ``clang`` 一起使用,以改善后续构建(尽管在不同构建之间 |
| 116 | +KBUILD_BUILD_TIMESTAMP_ 应设置为同一确定值,以避免 100% 的缓存未命中, |
| 117 | +详见 Reproducible_builds_ 获取更多信息):: |
| 118 | + |
| 119 | + KBUILD_BUILD_TIMESTAMP='' make LLVM=1 CC="ccache clang" |
| 120 | + |
| 121 | +.. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp |
| 122 | +.. _Reproducible_builds: reproducible-builds.html#timestamps |
| 123 | + |
| 124 | +支持的架构 |
| 125 | +---------- |
| 126 | + |
| 127 | +LLVM 并不支持 Linux 内核所有可支持的架构,同样,即使 LLVM 支持某一架构,也并不意味着在 |
| 128 | +该架构下内核可以正常构建或工作。以下是当前 ``CC=clang`` 或 ``LLVM=1`` 支持的架构总结。 |
| 129 | +支持级别对应于 MAINTAINERS 文件中的 "S" 值。如果某个架构未列出,则表示 LLVM 不支持它 |
| 130 | +或存在已知问题。使用最新的稳定版 LLVM 或甚至开发版本通常会得到最佳结果。一个架构的 |
| 131 | +``defconfig`` 通常预期能够良好工作,但某些配置可能存在尚未发现的问题。欢迎在以下 |
| 132 | +问题跟踪器中提交错误报告! |
| 133 | + |
| 134 | +.. list-table:: |
| 135 | + :widths: 10 10 10 |
| 136 | + :header-rows: 1 |
| 137 | + |
| 138 | + * - 架构 |
| 139 | + - 支持级别 |
| 140 | + - ``make`` 命令 |
| 141 | + * - arm |
| 142 | + - 支持 |
| 143 | + - ``LLVM=1`` |
| 144 | + * - arm64 |
| 145 | + - 支持 |
| 146 | + - ``LLVM=1`` |
| 147 | + * - hexagon |
| 148 | + - 维护 |
| 149 | + - ``LLVM=1`` |
| 150 | + * - loongarch |
| 151 | + - 维护 |
| 152 | + - ``LLVM=1`` |
| 153 | + * - mips |
| 154 | + - 维护 |
| 155 | + - ``LLVM=1`` |
| 156 | + * - powerpc |
| 157 | + - 维护 |
| 158 | + - ``LLVM=1`` |
| 159 | + * - riscv |
| 160 | + - 支持 |
| 161 | + - ``LLVM=1`` |
| 162 | + * - s390 |
| 163 | + - 维护 |
| 164 | + - ``LLVM=1`` (LLVM >= 18.1.0),``CC=clang`` (LLVM < 18.1.0) |
| 165 | + * - um (用户模式) |
| 166 | + - 维护 |
| 167 | + - ``LLVM=1`` |
| 168 | + * - x86 |
| 169 | + - 支持 |
| 170 | + - ``LLVM=1`` |
| 171 | + |
| 172 | +获取帮助 |
| 173 | +-------- |
| 174 | + |
| 175 | +- `网站 <https://clangbuiltlinux.github.io/>`_ |
| 176 | +- `邮件列表 <https://lore.kernel.org/llvm/>`_: <llvm@lists.linux.dev> |
| 177 | +- `旧邮件列表档案 <https://groups.google.com/g/clang-built-linux>`_ |
| 178 | +- `问题跟踪器 <https://github.com/ClangBuiltLinux/linux/issues>`_ |
| 179 | +- IRC: #clangbuiltlinux 在 irc.libera.chat |
| 180 | +- `Telegram <https://t.me/ClangBuiltLinux>`_: @ClangBuiltLinux |
| 181 | +- `维基 <https://github.com/ClangBuiltLinux/linux/wiki>`_ |
| 182 | +- `初学者问题 <https://github.com/ClangBuiltLinux/linux/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22>`_ |
| 183 | + |
| 184 | +.. _zh_cn_getting_llvm: |
| 185 | + |
| 186 | +获取 LLVM |
| 187 | +--------- |
| 188 | + |
| 189 | +我们在 `kernel.org <https://kernel.org/pub/tools/llvm/>`_ 提供预编译的稳定版 LLVM。 |
| 190 | +这些版本已经针对 Linux 内核构建,使用配置文件数据进行优化。相较于其他发行版中的 LLVM,它们应该 |
| 191 | +能提高内核构建时间。 |
| 192 | + |
| 193 | +以下是一些有助于从源代码构建 LLVM 或通过发行版的包管理器获取 LLVM 的链接。 |
| 194 | + |
| 195 | +- https://releases.llvm.org/download.html |
| 196 | +- https://github.com/llvm/llvm-project |
| 197 | +- https://llvm.org/docs/GettingStarted.html |
| 198 | +- https://llvm.org/docs/CMake.html |
| 199 | +- https://apt.llvm.org/ |
| 200 | +- https://www.archlinux.org/packages/extra/x86_64/llvm/ |
| 201 | +- https://github.com/ClangBuiltLinux/tc-build |
| 202 | +- https://github.com/ClangBuiltLinux/linux/wiki/Building-Clang-from-source |
| 203 | +- https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/ |
0 commit comments