Bazel 调度C++;将生成的文件转换为SRC和HDR
在Bazel官方文档中,有一个解释如何创建一个Java库,该库由常规Java文件和由:gen_Java_srcs规则生成的文件构建。为了便于阅读,我在此处重写了此代码:Bazel 调度C++;将生成的文件转换为SRC和HDR,bazel,Bazel,在Bazel官方文档中,有一个解释如何创建一个Java库,该库由常规Java文件和由:gen_Java_srcs规则生成的文件构建。为了便于阅读,我在此处重写了此代码: java_library( name = "mylib", srcs = glob(["*.java"]) + [":gen_java_srcs"], deps = "...", ) genrule( name = "gen_java_srcs", outs = [ "F
java_library(
name = "mylib",
srcs = glob(["*.java"]) + [":gen_java_srcs"],
deps = "...",
)
genrule(
name = "gen_java_srcs",
outs = [
"Foo.java",
"Bar.java",
],
...
)
现在,在C++的视角下,我的场景是GEnGrand生成两种文件:.HPP和.CPP:
genrule(
name = "gen_cpp_srcs",
outs = [
"myFile_1.hpp","myFile_2.hpp",...,"myFile_N.hpp",
"myFile.cpp","myFile_2.cpp",...,"myFile_N.cpp",
],
...
)
其中N是大约十
我的问题是:如何编写cc_库规则,将hpp和cpp文件自动分派到hdrs和srcs字段?
我想要像这样的东西:
cc_library(
name = "mylib",
srcs = glob(["*.cpp"]) + (howto: .cpp files of [":gen_cpp_srcs"]),
hdrs = glob(["*.hpp"]) + (howto: .hpp files of [":gen_cpp_srcs"]),
...
)
一些魔术,比如:
output_filter(":gen_cpp_srcs","*.cpp")
很好,但我对Bazel了解不够,无法将其实现。根据genrule的名称(
:gen_cpp_srcs
)将为您提供genrule的所有输出,如您所述。相反,您可以依赖genrule的单独输出(例如,hdrs=[:myFile.hpp]
和srcs=[:myFile.cpp]
)
另请参见的答案。看起来您知道应该生成的文件总数。你能把它们放在各自的变量中,然后在两个目标中重用它们吗。在生成文件中类似于以下内容:
output_cpp_files = [
"myFile_1.cpp",
"myFile_2.cpp",
"myFile_3.cpp"
]
output_hpp_files = [
"myFile_1.hpp",
"myFile_2.hpp",
"myFile_3.hpp"
]
genrule(
name = "gen_cpp_srcs",
outs = output_cpp_files + output_hpp_files,
cmd = """
touch $(OUTS)
"""
)
cc_library(
name = "mylib",
srcs = output_cpp_files,
hdrs = output_hpp_files
)
glob只有在被传递到规则中时才会被扩展,所以您需要编写一个简单的。我想这样打包(在一个名为
filter.bzl
的文件中):
这就是我的演示BUILD
文件的样子(我更改了globs,使它们都包含*.cpp和*.hpp文件;使用genrule的标签将以相同的方式工作):
通过更改
\u do\u filter\u impl
,这很容易扩展到更复杂的过滤。特别是,将后缀
更改为,这样您就可以接受多个C/C++源代码/标题扩展,这似乎是个好主意。阅读您的答案后,我才意识到我的问题没有得到清楚的解释。我重新编辑了我的问题,使它更容易理解。总之,我想知道如何将一个规则输出过滤成另一个规则输入,只选择某些类型的文件多谢,你的代码对我学习如何为我的东西扩展Bazel非常有价值(我认为官方文档缺少一些关于Skylark语言的示例/解释),我刚刚看到returnstruct(…)
已被弃用。我用return[DefaultInfo(files=…)]
修改了您的代码。不幸的是,我没有关于大小的信息,这就是我希望以编程方式执行此操作的原因。无论如何,谢谢你:我喜欢你的genrule(),这是一个生成假输出的好技巧。
# The actual rule which does the filtering.
def _do_filter_impl(ctx):
return struct(
files = set([f for f in ctx.files.srcs if f.path.endswith(ctx.attr.suffix)]),
)
_do_filter = rule(
implementation = _do_filter_impl,
attrs = {
"srcs": attr.label_list(
mandatory = True,
allow_files = True,
),
"suffix": attr.string(
mandatory = True,
),
},
)
# A convenient macro to wrap the custom rule and cc_library.
def filtered_cc_library(name, srcs, hdrs, **kwargs):
_do_filter(
name = "%s_hdrs" % name,
visibility = ["//visibility:private"],
srcs = hdrs,
suffix = ".hpp",
)
_do_filter(
name = "%s_srcs" % name,
visibility = ["//visibility:private"],
srcs = srcs,
suffix = ".cpp",
)
native.cc_library(
name = name,
srcs = [ ":%s_srcs" % name ],
hdrs = [ ":%s_hdrs" % name ],
**kwargs
)
load("//:filter.bzl", "filtered_cc_library")
filtered_cc_library(
name = "mylib",
srcs = glob(["*.*pp"]),
hdrs = glob(["*.*pp"]),
)