There are several ways. As a one-off, you can simply create a genrule to execute a command on specific inputs:
genrule( name = "my-proto-gen", outs = ["my-proto.cc", "my-proto.h"], cmd = "$(location //path/to:protoc) --cpp_out=$@ $<", srcs = ["my-proto.proto"], tools = ["//path/to:protoc"], ) cc_library( name = "my-proto", srcs = ["my-proto.cc"], hdrs = ["my-proto.h"], )
Based on your make rule, I would suggest that you want to do this several times. In this case, you can define the macro in the .bzl file. Macros are basically functions that invoke assembly rules:
# In, say, foo/bar.bzl. def cpp_proto(name, src): native.genrule( name = "%s-gen" % name, outs = ["%s.cc" % name, "%sh" % name], cmd = "$(location //path/to:protoc) --cpp_out=$@ $<", srcs = [src], tools = ["//path/to:protoc"], ) native.cc_library( name = name, srcs = ["%s.cc" % name], hdrs = ["%sh" % name], )
Then, say foo / BUILD, you can import and use your macro to briefly name the rules:
load('//foo:bar.bzl', 'cpp_proto') cpp_proto('my-proto', 'my_proto.proto')
Then you can depend on //foo:my-proto on cc_library s, cc_binary s and cc_test s.
Finally, you might want to follow https://github.com/bazelbuild/bazel/issues/52 (and just use the mzhaom macro).