diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 1b67c6293a..008ff18b92 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -654,6 +654,8 @@ def establish_cc_info(ctx, crate_info, toolchain, cc_toolchain, feature_configur feature_configuration = feature_configuration, cc_toolchain = cc_toolchain, static_library = crate_info.output, + # TODO(hlopko): handle PIC/NOPIC correctly + pic_static_library = crate_info.output, ) elif crate_info.type in ("rlib", "lib"): # bazel hard-codes a check for endswith((".a", ".pic.a", @@ -661,12 +663,12 @@ def establish_cc_info(ctx, crate_info, toolchain, cc_toolchain, feature_configur # by creating a symlink to the .rlib with a .a extension. dot_a = ctx.actions.declare_file(crate_info.name + ".a", sibling = crate_info.output) ctx.actions.symlink(output = dot_a, target_file = crate_info.output) - # TODO(hlopko): handle PIC/NOPIC correctly library_to_link = cc_common.create_library_to_link( actions = ctx.actions, feature_configuration = feature_configuration, cc_toolchain = cc_toolchain, static_library = dot_a, + # TODO(hlopko): handle PIC/NOPIC correctly pic_static_library = dot_a, ) elif crate_info.type == "cdylib": diff --git a/test/unit/cc_info/BUILD b/test/unit/cc_info/BUILD new file mode 100644 index 0000000000..425bb37162 --- /dev/null +++ b/test/unit/cc_info/BUILD @@ -0,0 +1,4 @@ +load(":cc_info_test.bzl", "cc_info_test_suite") + +############################ UNIT TESTS ############################# +cc_info_test_suite(name = "cc_info_test_suite") diff --git a/test/unit/cc_info/bin_using_native_dep.rs b/test/unit/cc_info/bin_using_native_dep.rs new file mode 100644 index 0000000000..6250ab356b --- /dev/null +++ b/test/unit/cc_info/bin_using_native_dep.rs @@ -0,0 +1,6 @@ +extern "C" { + fn native_dep() -> isize; +} +fn main() { + println!("{}", unsafe { native_dep() }) +} \ No newline at end of file diff --git a/test/unit/cc_info/cc_info_test.bzl b/test/unit/cc_info/cc_info_test.bzl new file mode 100644 index 0000000000..23674769df --- /dev/null +++ b/test/unit/cc_info/cc_info_test.bzl @@ -0,0 +1,137 @@ +"""Unittests for rust rules.""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("//rust:defs.bzl", "rust_binary", "rust_library", "rust_proc_macro", "rust_shared_library", "rust_static_library") + +def _assert_cc_info_has_library_to_link(env, tut, type): + asserts.true(env, CcInfo in tut, "rust_library should provide CcInfo") + cc_info = tut[CcInfo] + linker_inputs = cc_info.linking_context.linker_inputs.to_list() + asserts.equals(env, len(linker_inputs), 1) + library_to_link = linker_inputs[0].libraries[0] + asserts.equals(env, False, library_to_link.alwayslink) + + asserts.equals(env, [], library_to_link.lto_bitcode_files) + asserts.equals(env, [], library_to_link.pic_lto_bitcode_files) + + asserts.equals(env, [], library_to_link.objects) + asserts.equals(env, [], library_to_link.pic_objects) + + if type == "cdylib": + asserts.true(env, library_to_link.dynamic_library != None) + asserts.equals(env, None, library_to_link.interface_library) + asserts.true(env, library_to_link.resolved_symlink_dynamic_library != None) + asserts.equals(env, None, library_to_link.resolved_symlink_interface_library) + asserts.equals(env, None, library_to_link.static_library) + asserts.equals(env, None, library_to_link.pic_static_library) + else: + asserts.equals(env, None, library_to_link.dynamic_library) + asserts.equals(env, None, library_to_link.interface_library) + asserts.equals(env, None, library_to_link.resolved_symlink_dynamic_library) + asserts.equals(env, None, library_to_link.resolved_symlink_interface_library) + asserts.true(env, library_to_link.static_library != None) + asserts.true(env, library_to_link.pic_static_library != None) + asserts.equals(env, library_to_link.static_library, library_to_link.pic_static_library) + +def _rlib_provides_cc_info_test_impl(ctx): + env = analysistest.begin(ctx) + tut = analysistest.target_under_test(env) + _assert_cc_info_has_library_to_link(env, tut, "rlib") + return analysistest.end(env) + +def _bin_does_not_provide_cc_info_test_impl(ctx): + env = analysistest.begin(ctx) + tut = analysistest.target_under_test(env) + asserts.false(env, CcInfo in tut, "rust_binary should not provide CcInfo") + return analysistest.end(env) + +def _proc_macro_does_not_provide_cc_info_test_impl(ctx): + env = analysistest.begin(ctx) + tut = analysistest.target_under_test(env) + asserts.false(env, CcInfo in tut, "rust_proc_macro should not provide CcInfo") + return analysistest.end(env) + +def _cdylib_provides_cc_info_test_impl(ctx): + env = analysistest.begin(ctx) + tut = analysistest.target_under_test(env) + _assert_cc_info_has_library_to_link(env, tut, "cdylib") + return analysistest.end(env) + +def _staticlib_provides_cc_info_test_impl(ctx): + env = analysistest.begin(ctx) + tut = analysistest.target_under_test(env) + _assert_cc_info_has_library_to_link(env, tut, "staticlib") + return analysistest.end(env) + +rlib_provides_cc_info_test = analysistest.make(_rlib_provides_cc_info_test_impl) +bin_does_not_provide_cc_info_test = analysistest.make(_bin_does_not_provide_cc_info_test_impl) +staticlib_provides_cc_info_test = analysistest.make(_staticlib_provides_cc_info_test_impl) +cdylib_provides_cc_info_test = analysistest.make(_cdylib_provides_cc_info_test_impl) +proc_macro_does_not_provide_cc_info_test = analysistest.make(_proc_macro_does_not_provide_cc_info_test_impl) + +def _cc_info_test(): + rust_library( + name = "rlib", + srcs = ["foo.rs"], + ) + + rust_binary( + name = "bin", + srcs = ["foo.rs"], + ) + + rust_static_library( + name = "staticlib", + srcs = ["foo.rs"], + ) + + rust_shared_library( + name = "cdylib", + srcs = ["foo.rs"], + ) + + rust_proc_macro( + name = "proc_macro", + srcs = ["proc_macro.rs"], + edition = "2018", + ) + + rlib_provides_cc_info_test( + name = "rlib_provides_cc_info_test", + target_under_test = ":rlib", + ) + bin_does_not_provide_cc_info_test( + name = "bin_does_not_provide_cc_info_test", + target_under_test = ":bin", + ) + cdylib_provides_cc_info_test( + name = "cdylib_provides_cc_info_test", + target_under_test = ":cdylib", + ) + staticlib_provides_cc_info_test( + name = "staticlib_provides_cc_info_test", + target_under_test = ":staticlib", + ) + proc_macro_does_not_provide_cc_info_test( + name = "proc_macro_does_not_provide_cc_info_test", + target_under_test = ":proc_macro", + ) + +def cc_info_test_suite(name): + """Entry-point macro called from the BUILD file. + + Args: + name: Name of the macro. + """ + _cc_info_test() + + native.test_suite( + name = name, + tests = [ + ":rlib_provides_cc_info_test", + ":staticlib_provides_cc_info_test", + ":cdylib_provides_cc_info_test", + ":proc_macro_does_not_provide_cc_info_test", + ":bin_does_not_provide_cc_info_test", + ], + ) diff --git a/test/unit/cc_info/foo.rs b/test/unit/cc_info/foo.rs new file mode 100644 index 0000000000..9bda8eef2c --- /dev/null +++ b/test/unit/cc_info/foo.rs @@ -0,0 +1 @@ +pub fn main() { dbg!(42); } \ No newline at end of file diff --git a/test/unit/cc_info/proc_macro.rs b/test/unit/cc_info/proc_macro.rs new file mode 100644 index 0000000000..0ab4b9e55c --- /dev/null +++ b/test/unit/cc_info/proc_macro.rs @@ -0,0 +1,9 @@ +use proc_macro::TokenStream; + +extern "C" { + fn native_dep() -> isize; +} +#[proc_macro_derive(UsingNativeDep)] +pub fn use_native_dep(_input: TokenStream) -> TokenStream { + panic!("done") +} \ No newline at end of file