From a6d9d428f6ef100f9cf8a77a0c21e56fb60a6e1f Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Thu, 17 Apr 2014 17:14:31 -0500 Subject: [PATCH 1/5] Introducing libmachine: a small crate shared between librustc, libsyntax, and compiletest. Currently, it houses the Os and Architecture enums, as well as the larger Triple structure. I choose to put Triple into it's own crate so compiletest wouldn't need to import all of librustc (Triple's original home). --- mk/crates.mk | 9 +- src/libmachine/abi.rs | 74 ++++++++ src/libmachine/lib.rs | 20 ++ src/libmachine/triple.rs | 392 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 491 insertions(+), 4 deletions(-) create mode 100644 src/libmachine/abi.rs create mode 100644 src/libmachine/lib.rs create mode 100644 src/libmachine/triple.rs diff --git a/mk/crates.mk b/mk/crates.mk index 28330010dc2ac..3cbd6e8ba95ad 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -52,7 +52,7 @@ TARGET_CRATES := libc std green rustuv native flate arena glob term semver \ uuid serialize sync getopts collections num test time rand \ workcache url log -HOST_CRATES := syntax rustc rustdoc fourcc hexfloat +HOST_CRATES := syntax rustc rustdoc fourcc hexfloat machine CRATES := $(TARGET_CRATES) $(HOST_CRATES) TOOLS := compiletest rustdoc rustc @@ -60,9 +60,9 @@ DEPS_std := libc native:rustrt native:compiler-rt native:backtrace DEPS_green := std rand native:context_switch DEPS_rustuv := std native:uv native:uv_support DEPS_native := std -DEPS_syntax := std term serialize collections log +DEPS_syntax := std term serialize collections log machine DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \ - collections time log + collections time log machine DEPS_rustdoc := rustc native:sundown serialize sync getopts collections \ test time DEPS_flate := std native:miniz @@ -84,8 +84,9 @@ DEPS_rand := std DEPS_url := std collections DEPS_workcache := std serialize collections log DEPS_log := std sync +DEPS_machine := std -TOOL_DEPS_compiletest := test green rustuv getopts +TOOL_DEPS_compiletest := test green rustuv getopts machine TOOL_DEPS_rustdoc := rustdoc native TOOL_DEPS_rustc := rustc native TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs diff --git a/src/libmachine/abi.rs b/src/libmachine/abi.rs new file mode 100644 index 0000000000000..e1267a60c71d6 --- /dev/null +++ b/src/libmachine/abi.rs @@ -0,0 +1,74 @@ +// Copyright 2012-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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt; +use std::from_str; + +#[deriving(Eq, Hash, Clone, TotalEq)] +pub enum Os { + OsWin32, + OsMacos, + OsLinux, + OsAndroid, + OsFreebsd, +} + +impl from_str::FromStr for Os { + fn from_str(s: &str) -> Option { + match s { + "mingw32" => Some(OsWin32), + "win32" => Some(OsWin32), + "darwin" => Some(OsMacos), + "android" => Some(OsAndroid), + "linux" => Some(OsLinux), + "freebsd" => Some(OsFreebsd), + _ => None, + } + } +} + +impl fmt::Show for Os { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + &OsWin32 => "win32".fmt(f), + &OsMacos => "darwin".fmt(f), + &OsLinux => "linux".fmt(f), + &OsAndroid => "android".fmt(f), + &OsFreebsd => "freebsd".fmt(f), + } + } +} + +#[allow(non_camel_case_types)] +#[deriving(Eq, Clone, Hash, TotalEq)] +pub enum Architecture { + // NB. You cannot change the ordering of these + // constants without adjusting IntelBits below. + // (This is ensured by the test indices_are_correct().) + X86, + X86_64, + Arm, + Mips +} +impl from_str::FromStr for Architecture { + fn from_str(s: &str) -> Option { + match s { + "i386" | "i486" | "i586" | "i686" | "i786" => Some(X86), + "x86_64" => Some(X86_64), + "arm" | "xscale" | "thumb" => Some(Arm), + "mips" => Some(Mips), + _ => None, + } + } +} + +pub static IntelBits: u32 = (1 << (X86 as uint)) | (1 << (X86_64 as uint)); +pub static ArmBits: u32 = (1 << (Arm as uint)); + diff --git a/src/libmachine/lib.rs b/src/libmachine/lib.rs new file mode 100644 index 0000000000000..735e37f3765e5 --- /dev/null +++ b/src/libmachine/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2012-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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_id = "machine#0.11-pre"] +#![license = "MIT/ASL2"] +#![crate_type = "rlib"] +#![crate_type = "dylib"] +#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_root_url = "http://static.rust-lang.org/doc/master")] + +pub mod abi; +pub mod triple; diff --git a/src/libmachine/triple.rs b/src/libmachine/triple.rs new file mode 100644 index 0000000000000..2d1778b5684b2 --- /dev/null +++ b/src/libmachine/triple.rs @@ -0,0 +1,392 @@ +// Copyright 2012-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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::result::{Result, Ok, Err}; +use std::from_str::FromStr; +use std::{cmp, fmt, default}; +use std::os::consts::{macos, freebsd, linux, android, win32}; +use abi; + +pub type KnownType = Result; +pub trait Known { + // Unwrap the value, or fails with a message using name. + fn expect_known<'a>(&'a self, name: &str) -> &'a T; +} +impl Known for KnownType { + fn expect_known<'a>(&'a self, name: &str) -> &'a T { + match self { + &Ok(ref v) => v, + &Err(ref v) => { + fail!("Tried to unwrap unknown value `{}`. The unknown string was `{}`.", + name, v); + } + } + } +} +pub trait ParseFromStr { + fn parse_str(s: &str) -> KnownType; +} +impl ParseFromStr for T { + fn parse_str(s: &str) -> KnownType { + let opt: Option = FromStr::from_str(s); + match opt { + Some(v) => Ok(v), + None => Err(s.to_str()), + } + } +} + +#[deriving(Hash, Clone, Eq, TotalEq)] +pub enum GnuType { + GnuDefault, + GnuEAbi, + GnuEAbiHf, + GnuX32, +} +impl FromStr for GnuType { + fn from_str(s: &str) -> Option { + match s { + "gnu" => Some(GnuDefault), + "gnueabi" => Some(GnuEAbi), + "gnueabihf" => Some(GnuEAbiHf), + "gnux32" => Some(GnuX32), + _ => None, + } + } +} + +#[deriving(Hash, Clone, Eq, TotalEq)] +pub enum Env { + GnuEnv(GnuType), + EAbiEnv, + EAbiHfEnv, + AndroidEnv, + AndroidEAbiEnv, + MsvcEnv, + // here for completeness: + ItaniumEnv, +} +impl FromStr for Env { + fn from_str(s: &str) -> Option { + let gnu_opt: Option = FromStr::from_str(s); + match gnu_opt { + Some(gnu) => Some(GnuEnv(gnu)), + None => { + match s { + "eabi" => Some(EAbiEnv), + "eabihf" => Some(EAbiHfEnv), + "android" => Some(AndroidEnv), + "androideabi" => Some(AndroidEAbiEnv), + "msvc" => Some(MsvcEnv), + "itanium" => Some(ItaniumEnv), + _ => None, + } + } + } + } +} +#[deriving(Hash, Clone, Eq, TotalEq)] +pub enum Vendor { + UnknownVendor, + PCVendor, + AppleVendor, +} +impl FromStr for Vendor { + fn from_str(s: &str) -> Option { + match s { + "unknown" => Some(UnknownVendor), + "pc" | "w64" => Some(PCVendor), + "apple" => Some(AppleVendor), + _ => None, + } + } +} + +#[deriving(Hash, Clone, TotalEq)] +pub struct Triple { + pub full: ~str, + + pub arch: abi::Architecture, + pub os: KnownType, + pub vendor: Option>, + pub env: Option>, +} +impl Triple { + pub fn host_triple() -> Triple { + // Get the host triple out of the build environment. This ensures that our + // idea of the host triple is the same as for the set of libraries we've + // actually built. We can't just take LLVM's host triple because they + // normalize all ix86 architectures to i386. + // + // Instead of grabbing the host triple (for the current host), we grab (at + // compile time) the target triple that this rustc is built with and + // calling that (at runtime) the host triple. + FromStr::from_str(env!("CFG_COMPILER_HOST_TRIPLE")).unwrap() + } + pub fn expect_known_os(&self) -> abi::Os { + self.os.expect_known("os").clone() + } + + // Returns the corresponding (prefix, suffix) that files need to have for + // dynamic libraries. Note this expects a known OS, which should all be + // fine except for the session builder (the session builder won't proceed + // if we don't have a known OS). + pub fn dylibname(&self) -> (&'static str, &'static str) { + match self.expect_known_os() { + abi::OsWin32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX), + abi::OsMacos => (macos::DLL_PREFIX, macos::DLL_SUFFIX), + abi::OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX), + abi::OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX), + abi::OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX), + } + } + + // Are we targeting Android? + pub fn is_android(&self) -> bool { + use abi::OsAndroid; + + self.os == Ok(OsAndroid) && + self.env == Some(Ok(AndroidEAbiEnv)) + } + // Are we targeting Android on an Arm processor? + pub fn is_android_on_arm(&self) -> bool { + use abi::Arm; + + self.arch == Arm && self.is_android() + } +} + +impl FromStr for Triple { + fn from_str(s: &str) -> Option { + // we require at least an arch. + + let splits: Vec<&str> = s.split_terminator('-').collect(); + if splits.len() < 2 { + None + } else { + let splits = splits.as_slice(); + let arch = match FromStr::from_str(splits[0]) { + Some(arch) => arch, + None => return None, + }; + if splits.len() == 2 { + match splits[1] { + "mingw32msvc" => { + return Some(Triple { + full: s.to_str(), + arch: arch, + os: Ok(abi::OsWin32), + vendor: None, + env: Some(Ok(MsvcEnv)), + }); + } + os => { + return Some(Triple { + full: s.to_str(), + arch: arch, + os: ParseFromStr::parse_str(os), + vendor: None, + env: None, + }) + } + } + } else if splits.len() == 3 { + match (splits[1], splits[2]) { + ("linux", "androideabi") => { + return Some(Triple { + full: s.to_str(), + arch: arch, + os: Ok(abi::OsAndroid), + vendor: None, + env: Some(Ok(AndroidEAbiEnv)), + }) + } + _ => { + return Some(Triple { + full: s.to_str(), + arch: arch, + os: ParseFromStr::parse_str(splits[2]), + vendor: Some(ParseFromStr::parse_str(splits[1])), + env: None, + }); + } + } + } else { + Some(Triple { + full: s.to_str(), + arch: arch, + vendor: Some(ParseFromStr::parse_str(splits[1])), + os: ParseFromStr::parse_str(splits[2]), + env: Some(ParseFromStr::parse_str(splits[3])), + }) + } + } + } +} +impl default::Default for Triple { + fn default() -> Triple { + Triple::host_triple() + } +} +impl fmt::Show for Triple { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.full.fmt(f) + } +} +impl cmp::Eq for Triple { + fn eq(&self, rhs: &Triple) -> bool { + self.arch == rhs.arch && + self.os == rhs.os && + self.env == rhs.env + } +} + +#[cfg(test)] +mod test { + use super::{Triple, + UnknownVendor, + GnuEnv, GnuDefault, + AndroidEAbiEnv, MsvcEnv}; + use abi; + use std::to_str::ToStr; + use std::from_str::FromStr; + + #[test] + fn x86_64_unknown_linux_gnu() { + let original = "x86_64-unknown-linux-gnu"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86_64); + assert!(triple.os == Ok(abi::OsLinux)); + assert!(triple.vendor == Some(Ok(UnknownVendor))); + assert!(triple.env == Some(Ok(GnuEnv(GnuDefault)))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] + fn i386_unknown_linux_gnu() { + let original = "i386-unknown-linux-gnu"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86); + assert!(triple.os == Ok(abi::OsLinux)); + assert!(triple.vendor == Some(Ok(UnknownVendor))); + assert!(triple.env == Some(Ok(GnuEnv(GnuDefault)))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] + fn i486_unknown_linux_gnu() { + let original = "i486-unknown-linux-gnu"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86); + assert!(triple.os == Ok(abi::OsLinux)); + assert!(triple.vendor == Some(Ok(UnknownVendor))); + assert!(triple.env == Some(Ok(GnuEnv(GnuDefault)))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] + fn i586_unknown_linux_gnu() { + let original = "i586-unknown-linux-gnu"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86); + assert!(triple.os == Ok(abi::OsLinux)); + assert!(triple.vendor == Some(Ok(UnknownVendor))); + assert!(triple.env == Some(Ok(GnuEnv(GnuDefault)))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] + fn i686_unknown_linux_gnu() { + let original = "i686-unknown-linux-gnu"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86); + assert!(triple.os == Ok(abi::OsLinux)); + assert!(triple.vendor == Some(Ok(UnknownVendor))); + assert!(triple.env == Some(Ok(GnuEnv(GnuDefault)))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] + fn i786_unknown_linux_gnu() { + let original = "i786-unknown-linux-gnu"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86); + assert!(triple.os == Ok(abi::OsLinux)); + assert!(triple.vendor == Some(Ok(UnknownVendor))); + assert!(triple.env == Some(Ok(GnuEnv(GnuDefault)))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] #[should_fail] + fn unknownarch_unknown_linux_gnu() { + let original = "unknownarch-unknown-linux-gnu"; + let _: Triple = FromStr::from_str(original).unwrap(); + } + #[test] + fn x86_64_ununknown_linux_gnu() { + // unknown vendor + let original = "x86_64-ununknown-linux-gnu"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86_64); + assert!(triple.os == Ok(abi::OsLinux)); + assert!(triple.vendor == Some(Err(~"ununknown"))); + assert!(triple.env == Some(Ok(GnuEnv(GnuDefault)))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] + fn x86_64_unknown_notlinux_gnu() { + // unknown os + let original = "x86_64-unknown-notlinux-gnu"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86_64); + assert!(triple.os == Err(~"notlinux")); + assert!(triple.vendor == Some(Ok(UnknownVendor))); + assert!(triple.env == Some(Ok(GnuEnv(GnuDefault)))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] + fn x86_64_unknown_linux_notgnu() { + // unknown os + let original = "x86_64-unknown-linux-notgnu"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86_64); + assert!(triple.os == Ok(abi::OsLinux)); + assert!(triple.vendor == Some(Ok(UnknownVendor))); + assert!(triple.env == Some(Err(~"notgnu"))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] + fn i686_mingw32msvc() { + // Odd one, this is. + let original = "i686-mingw32msvc"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::X86); + assert!(triple.os == Ok(abi::OsWin32)); + assert!(triple.vendor == None); + assert!(triple.env == Some(Ok(MsvcEnv))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] + fn arm_linux_androideabi() { + // Another odd one, this one. Really should be arm-unknown-linux-androideabi or + // maybe arm-android-linux-eabi. + let original = "arm-linux-androideabi"; + let triple: Triple = FromStr::from_str(original).unwrap(); + assert!(triple.arch == abi::Arm); + assert!(triple.os == Ok(abi::OsAndroid)); + assert!(triple.vendor == None); + assert!(triple.env == Some(Ok(AndroidEAbiEnv))); + assert_eq!(triple.to_str(), original.to_str()); + } + #[test] #[should_fail] + fn blank() { + let original = ""; + let _: Triple = FromStr::from_str(original).unwrap(); + } + #[test] #[should_fail] + fn blank_hyphen() { + let original = "-"; + let _: Triple = FromStr::from_str(original).unwrap(); + } +} From 61e98ee0c3e4730119e88944b5dd0130843092b5 Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Thu, 17 Apr 2014 17:45:38 -0500 Subject: [PATCH 2/5] Use libmachine in librustc. Also removed Os in metadata/loader.rs. --- src/librustc/back/archive.rs | 4 +- src/librustc/back/arm.rs | 5 +- src/librustc/back/link.rs | 42 +++++++-------- src/librustc/back/mips.rs | 5 +- src/librustc/back/rpath.rs | 28 ++++++---- src/librustc/back/x86.rs | 5 +- src/librustc/back/x86_64.rs | 5 +- src/librustc/driver/driver.rs | 74 ++++++++------------------ src/librustc/driver/session.rs | 40 ++++++++------ src/librustc/lib.rs | 1 + src/librustc/metadata/creader.rs | 17 +++--- src/librustc/metadata/filesearch.rs | 38 ++++++++----- src/librustc/metadata/loader.rs | 9 +--- src/librustc/middle/trans/adt.rs | 4 +- src/librustc/middle/trans/base.rs | 11 ++-- src/librustc/middle/trans/cabi.rs | 4 +- src/librustc/middle/trans/cabi_x86.rs | 4 +- src/librustc/middle/trans/debuginfo.rs | 5 +- src/librustc/middle/trans/foreign.rs | 4 +- src/librustc/middle/trans/type_.rs | 4 +- 20 files changed, 147 insertions(+), 162 deletions(-) diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs index 27211c4779f8e..db324cc816f18 100644 --- a/src/librustc/back/archive.rs +++ b/src/librustc/back/archive.rs @@ -23,7 +23,7 @@ use std::os; use std::io::process::{ProcessConfig, Process, ProcessOutput}; use std::str; use std::raw; -use syntax::abi; +use machine::abi; pub static METADATA_FILENAME: &'static str = "rust.metadata.bin"; @@ -175,7 +175,7 @@ impl<'a> Archive<'a> { } fn find_library(&self, name: &str) -> Path { - let (osprefix, osext) = match self.sess.targ_cfg.os { + let (osprefix, osext) = match self.sess.target_os() { abi::OsWin32 => ("", "lib"), _ => ("lib", "a"), }; // On Windows, static libraries sometimes show up as libfoo.a and other diff --git a/src/librustc/back/arm.rs b/src/librustc/back/arm.rs index f86c87af72674..cdd29601d6f46 100644 --- a/src/librustc/back/arm.rs +++ b/src/librustc/back/arm.rs @@ -9,9 +9,8 @@ // except according to those terms. use back::target_strs; -use driver::session::sess_os_to_meta_os; use metadata::loader::meta_section_name; -use syntax::abi; +use machine::abi; pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::t { let cc_args = if target_triple.contains("thumb") { @@ -22,7 +21,7 @@ pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs:: return target_strs::t { module_asm: ~"", - meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)).to_owned(), + meta_sect_name: meta_section_name(target_os).to_owned(), data_layout: match target_os { abi::OsMacos => { diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 9ac99b267169e..f8edbcf92ad1b 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -30,13 +30,12 @@ use std::c_str::{ToCStr, CString}; use std::char; use std::io::{fs, TempDir, Process}; use std::io; -use std::os::consts::{macos, freebsd, linux, android, win32}; use std::ptr; use std::str; use std::strbuf::StrBuf; use flate; use serialize::hex::ToHex; -use syntax::abi; +use machine::abi; use syntax::ast; use syntax::ast_map::{PathElem, PathElems, PathName}; use syntax::ast_map; @@ -99,7 +98,6 @@ pub mod write { use lib::llvm::{ModuleRef, TargetMachineRef, PassManagerRef}; use lib; use util::common::time; - use syntax::abi; use std::c_str::ToCStr; use std::io::Process; @@ -112,7 +110,8 @@ pub mod write { // cases, so if any sort of target feature is specified we don't append v7 // to the feature list. fn target_feature<'a>(sess: &'a Session) -> &'a str { - match sess.targ_cfg.os { + use machine::abi; + match sess.target_os() { abi::OsAndroid => { if "" == sess.opts.cg.target_feature { "+v7" @@ -128,6 +127,7 @@ pub mod write { trans: &CrateTranslation, output_types: &[OutputType], output: &OutputFilenames) { + use machine::abi; let llmod = trans.module; let llcx = trans.context; unsafe { @@ -150,8 +150,8 @@ pub mod write { // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a parameter. // FIXME: #11954: mac64 unwinding may not work with fp elim let no_fp_elim = (sess.opts.debuginfo != NoDebugInfo) || - (sess.targ_cfg.os == abi::OsMacos && - sess.targ_cfg.arch == abi::X86_64); + (sess.target_os() == abi::OsMacos && + sess.target_arch() == abi::X86_64); let reloc_model = match sess.opts.cg.relocation_model.as_slice() { "pic" => lib::llvm::RelocPIC, @@ -737,7 +737,7 @@ pub fn get_cc_prog(sess: &Session) -> ~str { // It would be flexible to use cc (system's default C compiler) // instead of hard-coded gcc. // For win32, there is no cc command, so we add a condition to make it use gcc. - match sess.targ_cfg.os { + match sess.target_os() { abi::OsWin32 => return ~"gcc", _ => {}, } @@ -755,7 +755,7 @@ pub fn get_ar_prog(sess: &Session) -> ~str { } fn get_system_tool(sess: &Session, tool: &str) -> ~str { - match sess.targ_cfg.os { + match sess.target_os() { abi::OsAndroid => match sess.opts.cg.android_cross_path { Some(ref path) => { let tool_str = match tool { @@ -821,13 +821,7 @@ pub fn filename_for_input(sess: &Session, crate_type: session::CrateType, out_filename.with_filename(format!("lib{}.rlib", libname)) } session::CrateTypeDylib => { - let (prefix, suffix) = match sess.targ_cfg.os { - abi::OsWin32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX), - abi::OsMacos => (macos::DLL_PREFIX, macos::DLL_SUFFIX), - abi::OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX), - abi::OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX), - abi::OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX), - }; + let (prefix, suffix) = sess.target_triple().dylibname(); out_filename.with_filename(format!("{}{}{}", prefix, libname, suffix)) } session::CrateTypeStaticlib => { @@ -973,7 +967,7 @@ fn link_rlib<'a>(sess: &'a Session, // After adding all files to the archive, we need to update the // symbol table of the archive. This currently dies on OSX (see // #11162), and isn't necessary there anyway - match sess.targ_cfg.os { + match sess.target_os() { abi::OsMacos => {} _ => { a.update_symbols(); } } @@ -1066,7 +1060,7 @@ fn link_natively(sess: &Session, dylib: bool, obj_filename: &Path, // On OSX, debuggers need this utility to get run to do some munging of // the symbols - if sess.targ_cfg.os == abi::OsMacos && (sess.opts.debuginfo != NoDebugInfo) { + if sess.target_os() == abi::OsMacos && (sess.opts.debuginfo != NoDebugInfo) { // FIXME (#9639): This needs to handle non-utf8 paths match Process::status("dsymutil", [out_filename.as_str().unwrap().to_owned()]) { @@ -1130,11 +1124,11 @@ fn link_args(sess: &Session, // subset we wanted. // // FIXME(#11937) we should invoke the system linker directly - if sess.targ_cfg.os != abi::OsWin32 { + if sess.target_os() != abi::OsWin32 { args.push(~"-nodefaultlibs"); } - if sess.targ_cfg.os == abi::OsLinux { + if sess.target_os() == abi::OsLinux { // GNU-style linkers will use this to omit linking to libraries which // don't actually fulfill any relocations, but only for libraries which // follow this flag. Thus, use it before specifying libraries to link to. @@ -1150,7 +1144,7 @@ fn link_args(sess: &Session, } } - if sess.targ_cfg.os == abi::OsWin32 { + if sess.target_os() == abi::OsWin32 { // Make sure that we link to the dynamic libgcc, otherwise cross-module // DWARF stack unwinding will not work. // This behavior may be overridden by --link-args "-static-libgcc" @@ -1184,7 +1178,7 @@ fn link_args(sess: &Session, args.push(~"-Wl,--enable-long-section-names"); } - if sess.targ_cfg.os == abi::OsAndroid { + if sess.target_os() == abi::OsAndroid { // Many of the symbols defined in compiler-rt are also defined in libgcc. // Android linker doesn't like that by default. args.push(~"-Wl,--allow-multiple-definition"); @@ -1231,7 +1225,7 @@ fn link_args(sess: &Session, if dylib { // On mac we need to tell the linker to let this library be rpathed - if sess.targ_cfg.os == abi::OsMacos { + if sess.target_os() == abi::OsMacos { args.push(~"-dynamiclib"); args.push(~"-Wl,-dylib"); // FIXME (#9639): This needs to handle non-utf8 paths @@ -1244,7 +1238,7 @@ fn link_args(sess: &Session, } } - if sess.targ_cfg.os == abi::OsFreebsd { + if sess.target_os() == abi::OsFreebsd { args.push_all([~"-L/usr/local/lib", ~"-L/usr/local/lib/gcc46", ~"-L/usr/local/lib/gcc44"]); @@ -1388,7 +1382,7 @@ fn add_upstream_rust_crates(args: &mut Vec<~str>, sess: &Session, // Converts a library file-stem into a cc -l argument fn unlib(config: &session::Config, stem: &str) -> ~str { - if stem.starts_with("lib") && config.os != abi::OsWin32 { + if stem.starts_with("lib") && config.os() != abi::OsWin32 { stem.slice(3, stem.len()).to_owned() } else { stem.to_owned() diff --git a/src/librustc/back/mips.rs b/src/librustc/back/mips.rs index 9667d7b84e9c0..d6b7d506f992f 100644 --- a/src/librustc/back/mips.rs +++ b/src/librustc/back/mips.rs @@ -9,15 +9,14 @@ // except according to those terms. use back::target_strs; -use driver::session::sess_os_to_meta_os; use metadata::loader::meta_section_name; -use syntax::abi; +use machine::abi; pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::t { return target_strs::t { module_asm: ~"", - meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)).to_owned(), + meta_sect_name: meta_section_name(target_os).to_owned(), data_layout: match target_os { abi::OsMacos => { diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index b96e4b06c46d3..051e2b3368b43 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -12,18 +12,19 @@ use driver::session::Session; use metadata::cstore; use metadata::filesearch; +use machine::triple; use util::fs; use collections::HashSet; use std::os; -use syntax::abi; +use machine::abi; fn not_win32(os: abi::Os) -> bool { os != abi::OsWin32 } pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<~str> { - let os = sess.targ_cfg.os; + let os = sess.target_os(); // No rpath on windows if os == abi::OsWin32 { @@ -32,7 +33,7 @@ pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<~str> { let mut flags = Vec::new(); - if sess.targ_cfg.os == abi::OsFreebsd { + if sess.target_os() == abi::OsFreebsd { flags.push_all([~"-Wl,-rpath,/usr/local/lib/gcc46", ~"-Wl,-rpath,/usr/local/lib/gcc44", ~"-Wl,-z,origin"]); @@ -48,7 +49,7 @@ pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<~str> { }).collect::<~[_]>(); let rpaths = get_rpaths(os, sysroot, output, libs, - sess.opts.target_triple); + sess.target_triple()); flags.push_all(rpaths_to_flags(rpaths.as_slice()).as_slice()); flags } @@ -65,7 +66,7 @@ fn get_rpaths(os: abi::Os, sysroot: &Path, output: &Path, libs: &[Path], - target_triple: &str) -> Vec<~str> { + target_triple: &triple::Triple) -> Vec<~str> { debug!("sysroot: {}", sysroot.display()); debug!("output: {}", output.display()); debug!("libs:"); @@ -132,7 +133,7 @@ pub fn get_rpath_relative_to_output(os: abi::Os, prefix+"/"+relative.as_str().expect("non-utf8 component in path") } -pub fn get_install_prefix_rpath(sysroot: &Path, target_triple: &str) -> ~str { +pub fn get_install_prefix_rpath(sysroot: &Path, target_triple: &triple::Triple) -> ~str { let install_prefix = env!("CFG_PREFIX"); let tlib = filesearch::relative_target_lib_path(sysroot, target_triple); @@ -156,11 +157,17 @@ pub fn minimize_rpaths(rpaths: &[~str]) -> Vec<~str> { #[cfg(unix, test)] mod test { + use std::from_str::FromStr; use back::rpath::get_install_prefix_rpath; use back::rpath::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output}; - use syntax::abi; + use machine::triple::Triple; + use machine::abi; use metadata::filesearch; + fn triple() -> Triple { + FromStr::from_str("x86_64-unknown-linux-gnu").unwrap() + } + #[test] fn test_rpaths_to_flags() { let flags = rpaths_to_flags([~"path1", ~"path2"]); @@ -170,11 +177,12 @@ mod test { #[test] fn test_prefix_rpath() { let sysroot = filesearch::get_or_default_sysroot(); - let res = get_install_prefix_rpath(&sysroot, "triple"); + let triple = triple(); + let res = get_install_prefix_rpath(&sysroot, &triple); let mut d = Path::new(env!("CFG_PREFIX")); d.push("lib"); d.push(filesearch::rustlibdir()); - d.push("triple/lib"); + d.push("x86_64-unknown-linux-gnu/lib"); debug!("test_prefix_path: {} vs. {}", res, d.display()); @@ -184,7 +192,7 @@ mod test { #[test] fn test_prefix_rpath_abs() { let sysroot = filesearch::get_or_default_sysroot(); - let res = get_install_prefix_rpath(&sysroot, "triple"); + let res = get_install_prefix_rpath(&sysroot, &triple()); assert!(Path::new(res).is_absolute()); } diff --git a/src/librustc/back/x86.rs b/src/librustc/back/x86.rs index 9b22c82e91776..c831758182a5e 100644 --- a/src/librustc/back/x86.rs +++ b/src/librustc/back/x86.rs @@ -10,15 +10,14 @@ use back::target_strs; -use driver::session::sess_os_to_meta_os; use metadata::loader::meta_section_name; -use syntax::abi; +use machine::abi; pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::t { return target_strs::t { module_asm: ~"", - meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)).to_owned(), + meta_sect_name: meta_section_name(target_os).to_owned(), data_layout: match target_os { abi::OsMacos => { diff --git a/src/librustc/back/x86_64.rs b/src/librustc/back/x86_64.rs index 524ae5e552484..a4433c3a9ff3a 100644 --- a/src/librustc/back/x86_64.rs +++ b/src/librustc/back/x86_64.rs @@ -10,15 +10,14 @@ use back::target_strs; -use driver::session::sess_os_to_meta_os; use metadata::loader::meta_section_name; -use syntax::abi; +use machine::abi; pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::t { return target_strs::t { module_asm: ~"", - meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)).to_owned(), + meta_sect_name: meta_section_name(target_os).to_owned(), data_layout: match target_os { abi::OsMacos => { diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 1637785d6d49a..880992ac34071 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -28,6 +28,7 @@ use middle; use util::common::time; use util::ppaux; use util::nodemap::{NodeMap, NodeSet}; +use machine::triple; use serialize::{json, Encodable}; @@ -37,10 +38,10 @@ use std::io::fs; use std::io::MemReader; use std::mem::drop; use std::os; +use std::from_str::FromStr; use getopts::{optopt, optmulti, optflag, optflagopt}; use getopts; use syntax::ast; -use syntax::abi; use syntax::attr; use syntax::attr::{AttrMetaMethods}; use syntax::codemap; @@ -80,7 +81,8 @@ pub fn source_name(input: &Input) -> ~str { pub fn default_configuration(sess: &Session) -> ast::CrateConfig { - let tos = match sess.targ_cfg.os { + use machine::abi; + let tos = match sess.target_os() { abi::OsWin32 => InternedString::new("win32"), abi::OsMacos => InternedString::new("macos"), abi::OsLinux => InternedString::new("linux"), @@ -90,14 +92,14 @@ pub fn default_configuration(sess: &Session) -> // ARM is bi-endian, however using NDK seems to default // to little-endian unless a flag is provided. - let (end,arch,wordsz) = match sess.targ_cfg.arch { + let (end,arch,wordsz) = match sess.target_arch() { abi::X86 => ("little", "x86", "32"), abi::X86_64 => ("little", "x86_64", "64"), abi::Arm => ("little", "arm", "32"), abi::Mips => ("big", "mips", "32") }; - let fam = match sess.targ_cfg.os { + let fam = match sess.target_os() { abi::OsWin32 => InternedString::new("windows"), _ => InternedString::new("unix") }; @@ -285,7 +287,7 @@ pub fn phase_3_run_analysis_passes(sess: Session, time(time_passes, "external crate/lib resolution", (), |_| creader::read_crates(&sess, krate, - session::sess_os_to_meta_os(sess.targ_cfg.os), + sess.target_os(), token::get_ident_interner())); let lang_items = time(time_passes, "language item collection", (), |_| @@ -734,66 +736,33 @@ pub fn pretty_print_input(sess: Session, } -pub fn get_os(triple: &str) -> Option { - for &(name, os) in os_names.iter() { - if triple.contains(name) { return Some(os) } - } - None -} -static os_names : &'static [(&'static str, abi::Os)] = &'static [ - ("mingw32", abi::OsWin32), - ("win32", abi::OsWin32), - ("darwin", abi::OsMacos), - ("android", abi::OsAndroid), - ("linux", abi::OsLinux), - ("freebsd", abi::OsFreebsd)]; - -pub fn get_arch(triple: &str) -> Option { - for &(arch, abi) in architecture_abis.iter() { - if triple.contains(arch) { return Some(abi) } - } - None -} -static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'static [ - ("i386", abi::X86), - ("i486", abi::X86), - ("i586", abi::X86), - ("i686", abi::X86), - ("i786", abi::X86), - - ("x86_64", abi::X86_64), - - ("arm", abi::Arm), - ("xscale", abi::Arm), - ("thumb", abi::Arm), - - ("mips", abi::Mips)]; - pub fn build_target_config(sopts: &session::Options) -> session::Config { - let os = match get_os(sopts.target_triple) { - Some(os) => os, - None => early_error("unknown operating system") - }; - let arch = match get_arch(sopts.target_triple) { - Some(arch) => arch, - None => early_error("unknown architecture: " + sopts.target_triple) + use machine::abi; + let triple: triple::Triple = + match FromStr::from_str(sopts.target_triple) { + Some(triple) => triple, + None => early_error(format!("unknown architecture or missing operating system: `{}`", + sopts.target_triple)), + }; + let os = match triple.os { + Ok(ref os) => os.clone(), + Err(ref os_str) => early_error("unknown operating system: " + *os_str), }; - let (int_type, uint_type) = match arch { + let (int_type, uint_type) = match triple.arch { abi::X86 => (ast::TyI32, ast::TyU32), abi::X86_64 => (ast::TyI64, ast::TyU64), abi::Arm => (ast::TyI32, ast::TyU32), abi::Mips => (ast::TyI32, ast::TyU32) }; let target_triple = sopts.target_triple.clone(); - let target_strs = match arch { + let target_strs = match triple.arch { abi::X86 => x86::get_target_strs(target_triple, os), abi::X86_64 => x86_64::get_target_strs(target_triple, os), abi::Arm => arm::get_target_strs(target_triple, os), abi::Mips => mips::get_target_strs(target_triple, os) }; session::Config { - os: os, - arch: arch, + target: triple, target_strs: target_strs, int_type: int_type, uint_type: uint_type, @@ -1224,8 +1193,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( - session::sess_os_to_meta_os(sess.targ_cfg.os), path, out) + metadata::loader::list_file_metadata(sess.target_os(), path, out) } #[cfg(test)] diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 09222c39403e0..a2006fba034e6 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -27,16 +27,26 @@ use syntax::parse::ParseSess; use syntax::{abi, ast, codemap}; use syntax; +use machine::triple::Triple; + use std::cell::{Cell, RefCell}; +use std::default::Default; use collections::HashSet; pub struct Config { - pub os: abi::Os, - pub arch: abi::Architecture, + pub target: Triple, pub target_strs: target_strs::t, pub int_type: IntTy, pub uint_type: UintTy, } +impl Config { + pub fn os(&self) -> abi::Os { + self.target.expect_known_os() + } + pub fn arch(&self) -> abi::Architecture { + self.target.arch.clone() + } +} macro_rules! debugging_opts( ([ $opt:ident ] $cnt:expr ) => ( @@ -327,9 +337,21 @@ impl Session { }; filesearch::FileSearch::new( sysroot, - self.opts.target_triple, + self.target_triple().clone(), &self.opts.addl_lib_search_paths) } + pub fn target_os(&self) -> abi::Os { + self.targ_cfg.os() + } + pub fn target_arch(&self) -> abi::Architecture { + self.targ_cfg.arch() + } + pub fn target_triple<'a>(&'a self) -> &'a Triple { + &self.targ_cfg.target + } + pub fn cross_compiling(&self) -> bool { + *self.target_triple() != Default::default() + } } /// Some reasonable defaults @@ -546,15 +568,3 @@ pub fn collect_crate_types(session: &Session, return base; } } - -pub fn sess_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 - } -} diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 7b1d0068035c8..58ab26a7ac616 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -40,6 +40,7 @@ extern crate getopts; extern crate collections; extern crate time; extern crate libc; +extern crate machine; #[phase(syntax, link)] extern crate log; diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 799da4150c5d3..e0bc984d5f1b4 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -14,20 +14,18 @@ use back::link; use back::svh::Svh; -use driver::{driver, session}; use driver::session::Session; use metadata::cstore; use metadata::cstore::CStore; use metadata::decoder; use metadata::loader; -use metadata::loader::Os; use metadata::loader::CratePaths; use std::cell::RefCell; use std::rc::Rc; use collections::HashMap; +use syntax; use syntax::ast; -use syntax::abi; use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::codemap::{Span}; @@ -37,10 +35,11 @@ use syntax::parse::token::{IdentInterner, InternedString}; use syntax::parse::token; use syntax::crateid::CrateId; use syntax::visit; +use machine::abi; struct Env<'a> { sess: &'a Session, - os: loader::Os, + os: abi::Os, next_crate_num: ast::CrateNum, intr: Rc } @@ -49,7 +48,7 @@ struct Env<'a> { // libraries necessary for later resolving, typechecking, linking, etc. pub fn read_crates(sess: &Session, krate: &ast::Crate, - os: loader::Os, + os: abi::Os, intr: Rc) { let mut e = Env { sess: sess, @@ -178,7 +177,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option { fn visit_item(e: &Env, i: &ast::Item) { match i.node { ast::ItemForeignMod(ref fm) => { - if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic { + if fm.abi == syntax::abi::Rust || fm.abi == syntax::abi::RustIntrinsic { return; } @@ -215,7 +214,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 && + } else if e.sess.target_os() == abi::OsMacos && k.equiv(&("framework")) { cstore::NativeFramework } else if k.equiv(&("framework")) { @@ -387,8 +386,8 @@ pub struct Loader<'a> { impl<'a> Loader<'a> { pub fn new(sess: &'a Session) -> Loader<'a> { - let os = driver::get_os(driver::host_triple()).unwrap(); - let os = session::sess_os_to_meta_os(os); + use machine::triple::Triple; + let os = Triple::host_triple().expect_known_os(); Loader { env: Env { sess: sess, diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index f4ea386a2ecad..7b2a35059cc9a 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -11,9 +11,10 @@ #![allow(non_camel_case_types)] use std::cell::RefCell; -use std::os; +use std::{os, clone}; use std::io::fs; use collections::HashSet; +use machine::triple::Triple; use myfs = util::fs; @@ -30,7 +31,16 @@ pub type pick<'a> = |path: &Path|: 'a -> FileMatch; pub struct FileSearch<'a> { pub sysroot: &'a Path, pub addl_lib_search_paths: &'a RefCell>, - pub target_triple: &'a str + pub target_triple: Triple, +} +impl<'a> clone::Clone for FileSearch<'a> { + fn clone(&self) -> FileSearch<'a> { + FileSearch { + sysroot: self.sysroot, + addl_lib_search_paths: self.addl_lib_search_paths, + target_triple: self.target_triple.clone(), + } + } } impl<'a> FileSearch<'a> { @@ -50,7 +60,7 @@ impl<'a> FileSearch<'a> { debug!("filesearch: searching target lib path"); let tlib_path = make_target_lib_path(self.sysroot, - self.target_triple); + &self.target_triple); if !visited_dirs.contains_equiv(&tlib_path.as_vec()) { match f(&tlib_path) { FileMatches => found = true, @@ -63,7 +73,7 @@ impl<'a> FileSearch<'a> { let rustpath = rust_path(); for path in rustpath.iter() { let tlib_path = make_rustpkg_target_lib_path( - self.sysroot, path, self.target_triple); + self.sysroot, path, &self.target_triple); debug!("is {} in visited_dirs? {:?}", tlib_path.display(), visited_dirs.contains_equiv(&tlib_path.as_vec().to_owned())); @@ -83,7 +93,7 @@ impl<'a> FileSearch<'a> { } pub fn get_target_lib_path(&self) -> Path { - make_target_lib_path(self.sysroot, self.target_triple) + make_target_lib_path(self.sysroot, &self.target_triple) } pub fn search(&self, pick: pick) { @@ -122,7 +132,7 @@ impl<'a> FileSearch<'a> { } pub fn new(sysroot: &'a Path, - target_triple: &'a str, + target_triple: Triple, addl_lib_search_paths: &'a RefCell>) -> FileSearch<'a> { debug!("using sysroot = {}", sysroot.display()); FileSearch { @@ -133,25 +143,29 @@ impl<'a> FileSearch<'a> { } } -pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path { +pub fn get_host_lib_path(sysroot: &Path) -> Path { + sysroot.join(find_libdir(sysroot)) +} + +pub fn relative_target_lib_path(sysroot: &Path, target_triple: &Triple) -> Path { let mut p = Path::new(find_libdir(sysroot)); assert!(p.is_relative()); p.push(rustlibdir()); - p.push(target_triple); + p.push(target_triple.to_str()); p.push("lib"); p } -fn make_target_lib_path(sysroot: &Path, - target_triple: &str) -> Path { +pub fn make_target_lib_path(sysroot: &Path, + target_triple: &Triple) -> Path { sysroot.join(&relative_target_lib_path(sysroot, target_triple)) } fn make_rustpkg_target_lib_path(sysroot: &Path, dir: &Path, - target_triple: &str) -> Path { + target_triple: &Triple) -> Path { let mut p = dir.join(find_libdir(sysroot)); - p.push(target_triple); + p.push(target_triple.to_str()); p } diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 5a342e39d701a..0f4ec3d4e9793 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -23,6 +23,7 @@ use syntax::diagnostic::SpanHandler; use syntax::parse::token::IdentInterner; use syntax::crateid::CrateId; use syntax::attr::AttrMetaMethods; +use machine::abi::{Os, OsLinux, OsMacos, OsWin32, OsAndroid, OsFreebsd}; use std::c_str::ToCStr; use std::cast; @@ -38,14 +39,6 @@ use collections::{HashMap, HashSet}; use flate; use time; -pub enum Os { - OsMacos, - OsWin32, - OsLinux, - OsAndroid, - OsFreebsd -} - pub struct HashMismatch { path: Path, } diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index da78b650852e8..fd53e621da69d 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -57,7 +57,7 @@ use middle::trans::type_::Type; use middle::trans::type_of; use middle::ty; use middle::ty::Disr; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use machine::abi::{X86, X86_64, Arm, Mips}; use syntax::ast; use syntax::attr; use syntax::attr::IntType; @@ -326,7 +326,7 @@ fn range_to_inttype(cx: &CrateContext, hint: Hint, bounds: &IntBounds) -> IntTyp return ity; } attr::ReprExtern => { - attempts = match cx.sess().targ_cfg.arch { + attempts = match cx.sess().target_arch() { X86 | X86_64 => at_least_32, // WARNING: the ARM EABI has two variants; the one corresponding to `at_least_32` // appears to be used on Linux and NetBSD, but some systems may use the variant diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 5f063bb31ca5a..af37affceeb14 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -75,7 +75,8 @@ use libc::c_uint; use std::c_str::ToCStr; use std::cell::{Cell, RefCell}; use std::local_data; -use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic}; +use machine::abi::{X86, X86_64, Arm, Mips}; +use syntax::abi::{Rust, RustIntrinsic}; use syntax::ast_util::{local_def, is_local}; use syntax::attr::AttrMetaMethods; use syntax::attr; @@ -808,8 +809,8 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val let name = csearch::get_symbol(&ccx.sess().cstore, did); match ty::get(t).sty { ty::ty_bare_fn(ref fn_ty) => { - match fn_ty.abi.for_target(ccx.sess().targ_cfg.os, - ccx.sess().targ_cfg.arch) { + match fn_ty.abi.for_target(ccx.sess().target_os(), + ccx.sess().target_arch()) { Some(Rust) | Some(RustIntrinsic) => { get_extern_rust_fn(ccx, fn_ty.sig.inputs.as_slice(), @@ -973,7 +974,7 @@ pub fn with_cond<'a>( pub fn call_memcpy(cx: &Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) { let _icx = push_ctxt("call_memcpy"); let ccx = cx.ccx(); - let key = match ccx.sess().targ_cfg.arch { + let key = match ccx.sess().target_arch() { X86 | Arm | Mips => "llvm.memcpy.p0i8.p0i8.i32", X86_64 => "llvm.memcpy.p0i8.p0i8.i64" }; @@ -1017,7 +1018,7 @@ fn memzero(b: &Builder, llptr: ValueRef, ty: Type) { let _icx = push_ctxt("memzero"); let ccx = b.ccx; - let intrinsic_key = match ccx.sess().targ_cfg.arch { + let intrinsic_key = match ccx.sess().target_arch() { X86 | Arm | Mips => "llvm.memset.p0i8.i32", X86_64 => "llvm.memset.p0i8.i64" }; diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index 2c9be587eaa9e..c98be044f6332 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -16,7 +16,7 @@ use middle::trans::cabi_x86_64; use middle::trans::cabi_arm; use middle::trans::cabi_mips; use middle::trans::type_::Type; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use machine::abi::{X86, X86_64, Arm, Mips}; #[deriving(Clone, Eq)] pub enum ArgKind { @@ -105,7 +105,7 @@ pub fn compute_abi_info(ccx: &CrateContext, atys: &[Type], rty: Type, ret_def: bool) -> FnType { - match ccx.sess().targ_cfg.arch { + match ccx.sess().target_arch() { X86 => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def), X86_64 => cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def), Arm => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def), diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index 93b6fdd8988c5..4b97931667032 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -9,7 +9,7 @@ // except according to those terms. -use syntax::abi::{OsWin32, OsMacos}; +use machine::abi::{OsWin32, OsMacos}; use lib::llvm::*; use super::cabi::*; use super::common::*; @@ -35,7 +35,7 @@ pub fn compute_abi_info(ccx: &CrateContext, // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp enum Strategy { RetValue(Type), RetPointer } - let strategy = match ccx.sess().targ_cfg.os { + let strategy = match ccx.sess().target_os() { OsWin32 | OsMacos => { match llsize_of_alloc(ccx, rty) { 1 => RetValue(Type::i8(ccx)), diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 60c6c5ee97aa4..76a1a7a8a5274 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -150,8 +150,9 @@ use libc::{c_uint, c_ulonglong, c_longlong}; use std::ptr; use std::strbuf::StrBuf; use std::sync::atomics; +use machine::abi; use syntax::codemap::{Span, Pos}; -use syntax::{abi, ast, codemap, ast_util, ast_map}; +use syntax::{ast, codemap, ast_util, ast_map}; use syntax::owned_slice::OwnedSlice; use syntax::parse::token; use syntax::parse::token::special_idents; @@ -275,7 +276,7 @@ pub fn finalize(cx: &CrateContext) { // instruct LLVM to emit an older version of dwarf, however, // for OS X to understand. For more info see #11352 // This can be overridden using --llvm-opts -dwarf-version,N. - if cx.sess().targ_cfg.os == abi::OsMacos { + if cx.sess().target_os() == abi::OsMacos { "Dwarf Version".with_c_str( |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 2)); } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 0a2bf60bf04e2..14119cd2062d8 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -74,8 +74,8 @@ struct LlvmSignature { pub fn llvm_calling_convention(ccx: &CrateContext, abi: Abi) -> Option { - let os = ccx.sess().targ_cfg.os; - let arch = ccx.sess().targ_cfg.arch; + let os = ccx.sess().target_os(); + let arch = ccx.sess().target_arch(); abi.for_target(os, arch).map(|abi| { match abi { RustIntrinsic => { diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 6f91ec53419e0..4b830ea77e8a9 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -16,7 +16,7 @@ use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use middle::trans::context::CrateContext; use syntax::ast; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use machine::abi::{X86, X86_64, Arm, Mips}; use std::c_str::ToCStr; use std::cast; @@ -101,7 +101,7 @@ impl Type { } pub fn int(ccx: &CrateContext) -> Type { - match ccx.tcx.sess.targ_cfg.arch { + match ccx.tcx.sess.target_arch() { X86 | Arm | Mips => Type::i32(ccx), X86_64 => Type::i64(ccx) } From ee4f9535c1bcdaaa55d9d024387d63cd4dd10b57 Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Thu, 17 Apr 2014 17:54:00 -0500 Subject: [PATCH 3/5] Move FileSearch::dylibname to Os::dylibname. De-duplicate Triple::dylibname, instead hand to OS. --- src/libmachine/abi.rs | 14 ++++++++++++++ src/libmachine/triple.rs | 11 ++--------- src/librustc/metadata/loader.rs | 15 +-------------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/libmachine/abi.rs b/src/libmachine/abi.rs index e1267a60c71d6..e34ec2836a850 100644 --- a/src/libmachine/abi.rs +++ b/src/libmachine/abi.rs @@ -10,6 +10,7 @@ use std::fmt; use std::from_str; +use std::os::consts::{macos, freebsd, linux, android, win32}; #[deriving(Eq, Hash, Clone, TotalEq)] pub enum Os { @@ -19,6 +20,19 @@ pub enum Os { OsAndroid, OsFreebsd, } +impl Os { + // Returns the corresponding (prefix, suffix) that files need to have for + // dynamic libraries for the specified OS. + pub fn dylibname(&self) -> (&'static str, &'static str) { + match self { + &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), + } + } +} impl from_str::FromStr for Os { fn from_str(s: &str) -> Option { diff --git a/src/libmachine/triple.rs b/src/libmachine/triple.rs index 2d1778b5684b2..44bdc7106e95c 100644 --- a/src/libmachine/triple.rs +++ b/src/libmachine/triple.rs @@ -11,7 +11,6 @@ use std::result::{Result, Ok, Err}; use std::from_str::FromStr; use std::{cmp, fmt, default}; -use std::os::consts::{macos, freebsd, linux, android, win32}; use abi; pub type KnownType = Result; @@ -138,14 +137,8 @@ impl Triple { // dynamic libraries. Note this expects a known OS, which should all be // fine except for the session builder (the session builder won't proceed // if we don't have a known OS). - pub fn dylibname(&self) -> (&'static str, &'static str) { - match self.expect_known_os() { - abi::OsWin32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX), - abi::OsMacos => (macos::DLL_PREFIX, macos::DLL_SUFFIX), - abi::OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX), - abi::OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX), - abi::OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX), - } + #[inline] pub fn dylibname(&self) -> (&'static str, &'static str) { + self.expect_known_os().dylibname() } // Are we targeting Android? diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 0f4ec3d4e9793..b5158d301bc0d 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -29,7 +29,6 @@ use std::c_str::ToCStr; use std::cast; use std::cmp; use std::io; -use std::os::consts::{macos, freebsd, linux, android, win32}; use std::ptr; use std::rc::Rc; use std::slice; @@ -143,7 +142,7 @@ impl<'a> Context<'a> { fn find_library_crate(&mut self) -> Option { let filesearch = self.sess.filesearch(); - let (dyprefix, dysuffix) = self.dylibname(); + let (dyprefix, dysuffix) = self.os.dylibname(); // want: crate_name.dir_part() + prefix + crate_name.file_part + "-" let dylib_prefix = format!("{}{}-", dyprefix, self.crate_id.name); @@ -386,18 +385,6 @@ impl<'a> Context<'a> { } } } - - // Returns the corresponding (prefix, suffix) that files need to have for - // dynamic libraries - fn dylibname(&self) -> (&'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), - } - } } pub fn note_crateid_attr(diag: &SpanHandler, crateid: &CrateId) { From 3463e283bf5e37e210a9aedace7f3d99f515a79d Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Thu, 17 Apr 2014 17:55:56 -0500 Subject: [PATCH 4/5] Use libmachine in libsyntax. I choose to use ```pub use```s to ease the transition to the new crate. --- src/libsyntax/abi.rs | 53 ++++++++++++++++++-------------------------- src/libsyntax/lib.rs | 1 + 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 17251d31351ab..4997701d0551f 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -9,9 +9,9 @@ // except according to those terms. use std::fmt; - -#[deriving(Eq)] -pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, } +use machine::abi; +pub use machine::abi::Os; +pub use machine::abi::Architecture; #[deriving(Eq, TotalEq, Hash, Encodable, Decodable, Clone)] pub enum Abi { @@ -32,21 +32,6 @@ pub enum Abi { RustIntrinsic, } -#[allow(non_camel_case_types)] -#[deriving(Eq)] -pub enum Architecture { - // NB. You cannot change the ordering of these - // constants without adjusting IntelBits below. - // (This is ensured by the test indices_are_correct().) - X86, - X86_64, - Arm, - Mips -} - -static IntelBits: u32 = (1 << (X86 as uint)) | (1 << (X86_64 as uint)); -static ArmBits: u32 = (1 << (Arm as uint)); - pub struct AbiData { abi: Abi, @@ -66,12 +51,12 @@ pub enum AbiArchitecture { static AbiDatas: &'static [AbiData] = &[ // Platform-specific ABIs - AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(IntelBits)}, - AbiData {abi: Stdcall, name: "stdcall", abi_arch: Archs(IntelBits)}, - AbiData {abi: Fastcall, name:"fastcall", abi_arch: Archs(IntelBits)}, - AbiData {abi: Aapcs, name: "aapcs", abi_arch: Archs(ArmBits)}, + AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(abi::IntelBits)}, + AbiData {abi: Stdcall, name: "stdcall", abi_arch: Archs(abi::IntelBits)}, + AbiData {abi: Fastcall, name:"fastcall", abi_arch: Archs(abi::IntelBits)}, + AbiData {abi: Aapcs, name: "aapcs", abi_arch: Archs(abi::ArmBits)}, AbiData {abi: Win64, name: "win64", - abi_arch: Archs(1 << (X86_64 as uint))}, + abi_arch: Archs(1 << (abi::X86_64 as uint))}, // Cross-platform ABIs // @@ -130,7 +115,7 @@ impl Abi { self.data().name } - pub fn for_target(&self, os: Os, arch: Architecture) -> Option { + pub fn for_target(&self, os: abi::Os, arch: abi::Architecture) -> Option { // If this ABI isn't actually for the specified architecture, then we // short circuit early match self.data().abi_arch { @@ -140,14 +125,18 @@ impl Abi { // Transform this ABI as appropriate for the requested os/arch // combination. Some(match (*self, os, arch) { - (System, OsWin32, X86) => Stdcall, + (System, abi::OsWin32, abi::X86) => Stdcall, (System, _, _) => C, (me, _, _) => me, }) } } -impl Architecture { +trait ArchBit { + fn bit(&self) -> u32; +} + +impl ArchBit for Architecture { fn bit(&self) -> u32 { 1 << (*self as u32) } @@ -183,16 +172,18 @@ fn indices_are_correct() { assert_eq!(i, abi_data.abi.index()); } - let bits = 1 << (X86 as u32); - let bits = bits | 1 << (X86_64 as u32); - assert_eq!(IntelBits, bits); + let bits = 1 << (abi::X86 as u32); + let bits = bits | 1 << (abi::X86_64 as u32); + assert_eq!(abi::IntelBits, bits); - let bits = 1 << (Arm as u32); - assert_eq!(ArmBits, bits); + let bits = 1 << (abi::Arm as u32); + assert_eq!(abi::ArmBits, bits); } #[test] fn pick_uniplatform() { + use machine::abi::{OsLinux, OsWin32, + X86, X86_64, Arm}; assert_eq!(Stdcall.for_target(OsLinux, X86), Some(Stdcall)); assert_eq!(Stdcall.for_target(OsLinux, Arm), None); assert_eq!(System.for_target(OsLinux, X86), Some(C)); diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 012bc50ecabc8..2e1b272decc05 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -35,6 +35,7 @@ extern crate term; extern crate collections; #[phase(syntax, link)] extern crate log; +extern crate machine; pub mod util { pub mod interner; From bae44b198caf060f0fec23e2eeedfaab17839bbe Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Thu, 17 Apr 2014 18:16:53 -0500 Subject: [PATCH 5/5] Use libmachine in compiletest. --- src/compiletest/common.rs | 17 ++- src/compiletest/compiletest.rs | 19 ++- src/compiletest/header.rs | 3 +- src/compiletest/runtest.rs | 251 +++++++++++++++------------------ 4 files changed, 147 insertions(+), 143 deletions(-) diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index ea6e98fafa7cd..65754c52b0a44 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use machine::triple::Triple; + #[deriving(Clone, Eq)] pub enum mode { mode_compile_fail, @@ -87,10 +89,10 @@ pub struct config { pub jit: bool, // Target system to be tested - pub target: ~str, + pub target: Triple, // Host triple for the compiler being invoked - pub host: ~str, + pub host: Triple, // Extra parameter to run adb on arm-linux-androideabi pub adb_path: ~str, @@ -105,3 +107,14 @@ pub struct config { pub verbose: bool } + +impl config { + pub fn is_cross_compile(&self) -> bool { + self.target != self.host + } + + pub fn is_target_android(&self) -> bool { + self.target.is_android() + } +} + diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index d2499ea33bdd6..98b57e32e3282 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -23,6 +23,7 @@ extern crate getopts; extern crate log; extern crate green; extern crate rustuv; +extern crate machine; use std::os; use std::io; @@ -58,6 +59,8 @@ pub fn main() { } pub fn parse_config(args: Vec<~str> ) -> config { + use std::from_str::FromStr; + use std::default::Default; let groups : Vec = vec!(reqopt("", "compile-lib-path", "path to host shared libraries", "PATH"), @@ -145,8 +148,18 @@ pub fn parse_config(args: Vec<~str> ) -> config { host_rustcflags: matches.opt_str("host-rustcflags"), target_rustcflags: matches.opt_str("target-rustcflags"), jit: matches.opt_present("jit"), - target: opt_str2(matches.opt_str("target")).to_str(), - host: opt_str2(matches.opt_str("host")).to_str(), + target: matches + .opt_str("target") + .and_then(|triple| { + FromStr::from_str(triple) + }) + .unwrap_or_else(|| Default::default() ), + host: matches + .opt_str("host") + .and_then(|triple| { + FromStr::from_str(triple) + }) + .unwrap_or_else(|| Default::default() ), adb_path: opt_str2(matches.opt_str("adb-path")).to_str(), adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")).to_str(), @@ -226,7 +239,7 @@ pub fn mode_str(mode: mode) -> ~str { } pub fn run_tests(config: &config) { - if config.target == ~"arm-linux-androideabi" { + if config.is_target_android() { match config.mode{ mode_debug_info => { println!("arm-linux-androideabi debug-info \ diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index b45a68518a3ec..f8e0d11e3b6dd 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -10,7 +10,6 @@ use common::config; use common; -use util; pub struct TestProps { // Lines that should be expected, in order, on standard out @@ -112,7 +111,7 @@ pub fn load_props(testfile: &Path) -> TestProps { pub fn is_test_ignored(config: &config, testfile: &Path) -> bool { fn ignore_target(config: &config) -> ~str { - ~"ignore-" + util::get_os(config.target) + ~"ignore-" + config.target.expect_known_os().to_str() } fn ignore_stage(config: &config) -> ~str { ~"ignore-" + config.stage_id.split('-').next().unwrap() diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 17b5aa4a83af3..83001faf3f8f2 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -37,15 +37,10 @@ use test::MetricMap; pub fn run(config: config, testfile: ~str) { - match config.target.as_slice() { - - "arm-linux-androideabi" => { - if !config.adb_device_status { - fail!("android device not available"); - } + if config.is_target_android() { + if !config.adb_device_status { + fail!("android device not available"); } - - _=> { } } let mut _mm = MetricMap::new(); @@ -208,7 +203,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) { fn make_pp_args(config: &config, _testfile: &Path) -> ProcArgs { let args = vec!(~"-", ~"--pretty", ~"normal", - ~"--target=" + config.target); + ~"--target=" + config.target.full); // FIXME (#9639): This needs to handle non-utf8 paths return ProcArgs {prog: config.rustc_path.as_str().unwrap().to_owned(), args: args}; } @@ -240,9 +235,9 @@ actual:\n\ fn make_typecheck_args(config: &config, props: &TestProps, testfile: &Path) -> ProcArgs { let aux_dir = aux_output_dir_name(config, testfile); let target = if props.force_host { - config.host.as_slice() + config.host.full.as_slice() } else { - config.target.as_slice() + config.target.full.as_slice() }; // FIXME (#9639): This needs to handle non-utf8 paths let mut args = vec!(~"-", @@ -278,119 +273,114 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) { let exe_file = make_exe_name(config, testfile); let mut proc_args; - match config.target.as_slice() { - "arm-linux-androideabi" => { - - cmds = cmds.replace("run","continue"); - - // write debugger script - let script_str = [~"set charset UTF-8", - format!("file {}",exe_file.as_str().unwrap().to_owned()), - ~"target remote :5039", - cmds, - ~"quit"].connect("\n"); - debug!("script_str = {}", script_str); - dump_output_file(config, testfile, script_str, "debugger.script"); - - - procsrv::run("", config.adb_path, - [~"push", exe_file.as_str().unwrap().to_owned(), - config.adb_test_dir.clone()], - vec!((~"",~"")), Some(~"")) - .expect(format!("failed to exec `{}`", config.adb_path)); - - procsrv::run("", config.adb_path, - [~"forward", ~"tcp:5039", ~"tcp:5039"], - vec!((~"",~"")), Some(~"")) - .expect(format!("failed to exec `{}`", config.adb_path)); - - let adb_arg = format!("export LD_LIBRARY_PATH={}; gdbserver :5039 {}/{}", - config.adb_test_dir.clone(), config.adb_test_dir.clone(), - str::from_utf8(exe_file.filename().unwrap()).unwrap()); - - let mut process = procsrv::run_background("", config.adb_path, - [~"shell",adb_arg.clone()], - vec!((~"",~"")), Some(~"")) - .expect(format!("failed to exec `{}`", config.adb_path)); - loop { - //waiting 1 second for gdbserver start - timer::sleep(1000); - let result = task::try(proc() { - tcp::TcpStream::connect(SocketAddr { - ip: Ipv4Addr(127, 0, 0, 1), - port: 5039, - }).unwrap(); - }); - if result.is_err() { - continue; - } - break; - } + if config.is_target_android() { + cmds = cmds.replace("run","continue"); + + // write debugger script + let script_str = [~"set charset UTF-8", + format!("file {}", exe_file.as_str().unwrap().to_owned()), + ~"target remote :5039", + cmds, + ~"quit"].connect("\n"); + debug!("script_str = {}", script_str); + dump_output_file(config, testfile, script_str, "debugger.script"); + + + procsrv::run("", config.adb_path, + [~"push", exe_file.as_str().unwrap().to_owned(), + config.adb_test_dir.clone()], + vec!((~"",~"")), Some(~"")) + .expect(format!("failed to exec `{}`", config.adb_path)); - let args = split_maybe_args(&config.target_rustcflags); - let mut tool_path = StrBuf::new(); - for arg in args.iter() { - if arg.contains("android-cross-path=") { - tool_path = StrBuf::from_str(arg.replace("android-cross-path=", "")); - break; - } + procsrv::run("", config.adb_path, + [~"forward", ~"tcp:5039", ~"tcp:5039"], + vec!((~"",~"")), Some(~"")) + .expect(format!("failed to exec `{}`", config.adb_path)); + + let adb_arg = format!("export LD_LIBRARY_PATH={}; gdbserver :5039 {}/{}", + config.adb_test_dir.clone(), config.adb_test_dir.clone(), + str::from_utf8(exe_file.filename().unwrap()).unwrap()); + + let mut process = procsrv::run_background("", config.adb_path, + [~"shell", adb_arg.clone()], + vec!((~"",~"")), Some(~"")) + .expect(format!("failed to exec `{}`", config.adb_path)); + loop { + //waiting 1 second for gdbserver start + timer::sleep(1000); + let result = task::try(proc() { + tcp::TcpStream::connect(SocketAddr { + ip: Ipv4Addr(127, 0, 0, 1), + port: 5039, + }).unwrap(); + }); + if result.is_err() { + continue; } + break; + } - if tool_path.is_empty() { - fatal(~"cannot found android cross path"); + let args = split_maybe_args(&config.target_rustcflags); + let mut tool_path = StrBuf::new(); + for arg in args.iter() { + if arg.contains("android-cross-path=") { + tool_path = StrBuf::from_str(arg.replace("android-cross-path=", "")); + break; } + } - let debugger_script = make_out_name(config, testfile, "debugger.script"); - // FIXME (#9639): This needs to handle non-utf8 paths - let debugger_opts = vec!(~"-quiet", ~"-batch", ~"-nx", - "-command=" + debugger_script.as_str().unwrap().to_owned()); - - let gdb_path = tool_path.append("/bin/arm-linux-androideabi-gdb"); - let procsrv::Result{ out, err, status }= - procsrv::run("", - gdb_path.as_slice(), - debugger_opts.as_slice(), - vec!((~"",~"")), - None) - .expect(format!("failed to exec `{}`", gdb_path)); - let cmdline = { - let cmdline = make_cmdline("", - "arm-linux-androideabi-gdb", - debugger_opts.as_slice()); - logv(config, format!("executing {}", cmdline)); - cmdline - }; - - proc_res = ProcRes {status: status, - stdout: out, - stderr: err, - cmdline: cmdline}; - process.signal_kill().unwrap(); + if tool_path.is_empty() { + fatal(~"cannot found android cross path"); } - _=> { - // write debugger script - let script_str = [~"set charset UTF-8", - cmds, - ~"quit\n"].connect("\n"); - debug!("script_str = {}", script_str); - dump_output_file(config, testfile, script_str, "debugger.script"); + let debugger_script = make_out_name(config, testfile, "debugger.script"); + // FIXME (#9639): This needs to handle non-utf8 paths + let debugger_opts = vec!(~"-quiet", ~"-batch", ~"-nx", + "-command=" + debugger_script.as_str().unwrap().to_owned()); + + let gdb_path = tool_path.append("/bin/arm-linux-androideabi-gdb"); + let procsrv::Result { out, err, status } = + procsrv::run("", + gdb_path.as_slice(), + debugger_opts.as_slice(), + vec!((~"",~"")), + None) + .expect(format!("failed to exec `{}`", gdb_path)); + let cmdline = { + let cmdline = make_cmdline("", + "arm-linux-androideabi-gdb", + debugger_opts.as_slice()); + logv(config, format!("executing {}", cmdline)); + cmdline + }; - // run debugger script with gdb - #[cfg(windows)] - fn debugger() -> ~str { ~"gdb.exe" } - #[cfg(unix)] - fn debugger() -> ~str { ~"gdb" } + proc_res = ProcRes {status: status, + stdout: out, + stderr: err, + cmdline: cmdline}; + process.signal_kill().unwrap(); + } else { + // write debugger script + let script_str = [~"set charset UTF-8", + cmds, + ~"quit\n"].connect("\n"); + debug!("script_str = {}", script_str); + dump_output_file(config, testfile, script_str, "debugger.script"); - let debugger_script = make_out_name(config, testfile, "debugger.script"); + // run debugger script with gdb + #[cfg(windows)] + fn debugger() -> ~str { ~"gdb.exe" } + #[cfg(unix)] + fn debugger() -> ~str { ~"gdb" } - // FIXME (#9639): This needs to handle non-utf8 paths - let debugger_opts = vec!(~"-quiet", ~"-batch", ~"-nx", - "-command=" + debugger_script.as_str().unwrap().to_owned(), - exe_file.as_str().unwrap().to_owned()); - proc_args = ProcArgs {prog: debugger(), args: debugger_opts}; - proc_res = compose_and_run(config, testfile, proc_args, Vec::new(), "", None); - } + let debugger_script = make_out_name(config, testfile, "debugger.script"); + + // FIXME (#9639): This needs to handle non-utf8 paths + let debugger_opts = vec!(~"-quiet", ~"-batch", ~"-nx", + "-command=" + debugger_script.as_str().unwrap().to_owned(), + exe_file.as_str().unwrap().to_owned()); + proc_args = ProcArgs {prog: debugger(), args: debugger_opts}; + proc_res = compose_and_run(config, testfile, proc_args, Vec::new(), "", None); } if !proc_res.status.success() { @@ -692,18 +682,13 @@ fn exec_compiled_test(config: &config, props: &TestProps, let env = props.exec_env.clone(); - match config.target.as_slice() { - - "arm-linux-androideabi" => { - _arm_exec_compiled_test(config, props, testfile, env) - } - - _=> { - compose_and_run(config, testfile, - make_run_args(config, props, testfile), - env, - config.run_lib_path, None) - } + if config.is_target_android() { + _arm_exec_compiled_test(config, props, testfile, env) + } else { + compose_and_run(config, testfile, + make_run_args(config, props, testfile), + env, + config.run_lib_path, None) } } @@ -746,14 +731,8 @@ fn compose_and_run_compiler( abs_ab.display()), &auxres); } - - match config.target.as_slice() { - - "arm-linux-androideabi" => { - _arm_push_aux_shared_library(config, testfile); - } - - _=> { } + if config.is_target_android() { + _arm_push_aux_shared_library(config, testfile); } } @@ -788,9 +767,9 @@ fn make_compile_args(config: &config, -> ProcArgs { let xform_file = xform(config, testfile); let target = if props.force_host { - config.host.as_slice() + config.host.full.as_slice() } else { - config.target.as_slice() + config.target.full.as_slice() }; // FIXME (#9639): This needs to handle non-utf8 paths let mut args = vec!(testfile.as_str().unwrap().to_owned(),