Skip to content

Commit

Permalink
rust: add rust_dynamic_std option
Browse files Browse the repository at this point in the history
As an initial implementation, simply adding "-C prefer-dynamic" works
for binary crates (as well as dylib and proc-macro that already used it).
In the future this could be extended to other crate types.  For more
information see the comment in the changed file, as well as
#8828 and
#14215.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
bonzini committed Feb 5, 2025
1 parent ba7ae7c commit df1552f
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 3 deletions.
8 changes: 8 additions & 0 deletions docs/markdown/snippets/rust-dynamic-std.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## New experimental option `rust_dynamic_std`

A new option `rust_dynamic_std` can be used to link Rust programs so
that they use a dynamic library for the Rust `libstd`.

Right now, C ABI crates (corresponding to Rust crate types `cdylib` and
`staticlib`) cannot be produced if `rust_dynamic_std` is true, but this
may change in the future.
17 changes: 15 additions & 2 deletions mesonbuild/backend/ninjabackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -2115,13 +2115,26 @@ def _link_library(libname: str, static: bool, bundle: bool = False):
and dep.rust_crate_type == 'dylib'
for dep in target_deps)

if target.rust_crate_type in {'dylib', 'proc-macro'} or has_rust_shared_deps:
if target.rust_crate_type in {'cdylib', 'staticlib'} \
and target.get_option(OptionKey('rust_dynamic_std')):
# cdylib and staticlib crates always include a copy of the Rust
# libstd, therefore it is not possible to also link it dynamically.
# The options to avoid this (-Z staticlib-allow-rdylib-deps and
# -Z staticlib-prefer-dynamic) are not yet stable; alternatively,
# one could use "--emit obj" (implemented in the pull request at
# https://github.com/mesonbuild/meson/pull/11213) or "--emit rlib"
# (officially not recommended for linking with C programs).
raise MesonException('rust_dynamic_std does not support cdylib and staticlib crates yet')

if target.rust_crate_type in {'dylib', 'proc-macro'} or has_rust_shared_deps \
or target.get_option(OptionKey('rust_dynamic_std')):
# add prefer-dynamic if any of the Rust libraries we link
# against are dynamic or this is a dynamic library itself,
# otherwise we'll end up with multiple implementations of libstd.
args += ['-C', 'prefer-dynamic']

if isinstance(target, build.SharedLibrary) or has_shared_deps:
if isinstance(target, build.SharedLibrary) or has_shared_deps \
or target.get_option(OptionKey('rust_dynamic_std')):
args += self.get_build_rpath_args(target, rustc)

proc_macro_dylib_path = None
Expand Down
1 change: 1 addition & 0 deletions mesonbuild/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ def add_to_argparse(self, name: str, parser: argparse.ArgumentParser, help_suffi
(OptionKey('layout'), BuiltinOption(UserComboOption, 'Build directory layout', 'mirror', choices=['mirror', 'flat'])),
(OptionKey('optimization'), BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['plain', '0', 'g', '1', '2', '3', 's'])),
(OptionKey('prefer_static'), BuiltinOption(UserBooleanOption, 'Whether to try static linking before shared linking', False)),
(OptionKey('rust_dynamic_std'), BuiltinOption(UserBooleanOption, 'Whether to link Rust programs to a dynamic libstd', False)),
(OptionKey('stdsplit'), BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
(OptionKey('strip'), BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
(OptionKey('unity'), BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects'])),
Expand Down
6 changes: 6 additions & 0 deletions test cases/rust/1 basic/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ e = executable('rust-program', 'prog.rs',
)
test('rusttest', e)

e = executable('rust-dynamic', 'prog.rs',
override_options: {'rust_dynamic_std': true},
install : true
)
test('rusttest-dynamic', e)

subdir('subdir')

# this should fail due to debug_assert
Expand Down
4 changes: 3 additions & 1 deletion test cases/rust/1 basic/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
{"type": "exe", "file": "usr/bin/rust-program"},
{"type": "pdb", "file": "usr/bin/rust-program"},
{"type": "exe", "file": "usr/bin/rust-program2"},
{"type": "pdb", "file": "usr/bin/rust-program2"}
{"type": "pdb", "file": "usr/bin/rust-program2"},
{"type": "exe", "file": "usr/bin/rust-dynamic"},
{"type": "pdb", "file": "usr/bin/rust-dynamic"}
]
}

0 comments on commit df1552f

Please sign in to comment.