Skip to content

Commit 4e48662

Browse files
committed
rust: add rust_dynamic_std option
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 mesonbuild#8828 and mesonbuild#14215. Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 008dfb3 commit 4e48662

File tree

6 files changed

+39
-3
lines changed

6 files changed

+39
-3
lines changed

docs/markdown/Builtin-options.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ or compiler being used:
290290
| cpp_thread_count | 4 | integer value ≥ 0 | Number of threads to use with emcc when using threads |
291291
| cpp_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against |
292292
| fortran_std | none | [none, legacy, f95, f2003, f2008, f2018] | Fortran language standard to use |
293+
| rust_dynamic_std | false | true, false | Whether to link dynamically to the Rust standard library *(Added in 1.8.0)* |
293294
| cuda_ccbindir | | filesystem path | CUDA non-default toolchain directory to use (-ccbin) *(Added in 0.57.1)* |
294295

295296
The default values of `c_winlibs` and `cpp_winlibs` are in
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## New experimental option `rust_dynamic_std`
2+
3+
A new option `rust_dynamic_std` can be used to link Rust programs so
4+
that they use a dynamic library for the Rust `libstd`.
5+
6+
Right now, C ABI crates (corresponding to Rust crate types `cdylib` and
7+
`staticlib`) cannot be produced if `rust_dynamic_std` is true, but this
8+
may change in the future.

mesonbuild/backend/ninjabackend.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,13 +2116,26 @@ def _link_library(libname: str, static: bool, bundle: bool = False):
21162116
and dep.rust_crate_type == 'dylib'
21172117
for dep in target_deps)
21182118

2119-
if target.rust_crate_type in {'dylib', 'proc-macro'} or has_rust_shared_deps:
2119+
if target.rust_crate_type in {'cdylib', 'staticlib'} \
2120+
and self.get_target_option(target, 'rust_dynamic_std'):
2121+
# cdylib and staticlib crates always include a copy of the Rust
2122+
# libstd, therefore it is not possible to also link it dynamically.
2123+
# The options to avoid this (-Z staticlib-allow-rdylib-deps and
2124+
# -Z staticlib-prefer-dynamic) are not yet stable; alternatively,
2125+
# one could use "--emit obj" (implemented in the pull request at
2126+
# https://github.com/mesonbuild/meson/pull/11213) or "--emit rlib"
2127+
# (officially not recommended for linking with C programs).
2128+
raise MesonException('rust_dynamic_std does not support cdylib and staticlib crates yet')
2129+
2130+
if target.rust_crate_type in {'dylib', 'proc-macro'} or has_rust_shared_deps \
2131+
or self.get_target_option(target, 'rust_dynamic_std'):
21202132
# add prefer-dynamic if any of the Rust libraries we link
21212133
# against are dynamic or this is a dynamic library itself,
21222134
# otherwise we'll end up with multiple implementations of libstd.
21232135
args += ['-C', 'prefer-dynamic']
21242136

2125-
if isinstance(target, build.SharedLibrary) or has_shared_deps:
2137+
if isinstance(target, build.SharedLibrary) or has_shared_deps \
2138+
or self.get_target_option(target, 'rust_dynamic_std'):
21262139
args += self.get_build_rpath_args(target, rustc)
21272140

21282141
proc_macro_dylib_path = None

mesonbuild/compilers/rust.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,12 @@ def get_options(self) -> MutableKeyedOptionDictType:
244244
'none',
245245
choices=['none', '2015', '2018', '2021', '2024'])
246246

247+
key = self.form_compileropt_key('dynamic_std')
248+
opts[key] = options.UserBooleanOption(
249+
self.make_option_name(key),
250+
'Whether to link Rust programs to a dynamic libstd',
251+
False)
252+
247253
return opts
248254

249255
def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]:

test cases/rust/1 basic/meson.build

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ e = executable('rust-program', 'prog.rs',
66
)
77
test('rusttest', e)
88

9+
e = executable('rust-dynamic', 'prog.rs',
10+
override_options: {'rust_dynamic_std': true},
11+
install : true
12+
)
13+
test('rusttest-dynamic', e)
14+
915
subdir('subdir')
1016

1117
# this should fail due to debug_assert

test cases/rust/1 basic/test.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
{"type": "exe", "file": "usr/bin/rust-program"},
44
{"type": "pdb", "file": "usr/bin/rust-program"},
55
{"type": "exe", "file": "usr/bin/rust-program2"},
6-
{"type": "pdb", "file": "usr/bin/rust-program2"}
6+
{"type": "pdb", "file": "usr/bin/rust-program2"},
7+
{"type": "exe", "file": "usr/bin/rust-dynamic"},
8+
{"type": "pdb", "file": "usr/bin/rust-dynamic"}
79
]
810
}

0 commit comments

Comments
 (0)