rollup merge of #18470 : alexcrichton/dash-l
This commit is contained in:
commit
6478fcfafe
16 changed files with 234 additions and 40 deletions
|
|
@ -20,6 +20,7 @@ use back::write;
|
|||
use back::target_strs;
|
||||
use back::{arm, x86, x86_64, mips, mipsel};
|
||||
use lint;
|
||||
use metadata::cstore;
|
||||
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
|
|
@ -78,6 +79,7 @@ pub struct Options {
|
|||
// parsed code. It remains mutable in case its replacements wants to use
|
||||
// this.
|
||||
pub addl_lib_search_paths: RefCell<Vec<Path>>,
|
||||
pub libs: Vec<(String, cstore::NativeLibaryKind)>,
|
||||
pub maybe_sysroot: Option<Path>,
|
||||
pub target_triple: String,
|
||||
// User-specified cfg meta items. The compiler itself will add additional
|
||||
|
|
@ -130,6 +132,7 @@ pub fn basic_options() -> Options {
|
|||
externs: HashMap::new(),
|
||||
crate_name: None,
|
||||
alt_std_name: None,
|
||||
libs: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -575,6 +578,10 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
|
|||
optflag("h", "help", "Display this message"),
|
||||
optmulti("", "cfg", "Configure the compilation environment", "SPEC"),
|
||||
optmulti("L", "", "Add a directory to the library search path", "PATH"),
|
||||
optmulti("l", "", "Link the generated crate(s) to the specified native
|
||||
library NAME. The optional KIND can be one of,
|
||||
static, dylib, or framework. If omitted, dylib is
|
||||
assumed.", "NAME[:KIND]"),
|
||||
optmulti("", "crate-type", "Comma separated list of types of crates
|
||||
for the compiler to emit",
|
||||
"[bin|lib|rlib|dylib|staticlib]"),
|
||||
|
|
@ -767,6 +774,23 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
Path::new(s.as_slice())
|
||||
}).collect();
|
||||
|
||||
let libs = matches.opt_strs("l").into_iter().map(|s| {
|
||||
let mut parts = s.as_slice().rsplitn(1, ':');
|
||||
let kind = parts.next().unwrap();
|
||||
let (name, kind) = match (parts.next(), kind) {
|
||||
(None, name) |
|
||||
(Some(name), "dylib") => (name, cstore::NativeUnknown),
|
||||
(Some(name), "framework") => (name, cstore::NativeFramework),
|
||||
(Some(name), "static") => (name, cstore::NativeStatic),
|
||||
(_, s) => {
|
||||
early_error(format!("unknown library kind `{}`, expected \
|
||||
one of dylib, framework, or static",
|
||||
s).as_slice());
|
||||
}
|
||||
};
|
||||
(name.to_string(), kind)
|
||||
}).collect();
|
||||
|
||||
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
|
||||
let test = matches.opt_present("test");
|
||||
let write_dependency_info = (matches.opt_present("dep-info"),
|
||||
|
|
@ -843,7 +867,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
color: color,
|
||||
externs: externs,
|
||||
crate_name: crate_name,
|
||||
alt_std_name: None
|
||||
alt_std_name: None,
|
||||
libs: libs,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,11 @@ pub fn read_crates(sess: &Session,
|
|||
visit_crate(&e, krate);
|
||||
visit::walk_crate(&mut e, krate);
|
||||
dump_crates(&sess.cstore);
|
||||
warn_if_multiple_versions(sess.diagnostic(), &sess.cstore)
|
||||
warn_if_multiple_versions(sess.diagnostic(), &sess.cstore);
|
||||
|
||||
for &(ref name, kind) in sess.opts.libs.iter() {
|
||||
register_native_lib(sess, None, name.clone(), kind);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'v> visit::Visitor<'v> for Env<'a> {
|
||||
|
|
@ -233,14 +237,7 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
|||
Some(k) => {
|
||||
if k.equiv(&("static")) {
|
||||
cstore::NativeStatic
|
||||
} else if (e.sess.targ_cfg.os == abi::OsMacos ||
|
||||
e.sess.targ_cfg.os == abi::OsiOS) &&
|
||||
k.equiv(&("framework")) {
|
||||
cstore::NativeFramework
|
||||
} else if k.equiv(&("framework")) {
|
||||
e.sess.span_err(m.span,
|
||||
"native frameworks are only available \
|
||||
on OSX targets");
|
||||
cstore::NativeUnknown
|
||||
} else {
|
||||
e.sess.span_err(m.span,
|
||||
|
|
@ -263,15 +260,8 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
|||
InternedString::new("foo")
|
||||
}
|
||||
};
|
||||
if n.get().is_empty() {
|
||||
e.sess.span_err(m.span,
|
||||
"#[link(name = \"\")] given with \
|
||||
empty name");
|
||||
} else {
|
||||
e.sess
|
||||
.cstore
|
||||
.add_used_library(n.get().to_string(), kind);
|
||||
}
|
||||
register_native_lib(e.sess, Some(m.span),
|
||||
n.get().to_string(), kind);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
|
@ -281,6 +271,32 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
|||
}
|
||||
}
|
||||
|
||||
fn register_native_lib(sess: &Session, span: Option<Span>, name: String,
|
||||
kind: cstore::NativeLibaryKind) {
|
||||
if name.as_slice().is_empty() {
|
||||
match span {
|
||||
Some(span) => {
|
||||
sess.span_err(span, "#[link(name = \"\")] given with \
|
||||
empty name");
|
||||
}
|
||||
None => {
|
||||
sess.err("empty library name given via `-l`");
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
let is_osx = sess.targ_cfg.os == abi::OsMacos ||
|
||||
sess.targ_cfg.os == abi::OsiOS;
|
||||
if kind == cstore::NativeFramework && !is_osx {
|
||||
let msg = "native frameworks are only available on OSX targets";
|
||||
match span {
|
||||
Some(span) => sess.span_err(span, msg),
|
||||
None => sess.err(msg),
|
||||
}
|
||||
}
|
||||
sess.cstore.add_used_library(name, kind);
|
||||
}
|
||||
|
||||
fn existing_match(e: &Env, name: &str,
|
||||
hash: Option<&Svh>) -> Option<ast::CrateNum> {
|
||||
let mut ret = None;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ pub enum LinkagePreference {
|
|||
RequireStatic,
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, FromPrimitive)]
|
||||
#[deriving(PartialEq, FromPrimitive, Clone)]
|
||||
pub enum NativeLibaryKind {
|
||||
NativeStatic, // native static library (.a archive)
|
||||
NativeFramework, // OSX-specific
|
||||
|
|
|
|||
|
|
@ -675,26 +675,19 @@ pub fn check_zero_tts(cx: &ExtCtxt,
|
|||
|
||||
/// Extract the string literal from the first token of `tts`. If this
|
||||
/// is not a string literal, emit an error and return None.
|
||||
pub fn get_single_str_from_tts(cx: &ExtCtxt,
|
||||
pub fn get_single_str_from_tts(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[ast::TokenTree],
|
||||
name: &str)
|
||||
-> Option<String> {
|
||||
if tts.len() != 1 {
|
||||
cx.span_err(sp, format!("{} takes 1 argument.", name).as_slice());
|
||||
} else {
|
||||
match tts[0] {
|
||||
ast::TtToken(_, token::LitStr(ident)) => return Some(parse::str_lit(ident.as_str())),
|
||||
ast::TtToken(_, token::LitStrRaw(ident, _)) => {
|
||||
return Some(parse::raw_str_lit(ident.as_str()))
|
||||
}
|
||||
_ => {
|
||||
cx.span_err(sp,
|
||||
format!("{} requires a string.", name).as_slice())
|
||||
}
|
||||
}
|
||||
let mut p = cx.new_parser_from_tts(tts);
|
||||
let ret = cx.expander().fold_expr(p.parse_expr());
|
||||
if p.token != token::Eof {
|
||||
cx.span_err(sp, format!("{} takes 1 argument", name).as_slice());
|
||||
}
|
||||
None
|
||||
expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| {
|
||||
s.get().to_string()
|
||||
})
|
||||
}
|
||||
|
||||
/// Extract comma-separated expressions from `tts`. If there is a
|
||||
|
|
|
|||
|
|
@ -9,14 +9,16 @@
|
|||
// except according to those terms.
|
||||
|
||||
use ast;
|
||||
use codemap;
|
||||
use codemap::{Pos, Span};
|
||||
use codemap;
|
||||
use ext::base::*;
|
||||
use ext::base;
|
||||
use ext::build::AstBuilder;
|
||||
use parse;
|
||||
use parse::token;
|
||||
use parse;
|
||||
use print::pprust;
|
||||
use ptr::P;
|
||||
use util::small_vector::SmallVector;
|
||||
|
||||
use std::io::File;
|
||||
use std::rc::Rc;
|
||||
|
|
@ -82,14 +84,14 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
|||
/// include! : parse the given file as an expr
|
||||
/// This is generally a bad idea because it's going to behave
|
||||
/// unhygienically.
|
||||
pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||
-> Box<base::MacResult+'cx> {
|
||||
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
|
||||
Some(f) => f,
|
||||
None => return DummyResult::expr(sp),
|
||||
};
|
||||
// The file will be added to the code map by the parser
|
||||
let mut p =
|
||||
let p =
|
||||
parse::new_sub_parser_from_file(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
&res_rel_file(cx,
|
||||
|
|
@ -98,7 +100,28 @@ pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
|||
true,
|
||||
None,
|
||||
sp);
|
||||
base::MacExpr::new(p.parse_expr())
|
||||
|
||||
struct ExpandResult<'a> {
|
||||
p: parse::parser::Parser<'a>,
|
||||
}
|
||||
impl<'a> base::MacResult for ExpandResult<'a> {
|
||||
fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
|
||||
Some(self.p.parse_expr())
|
||||
}
|
||||
fn make_items(mut self: Box<ExpandResult<'a>>)
|
||||
-> Option<SmallVector<P<ast::Item>>> {
|
||||
let mut ret = SmallVector::zero();
|
||||
loop {
|
||||
match self.p.parse_item_with_outer_attributes() {
|
||||
Some(item) => ret.push(item),
|
||||
None => break
|
||||
}
|
||||
}
|
||||
Some(ret)
|
||||
}
|
||||
}
|
||||
|
||||
box ExpandResult { p: p }
|
||||
}
|
||||
|
||||
// include_str! : read the given file, insert it as a literal string expr
|
||||
|
|
|
|||
13
src/test/auxiliary/macro-include-items-expr.rs
Normal file
13
src/test/auxiliary/macro-include-items-expr.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// ignore-test: this is not a test
|
||||
|
||||
1
|
||||
13
src/test/auxiliary/macro-include-items-item.rs
Normal file
13
src/test/auxiliary/macro-include-items-item.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// ignore-test: this is not a test
|
||||
|
||||
fn foo() { bar() }
|
||||
17
src/test/compile-fail/manual-link-bad-form.rs
Normal file
17
src/test/compile-fail/manual-link-bad-form.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// compile-flags:-l :static
|
||||
// error-pattern: empty library name given via `-l`
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
||||
|
||||
16
src/test/compile-fail/manual-link-bad-kind.rs
Normal file
16
src/test/compile-fail/manual-link-bad-kind.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// compile-flags:-l foo:bar
|
||||
// error-pattern: unknown library kind `bar`, expected one of dylib, framework, or static
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
||||
17
src/test/compile-fail/manual-link-framework.rs
Normal file
17
src/test/compile-fail/manual-link-framework.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// ignore-macos
|
||||
// ignore-ios
|
||||
// compile-flags:-l foo:framework
|
||||
// error-pattern: native frameworks are only available on OSX targets
|
||||
|
||||
fn main() {
|
||||
}
|
||||
7
src/test/run-make/manual-link/Makefile
Normal file
7
src/test/run-make/manual-link/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
-include ../tools.mk
|
||||
|
||||
all: $(TMPDIR)/libbar.a
|
||||
$(RUSTC) foo.rs -lbar:static
|
||||
$(RUSTC) main.rs
|
||||
$(call RUN,main)
|
||||
|
||||
1
src/test/run-make/manual-link/bar.c
Normal file
1
src/test/run-make/manual-link/bar.c
Normal file
|
|
@ -0,0 +1 @@
|
|||
void bar() {}
|
||||
1
src/test/run-make/manual-link/foo.c
Normal file
1
src/test/run-make/manual-link/foo.c
Normal file
|
|
@ -0,0 +1 @@
|
|||
void bar() {}
|
||||
19
src/test/run-make/manual-link/foo.rs
Normal file
19
src/test/run-make/manual-link/foo.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
extern {
|
||||
fn bar();
|
||||
}
|
||||
|
||||
pub fn foo() {
|
||||
unsafe { bar(); }
|
||||
}
|
||||
15
src/test/run-make/manual-link/main.rs
Normal file
15
src/test/run-make/manual-link/main.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
extern crate foo;
|
||||
|
||||
fn main() {
|
||||
foo::foo();
|
||||
}
|
||||
18
src/test/run-pass/macro-include-items.rs
Normal file
18
src/test/run-pass/macro-include-items.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2014 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 bar() {}
|
||||
|
||||
include!(concat!("", "", "../auxiliary/", "macro-include-items-item.rs"))
|
||||
|
||||
fn main() {
|
||||
foo();
|
||||
assert_eq!(include!(concat!("", "../auxiliary/", "macro-include-items-expr.rs")), 1u);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue