Fuchsia 使用 Clang 作为官方编译器。
前提条件
您需要安装 CMake 3.13.4 或更高版本 执行这些命令这是要求的最低版本 构建 LLVM。
虽然 CMake 支持不同的构建系统,但建议使用 忍者。
两者都应作为预构建版本出现在您的 Fuchsia 结账界面中。以下命令
假设您的 PATH
中包含 cmake
和 ninja
:
export PATH=${FUCHSIA_DIR}/prebuilt/third_party/cmake/${platform}/bin:${PATH}
export PATH=${FUCHSIA_DIR}/prebuilt/third_party/ninja/${platform}/bin:${PATH}
其中 ${FUCHSIA_DIR}
是指 Fuchsia 源代码树的根目录。
正在获取来源
以下示例命令使用 ${LLVM_SRCDIR}
引用
LLVM 源代码树检出。您可以使用官方 monorepo
https://github.com/llvm/llvm-project
以下功能:
LLVM_SRCDIR=${HOME}/llvm/llvm-project
git clone https://github.com/llvm/llvm-project ${LLVM_SRCDIR}
cd ${LLVM_SRCDIR}
git checkout ${REVISON_NUMBER}
紫红色 IDK
在构建随
工具链,则需要 Fuchsia IDK
(以前称为 SDK)。
IDK 必须位于 ${IDK_DIR}
所指向的目录中
变量:
IDK_DIR=${HOME}/fuchsia-idk
如需下载最新的 IDK,您可以使用以下代码:
# For Linux
cipd install fuchsia/sdk/core/linux-amd64 latest -root ${IDK_DIR}
适用于 Linux 的 Sysroot
如需添加适用于 Linux 的编译器运行时和 C++ 库,请下载 sysroot。
它必须位于 ${SYSROOT_DIR}
变量所指向的目录中。
SYSROOT_DIR=${FUCHSIA_DIR}/prebuilt/third_party/sysroot
为 Fuchsia 构建 Clang 工具链
Clang CMake 构建系统支持引导加载程序(也称为多阶段) build。Fuchsia 针对 Clang 编译器。 不过,对于工具链相关的开发,建议使用 单阶段构建。
如果您的目标是试用 Clang,则单阶段 build 可能就是您想要的方案。 第一阶段编译器是主机专用编译器,设置了一些选项 第二阶段所需的配置。第二阶段编译器 经过优化的编译器
设置这些编译器需要许多选项。为了简化
配置,CMake 中包含 Fuchsia Clang 构建设置
缓存文件,它们属于 Clang 代码库(Fuchsia.cmake
和
Fuchsia-stage2.cmake
)。
mkdir llvm-build
mkdir llvm-install # For placing stripped binaries here
INSTALL_DIR=${pwd}/llvm-install
cd llvm-build
单阶段 build Fuchsia 配置
为 Fuchsia 开发 Clang 时,您可以使用缓存文件 测试 Fuchsia 配置,但使用 LTO 仅运行第二阶段 这使得您可以缩短构建时间, 增量开发,而无需手动指定所有选项:
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_TOOLCHAIN_FILE=${FUCHSIA_DIR}/scripts/clang/ToolChain.cmake \
-DLLVM_ENABLE_LTO=OFF \
-DLINUX_x86_64-unknown-linux-gnu_SYSROOT=${SYSROOT_DIR}/linux \
-DLINUX_aarch64-unknown-linux-gnu_SYSROOT=${SYSROOT_DIR}/linux \
-DLINUX_riscv64-unknown-linux-gnu_SYSROOT=${SYSROOT_DIR}/ubuntu20.04 \
-DFUCHSIA_SDK=${IDK_DIR} \
-DCMAKE_INSTALL_PREFIX= \
-C ${LLVM_SRCDIR}/clang/cmake/caches/Fuchsia-stage2.cmake \
${LLVM_SRCDIR}/llvm
ninja toolchain-distribution -j1000 # Build the distribution
如果执行上述操作失败并显示与 Ninja 相关的错误,那么您可能需要将
ninja
到您的 PATH。您可以在以下位置找到预构建的可执行文件:
${FUCHSIA_DIR}//prebuilt/third_party/ninja/${platform}/bin
。
ninja toolchain-distribution
应该足以构建所有二进制文件,但
Fuchsia build 假定部分库已剥离,因此需要 ninja
install-toolchain-distribution-stripped
。
两阶段 build Fuchsia 配置
这大致相当于在 prod Builder 上运行的代码,用于构建 是 Fuchsia 提供给用户的工具链。
cmake -GNinja \
-DCMAKE_TOOLCHAIN_FILE=${FUCHSIA_DIR}/scripts/clang/ToolChain.cmake \
-DCMAKE_INSTALL_PREFIX= \
-DSTAGE2_LINUX_x86_64-unknown-linux-gnu_SYSROOT=${SYSROOT_DIR}/linux \
-DSTAGE2_LINUX_aarch64-unknown-linux-gnu_SYSROOT=${SYSROOT_DIR}/linux \
-DSTAGE2_LINUX_riscv64-unknown-linux-gnu_SYSROOT=${SYSROOT_DIR}/ubuntu20.04 \
-DSTAGE2_FUCHSIA_SDK=${IDK_DIR} \
-C ${LLVM_SRCDIR}/clang/cmake/caches/Fuchsia.cmake \
${LLVM_SRCDIR}/llvm
ninja stage2-toolchain-distribution -j1000
DESTDIR=${INSTALL_DIR} ninja stage2-install-toolchain-distribution-stripped -j1000
runtime.json
如果 Fuchsia 构建因缺少 runtime.json
文件而失败,您必须运行以下命令来生成新的 runtime.json
文件:
python3 ${FUCHSIA_DIR}/scripts/clang/generate_runtimes.py \
--clang-prefix ${INSTALL_DIR} --sdk-dir ${IDK_DIR} \
--build-id-dir ${INSTALL_DIR}/lib/.build-id > ${INSTALL_DIR}/lib/runtime.json
生成的文件包含 Fuchsia build 用于了解 工具链中的各种库都位于该位置。
融会贯通
复制并粘贴用于构建单阶段工具链的代码。此代码可以运行 从 LLVM 构建目录内启动,并假设使用的是 Linux 环境。
cd ${LLVM_BUILD_DIR} # The directory your toolchain will be installed in
# Environment setup
FUCHSIA_DIR=${HOME}/fuchsia/ # Replace with wherever Fuchsia lives
LLVM_SRCDIR=${HOME}/llvm/llvm-project # Replace with wherever llvm-project lives
IDK_DIR=${HOME}/fuchsia-idk/
SYSROOT_DIR=${FUCHSIA_DIR}/prebuilt/third_party/sysroot
CLANG_TOOLCHAIN_PREFIX=${FUCHSIA_DIR}/prebuilt/third_party/clang/linux-x64/bin/
# Download necessary dependencies
cipd install fuchsia/sdk/core/linux-amd64 latest -root ${IDK_DIR}
# CMake invocation
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=${FUCHSIA_DIR}/scripts/clang/ToolChain.cmake \
-DLLVM_ENABLE_LTO=OFF \
-DLINUX_x86_64-unknown-linux-gnu_SYSROOT=${SYSROOT_DIR}/linux \
-DLINUX_aarch64-unknown-linux-gnu_SYSROOT=${SYSROOT_DIR}/linux \
-DLINUX_riscv64-unknown-linux-gnu_SYSROOT=${SYSROOT_DIR}/ubuntu20.04 \
-DFUCHSIA_SDK=${IDK_DIR} \
-DCMAKE_INSTALL_PREFIX= \
-C ${LLVM_SRCDIR}/clang/cmake/caches/Fuchsia-stage2.cmake \
${LLVM_SRCDIR}/llvm
# Build and strip binaries and place them in the install directory
ninja toolchain-distribution -j1000
DESTDIR=${INSTALL_DIR} ninja install-toolchain-distribution-stripped -j1000
# Generate runtime.json
python3 ${FUCHSIA_DIR}/scripts/clang/generate_runtimes.py \
--clang-prefix ${INSTALL_DIR} --sdk-dir ${IDK_DIR} \
--build-id-dir ${INSTALL_DIR}/lib/.build-id > ${INSTALL_DIR}/lib/runtime.json
使用自定义 Clang 构建 Fuchsia
要指定用于构建 Fuchsia 的自定义 Clang 工具链,请在调用时传递
--args clang_prefix=\"${INSTALL_DIR}/bin\"
到 fx set
命令并运行 fx build
。
fx set core.x64 --args=clang_prefix=\"${INSTALL_DIR}/bin\"
fx build
此文件包含 Fuchsia 构建使用的相对路径,用于了解 工具链中的各种库都位于该位置。
开发 Clang
开发 Clang 时,您可能需要使用更适合 增量开发和较短的周转时间。
构建 LLVM 的最简单方法是使用以下命令:
cmake -GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" \
${LLVM_SRCDIR}/llvm
ninja
您可以使用 LLVM_ENABLE_PROJECTS
启用其他项目
变量。如需启用所有常见项目,您可以使用:
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;compiler-rt;libcxx;libcxxabi;libunwind"
同样,您也可以将某些项目构建为运行时 这意味着这些项目将使用刚刚构建的 与主机编译器相比:
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" \
-DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \
LLVM_ENABLE_PROJECTS
和 LLVM_ENABLE_RUNTIMES
均已在
CMake 缓存文件,因此您通常不需要设置这些文件,除非您
明确添加更多项目或运行时。
Clang 是一个大型项目,编译器的性能至关重要。接收者 缩短构建时间,建议使用 Clang 作为主机编译器,并且 LLD 作为主机链接器。理想情况下,应使用 LTO 和 以获得最佳性能,也可以使用配置文件引导型优化 (PGO)。
如需将主机编译器设置为 Clang 并将主机链接器设置为 LLD,您可以 请使用以下额外标志:
-DCMAKE_C_COMPILER=${CLANG_TOOLCHAIN_PREFIX}clang \
-DCMAKE_CXX_COMPILER=${CLANG_TOOLCHAIN_PREFIX}clang++ \
-DLLVM_ENABLE_LLD=ON
此示例假设 ${CLANG_TOOLCHAIN_PREFIX}
指向 bin
目录
带有尾部斜杠(因为使用此 Make 变量时)
(在 Zircon build 中)。例如,要在您的 Fuchsia 中使用该编译器,
结账(Linux 上):
CLANG_TOOLCHAIN_PREFIX=${FUCHSIA_DIR}/prebuilt/third_party/clang/linux-x64/bin/
消毒用品
大多数排错程序都可以在 LLVM 工具上使用,方法是添加
LLVM_USE_SANITIZER=<sanitizer name>
添加到您的 cmake 调用。MSan 为
不过,由于某些 LLVM 工具会触发误报。接收者
使用 MSan 支持构建 您首先需要使用 MSan 构建 libc++
联系。您可以在同一 build 中执行此操作。使用 MSan 设置 build
支持首次使用 LLVM_USE_SANITIZER=Memory
运行 CMake,以及
LLVM_ENABLE_LIBCXX=ON
。
cmake -GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_COMPILER=${CLANG_TOOLCHAIN_PREFIX}clang \
-DCMAKE_CXX_COMPILER=${CLANG_TOOLCHAIN_PREFIX}clang++ \
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;libcxx;libcxxabi;libunwind" \
-DLLVM_USE_SANITIZER=Memory \
-DLLVM_ENABLE_LIBCXX=ON \
-DLLVM_ENABLE_LLD=ON \
${LLVM_SRCDIR}/llvm
通常,此时您会运行 Ninja,但我们希望构建
所有代码都使用 libc++ 的净化版本;但如果现在构建
将使用 ${CLANG_TOOLCHAIN_PREFIX}
中的 libc++,后者未经过清理。
首先,我们只构建 cxx 和 cxxabi 目标。这些内容将用于
替换${CLANG_TOOLCHAIN_PREFIX}
中的那些工具
针对 libcxx 动态链接
ninja cxx cxxabi
现在,您已经有了一个净化版本的 libc++,接下来可以将您的构建设置为使用
而非 ${CLANG_TOOLCHAIN_PREFIX}
中的相应代码,然后构建
什么都行
ninja
综合应用:
cmake -GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_COMPILER=${CLANG_TOOLCHAIN_PREFIX}clang \
-DCMAKE_CXX_COMPILER=${CLANG_TOOLCHAIN_PREFIX}clang++ \
-DLLVM_USE_SANITIZER=Address \
-DLLVM_ENABLE_LIBCXX=ON \
-DLLVM_ENABLE_LLD=ON \
${LLVM_SRCDIR}/llvm
ninja libcxx libcxxabi
ninja
测试 Clang
如需运行 Clang 测试,您可以使用 check-<component>
目标:
ninja check-llvm check-clang
您可以使用 check-all
运行所有测试,但请注意,
可能需要很长时间,具体取决于项目数量
启用此选项
如需仅测试一项特定测试,您可以使用环境变量
LIT_FILTER
。如果测试路径为 clang/test/subpath/testname.cpp
,则
可以使用:
LIT_FILTER=testname.cpp ninja check-clang
也可以将相同的技巧应用于其他子项目中运行测试,方法是
为不同的 check-<component>
指定不同的值。
从 CAS 下载工具链
我们的 Clang 工具链 CI 构建器会将所有构建工件上传到内容寻址存储 (CAS)。 它提供了一种便捷的方式来快速下载特定工具链,而无需从头开始构建。 这可以大大加快调查工具链问题的速度,因为除了构建 Fuchsia 之外,您还可以避免较长的 LLVM 构建时间。
以下示例展示了如何从头开始安装 cas
工具并将特定工具链下载到语料库目录中:
$ cipd install infra/tools/luci/cas/linux-amd64 latest -root luci
$ ./luci/cas download -cas-instance chromium-swarm -digest \
ad53e1f315a849955190594fde6b07e11e76b40563db5779fcc69d6a6e04dc71/267 -dir corpus
在上面的示例中,系统向 -digest
字段传递了一个唯一 ID,cas
工具使用该 ID 来获取正确的工件。
您可以从 Fuchsia 的 CI 构建器中获取 digest
,方法是选择需要工具链的构建器,然后展开 clang
->cas
->archive
字段,然后点击 CAS_UI
链接。
结果页面将显示有关 CAS 上传的一些信息,包括摘要。
有用的 CMake 标志
还有许多其他 CMake 标志 对构建很有用,但对于工具链 。
-DLLVM_PARALLEL_LINK_JOBS
增加可在本地并行运行的链接作业的数量。您获得的 链接作业取决于 RAM 大小。对于 LTO build,您需要 每个作业至少需要 10GB 空间。
其他资源
文档:
讲座:
- 2016 年 LLVM 开发者会议:C.Bieneman“使用 CMake 开发和发布 LLVM 和 Clang”
- 2017 年 LLVM 开发者会议:Petr Hosek“Compiling cross-toolchains with CMake and runtimes build”