一遍又一遍地阅读 Bazel 文档,没有什么新鲜感,但我似乎无法掌握如何为本机以外的变体(例如--cpu和 )设置配置和变体--compilation_mode。
为了解释我对配置和变体的含义,请考虑此配置行、变体点列和变体单元格的表(制作此表,希望它至少具有抽象意义):
| 有硬件模块 X | 接口已连接 | 快速失败 | |
|---|---|---|---|
| 客户配置1 | 是的 | 以太网 | 是的 |
| 客户配置2 | 是的 | USB | 是的 |
| 客户配置3 | 不 | USB | 不 |
| 调试硬件配置 | 不 | 串口 | 是的 |
从 Bazel 用户的角度来看:
-DVARIANT_POINT_CONNECTED_ETH用于以太网连接和-DVARIANT_POINT_CONNECTED_USBUSB 连接bazel build //my/target --//:configuration=debughwselect()规则您正在寻找平台。构建设置(您首先找到的)更适合独立的配置部分,其中以任何排列设置它们都是有用的,而不是平台将所有部分捆绑在一起。然后,生成的设置和约束可用于驱动编译器标志并将目标限制为某些配置。
对于你的例子,我认为这样的事情是有道理的:
constraint_setting(name = "has_x")
constraint_value(
name = "x_v1",
constraint_setting = ":has_x",
)
constraint_value(
name = "x_v2",
constraint_setting = ":has_x",
)
constraint_value(
name = "x_none",
constraint_setting = ":has_x",
)
constraint_setting(name = "interface")
constraint_value(
name = "interface_usb",
constraint_setting = ":interface",
)
constraint_value(
name = "interface_ethernet",
constraint_setting = ":interface",
)
constraint_value(
name = "interface_uart",
constraint_setting = ":interface",
)
constraint_setting(name = "failure_reporting")
constraint_value(
name = "fail_fast",
constraint_setting = ":failure_reporting",
)
constraint_value(
name = "fail_bugreport",
constraint_setting = ":failure_reporting",
)
platform(
name = "customer_1",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":x_v1",
":interface_ethernet",
":fail_fast",
],
)
platform(
name = "customer_2",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":x_v1",
":interface_usb",
":fail_fast",
],
)
platform(
name = "customer_3",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":x_none",
":interface_usb",
":fail_bugreport",
],
)
platform(
name = "debug_hw",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":x_none",
":interface_uart",
":fail_fast",
],
)
Run Code Online (Sandbox Code Playgroud)
请注意每个平台如何为每个约束指定设置。给定的编译器命令(由配置的 target创建)将仅使用一个平台。此外,即使输出相同,每个文件也会针对每个平台单独编译。平台旨在限制实际构建的约束排列。如果你想消除重复的约束,platform.parents可以让你构建平台的继承树,你不能同时使用两个平台。
target_complete_with属性将目标限制为特定的约束值。默认情况下,每个目标都被认为与所有平台兼容。如果您使用target_compatible_with限制这一点,那么当您尝试显式构建不兼容的目标时,它们将会产生错误,或者如果作为通配符的一部分包含在内,则会被跳过。对于您的用例,该目标将为任何平台构建:
cc_library(
name = "generic_linked_list",
<etc>
)
Run Code Online (Sandbox Code Playgroud)
但这只会为customer_1和构建customer_2:
cc_library(
name = "hardware_x_driver",
target_compatible_with = [":x_v1", ":x_v2"],
<etc>
)
cc_library(
name = "ethernet_driver",
# Or you could have a separate constraint for "has ethernet hardware",
# to use for some platforms which have the hardware but don't use it
# as the primary interface.
target_compatible_with = [":interface_ethernet"],
<etc>
)
Run Code Online (Sandbox Code Playgroud)
对于不同平台使用不同的编译器标志、依赖项或大多数其他规则属性是通过select完成的。选择可以constraint_value直接读取s。所以你可以这样写:
cc_library(
name = "selected_connection",
copts = select({
":interface_usb": [ "-DVARIANT_POINT_CONNECTED_USB" ],
":interface_ethernet": ["-DVARIANT_POINT_CONNECTED_ETH" ],
":interface_uart": ["-DVARIANT_POINT_CONNECTED_UART" ],
}),
deps = select({
":interface_ethernet": [ ":ethernet_driver" ],
"//conditions:default": [],
}),
<etc>
)
Run Code Online (Sandbox Code Playgroud)
请注意,如果您希望定义传播到依赖目标,请使用cc_library.defines而不是copts。此外,使用cc_library.local_defines将提供相同的非继承语义,并且还与使用不同命令行标志的编译器兼容。
指定平台的最简单方法是使用--platforms。在这种情况下,请使用类似--platforms=//:customer_1. 您可以直接在命令行上指定,或者将其放入.bazelrc 配置部分,如下所示:
build:customer_1 --platforms=//some/long/and/annoying/package:customer_1
Run Code Online (Sandbox Code Playgroud)
您将与 一起使用--config=customer_1。
| 归档时间: |
|
| 查看次数: |
1138 次 |
| 最近记录: |