diff --git a/docs/defs.md b/docs/defs.md index caa7ed3db5..a514497c00 100644 --- a/docs/defs.md +++ b/docs/defs.md @@ -159,6 +159,9 @@ INFO: Running command line: bazel-bin/examples/rust/hello_world/hello_world Hello world ``` +On Windows, a PDB file containing debugging information is available under the key `pdb_file` in `OutputGroupInfo`. +Similarly on macOS, a dSYM folder is available under the key `dsym_folder` in `OutputGroupInfo`. + **ATTRIBUTES** @@ -335,6 +338,9 @@ It is meant to be used when producing an artifact that is then consumed by some This rule provides CcInfo, so it can be used everywhere Bazel expects `rules_cc`. +On Windows, a PDB file containing debugging information is available under the key `pdb_file` in `OutputGroupInfo`. +Similarly on macOS, a dSYM folder is available under the key `dsym_folder` in `OutputGroupInfo`. + When building the whole binary in Bazel, use `rust_library` instead. diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index d0749c9fd7..a94c5506ac 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -794,26 +794,34 @@ def rustc_compile_action( outputs = [crate_info.output] + # For a cdylib that might be added as a dependency to a cc_* target on Windows, it is important to include the + # interface library that rustc generates in the output files. interface_library = None + if toolchain.os == "windows" and crate_info.type == "cdylib": + # Rustc generates the import library with a `.dll.lib` extension rather than the usual `.lib` one that msvc + # expects (see https://github.com/rust-lang/rust/pull/29520 for more context). + interface_library = ctx.actions.declare_file(crate_info.output.basename + ".lib") + outputs.append(interface_library) + + # The action might generate extra output that we don't want to include in the `DefaultInfo` files. + action_outputs = list(outputs) + + # Rustc generates a pdb file (on Windows) or a dsym folder (on macos) so provide it in an output group for crate + # types that benefit from having debug information in a separate file. pdb_file = None - if toolchain.os == "windows": - # For a cdylib that might be added as a dependency to a cc_* target on Windows, it is important to include the - # interface library that rustc generates in the output files. - if crate_info.type == "cdylib": - # Rustc generates the import library with a `.dll.lib` extension rather than the usual `.lib` one that msvc - # expects (see https://github.com/rust-lang/rust/pull/29520 for more context). - interface_library = ctx.actions.declare_file(crate_info.output.basename + ".lib") - outputs.append(interface_library) - - # Rustc always generates a pdb file so provide it in an output group for crate types that benefit from having - # debug information in a separate file. Note that test targets do really need a pdb we skip them. - if crate_info.type in ("cdylib", "bin") and not crate_info.is_test: + dsym_folder = None + if crate_info.type in ("cdylib", "bin") and not crate_info.is_test: + if toolchain.os == "windows": pdb_file = ctx.actions.declare_file(crate_info.output.basename[:-len(crate_info.output.extension)] + "pdb") + action_outputs.append(pdb_file) + elif toolchain.os == "darwin": + dsym_folder = ctx.actions.declare_directory(crate_info.output.basename + ".dSYM") + action_outputs.append(dsym_folder) ctx.actions.run( executable = ctx.executable._process_wrapper, inputs = compile_inputs, - outputs = outputs + [pdb_file] if pdb_file else outputs, + outputs = action_outputs, env = env, arguments = args.all, mnemonic = "Rustc", @@ -848,6 +856,8 @@ def rustc_compile_action( providers += establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library) if pdb_file: providers.append(OutputGroupInfo(pdb_file = depset([pdb_file]))) + if dsym_folder: + providers.append(OutputGroupInfo(dsym_folder = depset([dsym_folder]))) return providers diff --git a/test/unit/debug_info/BUILD.bazel b/test/unit/debug_info/BUILD.bazel new file mode 100644 index 0000000000..a577c0a74d --- /dev/null +++ b/test/unit/debug_info/BUILD.bazel @@ -0,0 +1,4 @@ +load(":debug_info_analysis_test.bzl", "debug_info_analysis_test_suite") + +############################ UNIT TESTS ############################# +debug_info_analysis_test_suite(name = "debug_info_analysis_test_suite") diff --git a/test/unit/debug_info/debug_info_analysis_test.bzl b/test/unit/debug_info/debug_info_analysis_test.bzl new file mode 100644 index 0000000000..bb79d3f973 --- /dev/null +++ b/test/unit/debug_info/debug_info_analysis_test.bzl @@ -0,0 +1,105 @@ +"""Analysis tests for debug info in cdylib and bin targets.""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("@rules_cc//cc:defs.bzl", "cc_binary") +load("//rust:defs.bzl", "rust_binary", "rust_shared_library") + +def _pdb_file_test_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + + files = target[DefaultInfo].files.to_list() + asserts.equals(env, len(files), 1) + file = files[0] + asserts.equals(env, file.extension, "pdb") + + return analysistest.end(env) + +pdb_file_test = analysistest.make(_pdb_file_test_impl) + +def _dsym_folder_test_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + + files = target[DefaultInfo].files.to_list() + asserts.equals(env, len(files), 1) + file = files[0] + asserts.equals(env, file.extension, "dSYM") + + return analysistest.end(env) + +dsym_folder_test = analysistest.make(_dsym_folder_test_impl) + +def debug_info_analysis_test_suite(name): + """Analysis tests for debug info in cdylib and bin targets. + + Args: + name: the test suite name + """ + rust_shared_library( + name = "mylib", + srcs = ["lib.rs"], + ) + + native.filegroup( + name = "mylib.pdb", + srcs = [":mylib"], + output_group = "pdb_file", + ) + + pdb_file_test( + name = "lib_pdb_test", + target_under_test = ":mylib.pdb", + target_compatible_with = ["@platforms//os:windows"], + ) + + native.filegroup( + name = "mylib.dSYM", + srcs = [":mylib"], + output_group = "dsym_folder", + ) + + dsym_folder_test( + name = "lib_dsym_test", + target_under_test = ":mylib.dSYM", + target_compatible_with = ["@platforms//os:macos"], + ) + + rust_binary( + name = "myrustbin", + srcs = ["main.rs"], + ) + + native.filegroup( + name = "mybin.pdb", + srcs = [":myrustbin"], + output_group = "pdb_file", + ) + + pdb_file_test( + name = "bin_pdb_test", + target_under_test = ":mybin.pdb", + target_compatible_with = ["@platforms//os:windows"], + ) + + native.filegroup( + name = "mybin.dSYM", + srcs = [":myrustbin"], + output_group = "dsym_folder", + ) + + dsym_folder_test( + name = "bin_dsym_test", + target_under_test = ":mybin.dSYM", + target_compatible_with = ["@platforms//os:macos"], + ) + + native.test_suite( + name = name, + tests = [ + ":lib_pdb_test", + ":lib_dsym_test", + ":bin_pdb_test", + ":bin_dsym_test", + ], + ) diff --git a/test/unit/debug_info/lib.rs b/test/unit/debug_info/lib.rs new file mode 100644 index 0000000000..1f19b6db39 --- /dev/null +++ b/test/unit/debug_info/lib.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn hello() { + println!("Hello"); +} diff --git a/test/unit/debug_info/main.rs b/test/unit/debug_info/main.rs new file mode 100644 index 0000000000..6d85883381 --- /dev/null +++ b/test/unit/debug_info/main.rs @@ -0,0 +1,3 @@ +pub fn main() { + println!("Hello"); +} diff --git a/test/unit/win_interface_library/win_interface_library_analysis_test.bzl b/test/unit/win_interface_library/win_interface_library_analysis_test.bzl index eced433ace..fef00f2db3 100644 --- a/test/unit/win_interface_library/win_interface_library_analysis_test.bzl +++ b/test/unit/win_interface_library/win_interface_library_analysis_test.bzl @@ -36,12 +36,6 @@ def win_interface_library_analysis_test_suite(name): target_compatible_with = ["@platforms//os:windows"], ) - native.filegroup( - name = "mylib.pdb", - srcs = [":mylib"], - output_group = "pdb_file", - ) - cc_binary( name = "mybin", srcs = ["bin.cc"], @@ -55,12 +49,6 @@ def win_interface_library_analysis_test_suite(name): target_compatible_with = ["@platforms//os:windows"], ) - native.filegroup( - name = "myrustbin.pdb", - srcs = [":myrustbin"], - output_group = "pdb_file", - ) - win_interface_library_test( name = "win_interface_library_test", target_under_test = ":mylib",