aboutsummaryrefslogtreecommitdiffstats
path: root/community/rust/musl-fix-static-linking.patch
diff options
context:
space:
mode:
authorJakub Jirutka <jakub@jirutka.cz>2017-05-01 00:43:19 +0200
committerJakub Jirutka <jakub@jirutka.cz>2017-05-01 00:43:19 +0200
commit41489596392977197d046ca034685664a3f4afa4 (patch)
treeef791ac83fd7635db59db40e12beb20a66ada3bd /community/rust/musl-fix-static-linking.patch
parentabfa07f26ff2837922903586b15e137b67b43219 (diff)
community/rust: move from testing
Diffstat (limited to 'community/rust/musl-fix-static-linking.patch')
-rw-r--r--community/rust/musl-fix-static-linking.patch200
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 00000000000..85de05e542f
--- /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,-)");
+ }
+ }
+