diff options
author | Jakub Jirutka <jakub@jirutka.cz> | 2017-05-01 00:43:19 +0200 |
---|---|---|
committer | Jakub Jirutka <jakub@jirutka.cz> | 2017-05-01 00:43:19 +0200 |
commit | 41489596392977197d046ca034685664a3f4afa4 (patch) | |
tree | ef791ac83fd7635db59db40e12beb20a66ada3bd /community/rust/musl-fix-static-linking.patch | |
parent | abfa07f26ff2837922903586b15e137b67b43219 (diff) | |
download | aports-41489596392977197d046ca034685664a3f4afa4.tar.bz2 aports-41489596392977197d046ca034685664a3f4afa4.tar.xz |
community/rust: move from testing
Diffstat (limited to 'community/rust/musl-fix-static-linking.patch')
-rw-r--r-- | community/rust/musl-fix-static-linking.patch | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/community/rust/musl-fix-static-linking.patch b/community/rust/musl-fix-static-linking.patch new file mode 100644 index 0000000000..85de05e542 --- /dev/null +++ b/community/rust/musl-fix-static-linking.patch @@ -0,0 +1,200 @@ +From: Shiz <hi@shiz.me> +Date: Fri, 21 Apr 2017 01:04:46 +0200 +Subject: [PATCH] Support fully static linking on *nix targets + +This patch adds support for full static linking on *nix targets. + +It adds `Session::fully_static()` to determine whether full static linking +should be utilised. By default, this is the case if the target is not +MSVC-like and the `crt-static` target feature is requested, as for *nix +targets this implies a fully static result. In the future, a target feature +or other compile option could perhaps be added to have the invoker decide +this more flexibly at run-time. + +It also adds the proper linker argument for static result objects to `Linker` +and implements them for `GnuLinker` and `MsvcLinker`. Additionally, when +statically linking, all the objects are linked in a group (-Wl,-( and -Wl,-) +on GNU-compatible linkers) to resolve dependency and order issues that may +normally arise. For `MsvcLinker`, this is a no-op as it already exhibits +this behavior by default. + +Finally, if no linking preference is given for native libraries +(`NativeLibraryKind::NativeUnknown`), they are linked statically if full +static linking is requested, instead of dynamically as before. + +--- a/src/librustc/session/mod.rs ++++ b/src/librustc/session/mod.rs +@@ -409,6 +409,11 @@ + return crt_static; + } + ++ pub fn fully_static(&self) -> bool { ++ // TODO: figure out better semantics for this, possibly a target option? ++ return self.crt_static() && !self.target.target.options.is_like_msvc ++ } ++ + pub fn must_not_eliminate_frame_pointers(&self) -> bool { + self.opts.debuginfo != DebugInfoLevel::NoDebugInfo || + !self.target.target.options.eliminate_frame_pointer +--- a/src/librustc_trans/back/link.rs ++++ b/src/librustc_trans/back/link.rs +@@ -239,8 +239,8 @@ + /// Checks if target supports crate_type as output + pub fn invalid_output_for_target(sess: &Session, + crate_type: config::CrateType) -> bool { +- match (sess.target.target.options.dynamic_linking, +- sess.target.target.options.executables, crate_type) { ++ let dynamic_linking = sess.target.target.options.dynamic_linking && !sess.fully_static(); ++ match (dynamic_linking, sess.target.target.options.executables, crate_type) { + (false, _, config::CrateTypeCdylib) | + (false, _, config::CrateTypeProcMacro) | + (false, _, config::CrateTypeDylib) => true, +@@ -840,6 +840,10 @@ + + let used_link_args = sess.cstore.used_link_args(); + ++ if crate_type == config::CrateTypeExecutable && sess.fully_static() { ++ cmd.static_executable(); ++ } ++ + if crate_type == config::CrateTypeExecutable && + t.options.position_independent_executables { + let empty_vec = Vec::new(); +@@ -870,15 +870,8 @@ + cmd.no_default_libraries(); + } + +- // Take careful note of the ordering of the arguments we pass to the linker +- // here. Linkers will assume that things on the left depend on things to the +- // right. Things on the right cannot depend on things on the left. This is +- // all formally implemented in terms of resolving symbols (libs on the right +- // resolve unknown symbols of libs on the left, but not vice versa). ++ // We have organized the arguments we pass to the linker as such: + // +- // For this reason, we have organized the arguments we pass to the linker as +- // such: +- // + // 1. The local object that LLVM just generated + // 2. Local native libraries + // 3. Upstream rust libraries +--- a/src/librustc_trans/back/link.rs ++++ b/src/librustc_trans/back/link.rs +@@ -951,17 +951,12 @@ + // list can't depend on items higher up in the list. For example nothing can + // depend on what we just generated (e.g. that'd be a circular dependency). + // Upstream rust libraries are not allowed to depend on our local native +- // libraries as that would violate the structure of the DAG, in that +- // scenario they are required to link to them as well in a shared fashion. +- // +- // Note that upstream rust libraries may contain native dependencies as +- // well, but they also can't depend on what we just started to add to the +- // link line. And finally upstream native libraries can't depend on anything +- // in this DAG so far because they're only dylibs and dylibs can only depend +- // on other dylibs (e.g. other native deps). ++ // libraries as that would violate the structure of the DAG. ++ cmd.start_group(); + add_local_native_libraries(cmd, sess); + add_upstream_rust_crates(cmd, sess, crate_type, tmpdir); + add_upstream_native_libraries(cmd, sess, crate_type); ++ cmd.end_group(); + + // # Telling the linker what we're doing + +@@ -983,11 +983,14 @@ + cmd.link_whole_staticlib(&l.name.as_str(), &search_path); + } + +- cmd.hint_dynamic(); ++ let fully_static = sess.fully_static(); ++ if !fully_static { ++ cmd.hint_dynamic(); ++ } + + for lib in others { + match lib.kind { +- NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()), ++ NativeLibraryKind::NativeUnknown => if fully_static { cmd.link_staticlib(&lib.name.as_str()) } else { cmd.link_dylib(&lib.name.as_str()) }, + NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()), + NativeLibraryKind::NativeStatic => bug!(), + } +--- a/src/librustc_trans/back/linker.rs ++++ b/src/librustc_trans/back/linker.rs +@@ -82,6 +82,7 @@ + fn add_object(&mut self, path: &Path); + fn gc_sections(&mut self, keep_metadata: bool); + fn position_independent_executable(&mut self); ++ fn static_executable(&mut self); + fn optimize(&mut self); + fn debuginfo(&mut self); + fn no_default_libraries(&mut self); +@@ -93,6 +93,8 @@ + fn no_whole_archives(&mut self); + fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType); + fn subsystem(&mut self, subsystem: &str); ++ fn start_group(&mut self); ++ fn end_group(&mut self); + } + + pub struct GnuLinker<'a> { +@@ -116,6 +117,9 @@ + fn output_filename(&mut self, path: &Path) { self.cmd.arg("-o").arg(path); } + fn add_object(&mut self, path: &Path) { self.cmd.arg(path); } + fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); } ++ fn static_executable(&mut self) { self.cmd.arg("-static"); } ++ fn start_group(&mut self) { self.cmd.arg("-Wl,-("); } ++ fn end_group(&mut self) { self.cmd.arg("-Wl,-)"); } + fn args(&mut self, args: &[String]) { self.cmd.args(args); } + + fn link_rust_dylib(&mut self, lib: &str, _path: &Path) { +@@ -359,6 +361,10 @@ + + fn position_independent_executable(&mut self) { + // noop ++ } ++ ++ fn static_executable(&mut self) { ++ self.cmd.arg("-MT"); + } + + fn no_default_libraries(&mut self) { +@@ -484,6 +488,14 @@ + if subsystem == "windows" { + self.cmd.arg("/ENTRY:mainCRTStartup"); + } ++ } ++ ++ fn start_group(&mut self) { ++ // Not needed ++ } ++ ++ fn end_group(&mut self) { ++ // Not needed + } + } + +@@ -562,6 +562,10 @@ + // noop + } + ++ fn static_executable(&mut self) { ++ // noop ++ } ++ + fn args(&mut self, args: &[String]) { + self.cmd.args(args); + } +@@ -657,6 +661,14 @@ + + fn subsystem(&mut self, _subsystem: &str) { + // noop ++ } ++ ++ fn start_group(&mut self) { ++ self.cmd.arg("-Wl,-("); ++ } ++ ++ fn end_group(&mut self) { ++ self.cmd.arg("-Wl,-)"); + } + } + |