diff --git a/tests/BUCK b/tests/BUCK index a96bfb8d0..42f780f19 100644 --- a/tests/BUCK +++ b/tests/BUCK @@ -1,15 +1,19 @@ +load("//tools/buck:cxxbridge_cxx_library.bzl", "cxxbridge_cxx_library") + rust_test( name = "test", srcs = ["test.rs"], deps = [":ffi"], ) +bridge_srcs = [ + "ffi/lib.rs", + "ffi/module.rs", +] + rust_library( name = "ffi", - srcs = [ - "ffi/lib.rs", - "ffi/module.rs", - ], + srcs = bridge_srcs, crate = "cxx_test_suite", deps = [ ":impl", @@ -17,38 +21,13 @@ rust_library( ], ) -cxx_library( +cxxbridge_cxx_library( name = "impl", - srcs = [ - "ffi/tests.cc", - ":gen-lib-source", - ":gen-module-source", - ], - header_namespace = "cxx-test-suite", + crate_name = "cxx-test-suite", + bridge_srcs = bridge_srcs, + srcs = ["ffi/tests.cc"], headers = { - "lib.rs.h": ":gen-lib-header", "tests.h": "ffi/tests.h", }, deps = ["//:core"], ) - -genrule( - name = "gen-lib-header", - srcs = ["ffi/lib.rs"], - out = "lib.rs.h", - cmd = "$(exe //:codegen) --header ${SRCS} > ${OUT}", -) - -genrule( - name = "gen-lib-source", - srcs = ["ffi/lib.rs"], - out = "lib.rs.cc", - cmd = "$(exe //:codegen) ${SRCS} > ${OUT}", -) - -genrule( - name = "gen-module-source", - srcs = ["ffi/module.rs"], - out = "module.rs.cc", - cmd = "$(exe //:codegen) ${SRCS} > ${OUT}", -) diff --git a/tests/BUILD b/tests/BUILD index 29cc79ce5..fb554b80b 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -1,3 +1,4 @@ +load("//tools/bazel:cxxbridge_cc_library.bzl", "cxxbridge_cc_library") load("//tools/bazel:rust.bzl", "rust_library", "rust_test") rust_test( @@ -6,60 +7,26 @@ rust_test( deps = [":cxx_test_suite"], ) +bridge_srcs = [ + "ffi/lib.rs", + "ffi/module.rs", +] + rust_library( name = "cxx_test_suite", - srcs = [ - "ffi/lib.rs", - "ffi/module.rs", - ], + srcs = bridge_srcs, deps = [ ":impl", "//:cxx", ], ) -cc_library( +cxxbridge_cc_library( name = "impl", - srcs = [ - "ffi/tests.cc", - ":gen-lib-source", - ":gen-module-source", - ], + crate_name = "cxx-test-suite", + bridge_srcs = bridge_srcs, + srcs = ["ffi/tests.cc"], hdrs = ["ffi/tests.h"], - include_prefix = "cxx-test-suite", strip_include_prefix = "ffi", - deps = [ - ":lib-include", - "//:core", - ], -) - -genrule( - name = "gen-lib-header", - srcs = ["ffi/lib.rs"], - outs = ["lib.rs.h"], - cmd = "$(location //:codegen) --header $< > $@", - tools = ["//:codegen"], -) - -genrule( - name = "gen-lib-source", - srcs = ["ffi/lib.rs"], - outs = ["lib.rs.cc"], - cmd = "$(location //:codegen) $< > $@", - tools = ["//:codegen"], -) - -cc_library( - name = "lib-include", - hdrs = [":gen-lib-header"], - include_prefix = "cxx-test-suite", -) - -genrule( - name = "gen-module-source", - srcs = ["ffi/module.rs"], - outs = ["module.rs.cc"], - cmd = "$(location //:codegen) $< > $@", - tools = ["//:codegen"], + deps = ["//:core"], ) diff --git a/tools/bazel/cxxbridge_cc_library.bzl b/tools/bazel/cxxbridge_cc_library.bzl new file mode 100644 index 000000000..f158c8644 --- /dev/null +++ b/tools/bazel/cxxbridge_cc_library.bzl @@ -0,0 +1,67 @@ +"""cxxbridge_cc_library macro""" + +load("@rules_cc//cc:defs.bzl", "cc_library") + +def cxxbridge_cc_library( + name, + crate_name, + bridge_srcs, + srcs = None, + hdrs = None, + deps = None, + strip_include_prefix = None, + visibility = None): + """Generate C++ source for one or more Rust cxx::bridges and bundle into a cc_library. + + Args: + name: A unique name for the cc_library rule. + crate_name: The name of the corresponding Rust crate, used as the include_prefix. + bridge_srcs: One or more Rust source files containing cxx::bridge modules. + srcs: Additional sources. Forwarded to cc_library unmodified. + hdrs: Additional headers. Forwarded to cc_library unmodified. + deps: Additional deps. Forwarded to cc_library unmodified. + strip_include_prefix: Forwarded to cc_library unmodified. + visibility: Visibility for all rules generated by this macro. + """ + + gen_srcs = [] + gen_hdrs = [] + for bridge_source in bridge_srcs: + source_basename = bridge_source.rsplit("/", 1)[-1] + header_target = name + "-" + source_basename + "-gen-header" + source_target = name + "-" + source_basename + "-gen-source" + + header_out = source_basename + ".h" + if strip_include_prefix: + header_out = strip_include_prefix + "/" + header_out + + native.genrule( + name = header_target, + srcs = [bridge_source], + outs = [header_out], + cmd = "$(location //:codegen) --header $< > $@", + tools = ["//:codegen"], + visibility = visibility, + ) + + native.genrule( + name = source_target, + srcs = [bridge_source], + outs = [source_basename + ".cc"], + cmd = "$(location //:codegen) $< > $@", + tools = ["//:codegen"], + visibility = visibility, + ) + + gen_hdrs.append(header_target) + gen_srcs.append(source_target) + + cc_library( + name = name, + srcs = srcs + gen_srcs, + hdrs = hdrs + gen_hdrs, + include_prefix = crate_name, + strip_include_prefix = strip_include_prefix, + deps = deps, + visibility = visibility, + ) diff --git a/tools/buck/cxxbridge_cxx_library.bzl b/tools/buck/cxxbridge_cxx_library.bzl new file mode 100644 index 000000000..e747cfe36 --- /dev/null +++ b/tools/buck/cxxbridge_cxx_library.bzl @@ -0,0 +1,58 @@ +"""cxxbridge_cxx_library macro""" + +def cxxbridge_cxx_library( + name, + crate_name, + bridge_srcs, + srcs = None, + headers = None, + deps = None, + visibility = None): + """Generate C++ source for one or more Rust cxx::bridges and bundle into a cxx_library. + + Args: + name: A unique name for the cc_library rule. + crate_name: The name of the corresponding Rust crate, used as the include_prefix. + bridge_srcs: One or more Rust source files containing cxx::bridge modules. + srcs: Additional sources. Forwarded to cxx_library unmodified. + headers: Additional headers. Forwarded to cxx_library unmodified. + deps: Additional deps. Forwarded to cxx_library unmodified. + visibility: Visibility for all rules generated by this macro. + """ + + gen_srcs = [] + gen_hdrs = {} + for bridge_source in bridge_srcs: + source_basename = bridge_source.rsplit("/", 1)[-1] + header_target = name + "-" + source_basename + "-gen-header" + source_target = name + "-" + source_basename + "-gen-source" + + hdr_out = source_basename + ".h" + genrule( + name = header_target, + srcs = [bridge_source], + out = hdr_out, + cmd = "$(exe //:codegen) --header ${SRCS} > ${OUT}", + visibility = visibility, + ) + + genrule( + name = source_target, + srcs = [bridge_source], + out = source_basename + ".cc", + cmd = "$(exe //:codegen) ${SRCS} > ${OUT}", + visibility = visibility, + ) + + gen_hdrs[hdr_out] = ":" + header_target + gen_srcs.append(":" + source_target) + + cxx_library( + name = name, + srcs = srcs + gen_srcs, + headers = flatten_dicts(headers, gen_hdrs), + header_namespace = crate_name, + deps = deps, + visibility = visibility, + ) +