构建规则中的Bazel环境变量 [英] Bazel environment variables in build rules
问题描述
我想在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 userepository_ctx.which
to find binaries on thePATH
.if you need to do registry queries, use
repository_ctx.execute
withreg.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屋!