Bazel选择在ctx.file中失败

时间:2018-09-10 11:42:20

标签: bazel

我试图根据运行bazel的操作系统指定构建条件,因此在我的.bzl脚本中,我有一条规则,使所有来自外部源的simlink都写入一个BUILD文件(使用ctx.file) ,在其中声明所有导入和库,并在其中添加选择函数。但是,在构建时会出现以下错误消息:

ERROR: no such package '@maya_repo//': Traceback (most recent call last):
        File "/var/tmp/doNotRemove/mdilena_plugins/MayaMathNodes/src/maya.bzl", line 149
                ctx.file("BUILD", _BUILD_STRUC.format(maya_...))
        File "/var/tmp/doNotRemove/mdilena_plugins/MayaMathNodes/src/maya.bzl", line 149, in ctx.file
                _BUILD_STRUC.format(maya_dir = maya_dir)
Invalid character '[' inside replacement field

所以这是我的代码示例以及我要实现的目标:

_BUILD_STRUC = \
"""
# Windows imports
cc_import(
    name = "Foundation-win",
    interface_library = "{maya_dir}/lib/Foundation.lib",
    shared_library = "{maya_dir}/bin/Foundation.dll",
)

cc_import(
    name = "OpenMaya-win",
    interface_library = "{maya_dir}/lib/OpenMaya.lib",
    shared_library = "{maya_dir}/bin/OpenMaya.dll",
)

# Linux imports
cc_import(
    name = "Foundation-lnx",
    shared_library = "{maya_dir}/bin/Foundation.so",
)

cc_import(
    name = "OpenMaya-lnx",
    shared_library = "{maya_dir}/bin/OpenMaya.so",
)

cc_library(
    name = "Foundation",
    deps = select({
        "@bazel_tools//src/conditions:windows": [":Foundation-win"],
        "//conditions:default": [":Foundation-lnx"],
        }),
    includes = ["{maya_dir}/include"],
    visibility = ["//visibility:public"],
)

cc_library(
    name = "OpenMaya",
    deps = select({
        "@bazel_tools//src/conditions:windows": [":OpenMaya-win"],
        "//conditions:default": [":OpenMaya-lnx"],
        }),
    includes = ["{maya_dir}/include"],
    visibility = ["//visibility:public"],
)
"""

def _impl(ctx):
    maya_src = ctx.os.environ["MAYA_LOCATION"]
    maya_ver = ctx.os.environ["MAYA_VERSION"]
    maya_dir = "maya{}".format(maya_ver)
    ctx.symlink(maya_src, maya_dir)
    ctx.file("BUILD", _BUILD_STRUC.format(maya_dir=maya_dir))


link_maya = repository_rule(
    implementation = _impl,
    local = True,
    environ = ["MAYA_LOCATION"],
)

有人知道为什么会这样吗?我查看了selectconfigurable attributes文档,看来这就是使用它的方式。我想知道是我做错了还是某处有错误。

感谢您的帮助!

  

编辑:

     

看起来Bazel确实不喜欢在ctx.file中使用select,   我将保留这个问题,以防有人能够抛弃一些   点亮它。同时,我通过制作所有cc_imports来解决了这个问题   并包括链接回购中的public,同时保留所有   cc_librariesselect到我插件的BUILD文件中;从那里我   能够使用条件,一切都建立起来。

1 个答案:

答案 0 :(得分:2)

错误似乎来自此行,特别是对string.format的调用。

ctx.file("BUILD", _BUILD_STRUC.format(maya_dir=maya_dir))

string.format在模板字符串中搜索诸如{}{key}之类的大括号,然后将其替换为位置或关键字参数。

您会看到此错误,因为string.format在模板中将select的dict参数误认为是替换品,因为它以花括号开头。通过加倍转义模板字符串中的花括号,可以解决此问题:

_BUILD_STRUC = \
"""
...
cc_library(
    name = "Foundation",
    deps = select({{
        "@bazel_tools//src/conditions:windows": [":Foundation-win"],
        "//conditions:default": [":Foundation-lnx"],
        }}),
    includes = ["{maya_dir}/include"],
    visibility = ["//visibility:public"],
)
...

仅供参考,您可能会更容易使用repository_ctx.template。它的语义略有不同:它按字面替换字符串,而无需查找诸如{之类的特殊字符,因此不需要转义。