Add a simple proto_cc_library rule
It only supports a single .proto file without any dependencies, but
that's enough for now.
Change-Id: Ibd80c8594b90956c3c5b0b46db10cf991d7ed1ad
diff --git a/build_tests/BUILD b/build_tests/BUILD
index cce2e01..be6a201 100644
--- a/build_tests/BUILD
+++ b/build_tests/BUILD
@@ -1,5 +1,6 @@
load('/tools/build_rules/ruby', 'ruby_binary')
load('/aos/build/queues', 'queue_library')
+load('/tools/build_rules/protobuf', 'proto_cc_library')
cc_test(
name = 'gflags_build_test',
@@ -69,3 +70,20 @@
],
size = 'small',
)
+
+proto_cc_library(
+ name = 'proto_build_test_library',
+ src = 'proto.proto',
+)
+
+cc_test(
+ name = 'proto_build_test',
+ srcs = [
+ 'proto.cc',
+ ],
+ deps = [
+ ':proto_build_test_library',
+ '//aos/testing:googletest',
+ ],
+ size = 'small',
+)
diff --git a/build_tests/proto.cc b/build_tests/proto.cc
new file mode 100644
index 0000000..23ff879
--- /dev/null
+++ b/build_tests/proto.cc
@@ -0,0 +1,16 @@
+#include "gtest/gtest.h"
+
+#include "build_tests/proto.pb.h"
+
+TEST(ProtoBuildTest, Serialize) {
+ ::frc971::TestProto test_proto1, test_proto2;
+ test_proto1.set_s("Hi!");
+ test_proto1.set_i(971);
+
+ ::std::string serialized;
+ ASSERT_TRUE(test_proto1.SerializeToString(&serialized));
+ ASSERT_TRUE(test_proto2.ParseFromString(serialized));
+
+ EXPECT_EQ("Hi!", test_proto2.s());
+ EXPECT_EQ(971, test_proto2.i());
+}
diff --git a/build_tests/proto.proto b/build_tests/proto.proto
new file mode 100644
index 0000000..367a650
--- /dev/null
+++ b/build_tests/proto.proto
@@ -0,0 +1,12 @@
+syntax = "proto3";
+
+package frc971;
+
+import "google/protobuf/empty.proto";
+
+message TestProto {
+ string s = 1;
+ int32 i = 2;
+ // Making sure that well-known protos work.
+ .google.protobuf.Empty empty = 3;
+}
diff --git a/third_party/protobuf/BUILD b/third_party/protobuf/BUILD
index bb5d889..6686800 100644
--- a/third_party/protobuf/BUILD
+++ b/third_party/protobuf/BUILD
@@ -171,6 +171,12 @@
WELL_KNOWN_PROTOS = ["src/" + s for s in RELATIVE_WELL_KNOWN_PROTOS]
+filegroup(
+ name = "well_known_protos",
+ srcs = WELL_KNOWN_PROTOS,
+ visibility = ["//visibility:public"],
+)
+
cc_proto_library(
name = "cc_wkt_protos",
srcs = WELL_KNOWN_PROTOS,
diff --git a/tools/build_rules/protobuf.bzl b/tools/build_rules/protobuf.bzl
new file mode 100644
index 0000000..fe6af4f
--- /dev/null
+++ b/tools/build_rules/protobuf.bzl
@@ -0,0 +1,71 @@
+def _do_proto_cc_library_impl(ctx):
+ message = 'Building %s and %s from %s' % (ctx.outputs.pb_h.short_path,
+ ctx.outputs.pb_cc.short_path,
+ ctx.file.src.short_path)
+ ctx.action(
+ inputs = ctx.files.src + ctx.files._well_known_protos,
+ executable = ctx.executable._protoc,
+ arguments = [
+ '--cpp_out=%s' % ctx.configuration.genfiles_dir.path,
+ '-I.',
+ '-Ithird_party/protobuf/src',
+ ctx.file.src.path,
+ ],
+ mnemonic = 'ProtocCc',
+ progress_message = message,
+ outputs = [
+ ctx.outputs.pb_h,
+ ctx.outputs.pb_cc,
+ ],
+ )
+
+def _do_proto_cc_library_outputs(attr):
+ basename = attr.src.name[:-len('.proto')]
+ return {
+ 'pb_h': '%s.pb.h' % basename,
+ 'pb_cc': '%s.pb.cc' % basename,
+ }
+
+_do_proto_cc_library = rule(
+ implementation = _do_proto_cc_library_impl,
+ attrs = {
+ 'src': attr.label(
+ allow_files = FileType(['.proto']),
+ mandatory = True,
+ single_file = True,
+ ),
+ '_protoc': attr.label(
+ default = Label('//third_party/protobuf:protoc'),
+ executable = True,
+ cfg = HOST_CFG,
+ ),
+ '_well_known_protos': attr.label(
+ default = Label('//third_party/protobuf:well_known_protos'),
+ ),
+ },
+ outputs = _do_proto_cc_library_outputs,
+ output_to_genfiles = True,
+)
+
+def proto_cc_library(name, src, visibility = None):
+ '''Generates a cc_library from a single .proto file. Does not support
+ dependencies on any .proto files except the well-known ones protobuf comes
+ with (which are unconditionally depended on).
+
+ Attrs:
+ src: The .proto file.
+ '''
+
+ _do_proto_cc_library(
+ name = '%s__proto_srcs' % name,
+ src = src,
+ visibility = ['//visibility:private'],
+ )
+ basename = src[:-len('.proto')]
+ native.cc_library(
+ name = name,
+ srcs = [ '%s.pb.cc' % basename ],
+ hdrs = [ '%s.pb.h' % basename ],
+ deps = [ '//third_party/protobuf' ],
+ visibility = visibility,
+ )