我可以在 Bazel 中生成 BUILD 文件吗?
Can I generate a BUILD file in Bazel?
我想使用go lint工具为bazel生成一个BUILD文件。
我会有一个 go 二进制文件来执行类似这样的事情 bash 脚本:
#!/bin/bash
cat <<EOF > BUILD
# THIS FILE IS AUTOGENERATED
package(default_visibility = ["//visibility:public"])
load("//go:def.bzl", "go_prefix", "go_library", "go_binary", "go_test")
EOF
for pkg in `go list -f {{.ImportPath}} ./...`; do
go list -f "`cat test.in`" $pkg >> "BUILD";
done
buildifier -mode fix BUILD
test.in 文件包含:
{{ if eq .Name "main" }}
go_binary
{{else}}
go_library
{{end}}
("{{.Name}}",
srcs=[
{{range .GoFiles}}
"{{.}}",
{{end}}
],
deps=[
{{range .Imports}}
"{{.}}",
{{end}}
],
csrcs=[
{{range .CgoFiles}}
"{{.}}",
{{end}}
],
swig_srcs=[
{{range .SwigFiles}}
"{{.}}",
{{end}}
],
cxxswig=[
{{range .SwigCXXFiles}}
"{{.}}",
{{end}}
],
cflags=[
{{range .CgoCFLAGS}}
"{{.}}",
{{end}}
],
cxxflags=[
{{range .CgoCXXFLAGS}}
"{{.}}",
{{end}}
],
cppflags=[
{{range .CgoCPPFLAGS}}
"{{.}}",
{{end}}
],
{{ with $ctx := context}}
{{$ctx.InstallSuffix}}
{{end}}
)
这会生成:
# THIS FILE IS AUTOGENERATED
package(default_visibility = ["//visibility:public"])
load("//go:def.bzl", "go_prefix", "go_library", "go_binary", "go_test")
go_library
(
"tensorflow",
srcs = [
"doc.go",
"gen.go",
"graph.go",
"session.go",
],
deps = [
"C",
"encoding/binary",
"fmt",
"github.com/golang/protobuf/proto",
"github.com/tensorflow/tensorflow/tensorflow/contrib/go/proto",
"math",
"reflect",
"runtime",
"strings",
"unsafe",
],
csrcs = [
"lib.go",
"tensor.go",
],
swig_srcs = [
],
cxxswig = [
"tensorflow.swigcxx",
],
cflags = [
"-I/Users/fmilo/workspace/gopath/src/github.com/tensorflow/tensorflow/tensorflow/contrib/go/../../../",
],
cxxflags = [
"-I/Users/fmilo/workspace/gopath/src/github.com/tensorflow/tensorflow/tensorflow/contrib/go/../../../",
"-std=c++11",
],
cppflags = [
],
)
go_library
(
"tensorflow",
srcs = [
"allocation_description.pb.go",
"attr_value.pb.go",
"config.pb.go",
"cost_graph.pb.go",
"device_attributes.pb.go",
"event.pb.go",
"function.pb.go",
"graph.pb.go",
"kernel_def.pb.go",
"log_memory.pb.go",
"master.pb.go",
"memmapped_file_system.pb.go",
"meta_graph.pb.go",
"named_tensor.pb.go",
"op_def.pb.go",
"queue_runner.pb.go",
"saved_tensor_slice.pb.go",
"saver.pb.go",
"step_stats.pb.go",
"summary.pb.go",
"tensor.pb.go",
"tensor_description.pb.go",
"tensor_shape.pb.go",
"tensor_slice.pb.go",
"tensorflow_server.pb.go",
"test_log.pb.go",
"tf_ops_def.go",
"types.pb.go",
"variable.pb.go",
"versions.pb.go",
"worker.pb.go",
],
deps = [
"fmt",
"github.com/golang/protobuf/proto",
"github.com/golang/protobuf/ptypes/any",
"math",
],
csrcs = [
],
swig_srcs = [
],
cxxswig = [
],
cflags = [
],
cxxflags = [
],
cppflags = [
],
)
go_library
(
"tensorflow_error",
srcs = [
"error_codes.pb.go",
],
deps = [
"fmt",
"github.com/golang/protobuf/proto",
"math",
],
csrcs = [
],
swig_srcs = [
],
cxxswig = [
],
cflags = [
],
cxxflags = [
],
cppflags = [
],
)
go_library
(
"tensorflow_grpc",
srcs = [
"master_service.pb.go",
"worker_service.pb.go",
],
deps = [
"fmt",
"github.com/golang/protobuf/proto",
"math",
"tensorflow/core/protobuf",
],
csrcs = [
],
swig_srcs = [
],
cxxswig = [
],
cflags = [
],
cxxflags = [
],
cppflags = [
],
)
当然上面的 BUILD 文件还不能工作,但我想首先确定我所追求的方法是有效的。
- 如何在 bazel 中指定预构建阶段?
- 可能吗?
一般情况下,您不能生成 BUILD 文件,它们必须在构建开始时就存在。 Bazel 的一般构建阶段是:
- 解析您在命令行中指定的目标。
- 在指定的每个目录中查找 BUILD 文件。
- 解析那些目标提到的构建文件(等等)。
- 生成要执行的操作树(例如,"Run shell script")。
- 实际执行动作。
因此,当您的脚本执行时,读取 BUILD 文件的时间早已结束。
此外,输出被放在它们自己的目录中(在 bazel-out 下),因此如果不进行修改,它们甚至不会出现在您的源代码树中。
也就是说...
Skylark 远程存储库允许您执行代码以在其他存储库中写入文件,包括 BUILD 文件。所以从理论上讲,你可以有类似(未经测试)的东西:
def _gen_repo_impl(repo_ctx):
# Writes external/reponame/BUILD
repo_ctx.execute("/your/bash/script.sh")
for path in repo_ctx.attr.paths:
repo_ctx.symlink(path, path.basename)
generated_repo = repository_rule(
implementation = _gen_repo_impl,
attrs = {"paths": attr.label_list(allow_files = True)}
)
然后在您的 WORKSPACE 文件中,执行如下操作:
load('//path/to/your:genrepo.bzl', 'generated_repo')
generated_repo(
name = "pwd",
paths = ["src", "test", "third_party"],
)
然后你可以在 @pwd//...
上 build/depend 并且存储库规则将生成一个外部存储库,其中包含指向 src、测试和 third_party 的符号链接(理论上......我的代码可能已经一些错别字)。
我想使用go lint工具为bazel生成一个BUILD文件。
我会有一个 go 二进制文件来执行类似这样的事情 bash 脚本:
#!/bin/bash
cat <<EOF > BUILD
# THIS FILE IS AUTOGENERATED
package(default_visibility = ["//visibility:public"])
load("//go:def.bzl", "go_prefix", "go_library", "go_binary", "go_test")
EOF
for pkg in `go list -f {{.ImportPath}} ./...`; do
go list -f "`cat test.in`" $pkg >> "BUILD";
done
buildifier -mode fix BUILD
test.in 文件包含:
{{ if eq .Name "main" }}
go_binary
{{else}}
go_library
{{end}}
("{{.Name}}",
srcs=[
{{range .GoFiles}}
"{{.}}",
{{end}}
],
deps=[
{{range .Imports}}
"{{.}}",
{{end}}
],
csrcs=[
{{range .CgoFiles}}
"{{.}}",
{{end}}
],
swig_srcs=[
{{range .SwigFiles}}
"{{.}}",
{{end}}
],
cxxswig=[
{{range .SwigCXXFiles}}
"{{.}}",
{{end}}
],
cflags=[
{{range .CgoCFLAGS}}
"{{.}}",
{{end}}
],
cxxflags=[
{{range .CgoCXXFLAGS}}
"{{.}}",
{{end}}
],
cppflags=[
{{range .CgoCPPFLAGS}}
"{{.}}",
{{end}}
],
{{ with $ctx := context}}
{{$ctx.InstallSuffix}}
{{end}}
)
这会生成:
# THIS FILE IS AUTOGENERATED
package(default_visibility = ["//visibility:public"])
load("//go:def.bzl", "go_prefix", "go_library", "go_binary", "go_test")
go_library
(
"tensorflow",
srcs = [
"doc.go",
"gen.go",
"graph.go",
"session.go",
],
deps = [
"C",
"encoding/binary",
"fmt",
"github.com/golang/protobuf/proto",
"github.com/tensorflow/tensorflow/tensorflow/contrib/go/proto",
"math",
"reflect",
"runtime",
"strings",
"unsafe",
],
csrcs = [
"lib.go",
"tensor.go",
],
swig_srcs = [
],
cxxswig = [
"tensorflow.swigcxx",
],
cflags = [
"-I/Users/fmilo/workspace/gopath/src/github.com/tensorflow/tensorflow/tensorflow/contrib/go/../../../",
],
cxxflags = [
"-I/Users/fmilo/workspace/gopath/src/github.com/tensorflow/tensorflow/tensorflow/contrib/go/../../../",
"-std=c++11",
],
cppflags = [
],
)
go_library
(
"tensorflow",
srcs = [
"allocation_description.pb.go",
"attr_value.pb.go",
"config.pb.go",
"cost_graph.pb.go",
"device_attributes.pb.go",
"event.pb.go",
"function.pb.go",
"graph.pb.go",
"kernel_def.pb.go",
"log_memory.pb.go",
"master.pb.go",
"memmapped_file_system.pb.go",
"meta_graph.pb.go",
"named_tensor.pb.go",
"op_def.pb.go",
"queue_runner.pb.go",
"saved_tensor_slice.pb.go",
"saver.pb.go",
"step_stats.pb.go",
"summary.pb.go",
"tensor.pb.go",
"tensor_description.pb.go",
"tensor_shape.pb.go",
"tensor_slice.pb.go",
"tensorflow_server.pb.go",
"test_log.pb.go",
"tf_ops_def.go",
"types.pb.go",
"variable.pb.go",
"versions.pb.go",
"worker.pb.go",
],
deps = [
"fmt",
"github.com/golang/protobuf/proto",
"github.com/golang/protobuf/ptypes/any",
"math",
],
csrcs = [
],
swig_srcs = [
],
cxxswig = [
],
cflags = [
],
cxxflags = [
],
cppflags = [
],
)
go_library
(
"tensorflow_error",
srcs = [
"error_codes.pb.go",
],
deps = [
"fmt",
"github.com/golang/protobuf/proto",
"math",
],
csrcs = [
],
swig_srcs = [
],
cxxswig = [
],
cflags = [
],
cxxflags = [
],
cppflags = [
],
)
go_library
(
"tensorflow_grpc",
srcs = [
"master_service.pb.go",
"worker_service.pb.go",
],
deps = [
"fmt",
"github.com/golang/protobuf/proto",
"math",
"tensorflow/core/protobuf",
],
csrcs = [
],
swig_srcs = [
],
cxxswig = [
],
cflags = [
],
cxxflags = [
],
cppflags = [
],
)
当然上面的 BUILD 文件还不能工作,但我想首先确定我所追求的方法是有效的。
- 如何在 bazel 中指定预构建阶段?
- 可能吗?
一般情况下,您不能生成 BUILD 文件,它们必须在构建开始时就存在。 Bazel 的一般构建阶段是:
- 解析您在命令行中指定的目标。
- 在指定的每个目录中查找 BUILD 文件。
- 解析那些目标提到的构建文件(等等)。
- 生成要执行的操作树(例如,"Run shell script")。
- 实际执行动作。
因此,当您的脚本执行时,读取 BUILD 文件的时间早已结束。
此外,输出被放在它们自己的目录中(在 bazel-out 下),因此如果不进行修改,它们甚至不会出现在您的源代码树中。
也就是说...
Skylark 远程存储库允许您执行代码以在其他存储库中写入文件,包括 BUILD 文件。所以从理论上讲,你可以有类似(未经测试)的东西:
def _gen_repo_impl(repo_ctx):
# Writes external/reponame/BUILD
repo_ctx.execute("/your/bash/script.sh")
for path in repo_ctx.attr.paths:
repo_ctx.symlink(path, path.basename)
generated_repo = repository_rule(
implementation = _gen_repo_impl,
attrs = {"paths": attr.label_list(allow_files = True)}
)
然后在您的 WORKSPACE 文件中,执行如下操作:
load('//path/to/your:genrepo.bzl', 'generated_repo')
generated_repo(
name = "pwd",
paths = ["src", "test", "third_party"],
)
然后你可以在 @pwd//...
上 build/depend 并且存储库规则将生成一个外部存储库,其中包含指向 src、测试和 third_party 的符号链接(理论上......我的代码可能已经一些错别字)。