aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-02-04 17:53:44 +0100
committerDylan Baker <dylan@pnwbakers.com>2025-07-18 09:42:56 -0700
commitff963e657cf1151cf002efc123563cb40dabab11 (patch)
tree99fde408ecc91fe6887a093e4a892f5a86cdd381
parent08798850c1c2798e55fe7099cbff231e48d52e42 (diff)
downloadmeson-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.md1
-rw-r--r--docs/markdown/snippets/rust-dynamic-std.md7
-rw-r--r--mesonbuild/backend/ninjabackend.py22
-rw-r--r--mesonbuild/compilers/rust.py6
-rw-r--r--test cases/rust/1 basic/meson.build6
-rw-r--r--test cases/rust/1 basic/test.json4
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"}
]
}