构建规则中的Bazel环境变量 [英] Bazel environment variables in build rules

查看:716
本文介绍了构建规则中的Bazel环境变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在BUILD文件中引用DirectX SDK.问题是(据我了解),Bazel仅支持通过Bazel的--action_env=DXSDK_DIR参数传递环境变量,并且只能在必须在插件(.bzl文件)中定义的操作中使用. >

有没有更简单的方法可以通过将其用作Make变量(includes = [ "$(DXSDK_DIR)/Include" ])来引用环境变量?还是需要编写插件?

解决方案

原则上,您需要一个cc_library规则,该规则的hdrs属性在DirectX标头中不起作用.为此,您需要假装DX SDK是您的源代码树的一部分. Bazel为此提供了存储库规则".

1.为DirectX SDK创建存储库规则

根据SDK的位置是已知的还是需要发现的,您有两种选择.

a.固定的SDK位置

如果不需要读取任何环境变量,运行任何二进制文件或查询注册表以查找SDK的位置,则可以使用此方法.如果所有构建您的规则的人都将SDK安装到同一位置,就是这种情况.

只需在您的WORKSPACE文件,将规则的path指向SDK的目录,并为其编写一个简单的build_file_content.

示例:

new_local_repository(
    name = "directx_sdk",
    path = "c:/program files/directx/sdk/includes",
    build_file_contents = """
cc_library(
    name = "sdk",
    hdrs = glob(["**/*.h"]),
    visibility = ["//visibility:public"],
)
""")

此规则使用根包@directx_sdk//:sdk中的一个规则创建@directx_sdk存储库.

b. SDK发现

如果需要读取环境变量,运行二进制文件或查询注册表以找到SDK的位置,则需要遵循这种方法.

您需要实现自己的规则,而不是使用new_local_repository规则. 更多信息和示例在这里.

要点:

  • 如果您的存储库规则需要读取环境变量,请将其添加到列表repository_rule(environ)中,例如repository_rule(..., environ = ["DXSDK_DIR"])

  • 如果需要运行一些二进制文件来告诉您SDK的位置,请使用 repository_ctx.which PATH.

  • 如果需要进行注册表查询,请使用 repository_ctx.execute reg.exe /query <args>

2.取决于SDK的cc_library

在您的项目中,仅依赖于SDK的库就好像它是普通的cc_library:

cc_library(
    name = "render",
    ...
    deps = [
        ...
        "@directx_sdk//:sdk",
    ],
)

I want to refer to a DirectX SDK in the BUILD file. The problem is that (as far as I understand) Bazel supports passing environment variables only through --action_env=DXSDK_DIR argument for Bazel and it is meant to be used in actions, which must be defined in a plugin (.bzl file).

Is there any easier way to refer to the environment variable by using it as Make variable (includes = [ "$(DXSDK_DIR)/Include" ]) or do I need to write a plugin?

解决方案

In principle you need a cc_library rule whose hdrs attribute globs the DirectX headers. For that you need to pretend that the DX SDK is part of your source tree. Bazel offers "repository rules" for that purpose.

1. Create a repository rule for the DirectX SDK

Depending on whether the SDK's location is known or needs to be discovered, you have two options.

a. Fixed SDK location

You can use this approach if you don't need to read any environment variables, run any binaries, or query the registry to find where the SDK is. This is the case if everyone who builds your rules will install the SDK to the same location.

Just add a new_local_repository rule to your WORKSPACE file, point the rule's path at the SDK's directory and write a simple build_file_content for it.

Example:

new_local_repository(
    name = "directx_sdk",
    path = "c:/program files/directx/sdk/includes",
    build_file_contents = """
cc_library(
    name = "sdk",
    hdrs = glob(["**/*.h"]),
    visibility = ["//visibility:public"],
)
""")

This rule creates the @directx_sdk repository with one rule in its root package, @directx_sdk//:sdk.

b. SDK discovery

You need to follow this approach if you need to read environment variables, run binaries, or query the registry to find where the SDK is.

Instead of using a new_local_repository rule, you need to implement your own. More info and examples are here.

Key points:

  • if your repository rule needs to read environment variables, add them to the list repository_rule(environ), e.g. repository_rule(..., environ = ["DXSDK_DIR"])

  • if you need to run some binaries that tell you where the SDK is, use repository_ctx.execute. You can use repository_ctx.which to find binaries on the PATH.

  • if you need to do registry queries, use repository_ctx.execute with reg.exe /query <args>

2. Depend on the SDK's cc_library

In your project, just depend on the SDK's library as if it was an ordinary cc_library:

cc_library(
    name = "render",
    ...
    deps = [
        ...
        "@directx_sdk//:sdk",
    ],
)

这篇关于构建规则中的Bazel环境变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆