-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rust: allow linking with dynamic libstd #14224
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2116,13 +2116,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 == 'staticlib' \ | ||
and self.get_target_option(target, 'rust_dynamic_std'): | ||
# 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') | ||
|
||
if target.rust_crate_type in {'dylib', 'proc-macro'} or has_rust_shared_deps \ | ||
or self.get_target_option(target, '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 \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's kinda confusing that it's just checking if the target is a rust shared lib at all ( |
||
or self.get_target_option(target, 'rust_dynamic_std'): | ||
args += self.get_build_rpath_args(target, rustc) | ||
|
||
proc_macro_dylib_path = None | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -203,15 +203,15 @@ def get_optimization_args(self, optimization_level: str) -> T.List[str]: | |
def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, | ||
rpath_paths: T.Tuple[str, ...], build_rpath: str, | ||
install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: | ||
args, to_remove = super().build_rpath_args(env, build_dir, from_dir, rpath_paths, | ||
build_rpath, install_rpath) | ||
# add rustc's sysroot to account for rustup installations | ||
args, to_remove = self.linker.build_rpath_args(env, build_dir, from_dir, rpath_paths, | ||
build_rpath, install_rpath, | ||
[self.get_target_libdir()]) | ||
|
||
# ... but then add rustc's sysroot to account for rustup | ||
# installations | ||
rustc_rpath_args = [] | ||
for arg in args: | ||
rustc_rpath_args.append('-C') | ||
rustc_rpath_args.append(f'link-arg={arg}:{self.get_target_libdir()}') | ||
rustc_rpath_args.append('link-arg=' + arg) | ||
Comment on lines
212
to
+214
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. quasi related, btw: meson currently doesn't have a unified way to specifically pass link args for rust, only these ad-hoc spots #13537 |
||
return rustc_rpath_args, to_remove | ||
|
||
def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], | ||
|
@@ -244,6 +244,12 @@ def get_options(self) -> MutableKeyedOptionDictType: | |
'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]: | ||
|
This comment was marked as resolved.
Sorry, something went wrong.