about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonathan Turner <jonathandturner@users.noreply.github.com>2016-09-26 17:29:47 -0700
committerGitHub <noreply@github.com>2016-09-26 17:29:47 -0700
commitc816720242ac75fb4131102e4365baef20963028 (patch)
treea6d4e9fd696f1ffbcbfa57c9db2c2ebc5c9a22bc
parente3ffde855a8c76dab84d5ca2e5c045538e52869a (diff)
parent2f71fa7150f9d6d9292b0a2c5f2beaf43d2058d3 (diff)
downloadrust-c816720242ac75fb4131102e4365baef20963028.tar.gz
rust-c816720242ac75fb4131102e4365baef20963028.zip
Rollup merge of #36574 - japaric:link-arg, r=alexcrichton
rustc: implement -C link-arg

this flag lets you pass a _single_ argument to the linker but can be
used _repeatedly_. For example, instead of using:

```
rustc -C link-args='-l bar' (..)
```

you could write

```
rustc -C link-arg='-l' -C link-arg='bar' (..)
```

This new flag can be used with RUSTFLAGS where `-C link-args` has
problems with "nested" spaces:

```
RUSTFLAGS='-C link-args="-Tlayout.ld -nostartfiles"'
```

This passes three arguments to rustc: `-C` `link-args="-Tlayout.ld` and
`-nostartfiles"` to `rustc`. That's not what we meant. But this does
what we want:

```
RUSTFLAGS='-C link-arg=-Tlayout.ld -C link-arg=-nostartfiles`
```

cc rust-lang/rfcs#1509

r? @alexcrichton
cc @Zoxc

This needs a test. Any suggestion?
-rw-r--r--src/librustc/session/config.rs10
-rw-r--r--src/librustc_trans/back/link.rs4
-rw-r--r--src/test/run-make/link-arg/Makefile5
-rw-r--r--src/test/run-make/link-arg/empty.rs11
4 files changed, 29 insertions, 1 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 2e01ec9b0a7..5907bdd2f59 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -606,6 +606,7 @@ macro_rules! options {
         pub const parse_opt_bool: Option<&'static str> =
             Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
         pub const parse_string: Option<&'static str> = Some("a string");
+        pub const parse_string_push: Option<&'static str> = Some("a string");
         pub const parse_opt_string: Option<&'static str> = Some("a string");
         pub const parse_list: Option<&'static str> = Some("a space-separated list of strings");
         pub const parse_opt_list: Option<&'static str> = Some("a space-separated list of strings");
@@ -668,6 +669,13 @@ macro_rules! options {
             }
         }
 
+        fn parse_string_push(slot: &mut Vec<String>, v: Option<&str>) -> bool {
+            match v {
+                Some(s) => { slot.push(s.to_string()); true },
+                None => false,
+            }
+        }
+
         fn parse_list(slot: &mut Vec<String>, v: Option<&str>)
                       -> bool {
             match v {
@@ -743,6 +751,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
         "tool to assemble archives with"),
     linker: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "system linker to link outputs with"),
+    link_arg: Vec<String> = (vec![], parse_string_push, [UNTRACKED],
+        "a single extra argument to pass to the linker (can be used several times)"),
     link_args: Option<Vec<String>> = (None, parse_opt_list, [UNTRACKED],
         "extra arguments to pass to the linker (space separated)"),
     link_dead_code: bool = (false, parse_bool, [UNTRACKED],
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 201e1e5f2ec..5dab82dbc7a 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -754,7 +754,8 @@ fn link_args(cmd: &mut Linker,
         let empty_vec = Vec::new();
         let empty_str = String::new();
         let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
-        let mut args = args.iter().chain(used_link_args.iter());
+        let more_args = &sess.opts.cg.link_arg;
+        let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter());
         let relocation_model = sess.opts.cg.relocation_model.as_ref()
                                    .unwrap_or(&empty_str);
         if (t.options.relocation_model == "pic" || *relocation_model == "pic")
@@ -844,6 +845,7 @@ fn link_args(cmd: &mut Linker,
     if let Some(ref args) = sess.opts.cg.link_args {
         cmd.args(args);
     }
+    cmd.args(&sess.opts.cg.link_arg);
     cmd.args(&used_link_args);
 }
 
diff --git a/src/test/run-make/link-arg/Makefile b/src/test/run-make/link-arg/Makefile
new file mode 100644
index 00000000000..0ee239af0fa
--- /dev/null
+++ b/src/test/run-make/link-arg/Makefile
@@ -0,0 +1,5 @@
+-include ../tools.mk
+RUSTC_FLAGS = -C link-arg="-lfoo" -C link-arg="-lbar" -Z print-link-args
+
+all:
+	$(RUSTC) $(RUSTC_FLAGS) empty.rs | grep lfoo | grep lbar
diff --git a/src/test/run-make/link-arg/empty.rs b/src/test/run-make/link-arg/empty.rs
new file mode 100644
index 00000000000..2b76fb24e5f
--- /dev/null
+++ b/src/test/run-make/link-arg/empty.rs
@@ -0,0 +1,11 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() { }