【问题标题】:Bazel: Mixing a Linux remote execution platform with a Mac OS local platformBazel:将 Linux 远程执行平台与 Mac OS 本地平台混合
【发布时间】:2020-05-02 23:54:49
【问题描述】:

目标

我正在使用 Bazel 构建一个多平台 C++ 客户端(iOS、OSX、Android、Windows)。

iOS 和 OSX 是在我的 Mac 上本地构建的(非必要)。 Android 和 Windows 构建在 Docker 容器中。

在构建结束时,我有一个 Bazel 规则,它采用每个平台的每个 cc_binary 规则并将它们放在 .zip 中。

我想利用 Bazel 的远程执行 API 在容器中构建我的一些二进制文件并在本地构建其他二进制文件,然后引用共享缓存将它们整理在一起——所有这些都使用一个 bazel build 命令。

Bazel 支持

Bazel 声称这些类型的 multiplatform 构建 - 其中 host (OSX x64)、execution (Linux x64) 和 target 平台(许多)都是不同的 - 是可能的。

见https://docs.bazel.build/versions/master/platforms.html

我的经历

但是,我遇到了这个确切的问题:https://github.com/bazelbuild/bazel/issues/5397(其中docker-sandbox 是remote 构建的正确代理。)

这与下面的 Github 问题一起,让我质疑 Bazel 关于 multiplatform 构建的说法。

https://github.com/bazelbuild/bazel/issues/5309

从根本上说,这些问题似乎表明一个平台(例如 OSX)的本地目标不能与另一个平台(例如 Linux)上的远程目标一起构建。

问题

我想知道:

(1) 我试图做的事情与 Bazel 的设计根本不一致吗?如果是这样,Bazel 是multiplatform 是什么意思?

(2) 有没有我可以采用的解决方法来保持封闭性并保留在 Bazel 构建系统中?可以挂载一个 Docker 卷,然后编写一个脚本,将 Docker 缓存与我的本地缓存结合起来,但似乎 Bazel 是为处理我的用例而构建的。我在这里遗漏了什么吗?

相关问题:Does bazel support remote execution on different platforms?(没有满意的答案。)

【问题讨论】:

    标签: bazel


    【解决方案1】:

    (1) 我试图做的事情与 Bazel 的设计根本不一致吗?

    理论上没有,实际上是的。 Bazel 提供了允许用户支持您的用例的功能,但默认情况下未实现。

    具体而言,如链接的 Bazel 问题中所述:Bazel 规则 目前对主机和目标平台之间的关系做出假设,这些假设不适用于您的情况,例如它将自动检测主机 (macOS) 上的 JDK 文件,然后默认在所有 Java 操作中使用这些 JDK 文件 - 无论目标平台如何。

    如果是这样,Bazel 是多平台是什么意思?

    实际上,这意味着您可以在多个平台上运行bazel build ...,并期望 Bazel 将您的输入转换为与当前平台兼容的输出。

    (2) 有没有我可以采用的解决方法来保持封闭性并保留在 Bazel 构建系统中?

    是的,您可以在 Windows VM 或 Docker 容器中运行 bazel build ...。这是我问这个问题时 Bazel 团队推荐的解决方法。

    相关的高级 Bazel 功能:

    • 如果您想通过一次 Bazel 调用为多个目标平台构建,请查看Bazel user-defined transitions(这将允许您同时为多个平台构建相同的规则,例如 iOS 和 macOS,但需要您编写你自己的规则)。
    • 如果您不想在容器/VM 中运行bazel build,您可以编写您的own C++ toolchain。 Bazel 的核心是为每个操作提供一个包含所有相关文件的沙箱,并保证它将执行特定命令。在自定义 C++ 工具链中,您可以告诉 Bazel 调用脚本而不是 clang,它接受命令 + 文件并从 VM 或容器中执行它们。这可能是很多的工作,但绝对有可能。

    【讨论】:

    • Yes, you can run bazel build ... from within a Windows VM or Docker container. 这不支持我构建 iOS 和 OSX 工件的要求。出于技术和法律原因,无法在 Docker 容器内为 OSX 和 iOS 编译 AFAIK。
    • 正确!建议是将构建命令分成 3 个部分:一个用于 macOS/iOS 工件,另一个用于 Linux(从容器内运行),另一个用于 Windows(从 Windows VM 运行)。这不是很好的用户体验,但很可能开箱即用(特别是如果您正在构建 cc_library/cc_binary 目标)。
    • 好的 - 是的,我的问题本质上是,我是否必须退回到您刚刚描述的方法,或者是否可以在单个 bazel build ... 中完成所有操作,以便我的 zip 规则(已经实现了用户定义的转换以解决平台差异)可以简单地依赖每个平台的cc_binary 规则使用deps。听起来现在的答案是接受轻微的用户体验冲击。
    • 更新:看来我可以通过添加 build:remote --incompatible_enable_cc_toolchain_resolution 来解决我的问题。现在可以正确选择 mingw-w64 编译器,而不是 Wrapped-clang。我不是 100% 清楚为什么新平台 API 的使用导致 bazel 使用容器化编译器而不是 clang,但嘿,这是进步。
    猜你喜欢
    • 2019-12-20
    • 2012-08-14
    • 2017-08-13
    • 2014-07-26
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 2013-11-11
    • 2013-05-24
    相关资源
    最近更新 更多