You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bazel规则中提取命令行--platform参数详情传给Python程序

在Bazel中提取--platform参数并传递给Python程序

要从命令行的--platform参数中提取设备类型(如stm32f405ig)并传递给Python程序,你可以通过以下两种方式实现:

方法一:直接从平台标签提取名称

Bazel的规则上下文(ctx)可以获取当前指定的平台目标,通过其Label对象提取名称作为设备类型,再传递给Python脚本。

1. 定义自定义包装规则

在你的Bazel规则文件(如//:rules.bzl)中编写自定义规则,用于包装Python二进制目标并注入设备类型参数:

load("@rules_python//python:defs.bzl", "py_binary")

def _py_with_device_impl(ctx):
    # 获取当前平台的Label对象,提取名称作为设备类型
    platform_label = ctx.configuration.host_platform
    device_type = platform_label.name

    # 生成包装脚本,将设备类型作为参数传递给Python程序
    wrapper = ctx.actions.declare_file(ctx.label.name)
    ctx.actions.run_shell(
        inputs = [ctx.attr.py_bin.executable],
        outputs = [wrapper],
        command = """
            #!/bin/bash
            {py_exec} --device-type={device} "$@"
        """.format(
            py_exec = ctx.attr.py_bin.executable.path,
            device = device_type,
        ),
    )
    ctx.actions.run_shell(
        inputs = [wrapper],
        command = "chmod +x {wrapper}".format(wrapper = wrapper.path),
    )

    return DefaultInfo(
        executable = wrapper,
        runfiles = ctx.attr.py_bin.default_runfiles,
    )

py_with_device = rule(
    implementation = _py_with_device_impl,
    attrs = {
        "py_bin": attr.label(
            executable = True,
            cfg = "target",
            providers = [DefaultInfo],
        ),
    },
    executable = True,
)

2. 在BUILD文件中使用规则

load("//:rules.bzl", "py_with_device")

# 原始Python二进制目标
py_binary(
    name = "my_script",
    srcs = ["my_script.py"],
)

# 包装后的目标,会自动注入设备类型参数
py_with_device(
    name = "target",
    py_bin = ":my_script",
)

3. Python脚本接收参数

在my_script.py中用argparse读取传递的设备类型:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--device-type", required=True)
args = parser.parse_args()

print(f"当前设备类型: {args.device_type}")

执行命令

运行以下命令即可自动传递设备类型:

bazel run //target --platform=//platform:stm32f405ig

方法二:通过平台自定义设置传递(更灵活)

如果需要设备类型与平台名称解耦,可以在平台目标中定义自定义设置,再在规则中读取该值。

1. 定义设备类型设置规则

在//platform:defs.bzl中定义自定义provider:

DeviceInfo = provider(
    fields = ["device_type"],
)

def _device_setting_impl(ctx):
    return DeviceInfo(device_type = ctx.attr.value)

device_setting = rule(
    implementation = _device_setting_impl,
    attrs = {"value": attr.string()},
)

2. 关联平台与设备类型

在//platform:stm32f405ig/BUILD中定义平台和对应的设备设置:

load("//platform:defs.bzl", "device_setting")

device_setting(
    name = "stm32f405ig_device",
    value = "stm32f405ig",  # 可自定义任意值
)

platform(
    name = "stm32f405ig",
    settings = [":stm32f405ig_device"],
)

3. 读取设置并传递给Python

修改自定义规则以读取平台中的DeviceInfo:

load("@rules_python//python:defs.bzl", "py_binary")
load("//platform:defs.bzl", "DeviceInfo")

def _py_with_device_impl(ctx):
    # 从平台设置中获取设备类型
    device_type = ctx.attr._device_setting[DeviceInfo].device_type
    py_target = ctx.attr.py_bin

    # 注入参数
    new_args = py_target.args + ["--device-type=" + device_type]

    return DefaultInfo(
        executable = py_target.executable,
        runfiles = py_target.default_runfiles,
        arguments = new_args,
    )

py_with_device = rule(
    implementation = _py_with_device_impl,
    attrs = {
        "py_bin": attr.label(
            executable = True,
            cfg = "target",
            providers = [DefaultInfo],
        ),
        "_device_setting": attr.label(
            cfg = "target",
        ),
    },
    executable = True,
)

4. 使用规则

在BUILD文件中指定对应的设备设置:

py_with_device(
    name = "target",
    py_bin = ":my_script",
    _device_setting = "//platform:stm32f405ig_device",
)

这样即使平台名称变化,也能通过修改device_setting的value来保持设备类型的正确性。

内容的提问来源于stack exchange,提问作者Hema

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 07:15:52