diff options
-rw-r--r-- | WORKSPACE.bazel | 6 | ||||
-rw-r--r-- | docs/flatten.md | 18 | ||||
-rw-r--r-- | docs/providers.md | 8 | ||||
-rw-r--r-- | docs/rust_repositories.md | 10 | ||||
-rw-r--r-- | rust/private/providers.bzl | 2 | ||||
-rw-r--r-- | rust/private/rustc.bzl | 14 | ||||
-rw-r--r-- | rust/private/utils.bzl | 12 | ||||
-rw-r--r-- | rust/settings/BUILD.bazel | 6 | ||||
-rw-r--r-- | rust/toolchain.bzl | 59 | ||||
-rw-r--r-- | test/link_std_dylib/BUILD | 3 | ||||
-rw-r--r-- | test/link_std_dylib/lib.rs | 7 | ||||
-rw-r--r-- | test/link_std_dylib/link_std_dylib_test.bzl | 118 | ||||
-rw-r--r-- | test/link_std_dylib/main.rs | 7 |
13 files changed, 241 insertions, 29 deletions
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index d32161aa..8845e38c 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -79,7 +79,7 @@ http_archive( http_archive( name = "rules_testing", - sha256 = "b84ed8546f1969d700ead4546de9f7637e0f058d835e47e865dcbb13c4210aed", - strip_prefix = "rules_testing-0.5.0", - url = "https://github.com/bazelbuild/rules_testing/releases/download/v0.5.0/rules_testing-v0.5.0.tar.gz", + sha256 = "02c62574631876a4e3b02a1820cb51167bb9cdcdea2381b2fa9d9b8b11c407c4", + strip_prefix = "rules_testing-0.6.0", + url = "https://github.com/bazelbuild/rules_testing/releases/download/v0.6.0/rules_testing-v0.6.0.tar.gz", ) diff --git a/docs/flatten.md b/docs/flatten.md index 58ec9cb8..14d2af66 100644 --- a/docs/flatten.md +++ b/docs/flatten.md @@ -1176,10 +1176,11 @@ Run the test with `bazel test //hello_lib:greeting_test`. <pre> rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>, - <a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-env">env</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-experimental_use_cc_common_link">experimental_use_cc_common_link</a>, - <a href="#rust_toolchain-extra_exec_rustc_flags">extra_exec_rustc_flags</a>, <a href="#rust_toolchain-extra_rustc_flags">extra_rustc_flags</a>, <a href="#rust_toolchain-global_allocator_library">global_allocator_library</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, - <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-per_crate_rustc_flags">per_crate_rustc_flags</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, - <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>) + <a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-env">env</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-experimental_link_std_dylib">experimental_link_std_dylib</a>, + <a href="#rust_toolchain-experimental_use_cc_common_link">experimental_use_cc_common_link</a>, <a href="#rust_toolchain-extra_exec_rustc_flags">extra_exec_rustc_flags</a>, <a href="#rust_toolchain-extra_rustc_flags">extra_rustc_flags</a>, + <a href="#rust_toolchain-global_allocator_library">global_allocator_library</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, + <a href="#rust_toolchain-per_crate_rustc_flags">per_crate_rustc_flags</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, + <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>) </pre> Declares a Rust toolchain for use. @@ -1241,6 +1242,7 @@ See `@rules_rust//rust:repositories.bzl` for examples of defining the `@rust_cpu | <a id="rust_toolchain-dylib_ext"></a>dylib_ext | The extension for dynamic libraries created from rustc. | String | required | | | <a id="rust_toolchain-env"></a>env | Environment variables to set in actions. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{}</code> | | <a id="rust_toolchain-exec_triple"></a>exec_triple | The platform triple for the toolchains execution environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | required | | +| <a id="rust_toolchain-experimental_link_std_dylib"></a>experimental_link_std_dylib | Label to a boolean build setting that controls whether whether to link libstd dynamically. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>@rules_rust//rust/settings:experimental_link_std_dylib</code> | | <a id="rust_toolchain-experimental_use_cc_common_link"></a>experimental_use_cc_common_link | Label to a boolean build setting that controls whether cc_common.link is used to link rust binaries. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>//rust/settings:experimental_use_cc_common_link</code> | | <a id="rust_toolchain-extra_exec_rustc_flags"></a>extra_exec_rustc_flags | Extra flags to pass to rustc in exec configuration | List of strings | optional | <code>[]</code> | | <a id="rust_toolchain-extra_rustc_flags"></a>extra_rustc_flags | Extra flags to pass to rustc in non-exec configuration | List of strings | optional | <code>[]</code> | @@ -1446,7 +1448,7 @@ A toolchain for [rustfmt](https://rust-lang.github.io/rustfmt/) <pre> CrateInfo(<a href="#CrateInfo-aliases">aliases</a>, <a href="#CrateInfo-compile_data">compile_data</a>, <a href="#CrateInfo-compile_data_targets">compile_data_targets</a>, <a href="#CrateInfo-data">data</a>, <a href="#CrateInfo-deps">deps</a>, <a href="#CrateInfo-edition">edition</a>, <a href="#CrateInfo-is_test">is_test</a>, <a href="#CrateInfo-metadata">metadata</a>, <a href="#CrateInfo-name">name</a>, <a href="#CrateInfo-output">output</a>, <a href="#CrateInfo-owner">owner</a>, <a href="#CrateInfo-proc_macro_deps">proc_macro_deps</a>, <a href="#CrateInfo-root">root</a>, <a href="#CrateInfo-rustc_env">rustc_env</a>, <a href="#CrateInfo-rustc_env_files">rustc_env_files</a>, <a href="#CrateInfo-rustc_output">rustc_output</a>, - <a href="#CrateInfo-rustc_rmeta_output">rustc_rmeta_output</a>, <a href="#CrateInfo-srcs">srcs</a>, <a href="#CrateInfo-type">type</a>, <a href="#CrateInfo-wrapped_crate_type">wrapped_crate_type</a>) + <a href="#CrateInfo-rustc_rmeta_output">rustc_rmeta_output</a>, <a href="#CrateInfo-srcs">srcs</a>, <a href="#CrateInfo-std_dylib">std_dylib</a>, <a href="#CrateInfo-type">type</a>, <a href="#CrateInfo-wrapped_crate_type">wrapped_crate_type</a>) </pre> A provider containing general Crate information. @@ -1474,6 +1476,7 @@ A provider containing general Crate information. | <a id="CrateInfo-rustc_output"></a>rustc_output | File: The output from rustc from producing the output file. It is optional. | | <a id="CrateInfo-rustc_rmeta_output"></a>rustc_rmeta_output | File: The rmeta file produced for this crate. It is optional. | | <a id="CrateInfo-srcs"></a>srcs | depset[File]: All source Files that are part of the crate. | +| <a id="CrateInfo-std_dylib"></a>std_dylib | File: libstd.so file | | <a id="CrateInfo-type"></a>type | str: The type of this crate (see [rustc --crate-type](https://doc.rust-lang.org/rustc/command-line-arguments.html#--crate-type-a-list-of-types-of-crates-for-the-compiler-to-emit)). | | <a id="CrateInfo-wrapped_crate_type"></a>wrapped_crate_type | str, optional: The original crate type for targets generated using a previously defined crate (typically tests using the <code>rust_test::crate</code> attribute) | @@ -1533,8 +1536,8 @@ Info about wasm-bindgen outputs. <pre> StdLibInfo(<a href="#StdLibInfo-alloc_files">alloc_files</a>, <a href="#StdLibInfo-between_alloc_and_core_files">between_alloc_and_core_files</a>, <a href="#StdLibInfo-between_core_and_std_files">between_core_and_std_files</a>, <a href="#StdLibInfo-core_files">core_files</a>, - <a href="#StdLibInfo-dot_a_files">dot_a_files</a>, <a href="#StdLibInfo-memchr_files">memchr_files</a>, <a href="#StdLibInfo-panic_files">panic_files</a>, <a href="#StdLibInfo-self_contained_files">self_contained_files</a>, <a href="#StdLibInfo-srcs">srcs</a>, <a href="#StdLibInfo-std_files">std_files</a>, <a href="#StdLibInfo-std_rlibs">std_rlibs</a>, - <a href="#StdLibInfo-test_files">test_files</a>) + <a href="#StdLibInfo-dot_a_files">dot_a_files</a>, <a href="#StdLibInfo-memchr_files">memchr_files</a>, <a href="#StdLibInfo-panic_files">panic_files</a>, <a href="#StdLibInfo-self_contained_files">self_contained_files</a>, <a href="#StdLibInfo-srcs">srcs</a>, <a href="#StdLibInfo-std_dylib">std_dylib</a>, <a href="#StdLibInfo-std_files">std_files</a>, + <a href="#StdLibInfo-std_rlibs">std_rlibs</a>, <a href="#StdLibInfo-test_files">test_files</a>) </pre> A collection of files either found within the `rust-stdlib` artifact or generated based on existing files. @@ -1553,6 +1556,7 @@ A collection of files either found within the `rust-stdlib` artifact or generate | <a id="StdLibInfo-panic_files"></a>panic_files | Depset[File]: <code>.a</code> files associated with <code>panic_unwind</code> and <code>panic_abort</code>. | | <a id="StdLibInfo-self_contained_files"></a>self_contained_files | List[File]: All <code>.o</code> files from the <code>self-contained</code> directory. | | <a id="StdLibInfo-srcs"></a>srcs | List[Target]: All targets from the original <code>srcs</code> attribute. | +| <a id="StdLibInfo-std_dylib"></a>std_dylib | File: libstd.so file | | <a id="StdLibInfo-std_files"></a>std_files | Depset[File]: <code>.a</code> files associated with the <code>std</code> module. | | <a id="StdLibInfo-std_rlibs"></a>std_rlibs | List[File]: All <code>.rlib</code> files | | <a id="StdLibInfo-test_files"></a>test_files | Depset[File]: <code>.a</code> files associated with the <code>test</code> module. | diff --git a/docs/providers.md b/docs/providers.md index 87a37924..bed0a6ff 100644 --- a/docs/providers.md +++ b/docs/providers.md @@ -12,7 +12,7 @@ <pre> CrateInfo(<a href="#CrateInfo-aliases">aliases</a>, <a href="#CrateInfo-compile_data">compile_data</a>, <a href="#CrateInfo-compile_data_targets">compile_data_targets</a>, <a href="#CrateInfo-data">data</a>, <a href="#CrateInfo-deps">deps</a>, <a href="#CrateInfo-edition">edition</a>, <a href="#CrateInfo-is_test">is_test</a>, <a href="#CrateInfo-metadata">metadata</a>, <a href="#CrateInfo-name">name</a>, <a href="#CrateInfo-output">output</a>, <a href="#CrateInfo-owner">owner</a>, <a href="#CrateInfo-proc_macro_deps">proc_macro_deps</a>, <a href="#CrateInfo-root">root</a>, <a href="#CrateInfo-rustc_env">rustc_env</a>, <a href="#CrateInfo-rustc_env_files">rustc_env_files</a>, <a href="#CrateInfo-rustc_output">rustc_output</a>, - <a href="#CrateInfo-rustc_rmeta_output">rustc_rmeta_output</a>, <a href="#CrateInfo-srcs">srcs</a>, <a href="#CrateInfo-type">type</a>, <a href="#CrateInfo-wrapped_crate_type">wrapped_crate_type</a>) + <a href="#CrateInfo-rustc_rmeta_output">rustc_rmeta_output</a>, <a href="#CrateInfo-srcs">srcs</a>, <a href="#CrateInfo-std_dylib">std_dylib</a>, <a href="#CrateInfo-type">type</a>, <a href="#CrateInfo-wrapped_crate_type">wrapped_crate_type</a>) </pre> A provider containing general Crate information. @@ -40,6 +40,7 @@ A provider containing general Crate information. | <a id="CrateInfo-rustc_output"></a>rustc_output | File: The output from rustc from producing the output file. It is optional. | | <a id="CrateInfo-rustc_rmeta_output"></a>rustc_rmeta_output | File: The rmeta file produced for this crate. It is optional. | | <a id="CrateInfo-srcs"></a>srcs | depset[File]: All source Files that are part of the crate. | +| <a id="CrateInfo-std_dylib"></a>std_dylib | File: libstd.so file | | <a id="CrateInfo-type"></a>type | str: The type of this crate (see [rustc --crate-type](https://doc.rust-lang.org/rustc/command-line-arguments.html#--crate-type-a-list-of-types-of-crates-for-the-compiler-to-emit)). | | <a id="CrateInfo-wrapped_crate_type"></a>wrapped_crate_type | str, optional: The original crate type for targets generated using a previously defined crate (typically tests using the <code>rust_test::crate</code> attribute) | @@ -79,8 +80,8 @@ A provider containing information about a Crate's dependencies. <pre> StdLibInfo(<a href="#StdLibInfo-alloc_files">alloc_files</a>, <a href="#StdLibInfo-between_alloc_and_core_files">between_alloc_and_core_files</a>, <a href="#StdLibInfo-between_core_and_std_files">between_core_and_std_files</a>, <a href="#StdLibInfo-core_files">core_files</a>, - <a href="#StdLibInfo-dot_a_files">dot_a_files</a>, <a href="#StdLibInfo-memchr_files">memchr_files</a>, <a href="#StdLibInfo-panic_files">panic_files</a>, <a href="#StdLibInfo-self_contained_files">self_contained_files</a>, <a href="#StdLibInfo-srcs">srcs</a>, <a href="#StdLibInfo-std_files">std_files</a>, <a href="#StdLibInfo-std_rlibs">std_rlibs</a>, - <a href="#StdLibInfo-test_files">test_files</a>) + <a href="#StdLibInfo-dot_a_files">dot_a_files</a>, <a href="#StdLibInfo-memchr_files">memchr_files</a>, <a href="#StdLibInfo-panic_files">panic_files</a>, <a href="#StdLibInfo-self_contained_files">self_contained_files</a>, <a href="#StdLibInfo-srcs">srcs</a>, <a href="#StdLibInfo-std_dylib">std_dylib</a>, <a href="#StdLibInfo-std_files">std_files</a>, + <a href="#StdLibInfo-std_rlibs">std_rlibs</a>, <a href="#StdLibInfo-test_files">test_files</a>) </pre> A collection of files either found within the `rust-stdlib` artifact or generated based on existing files. @@ -99,6 +100,7 @@ A collection of files either found within the `rust-stdlib` artifact or generate | <a id="StdLibInfo-panic_files"></a>panic_files | Depset[File]: <code>.a</code> files associated with <code>panic_unwind</code> and <code>panic_abort</code>. | | <a id="StdLibInfo-self_contained_files"></a>self_contained_files | List[File]: All <code>.o</code> files from the <code>self-contained</code> directory. | | <a id="StdLibInfo-srcs"></a>srcs | List[Target]: All targets from the original <code>srcs</code> attribute. | +| <a id="StdLibInfo-std_dylib"></a>std_dylib | File: libstd.so file | | <a id="StdLibInfo-std_files"></a>std_files | Depset[File]: <code>.a</code> files associated with the <code>std</code> module. | | <a id="StdLibInfo-std_rlibs"></a>std_rlibs | List[File]: All <code>.rlib</code> files | | <a id="StdLibInfo-test_files"></a>test_files | Depset[File]: <code>.a</code> files associated with the <code>test</code> module. | diff --git a/docs/rust_repositories.md b/docs/rust_repositories.md index 944f4e43..20d29816 100644 --- a/docs/rust_repositories.md +++ b/docs/rust_repositories.md @@ -37,10 +37,11 @@ A dedicated filegroup-like rule for Rust stdlib artifacts. <pre> rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>, - <a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-env">env</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-experimental_use_cc_common_link">experimental_use_cc_common_link</a>, - <a href="#rust_toolchain-extra_exec_rustc_flags">extra_exec_rustc_flags</a>, <a href="#rust_toolchain-extra_rustc_flags">extra_rustc_flags</a>, <a href="#rust_toolchain-global_allocator_library">global_allocator_library</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, - <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-per_crate_rustc_flags">per_crate_rustc_flags</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, - <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>) + <a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-env">env</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-experimental_link_std_dylib">experimental_link_std_dylib</a>, + <a href="#rust_toolchain-experimental_use_cc_common_link">experimental_use_cc_common_link</a>, <a href="#rust_toolchain-extra_exec_rustc_flags">extra_exec_rustc_flags</a>, <a href="#rust_toolchain-extra_rustc_flags">extra_rustc_flags</a>, + <a href="#rust_toolchain-global_allocator_library">global_allocator_library</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, + <a href="#rust_toolchain-per_crate_rustc_flags">per_crate_rustc_flags</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, + <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>) </pre> Declares a Rust toolchain for use. @@ -102,6 +103,7 @@ See `@rules_rust//rust:repositories.bzl` for examples of defining the `@rust_cpu | <a id="rust_toolchain-dylib_ext"></a>dylib_ext | The extension for dynamic libraries created from rustc. | String | required | | | <a id="rust_toolchain-env"></a>env | Environment variables to set in actions. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{}</code> | | <a id="rust_toolchain-exec_triple"></a>exec_triple | The platform triple for the toolchains execution environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | required | | +| <a id="rust_toolchain-experimental_link_std_dylib"></a>experimental_link_std_dylib | Label to a boolean build setting that controls whether whether to link libstd dynamically. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>@rules_rust//rust/settings:experimental_link_std_dylib</code> | | <a id="rust_toolchain-experimental_use_cc_common_link"></a>experimental_use_cc_common_link | Label to a boolean build setting that controls whether cc_common.link is used to link rust binaries. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>//rust/settings:experimental_use_cc_common_link</code> | | <a id="rust_toolchain-extra_exec_rustc_flags"></a>extra_exec_rustc_flags | Extra flags to pass to rustc in exec configuration | List of strings | optional | <code>[]</code> | | <a id="rust_toolchain-extra_rustc_flags"></a>extra_rustc_flags | Extra flags to pass to rustc in non-exec configuration | List of strings | optional | <code>[]</code> | diff --git a/rust/private/providers.bzl b/rust/private/providers.bzl index 2bb81ef7..c2770dc4 100644 --- a/rust/private/providers.bzl +++ b/rust/private/providers.bzl @@ -35,6 +35,7 @@ CrateInfo = provider( "rustc_output": "File: The output from rustc from producing the output file. It is optional.", "rustc_rmeta_output": "File: The rmeta file produced for this crate. It is optional.", "srcs": "depset[File]: All source Files that are part of the crate.", + "std_dylib": "File: libstd.so file", "type": ( "str: The type of this crate " + "(see [rustc --crate-type](https://doc.rust-lang.org/rustc/command-line-arguments.html#--crate-type-a-list-of-types-of-crates-for-the-compiler-to-emit))." @@ -122,6 +123,7 @@ StdLibInfo = provider( "panic_files": "Depset[File]: `.a` files associated with `panic_unwind` and `panic_abort`.", "self_contained_files": "List[File]: All `.o` files from the `self-contained` directory.", "srcs": "List[Target]: All targets from the original `srcs` attribute.", + "std_dylib": "File: libstd.so file", "std_files": "Depset[File]: `.a` files associated with the `std` module.", "std_rlibs": "List[File]: All `.rlib` files", "test_files": "Depset[File]: `.a` files associated with the `test` module.", diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 4abfdba1..e1012230 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -38,6 +38,7 @@ load( "make_static_lib_symlink", "relativize", ) +load(":utils.bzl", "is_std_dylib") BuildInfo = _BuildInfo @@ -1035,6 +1036,9 @@ def construct_arguments( # https://doc.rust-lang.org/rustc/instrument-coverage.html rustc_flags.add("--codegen=instrument-coverage") + if toolchain._experimental_link_std_dylib: + rustc_flags.add("--codegen=prefer-dynamic") + # Make bin crate data deps available to tests. for data in getattr(attr, "data", []): if rust_common.crate_info in data: @@ -1724,6 +1728,16 @@ def _compute_rpaths(toolchain, output_dir, dep_info, use_pic): for lib in linker_input.libraries if _is_dylib(lib) ] + + # Include std dylib if dylib linkage is enabled + if toolchain._experimental_link_std_dylib: + # TODO: Make toolchain.rust_std to only include libstd.so + # When dylib linkage is enabled, toolchain.rust_std should only need to + # include libstd.so. Hence, no filtering needed. + for file in toolchain.rust_std.to_list(): + if is_std_dylib(file): + dylibs.append(file) + if not dylibs: return depset([]) diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl index 783aa222..06a3d334 100644 --- a/rust/private/utils.bzl +++ b/rust/private/utils.bzl @@ -879,3 +879,15 @@ def generate_output_diagnostics(ctx, sibling, require_process_wrapper = True): sibling.basename + ".rustc-output", sibling = sibling, ) + +def is_std_dylib(file): + """Whether the file is a dylib crate for std + + """ + basename = file.basename + return ( + # for linux and darwin + basename.startswith("libstd-") and (basename.endswith(".so") or basename.endswith(".dylib")) or + # for windows + basename.startswith("std-") and basename.endswith(".dll") + ) diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index faaa1489..1160e975 100644 --- a/rust/settings/BUILD.bazel +++ b/rust/settings/BUILD.bazel @@ -99,6 +99,12 @@ incompatible_flag( issue = "https://github.com/bazelbuild/rules_rust/issues/2324", ) +# A flag to control whether to link libstd dynamically. +bool_flag( + name = "experimental_link_std_dylib", + build_setting_default = False, +) + # A flag to remove the SYSROOT environment variable from `Rustc` actions. incompatible_flag( name = "incompatible_no_rustc_sysroot_env", diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index 9580d7cf..1d268ec0 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -14,6 +14,8 @@ load( "dedent", "dedup_expand_location", "find_cc_toolchain", + "is_exec_configuration", + "is_std_dylib", "make_static_lib_symlink", ) load("//rust/settings:incompatible.bzl", "IncompatibleFlagInfo") @@ -75,6 +77,13 @@ def _rust_stdlib_filegroup_impl(ctx): print("File partitioned: {}".format(f.basename)) fail("rust_toolchain couldn't properly partition rlibs in rust_std. Partitioned {} out of {} files. This is probably a bug in the rule implementation.".format(partitioned_files_len, len(dot_a_files))) + std_dylib = None + + for file in rust_std: + if is_std_dylib(file): + std_dylib = file + break + return [ DefaultInfo( files = depset(ctx.files.srcs), @@ -87,6 +96,7 @@ def _rust_stdlib_filegroup_impl(ctx): core_files = core_files, between_core_and_std_files = between_core_and_std_files, std_files = std_files, + std_dylib = std_dylib, test_files = test_files, memchr_files = memchr_files, alloc_files = alloc_files, @@ -237,14 +247,27 @@ def _make_libstd_and_allocator_ccinfo(ctx, rust_std, allocator_library, std = "s transitive = [memchr_inputs], order = "topological", ) - std_inputs = depset( - [ - _ltl(f, ctx, cc_toolchain, feature_configuration) - for f in rust_stdlib_info.std_files - ], - transitive = [between_core_and_std_inputs], - order = "topological", - ) + + if _experimental_link_std_dylib(ctx): + # std dylib has everything so that we do not need to include all std_files + std_inputs = depset( + [cc_common.create_library_to_link( + actions = ctx.actions, + feature_configuration = feature_configuration, + cc_toolchain = cc_toolchain, + dynamic_library = rust_stdlib_info.std_dylib, + )], + ) + else: + std_inputs = depset( + [ + _ltl(f, ctx, cc_toolchain, feature_configuration) + for f in rust_stdlib_info.std_files + ], + transitive = [between_core_and_std_inputs], + order = "topological", + ) + test_inputs = depset( [ _ltl(f, ctx, cc_toolchain, feature_configuration) @@ -454,6 +477,9 @@ def _generate_sysroot( sysroot_anchor = sysroot_anchor, ) +def _experimental_use_cc_common_link(ctx): + return ctx.attr.experimental_use_cc_common_link[BuildSettingInfo].value + def _rust_toolchain_impl(ctx): """The rust_toolchain implementation @@ -477,15 +503,14 @@ def _rust_toolchain_impl(ctx): pipelined_compilation = ctx.attr._pipelined_compilation[BuildSettingInfo].value no_std = ctx.attr._no_std[BuildSettingInfo].value - experimental_use_cc_common_link = ctx.attr.experimental_use_cc_common_link[BuildSettingInfo].value experimental_use_global_allocator = ctx.attr._experimental_use_global_allocator[BuildSettingInfo].value - if experimental_use_cc_common_link: + if _experimental_use_cc_common_link(ctx): if experimental_use_global_allocator and not ctx.attr.global_allocator_library: fail("rust_toolchain.experimental_use_cc_common_link with --@rules_rust//rust/settings:experimental_use_global_allocator " + "requires rust_toolchain.global_allocator_library to be set") if not ctx.attr.allocator_library: fail("rust_toolchain.experimental_use_cc_common_link requires rust_toolchain.allocator_library to be set") - if experimental_use_global_allocator and not experimental_use_cc_common_link: + if experimental_use_global_allocator and not _experimental_use_cc_common_link(ctx): fail( "Using @rules_rust//rust/settings:experimental_use_global_allocator requires" + "--@rules_rust//rust/settings:experimental_use_cc_common_link to be set", @@ -639,7 +664,8 @@ def _rust_toolchain_impl(ctx): _rename_first_party_crates = rename_first_party_crates, _third_party_dir = third_party_dir, _pipelined_compilation = pipelined_compilation, - _experimental_use_cc_common_link = experimental_use_cc_common_link, + _experimental_link_std_dylib = _experimental_link_std_dylib(ctx), + _experimental_use_cc_common_link = _experimental_use_cc_common_link(ctx), _experimental_use_global_allocator = experimental_use_global_allocator, _experimental_use_coverage_metadata_files = ctx.attr._experimental_use_coverage_metadata_files[BuildSettingInfo].value, _experimental_toolchain_generated_sysroot = ctx.attr._experimental_toolchain_generated_sysroot[IncompatibleFlagInfo].enabled, @@ -652,6 +678,11 @@ def _rust_toolchain_impl(ctx): make_variable_info, ] +def _experimental_link_std_dylib(ctx): + return not is_exec_configuration(ctx) and \ + ctx.attr.experimental_link_std_dylib[BuildSettingInfo].value and \ + ctx.attr.rust_std[rust_common.stdlib_info].std_dylib != None + rust_toolchain = rule( implementation = _rust_toolchain_impl, fragments = ["cpp"], @@ -702,6 +733,10 @@ rust_toolchain = rule( ), mandatory = True, ), + "experimental_link_std_dylib": attr.label( + default = Label("@rules_rust//rust/settings:experimental_link_std_dylib"), + doc = "Label to a boolean build setting that controls whether whether to link libstd dynamically.", + ), "experimental_use_cc_common_link": attr.label( default = Label("//rust/settings:experimental_use_cc_common_link"), doc = "Label to a boolean build setting that controls whether cc_common.link is used to link rust binaries.", diff --git a/test/link_std_dylib/BUILD b/test/link_std_dylib/BUILD new file mode 100644 index 00000000..1a92fd40 --- /dev/null +++ b/test/link_std_dylib/BUILD @@ -0,0 +1,3 @@ +load(":link_std_dylib_test.bzl", "link_std_dylib_test_suite") + +link_std_dylib_test_suite(name = "link_std_dylib_test_suite") diff --git a/test/link_std_dylib/lib.rs b/test/link_std_dylib/lib.rs new file mode 100644 index 00000000..734312b8 --- /dev/null +++ b/test/link_std_dylib/lib.rs @@ -0,0 +1,7 @@ +// Analysis test shouldn't need this file. +// This is a workaround until +// https://github.com/bazelbuild/rules_rust/issues/2499 +// is fixed +pub fn example_test_dep_fn() -> u32 { + 1 +} diff --git a/test/link_std_dylib/link_std_dylib_test.bzl b/test/link_std_dylib/link_std_dylib_test.bzl new file mode 100644 index 00000000..f1338086 --- /dev/null +++ b/test/link_std_dylib/link_std_dylib_test.bzl @@ -0,0 +1,118 @@ +"""Analysis tests for experimental_link_std_dylib flag""" + +load("@rules_cc//cc:defs.bzl", "CcInfo") +load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library") +load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite") + +# buildifier: disable=bzl-visibility +load("//rust/private:utils.bzl", "is_std_dylib") + +def _test_rust_binary_impl(env, targets): + env.expect.that_action(targets.default_binary.actions[0]) \ + .contains_none_of_flag_values([ + ("--codegen", "prefer-dynamic"), + ]) + + # Make sure with @rules_rust//rust/settings:experimental_link_std_dylib, + # the linker flags are set up correct so that the binary dynamically links + # the stdlib + env.expect.that_action(targets.binary_with_std_dylib.actions[0]) \ + .contains_flag_values([ + ("--codegen", "prefer-dynamic"), + ]) + +def _test_rust_binary(name): + rust_binary( + name = name + "_rust_binary", + srcs = ["main.rs"], + edition = "2021", + tags = ["manual"], + ) + + analysis_test( + name = name, + impl = _test_rust_binary_impl, + targets = { + "binary_with_std_dylib": name + "_rust_binary", + "default_binary": name + "_rust_binary", + }, + attrs = { + "binary_with_std_dylib": { + "@config_settings": { + str(Label("@rules_rust//rust/settings:experimental_link_std_dylib")): True, + }, + }, + }, + ) + +def _export_static_stdlibs_in_cc_info(target): + linker_inputs = target[CcInfo].linking_context.linker_inputs + for linker_input in linker_inputs.to_list(): + for library in linker_input.libraries: + if hasattr(library, "pic_static_library") and library.pic_static_library != None: + basename = library.pic_static_library.basename + if basename.startswith("libstd") and basename.endswith(".a"): + return True + return False + +def _export_libstd_dylib_in_cc_info(target): + linker_inputs = target[CcInfo].linking_context.linker_inputs + for linker_input in linker_inputs.to_list(): + for library in linker_input.libraries: + if hasattr(library, "dynamic_library") and library.dynamic_library != None: + if is_std_dylib(library.dynamic_library): + return True + return False + +def _test_rust_library_impl(env, targets): + # By default, rust_library exports static stdlibs to downstream shared + # and binary targets to statically link + env.expect \ + .that_bool(_export_static_stdlibs_in_cc_info(targets.default_rlib)) \ + .equals(True) + env.expect \ + .that_bool(_export_libstd_dylib_in_cc_info(targets.default_rlib)) \ + .equals(False) + + # With @rules_rust//rust/settings:experimental_link_std_dylib + # rust_library exports dylib std and does not export static stdlibs to + # downstream shared and binary targets to dynamically link + env.expect \ + .that_bool(_export_static_stdlibs_in_cc_info(targets.rlib_with_std_dylib)) \ + .equals(False) + env.expect \ + .that_bool(_export_libstd_dylib_in_cc_info(targets.rlib_with_std_dylib)) \ + .equals(True) + +def _test_rust_library(name): + rust_library( + name = name + "_rust_library", + srcs = ["lib.rs"], + edition = "2021", + tags = ["manual"], + ) + + analysis_test( + name = name, + impl = _test_rust_library_impl, + targets = { + "default_rlib": name + "_rust_library", + "rlib_with_std_dylib": name + "_rust_library", + }, + attrs = { + "rlib_with_std_dylib": { + "@config_settings": { + str(Label("@rules_rust//rust/settings:experimental_link_std_dylib")): True, + }, + }, + }, + ) + +def link_std_dylib_test_suite(name): + test_suite( + name = name, + tests = [ + _test_rust_binary, + _test_rust_library, + ], + ) diff --git a/test/link_std_dylib/main.rs b/test/link_std_dylib/main.rs new file mode 100644 index 00000000..c5a415d2 --- /dev/null +++ b/test/link_std_dylib/main.rs @@ -0,0 +1,7 @@ +// Analysis test shouldn't need this file. +// This is a workaround until +// https://github.com/bazelbuild/rules_rust/issues/2499 +// is fixed +fn main() { + println!("Hello world"); +} |