diff --git a/examples/ffi/cc_calling_rust/BUILD b/examples/ffi/cc_calling_rust/BUILD new file mode 100644 index 0000000000..77bb13028f --- /dev/null +++ b/examples/ffi/cc_calling_rust/BUILD @@ -0,0 +1,7 @@ +load("@rules_cc//cc:defs.bzl", "cc_test") + +cc_test( + name = "main", + srcs = ["cc/main.c"], + deps = ["//ffi/cc_calling_rust/rust:libsimple_printer"], +) diff --git a/examples/ffi/cc_calling_rust/cc/main.c b/examples/ffi/cc_calling_rust/cc/main.c new file mode 100644 index 0000000000..73d865b5c3 --- /dev/null +++ b/examples/ffi/cc_calling_rust/cc/main.c @@ -0,0 +1,6 @@ +#include "simple_printer.h" + +int main() { + print_c_hello_rust(); + return 0; +} diff --git a/examples/ffi/cc_calling_rust/rust/BUILD b/examples/ffi/cc_calling_rust/rust/BUILD new file mode 100644 index 0000000000..b2d4f57d03 --- /dev/null +++ b/examples/ffi/cc_calling_rust/rust/BUILD @@ -0,0 +1,10 @@ +load("@rules_rust//rust:defs.bzl", "rust_static_library") + +rust_static_library( + name = "libsimple_printer", + srcs = ["libsimple_printer.rs"], + hdrs = ["simple_printer.h"], + crate_name = "simple_printer", + includes = ["."], + visibility = ["//visibility:public"], +) diff --git a/examples/ffi/cc_calling_rust/rust/libsimple_printer.rs b/examples/ffi/cc_calling_rust/rust/libsimple_printer.rs new file mode 100644 index 0000000000..2695864bfb --- /dev/null +++ b/examples/ffi/cc_calling_rust/rust/libsimple_printer.rs @@ -0,0 +1,7 @@ +//! A simple hello world example that can be called from C + +#[no_mangle] +/// Print "Hello Rust!" +pub extern fn print_c_hello_rust() { + println!("Hello Rust!"); +} diff --git a/examples/ffi/cc_calling_rust/rust/simple_printer.h b/examples/ffi/cc_calling_rust/rust/simple_printer.h new file mode 100644 index 0000000000..a249a779d3 --- /dev/null +++ b/examples/ffi/cc_calling_rust/rust/simple_printer.h @@ -0,0 +1,7 @@ +#ifndef SIMPLE_PRINTER_H +#define SIMPLE_PRINTER_H + +void print_c_hello_rust(); + + +#endif \ No newline at end of file diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 014d8d0d52..2d128a0b41 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -931,7 +931,11 @@ rust_library = rule( rust_static_library = rule( implementation = _rust_static_library_impl, - attrs = dict(_common_attrs.items()), + attrs = dict(_common_attrs.items() + { + "hdrs": attr.label_list(allow_files = True), + "includes": attr.string_list(), + }.items() + ), fragments = ["cpp"], host_fragments = ["cpp"], toolchains = [ diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index e76c20bde0..6eaed28711 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -1474,6 +1474,25 @@ def _collect_nonstatic_linker_inputs(cc_info): )) return shared_linker_inputs +# get_includes_paths expects a rule context, a list of directories, and +# whether the directories are package-relative and returns a list of exec +# root-relative paths. This handles the need to search for files both in the +# source tree and generated files. +def _get_includes_paths(ctx, dirs, package_relative = True): + execution_relative_dirs = [] + for rel_dir in dirs: + if rel_dir == ".": + rel_dir = "" + execution_rel_dir = rel_dir + if package_relative: + execution_rel_dir = ctx.label.package + if len(rel_dir) > 0: + execution_rel_dir = execution_rel_dir + "/" + rel_dir + + execution_relative_dirs.append(execution_rel_dir) + + return execution_relative_dirs + def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library): """If the produced crate is suitable yield a CcInfo to allow for interop with cc rules @@ -1548,8 +1567,15 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co linker_inputs = depset([link_input]), ) + compilation_context = None + if hasattr(ctx.attr, "hdrs") and hasattr(ctx.attr, "includes"): + compilation_context = cc_common.create_compilation_context( + headers = depset(ctx.files.hdrs), + includes = depset(_get_includes_paths(ctx, ctx.attr.includes, True)) + ) + cc_infos = [ - CcInfo(linking_context = linking_context), + CcInfo(linking_context = linking_context, compilation_context = compilation_context), toolchain.stdlib_linkflags, ]