mirror of https://github.com/rust-lang/rust.git
Support OSX frameworks
This adds support to link to OSX frameworks via the new link attribute when using `kind = "framework"`. It is a compiler error to request linkage to a framework when the target is not macos because other platforms don't support frameworks. Closes #2023
This commit is contained in:
parent
4252a24ae1
commit
f9d6fd20a5
|
@ -1015,7 +1015,7 @@ fn link_rlib(sess: Session, obj_filename: &Path,
|
|||
cstore::NativeStatic => {
|
||||
a.add_native_library(l.as_slice());
|
||||
}
|
||||
cstore::NativeUnknown => {}
|
||||
cstore::NativeFramework | cstore::NativeUnknown => {}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
|
@ -1044,8 +1044,13 @@ fn link_staticlib(sess: Session, obj_filename: &Path, out_filename: &Path) {
|
|||
};
|
||||
a.add_rlib(&p);
|
||||
let native_libs = csearch::get_native_libraries(sess.cstore, cnum);
|
||||
for lib in native_libs.iter() {
|
||||
sess.warn(format!("unlinked native library: {}", *lib));
|
||||
for &(kind, ref lib) in native_libs.iter() {
|
||||
let name = match kind {
|
||||
cstore::NativeStatic => "static library",
|
||||
cstore::NativeUnknown => "library",
|
||||
cstore::NativeFramework => "framework",
|
||||
};
|
||||
sess.warn(format!("unlinked native {}: {}", name, *lib));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1204,8 +1209,17 @@ fn add_upstream_rust_crates(args: &mut ~[~str], sess: Session,
|
|||
args.push(cratepath.as_str().unwrap().to_owned());
|
||||
|
||||
let libs = csearch::get_native_libraries(sess.cstore, cnum);
|
||||
for lib in libs.iter() {
|
||||
args.push("-l" + *lib);
|
||||
for &(kind, ref lib) in libs.iter() {
|
||||
match kind {
|
||||
cstore::NativeUnknown => args.push("-l" + *lib),
|
||||
cstore::NativeFramework => {
|
||||
args.push(~"-framework");
|
||||
args.push(lib.to_owned());
|
||||
}
|
||||
cstore::NativeStatic => {
|
||||
sess.bug("statics shouldn't be propagated");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -1262,7 +1276,15 @@ fn add_local_native_libraries(args: &mut ~[~str], sess: Session) {
|
|||
args.push("-L" + path.as_str().unwrap().to_owned());
|
||||
}
|
||||
|
||||
for &(ref l, _) in cstore::get_used_libraries(sess.cstore).iter() {
|
||||
args.push(~"-l" + *l);
|
||||
for &(ref l, kind) in cstore::get_used_libraries(sess.cstore).iter() {
|
||||
match kind {
|
||||
cstore::NativeUnknown | cstore::NativeStatic => {
|
||||
args.push("-l" + *l);
|
||||
}
|
||||
cstore::NativeFramework => {
|
||||
args.push(~"-framework");
|
||||
args.push(l.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -199,6 +199,8 @@ pub static tag_region_param_def_def_id: uint = 0x102;
|
|||
|
||||
pub static tag_native_libraries: uint = 0x103;
|
||||
pub static tag_native_libraries_lib: uint = 0x104;
|
||||
pub static tag_native_libraries_name: uint = 0x105;
|
||||
pub static tag_native_libraries_kind: uint = 0x106;
|
||||
|
||||
pub struct LinkMeta {
|
||||
name: @str,
|
||||
|
|
|
@ -18,6 +18,7 @@ use metadata::loader;
|
|||
use std::hashmap::HashMap;
|
||||
use syntax::ast;
|
||||
use std::vec;
|
||||
use syntax::abi;
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::{Span, dummy_sp};
|
||||
|
@ -191,10 +192,22 @@ fn visit_item(e: &Env, i: @ast::item) {
|
|||
"kind" == k.name()
|
||||
}).and_then(|a| a.value_str());
|
||||
let kind = match kind {
|
||||
Some(k) if "static" == k => cstore::NativeStatic,
|
||||
Some(k) => {
|
||||
e.sess.span_fatal(i.span,
|
||||
format!("unknown kind: `{}`", k));
|
||||
if "static" == k {
|
||||
cstore::NativeStatic
|
||||
} else if e.sess.targ_cfg.os == abi::OsMacos &&
|
||||
"framework" == k {
|
||||
cstore::NativeFramework
|
||||
} else if "framework" == k {
|
||||
e.sess.span_err(m.span,
|
||||
"native frameworks are only available \
|
||||
on OSX targets");
|
||||
cstore::NativeUnknown
|
||||
} else {
|
||||
e.sess.span_err(m.span,
|
||||
format!("unknown kind: `{}`", k));
|
||||
cstore::NativeUnknown
|
||||
}
|
||||
}
|
||||
None => cstore::NativeUnknown
|
||||
};
|
||||
|
@ -204,9 +217,10 @@ fn visit_item(e: &Env, i: @ast::item) {
|
|||
let n = match n {
|
||||
Some(n) => n,
|
||||
None => {
|
||||
e.sess.span_fatal(i.span,
|
||||
e.sess.span_err(m.span,
|
||||
"#[link(...)] specified without \
|
||||
`name = \"foo\"`");
|
||||
@"foo"
|
||||
}
|
||||
};
|
||||
cstore::add_used_library(cstore, n.to_owned(), kind);
|
||||
|
|
|
@ -263,7 +263,8 @@ pub fn get_item_visibility(cstore: @mut cstore::CStore,
|
|||
}
|
||||
|
||||
pub fn get_native_libraries(cstore: @mut cstore::CStore,
|
||||
crate_num: ast::CrateNum) -> ~[~str] {
|
||||
crate_num: ast::CrateNum)
|
||||
-> ~[(cstore::NativeLibaryKind, ~str)] {
|
||||
let cdata = cstore::get_crate_data(cstore, crate_num);
|
||||
decoder::get_native_libraries(cdata)
|
||||
}
|
||||
|
|
|
@ -40,10 +40,11 @@ pub enum LinkagePreference {
|
|||
RequireStatic,
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
#[deriving(Eq, FromPrimitive)]
|
||||
pub enum NativeLibaryKind {
|
||||
NativeStatic,
|
||||
NativeUnknown,
|
||||
NativeStatic, // native static library (.a archive)
|
||||
NativeFramework, // OSX-specific
|
||||
NativeUnknown, // default way to specify a dynamic library
|
||||
}
|
||||
|
||||
// Where a crate came from on the local filesystem. One of these two options
|
||||
|
|
|
@ -1530,11 +1530,16 @@ pub fn get_trait_of_method(cdata: Cmd, id: ast::NodeId, tcx: ty::ctxt)
|
|||
}
|
||||
|
||||
|
||||
pub fn get_native_libraries(cdata: Cmd) -> ~[~str] {
|
||||
pub fn get_native_libraries(cdata: Cmd) -> ~[(cstore::NativeLibaryKind, ~str)] {
|
||||
let libraries = reader::get_doc(reader::Doc(cdata.data), tag_native_libraries);
|
||||
let mut result = ~[];
|
||||
reader::tagged_docs(libraries, tag_native_libraries_lib, |lib_doc| {
|
||||
result.push(lib_doc.as_str());
|
||||
let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind);
|
||||
let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name);
|
||||
let kind: cstore::NativeLibaryKind =
|
||||
FromPrimitive::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
|
||||
let name = name_doc.as_str();
|
||||
result.push((kind, name));
|
||||
true
|
||||
});
|
||||
return result;
|
||||
|
|
|
@ -1640,10 +1640,18 @@ fn encode_native_libraries(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) {
|
|||
for &(ref lib, kind) in cstore::get_used_libraries(ecx.cstore).iter() {
|
||||
match kind {
|
||||
cstore::NativeStatic => {} // these libraries are not propagated
|
||||
cstore::NativeUnknown => {
|
||||
cstore::NativeFramework | cstore::NativeUnknown => {
|
||||
ebml_w.start_tag(tag_native_libraries_lib);
|
||||
|
||||
ebml_w.start_tag(tag_native_libraries_kind);
|
||||
ebml_w.writer.write_be_u32(kind as u32);
|
||||
ebml_w.end_tag();
|
||||
|
||||
ebml_w.start_tag(tag_native_libraries_name);
|
||||
ebml_w.writer.write(lib.as_bytes());
|
||||
ebml_w.end_tag();
|
||||
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
#[link()] //~ ERROR: specified without `name =
|
||||
#[link(name = "foo")]
|
||||
#[link(name = "foo", kind = "bar")] //~ ERROR: unknown kind
|
||||
extern {}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
// xfail-macos this is supposed to succeed on osx
|
||||
|
||||
#[link(name = "foo", kind = "framework")]
|
||||
extern {}
|
||||
//~^^ ERROR: native frameworks are only available on OSX
|
||||
|
||||
fn main() {
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
use std::libc;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[link(name = "CoreFoundation", kind = "framework")]
|
||||
extern {
|
||||
fn CFRunLoopGetTypeID() -> libc::c_ulong;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn main() {
|
||||
unsafe { CFRunLoopGetTypeID(); }
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
pub fn main() {}
|
Loading…
Reference in New Issue