Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break dependency on protobuf.bzl from google/protobuf for C++ #92

Merged
merged 2 commits into from
Aug 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 26 additions & 86 deletions bazel/pgv_proto_library.bzl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
load("@io_bazel_rules_go//proto:compiler.bzl", "go_proto_compiler")
load("@com_google_protobuf//:protobuf.bzl", "proto_gen", "cc_proto_library")
load(":protobuf.bzl", "cc_proto_gen_validate")

def pgv_go_proto_library(name, proto = None, deps = [], **kwargs):
go_proto_compiler(
Expand All @@ -18,94 +18,34 @@ def pgv_go_proto_library(name, proto = None, deps = [], **kwargs):
visibility = ["//visibility:public"],
**kwargs)

def _CcValidateHdrs(srcs):
ret = [s[:-len(".proto")] + ".pb.validate.h" for s in srcs]
return ret

def _CcValidateSrcs(srcs):
ret = [s[:-len(".proto")] + ".pb.validate.cc" for s in srcs]
return ret

def pgv_cc_proto_library(
name,
srcs=[],
deps=[],
external_deps=[],
cc_libs=[],
include=None,
protoc="@com_google_protobuf//:protoc",
protoc_gen_validate = "@com_lyft_protoc_gen_validate//:protoc-gen-validate",
internal_bootstrap_hack=False,
use_grpc_plugin=False,
default_runtime="@com_google_protobuf//:protobuf",
cc_deps=[],
**kargs):
"""Bazel rule to create a C++ protobuf validation library from proto source files

Args:
name: the name of the pgv_cc_proto_library.
srcs: the .proto files of the pgv_cc_proto_library.
deps: a list of PGV dependency labels; must be pgv_cc_proto_library.
external_deps: a list of dependency labels; must be cc_proto_library.
include: a string indicating the include path of the .proto files.
protoc: the label of the protocol compiler to generate the sources.
protoc_gen_validate: override the default version of protoc_gen_validate.
Most users won't need this.
default_runtime: the implicitly default runtime which will be depended on by
the generated cc_library target.
**kargs: other keyword arguments that are passed to cc_library.

"""

# Generate the C++ protos
cc_proto_library(
name=name + "_proto",
srcs=srcs,
deps=[d + "_proto" for d in deps] + [
"@com_lyft_protoc_gen_validate//validate:validate_cc",
] + external_deps,
cc_libs=cc_libs,
incude=include,
protoc=protoc,
internal_bootstrap_hack=internal_bootstrap_hack,
use_grpc_plugin=use_grpc_plugin,
default_runtime=default_runtime,
**kargs)

includes = []
if include != None:
includes = [include]

gen_hdrs = _CcValidateHdrs(srcs)
gen_srcs = _CcValidateSrcs(srcs)

proto_gen(
name=name + "_validate",
srcs=srcs,
# This is a hack to work around the fact that all the deps must have an
# import_flags field, which is only set on the proto_gen rules, so depend
# on the cc rule
deps=[d + "_validate" for d in deps] + [
"@com_lyft_protoc_gen_validate//validate:validate_cc_genproto"
] + [d + "_genproto" for d in external_deps],
includes=includes,
protoc=protoc,
plugin=protoc_gen_validate,
plugin_options=["lang=cc"],
outs=gen_hdrs + gen_srcs,
visibility=["//visibility:public"],
)
"""Bazel rule to create a C++ protobuf validation library from proto source files
Args:
name: the name of the pgv_cc_proto_library.
deps: proto_library rules that contains the necessary .proto files. Note that this
must include @com_lyft_protoc_gen_validate//validate:validate_proto
cc_deps: C++ dependencies of the protos being compiled. Likely cc_proto_library or pgv_cc_proto_library
**kargs: other keyword arguments that are passed to cc_library.
"""

cc_proto_gen_validate(
name=name+"_validate",
deps=deps,
)

if default_runtime and not default_runtime in cc_libs:
cc_libs = cc_libs + [default_runtime]
native.cc_library(
name=name,
hdrs=[":"+name+"_validate"],
srcs=[":"+name+"_validate"],
deps= cc_deps + [
"@com_lyft_protoc_gen_validate//validate:cc_validate",
"@com_lyft_protoc_gen_validate//validate:validate_cc",
"@com_google_protobuf//:protobuf",
],
alwayslink=1,
**kargs)

native.cc_library(
name=name,
hdrs=gen_hdrs,
srcs=gen_srcs,
deps=cc_libs + deps + [
":" + name + "_proto",
"@com_lyft_protoc_gen_validate//validate:cc_validate",
],
includes=includes,
alwayslink=1,
**kargs)
84 changes: 84 additions & 0 deletions bazel/protobuf.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
def _proto_path(proto):
"""
The proto path is not really a file path
It's the path to the proto that was seen when the descriptor file was generated.
"""
path = proto.path
root = proto.root.path
ws = proto.owner.workspace_root
if path.startswith(root):
path = path[len(root):]
if path.startswith("/"):
path = path[1:]
if path.startswith(ws):
path = path[len(ws):]
if path.startswith("/"):
path = path[1:]
return path

def _protoc_gen_validate_impl(ctx):
"""Generate protos using protoc-gen-validate plugin"""
protos = []
for dep in ctx.attr.deps:
protos += [f for f in dep.proto.direct_sources]

cc_hdrs = [p.basename[:-len(".proto")] + ".pb.validate.h" for p in protos]
cc_hdrs += [p.basename[:-len(".proto")] + ".pb.h" for p in protos]

cc_srcs = [p.basename[:-len(".proto")] + ".pb.validate.cc" for p in protos]
cc_srcs += [p.basename[:-len(".proto")] + ".pb.cc" for p in protos]

out_files = [ctx.actions.declare_file(out) for out in cc_hdrs+cc_srcs]

dir_out = ctx.genfiles_dir.path
if ctx.label.workspace_root:
dir_out += ("/"+ctx.label.workspace_root)

args = [
"--cpp_out="+dir_out,
"--plugin=protoc-gen-validate="+ctx.executable._plugin.path,
"--validate_out=lang=cc:"+ dir_out,
]

tds = depset([], transitive = [dep.proto.transitive_descriptor_sets for dep in ctx.attr.deps])
descriptor_args = [ds.path for ds in tds]

if len(descriptor_args) != 0:
args += ["--descriptor_set_in=%s" % ":".join(descriptor_args)]

ctx.action(
inputs=protos + tds.to_list() + [ctx.executable._plugin],
outputs=out_files,
arguments=args + [_proto_path(proto) for proto in protos],
executable=ctx.executable._protoc,
mnemonic="ProtoGenValidateCcGenerate",
use_default_shell_env=True,
)

return struct(
files=depset(out_files)
)

cc_proto_gen_validate = rule(
attrs = {
"deps": attr.label_list(
mandatory = True,
providers = ["proto"],
),

"_protoc": attr.label(
cfg = "host",
default = Label("@com_google_protobuf//:protoc"),
executable = True,
single_file = True,
),
"_plugin": attr.label(
cfg = "host",
default = Label("@com_lyft_protoc_gen_validate//:protoc-gen-validate"),
allow_files = True,
executable = True,
),
},
output_to_genfiles = True,
implementation = _protoc_gen_validate_impl,
)
8 changes: 2 additions & 6 deletions tests/harness/BUILD
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# gazelle:exclude harness.pb.go

load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
load("@com_google_protobuf//:protobuf.bzl", "cc_proto_library")

proto_library(
name = "harness_proto_target",
Expand All @@ -27,11 +26,8 @@ go_proto_library(

cc_proto_library(
name = "harness_proto",
srcs = ["harness.proto"],
default_runtime = "@com_google_protobuf//:protobuf",
protoc = "@com_google_protobuf//:protoc",
visibility = ["//visibility:public"],
deps = [
"@com_google_protobuf//:cc_wkt_protos",
":harness_proto_target",
],
visibility = ["//visibility:public"],
)
22 changes: 4 additions & 18 deletions tests/harness/cases/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ load(
)

proto_library(
name = "go_proto",
name = "cases_proto",
srcs = [
"bool.proto",
"bytes.proto",
Expand Down Expand Up @@ -36,7 +36,7 @@ proto_library(

pgv_go_proto_library(
name = "go",
proto = ":go_proto",
proto = ":cases_proto",
importpath = "github.com/lyft/protoc-gen-validate/tests/harness/cases/go",
deps = [
"//tests/harness/cases/other_package:go",
Expand Down Expand Up @@ -64,22 +64,8 @@ go_library(

pgv_cc_proto_library(
name = "cc",
srcs = [
"bool.proto",
"bytes.proto",
"enums.proto",
"maps.proto",
"messages.proto",
"numbers.proto",
"oneofs.proto",
"repeated.proto",
"strings.proto",
"wkt_any.proto",
"wkt_duration.proto",
"wkt_timestamp.proto",
"wkt_wrappers.proto",
],
deps = [
deps = [":cases_proto"],
cc_deps = [
"//tests/harness/cases/other_package:cc",
],
visibility = ["//tests:__subpackages__"],
Expand Down
4 changes: 1 addition & 3 deletions tests/harness/cases/other_package/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ go_library(

pgv_cc_proto_library(
name = "cc",
srcs = [
"embed.proto",
],
deps = [":embed_proto"],
visibility = ["//tests:__subpackages__"],
)
2 changes: 1 addition & 1 deletion tests/kitchensink/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pgv_go_proto_library(

pgv_cc_proto_library(
name = "fixed32_cc",
srcs = ["fixed32.proto"],
deps = [":fixed32_proto"],
)

proto_library(
Expand Down
7 changes: 2 additions & 5 deletions validate/BUILD
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# gazelle:exclude validate.pb.go

load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
load("@com_google_protobuf//:protobuf.bzl", "cc_proto_library", "py_proto_library")
load("@com_google_protobuf//:protobuf.bzl", "py_proto_library")

proto_library(
name = "validate_proto",
Expand All @@ -16,10 +16,7 @@ proto_library(

cc_proto_library(
name = "validate_cc",
srcs = ["validate.proto"],
protoc = "@com_google_protobuf//:protoc",
default_runtime = "@com_google_protobuf//:protobuf",
deps = ["@com_google_protobuf//:cc_wkt_protos"],
deps = [":validate_proto"],
visibility = ["//visibility:public"],
)

Expand Down