1
Fork 0

Better dylib skipping based on Alex Crichton code

This commit is contained in:
Valerii Hiora 2014-06-11 10:48:17 +03:00
parent a49b765f9a
commit 70a79a9e05
13 changed files with 125 additions and 121 deletions

View file

@ -9,8 +9,6 @@
// except according to those terms.
use back::target_strs;
use driver::config::cfg_os_to_meta_os;
use metadata::loader::meta_section_name;
use syntax::abi;
pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
@ -22,9 +20,6 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
return target_strs::t {
module_asm: "".to_string(),
meta_sect_name:
meta_section_name(cfg_os_to_meta_os(target_os)).to_string(),
data_layout: match target_os {
abi::OsMacos => {
"e-p:32:32:32\

View file

@ -806,6 +806,10 @@ pub fn link_binary(sess: &Session,
id: &CrateId) -> Vec<Path> {
let mut out_filenames = Vec::new();
for &crate_type in sess.crate_types.borrow().iter() {
if invalid_output_for_target(sess, crate_type) {
sess.bug(format!("invalid output type `{}` for target os `{}`",
crate_type, sess.targ_cfg.os).as_slice());
}
let out_file = link_binary_output(sess, trans, crate_type, outputs, id);
out_filenames.push(out_file);
}
@ -822,6 +826,32 @@ pub fn link_binary(sess: &Session,
out_filenames
}
/// Returns default crate type for target
///
/// Default crate type is used when crate type isn't provided neither
/// through cmd line arguments nor through crate attributes
///
/// It is CrateTypeExecutable for all platforms but iOS as there is no
/// way to run iOS binaries anyway without jailbreaking and
/// interaction with Rust code through static library is the only
/// option for now
pub fn default_output_for_target(sess: &Session) -> config::CrateType {
match sess.targ_cfg.os {
abi::OsiOS => config::CrateTypeStaticlib,
_ => config::CrateTypeExecutable
}
}
/// Checks if target supports crate_type as output
pub fn invalid_output_for_target(sess: &Session,
crate_type: config::CrateType) -> bool {
match (sess.targ_cfg.os, crate_type) {
(abi::OsiOS, config::CrateTypeDylib) => true,
_ => false
}
}
fn is_writeable(p: &Path) -> bool {
match p.stat() {
Err(..) => true,
@ -837,23 +867,18 @@ pub fn filename_for_input(sess: &Session, crate_type: config::CrateType,
out_filename.with_filename(format!("lib{}.rlib", libname))
}
config::CrateTypeDylib => {
// There is no support of DyLibs on iOS
if sess.targ_cfg.os == abi::OsiOS {
out_filename.with_filename(format!("lib{}.a", libname))
} else {
let (prefix, suffix) = match sess.targ_cfg.os {
abi::OsWin32 => (loader::WIN32_DLL_PREFIX, loader::WIN32_DLL_SUFFIX),
abi::OsMacos => (loader::MACOS_DLL_PREFIX, loader::MACOS_DLL_SUFFIX),
abi::OsLinux => (loader::LINUX_DLL_PREFIX, loader::LINUX_DLL_SUFFIX),
abi::OsAndroid => (loader::ANDROID_DLL_PREFIX, loader::ANDROID_DLL_SUFFIX),
abi::OsFreebsd => (loader::FREEBSD_DLL_PREFIX, loader::FREEBSD_DLL_SUFFIX),
abi::OsiOS => unreachable!(),
};
out_filename.with_filename(format!("{}{}{}",
prefix,
libname,
suffix))
}
let (prefix, suffix) = match sess.targ_cfg.os {
abi::OsWin32 => (loader::WIN32_DLL_PREFIX, loader::WIN32_DLL_SUFFIX),
abi::OsMacos => (loader::MACOS_DLL_PREFIX, loader::MACOS_DLL_SUFFIX),
abi::OsLinux => (loader::LINUX_DLL_PREFIX, loader::LINUX_DLL_SUFFIX),
abi::OsAndroid => (loader::ANDROID_DLL_PREFIX, loader::ANDROID_DLL_SUFFIX),
abi::OsFreebsd => (loader::FREEBSD_DLL_PREFIX, loader::FREEBSD_DLL_SUFFIX),
abi::OsiOS => unreachable!(),
};
out_filename.with_filename(format!("{}{}{}",
prefix,
libname,
suffix))
}
config::CrateTypeStaticlib => {
out_filename.with_filename(format!("lib{}.a", libname))
@ -904,14 +929,7 @@ fn link_binary_output(sess: &Session,
link_natively(sess, trans, false, &obj_filename, &out_filename);
}
config::CrateTypeDylib => {
if sess.targ_cfg.os == abi::OsiOS {
sess.warn(format!("No dylib for iOS -> saving static library {} to {}",
obj_filename.display(), out_filename.display()).as_slice());
link_staticlib(sess, &obj_filename, &out_filename);
}
else {
link_natively(sess, trans, true, &obj_filename, &out_filename);
}
link_natively(sess, trans, true, &obj_filename, &out_filename);
}
}

View file

@ -9,17 +9,12 @@
// except according to those terms.
use back::target_strs;
use driver::config::cfg_os_to_meta_os;
use metadata::loader::meta_section_name;
use syntax::abi;
pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
return target_strs::t {
module_asm: "".to_string(),
meta_sect_name:
meta_section_name(cfg_os_to_meta_os(target_os)).to_string(),
data_layout: match target_os {
abi::OsMacos => {
"E-p:32:32:32\

View file

@ -12,7 +12,6 @@
pub struct t {
pub module_asm: String,
pub meta_sect_name: String,
pub data_layout: String,
pub target_triple: String,
pub cc_args: Vec<String> ,

View file

@ -10,8 +10,6 @@
use back::target_strs;
use driver::config::cfg_os_to_meta_os;
use metadata::loader::meta_section_name;
use syntax::abi;
pub fn get_target_strs(target_triple: String, target_os: abi::Os)
@ -19,9 +17,6 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os)
return target_strs::t {
module_asm: "".to_string(),
meta_sect_name:
meta_section_name(cfg_os_to_meta_os(target_os)).to_string(),
data_layout: match target_os {
abi::OsMacos => {
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\

View file

@ -10,17 +10,12 @@
use back::target_strs;
use driver::config::cfg_os_to_meta_os;
use metadata::loader::meta_section_name;
use syntax::abi;
pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
return target_strs::t {
module_asm: "".to_string(),
meta_sect_name:
meta_section_name(cfg_os_to_meta_os(target_os)).to_string(),
data_layout: match target_os {
abi::OsMacos => {
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\

View file

@ -19,7 +19,6 @@ use back;
use back::link;
use back::target_strs;
use back::{arm, x86, x86_64, mips};
use metadata;
use middle::lint;
use syntax::abi;
@ -36,6 +35,7 @@ use getopts::{optopt, optmulti, optflag, optflagopt};
use getopts;
use lib::llvm::llvm;
use std::cell::{RefCell};
use std::fmt;
pub struct Config {
@ -354,19 +354,6 @@ pub fn default_lib_output() -> CrateType {
CrateTypeRlib
}
pub fn cfg_os_to_meta_os(os: abi::Os) -> metadata::loader::Os {
use metadata::loader;
match os {
abi::OsWin32 => loader::OsWin32,
abi::OsLinux => loader::OsLinux,
abi::OsAndroid => loader::OsAndroid,
abi::OsMacos => loader::OsMacos,
abi::OsFreebsd => loader::OsFreebsd,
abi::OsiOS => loader::OsiOS,
}
}
pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
let tos = match sess.targ_cfg.os {
abi::OsWin32 => InternedString::new("win32"),
@ -775,6 +762,16 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
}
impl fmt::Show for CrateType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
CrateTypeExecutable => "bin".fmt(f),
CrateTypeDylib => "dylib".fmt(f),
CrateTypeRlib => "rlib".fmt(f),
CrateTypeStaticlib => "staticlib".fmt(f)
}
}
}
#[cfg(test)]
mod test {

View file

@ -779,17 +779,26 @@ pub fn collect_crate_types(session: &Session,
// command line, then reuse the empty `base` Vec to hold the types that
// will be found in crate attributes.
let mut base = session.opts.crate_types.clone();
if base.len() > 0 {
return base
} else {
if base.len() == 0 {
base.extend(attr_types.move_iter());
if base.len() == 0 {
base.push(config::CrateTypeExecutable);
base.push(link::default_output_for_target(session));
}
base.as_mut_slice().sort();
base.dedup();
return base;
}
base.move_iter().filter(|crate_type| {
let res = !link::invalid_output_for_target(session, *crate_type);
if !res {
session.warn(format!("dropping unsupported crate type `{}` \
for target os `{}`",
*crate_type, session.targ_cfg.os).as_slice());
}
res
}).collect()
}
pub struct OutputFilenames {

View file

@ -349,8 +349,7 @@ pub fn early_error(msg: &str) -> ! {
pub fn list_metadata(sess: &Session, path: &Path,
out: &mut io::Writer) -> io::IoResult<()> {
metadata::loader::list_file_metadata(
config::cfg_os_to_meta_os(sess.targ_cfg.os), path, out)
metadata::loader::list_file_metadata(sess.targ_cfg.os, path, out)
}
/// Run a procedure which will detect failures in the compiler and print nicer

View file

@ -346,7 +346,7 @@ fn resolve_crate<'a>(e: &mut Env,
id_hash: id_hash.as_slice(),
hash: hash.map(|a| &*a),
filesearch: e.sess.target_filesearch(),
os: config::cfg_os_to_meta_os(e.sess.targ_cfg.os),
os: e.sess.targ_cfg.os,
triple: e.sess.targ_cfg.target_strs.target_triple.as_slice(),
root: root,
rejected_via_hash: vec!(),
@ -410,7 +410,7 @@ impl<'a> PluginMetadataReader<'a> {
hash: None,
filesearch: self.env.sess.host_filesearch(),
triple: driver::host_triple(),
os: config::cfg_os_to_meta_os(os),
os: os,
root: &None,
rejected_via_hash: vec!(),
rejected_via_triple: vec!(),
@ -421,7 +421,7 @@ impl<'a> PluginMetadataReader<'a> {
// try loading from target crates (only valid if there are
// no syntax extensions)
load_ctxt.triple = target_triple;
load_ctxt.os = config::cfg_os_to_meta_os(self.env.sess.targ_cfg.os);
load_ctxt.os = self.env.sess.targ_cfg.os;
load_ctxt.filesearch = self.env.sess.target_filesearch();
let lib = load_ctxt.load_library_crate();
if decoder::get_plugin_registrar_fn(lib.metadata.as_slice()).is_some() {

View file

@ -18,6 +18,7 @@ use metadata::cstore::{MetadataBlob, MetadataVec, MetadataArchive};
use metadata::decoder;
use metadata::encoder;
use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
use syntax::abi;
use syntax::codemap::Span;
use syntax::diagnostic::SpanHandler;
use syntax::crateid::CrateId;
@ -39,9 +40,6 @@ use time;
pub static MACOS_DLL_PREFIX: &'static str = "lib";
pub static MACOS_DLL_SUFFIX: &'static str = ".dylib";
pub static IOS_DLL_PREFIX: &'static str = "lib";
pub static IOS_DLL_SUFFIX: &'static str = ".dylib";
pub static WIN32_DLL_PREFIX: &'static str = "";
pub static WIN32_DLL_SUFFIX: &'static str = ".dll";
@ -54,15 +52,6 @@ pub static FREEBSD_DLL_SUFFIX: &'static str = ".so";
pub static ANDROID_DLL_PREFIX: &'static str = "lib";
pub static ANDROID_DLL_SUFFIX: &'static str = ".so";
pub enum Os {
OsMacos,
OsWin32,
OsLinux,
OsAndroid,
OsFreebsd,
OsiOS
}
pub struct CrateMismatch {
path: Path,
got: String,
@ -76,7 +65,7 @@ pub struct Context<'a> {
pub id_hash: &'a str,
pub hash: Option<&'a Svh>,
pub triple: &'a str,
pub os: Os,
pub os: abi::Os,
pub filesearch: FileSearch<'a>,
pub root: &'a Option<CratePaths>,
pub rejected_via_hash: Vec<CrateMismatch>,
@ -178,10 +167,12 @@ impl<'a> Context<'a> {
}
fn find_library_crate(&mut self) -> Option<Library> {
let (dyprefix, dysuffix) = self.dylibname();
let dypair = self.dylibname();
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
let dylib_prefix = format!("{}{}-", dyprefix, self.crate_id.name);
let dylib_prefix = dypair.map(|(prefix, _)| {
format!("{}{}-", prefix, self.crate_id.name)
});
let rlib_prefix = format!("lib{}-", self.crate_id.name);
let mut candidates = HashMap::new();
@ -222,12 +213,14 @@ impl<'a> Context<'a> {
FileDoesntMatch
}
}
} else if file.starts_with(dylib_prefix.as_slice()) &&
file.ends_with(dysuffix){
} else if dypair.map_or(false, |(_, suffix)| {
file.starts_with(dylib_prefix.get_ref().as_slice()) &&
file.ends_with(suffix)
}) {
let (_, suffix) = dypair.unwrap();
let dylib_prefix = dylib_prefix.get_ref().as_slice();
info!("dylib candidate: {}", path.display());
match self.try_match(file,
dylib_prefix.as_slice(),
dysuffix) {
match self.try_match(file, dylib_prefix, suffix) {
Some(hash) => {
info!("dylib accepted, hash: {}", hash);
let slot = candidates.find_or_insert_with(hash, |_| {
@ -452,14 +445,14 @@ impl<'a> Context<'a> {
// Returns the corresponding (prefix, suffix) that files need to have for
// dynamic libraries
fn dylibname(&self) -> (&'static str, &'static str) {
fn dylibname(&self) -> Option<(&'static str, &'static str)> {
match self.os {
OsWin32 => (WIN32_DLL_PREFIX, WIN32_DLL_SUFFIX),
OsMacos => (MACOS_DLL_PREFIX, MACOS_DLL_SUFFIX),
OsLinux => (LINUX_DLL_PREFIX, LINUX_DLL_SUFFIX),
OsAndroid => (ANDROID_DLL_PREFIX, ANDROID_DLL_SUFFIX),
OsFreebsd => (FREEBSD_DLL_PREFIX, FREEBSD_DLL_SUFFIX),
OsiOS => (IOS_DLL_PREFIX, IOS_DLL_SUFFIX),
abi::OsWin32 => Some((WIN32_DLL_PREFIX, WIN32_DLL_SUFFIX)),
abi::OsMacos => Some((MACOS_DLL_PREFIX, MACOS_DLL_SUFFIX)),
abi::OsLinux => Some((LINUX_DLL_PREFIX, LINUX_DLL_SUFFIX)),
abi::OsAndroid => Some((ANDROID_DLL_PREFIX, ANDROID_DLL_SUFFIX)),
abi::OsFreebsd => Some((FREEBSD_DLL_PREFIX, FREEBSD_DLL_SUFFIX)),
abi::OsiOS => None,
}
}
@ -501,7 +494,7 @@ impl ArchiveMetadata {
}
// Just a small wrapper to time how long reading metadata takes.
fn get_metadata_section(os: Os, filename: &Path) -> Result<MetadataBlob, String> {
fn get_metadata_section(os: abi::Os, filename: &Path) -> Result<MetadataBlob, String> {
let start = time::precise_time_ns();
let ret = get_metadata_section_imp(os, filename);
info!("reading {} => {}ms", filename.filename_display(),
@ -509,7 +502,7 @@ fn get_metadata_section(os: Os, filename: &Path) -> Result<MetadataBlob, String>
return ret;
}
fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, String> {
fn get_metadata_section_imp(os: abi::Os, filename: &Path) -> Result<MetadataBlob, String> {
if !filename.exists() {
return Err(format!("no such file: '{}'", filename.display()));
}
@ -595,30 +588,30 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, Str
}
}
pub fn meta_section_name(os: Os) -> &'static str {
pub fn meta_section_name(os: abi::Os) -> Option<&'static str> {
match os {
OsMacos => "__DATA,__note.rustc",
OsiOS => "__DATA,__note.rustc",
OsWin32 => ".note.rustc",
OsLinux => ".note.rustc",
OsAndroid => ".note.rustc",
OsFreebsd => ".note.rustc"
abi::OsMacos => Some("__DATA,__note.rustc"),
abi::OsiOS => Some("__DATA,__note.rustc"),
abi::OsWin32 => Some(".note.rustc"),
abi::OsLinux => Some(".note.rustc"),
abi::OsAndroid => Some(".note.rustc"),
abi::OsFreebsd => Some(".note.rustc")
}
}
pub fn read_meta_section_name(os: Os) -> &'static str {
pub fn read_meta_section_name(os: abi::Os) -> &'static str {
match os {
OsMacos => "__note.rustc",
OsiOS => "__note.rustc",
OsWin32 => ".note.rustc",
OsLinux => ".note.rustc",
OsAndroid => ".note.rustc",
OsFreebsd => ".note.rustc"
abi::OsMacos => "__note.rustc",
abi::OsiOS => "__note.rustc",
abi::OsWin32 => ".note.rustc",
abi::OsLinux => ".note.rustc",
abi::OsAndroid => ".note.rustc",
abi::OsFreebsd => ".note.rustc"
}
}
// A diagnostic function for dumping crate metadata to an output stream
pub fn list_file_metadata(os: Os, path: &Path,
pub fn list_file_metadata(os: abi::Os, path: &Path,
out: &mut io::Writer) -> io::IoResult<()> {
match get_metadata_section(os, path) {
Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out),

View file

@ -35,7 +35,7 @@ use driver::driver::{CrateAnalysis, CrateTranslation};
use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
use lib::llvm::{llvm, Vector};
use lib;
use metadata::{csearch, encoder};
use metadata::{csearch, encoder, loader};
use middle::lint;
use middle::astencode;
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
@ -2281,12 +2281,8 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
});
unsafe {
llvm::LLVMSetInitializer(llglobal, llconst);
cx.sess()
.targ_cfg
.target_strs
.meta_sect_name
.as_slice()
.with_c_str(|buf| {
let name = loader::meta_section_name(cx.sess().targ_cfg.os);
name.unwrap_or("rust_metadata").with_c_str(|buf| {
llvm::LLVMSetSection(llglobal, buf)
});
}

View file

@ -159,6 +159,19 @@ impl fmt::Show for Abi {
}
}
impl fmt::Show for Os {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
OsLinux => "linux".fmt(f),
OsWin32 => "win32".fmt(f),
OsMacos => "macos".fmt(f),
OsiOS => "ios".fmt(f),
OsAndroid => "android".fmt(f),
OsFreebsd => "freebsd".fmt(f)
}
}
}
#[allow(non_snake_case_functions)]
#[test]
fn lookup_Rust() {