diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2025-02-04 17:53:44 +0100 |
---|---|---|
committer | Dylan Baker <dylan@pnwbakers.com> | 2025-07-18 09:42:56 -0700 |
commit | ff963e657cf1151cf002efc123563cb40dabab11 (patch) | |
tree | 99fde408ecc91fe6887a093e4a892f5a86cdd381 | |
parent | 08798850c1c2798e55fe7099cbff231e48d52e42 (diff) | |
download | meson-ff963e657cf1151cf002efc123563cb40dabab11.zip meson-ff963e657cf1151cf002efc123563cb40dabab11.tar.gz meson-ff963e657cf1151cf002efc123563cb40dabab11.tar.bz2 |
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
https://github.com/mesonbuild/meson/issues/8828 and
https://github.com/mesonbuild/meson/issues/14215.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | docs/markdown/Builtin-options.md | 1 | ||||
-rw-r--r-- | docs/markdown/snippets/rust-dynamic-std.md | 7 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 22 | ||||
-rw-r--r-- | mesonbuild/compilers/rust.py | 6 | ||||
-rw-r--r-- | test cases/rust/1 basic/meson.build | 6 | ||||
-rw-r--r-- | test cases/rust/1 basic/test.json | 4 |
6 files changed, 41 insertions, 5 deletions
diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md index 7a4d7f0..c23eaae 100644 --- a/docs/markdown/Builtin-options.md +++ b/docs/markdown/Builtin-options.md @@ -303,6 +303,7 @@ or compiler being used: | cpp_thread_count | 4 | integer value ≥ 0 | Number of threads to use with emcc when using threads | | cpp_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against | | fortran_std | none | [none, legacy, f95, f2003, f2008, f2018] | Fortran language standard to use | +| rust_dynamic_std | false | true, false | Whether to link dynamically to the Rust standard library *(Added in 1.9.0)* | | cuda_ccbindir | | filesystem path | CUDA non-default toolchain directory to use (-ccbin) *(Added in 0.57.1)* | The default values of `c_winlibs` and `cpp_winlibs` are in diff --git a/docs/markdown/snippets/rust-dynamic-std.md b/docs/markdown/snippets/rust-dynamic-std.md new file mode 100644 index 0000000..ac4e8a7 --- /dev/null +++ b/docs/markdown/snippets/rust-dynamic-std.md @@ -0,0 +1,7 @@ +## 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, `staticlib` crates cannot be produced if `rust_dynamic_std` is +true, but this may change in the future. diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 10f77e7..bca6876 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2124,13 +2124,27 @@ class NinjaBackend(backends.Backend): 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: - # add prefer-dynamic if any of the Rust libraries we link + if target.rust_crate_type in {'dylib', 'proc-macro'}: + # also 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. + has_rust_shared_deps = True + elif self.get_target_option(target, 'rust_dynamic_std'): + if target.rust_crate_type == 'staticlib': + # 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 staticlib crates yet') + # want libstd as a shared dep + has_rust_shared_deps = True + + if has_rust_shared_deps: args += ['-C', 'prefer-dynamic'] - - if isinstance(target, build.SharedLibrary) or has_shared_deps: + if has_shared_deps or has_rust_shared_deps: args += self.get_build_rpath_args(target, rustc) return deps, fortran_order_deps, project_deps, args diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 38e7055..b72f6b0 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -241,6 +241,12 @@ class RustCompiler(Compiler): 'none', choices=['none', '2015', '2018', '2021', '2024']) + key = self.form_compileropt_key('dynamic_std') + opts[key] = options.UserBooleanOption( + self.make_option_name(key), + 'Whether to link Rust build targets to a dynamic libstd', + False) + return opts def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]: diff --git a/test cases/rust/1 basic/meson.build b/test cases/rust/1 basic/meson.build index f422beb..00bd212 100644 --- a/test cases/rust/1 basic/meson.build +++ b/test cases/rust/1 basic/meson.build @@ -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 diff --git a/test cases/rust/1 basic/test.json b/test cases/rust/1 basic/test.json index 95e6ced..3cbdefa 100644 --- a/test cases/rust/1 basic/test.json +++ b/test cases/rust/1 basic/test.json @@ -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"} ] } |