Skip to content

Commit

Permalink
Basic iOS support
Browse files Browse the repository at this point in the history
  • Loading branch information
vhbit committed Jun 12, 2014
1 parent 0c10c68 commit a49b765
Show file tree
Hide file tree
Showing 37 changed files with 461 additions and 65 deletions.
13 changes: 13 additions & 0 deletions src/liblibc/lib.rs
Expand Up @@ -278,10 +278,13 @@ pub use consts::os::extra::{MAP_STACK};
pub use consts::os::bsd44::{TCP_KEEPIDLE};

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
pub use consts::os::bsd44::{TCP_KEEPALIVE};
#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
pub use consts::os::extra::{F_FULLFSYNC};
#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
pub use types::os::arch::extra::{mach_timebase_info};


Expand Down Expand Up @@ -1286,6 +1289,7 @@ pub mod types {
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
pub mod os {
pub mod common {
pub mod posix01 {
Expand Down Expand Up @@ -3106,6 +3110,7 @@ pub mod consts {
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
pub mod os {
pub mod c95 {
use types::os::arch::c95::{c_int, c_uint};
Expand Down Expand Up @@ -3769,6 +3774,7 @@ pub mod funcs {
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
pub mod posix88 {
pub mod stat_ {
Expand All @@ -3783,6 +3789,7 @@ pub mod funcs {
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "android")]
#[cfg(target_os = "ios")]
pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int;

#[cfg(target_os = "macos")]
Expand All @@ -3795,6 +3802,7 @@ pub mod funcs {
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "android")]
#[cfg(target_os = "ios")]
pub fn stat(path: *c_char, buf: *mut stat) -> c_int;

#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -3967,6 +3975,7 @@ pub mod funcs {
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
pub mod posix01 {
pub mod stat_ {
Expand All @@ -3977,6 +3986,7 @@ pub mod funcs {
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "android")]
#[cfg(target_os = "ios")]
pub fn lstat(path: *c_char, buf: *mut stat) -> c_int;

#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -4076,6 +4086,7 @@ pub mod funcs {
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
pub mod posix08 {
pub mod unistd {
Expand Down Expand Up @@ -4156,6 +4167,7 @@ pub mod funcs {
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
pub mod bsd44 {
use types::common::c95::{c_void};
Expand Down Expand Up @@ -4209,6 +4221,7 @@ pub mod funcs {
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
pub mod extra {
use types::os::arch::c95::{c_char, c_int};

Expand Down
7 changes: 7 additions & 0 deletions src/libnative/io/c_unix.rs
Expand Up @@ -20,6 +20,7 @@ pub use self::signal::{SA_NODEFER, SA_NOCLDWAIT, SA_SIGINFO, SIGCHLD};
use libc;

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
pub static FIONBIO: libc::c_ulong = 0x8004667e;
#[cfg(target_os = "linux", not(target_arch = "mips"))]
Expand All @@ -29,6 +30,7 @@ pub static FIONBIO: libc::c_ulong = 0x5421;
pub static FIONBIO: libc::c_ulong = 0x667e;

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
pub static FIOCLEX: libc::c_ulong = 0x20006601;
#[cfg(target_os = "linux", not(target_arch = "mips"))]
Expand All @@ -38,6 +40,7 @@ pub static FIOCLEX: libc::c_ulong = 0x5451;
pub static FIOCLEX: libc::c_ulong = 0x6601;

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
pub static MSG_DONTWAIT: libc::c_int = 0x80;
#[cfg(target_os = "linux")]
Expand Down Expand Up @@ -75,6 +78,7 @@ extern {
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
mod select {
pub static FD_SETSIZE: uint = 1024;

Expand Down Expand Up @@ -187,6 +191,7 @@ mod signal {
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
mod signal {
use libc;
Expand All @@ -201,6 +206,7 @@ mod signal {
pub static SIGCHLD: libc::c_int = 20;

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
pub type sigset_t = u32;
#[cfg(target_os = "freebsd")]
pub struct sigset_t {
Expand All @@ -219,6 +225,7 @@ mod signal {
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
pub struct sigaction {
pub sa_handler: extern fn(libc::c_int),
sa_tramp: *mut libc::c_void,
Expand Down
3 changes: 2 additions & 1 deletion src/libnative/io/file_unix.rs
Expand Up @@ -133,14 +133,15 @@ impl rtio::RtioFileStream for FileDesc {
return super::mkerr_libc(os_datasync(self.fd()));

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
fn os_datasync(fd: c_int) -> c_int {
unsafe { libc::fcntl(fd, libc::F_FULLFSYNC) }
}
#[cfg(target_os = "linux")]
fn os_datasync(fd: c_int) -> c_int {
retry(|| unsafe { libc::fdatasync(fd) })
}
#[cfg(not(target_os = "macos"), not(target_os = "linux"))]
#[cfg(not(target_os = "macos"), not(target_os = "ios"), not(target_os = "linux"))]
fn os_datasync(fd: c_int) -> c_int {
retry(|| unsafe { libc::fsync(fd) })
}
Expand Down
1 change: 1 addition & 0 deletions src/libnative/io/mod.rs
Expand Up @@ -50,6 +50,7 @@ pub mod file;
pub mod file;

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "android")]
#[cfg(target_os = "linux")]
Expand Down
3 changes: 2 additions & 1 deletion src/libnative/io/net.rs
Expand Up @@ -320,6 +320,7 @@ impl TcpStream {
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPALIVE,
seconds as libc::c_int)
Expand All @@ -329,7 +330,7 @@ impl TcpStream {
setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPIDLE,
seconds as libc::c_int)
}
#[cfg(not(target_os = "macos"), not(target_os = "freebsd"))]
#[cfg(not(target_os = "macos"), not(target_os = "ios"), not(target_os = "freebsd"))]
fn set_tcp_keepalive(&mut self, _seconds: uint) -> IoResult<()> {
Ok(())
}
Expand Down
1 change: 1 addition & 0 deletions src/libnative/io/process.rs
Expand Up @@ -769,6 +769,7 @@ fn translate_status(status: c_int) -> rtio::ProcessExit {
}

#[cfg(target_os = "macos")]
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
mod imp {
pub fn WIFEXITED(status: i32) -> bool { (status & 0x7f) == 0 }
Expand Down
19 changes: 17 additions & 2 deletions src/libnative/io/timer_unix.rs
Expand Up @@ -93,7 +93,20 @@ pub fn now() -> u64 {
}
}

fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {

// Note: although the last parameter isn't used there is no way now to
// convert it to unit type, because LLVM dies in SjLj preparation
// step (unfortunately iOS uses SjLJ exceptions)
//
// It's definitely a temporary workaround just to get it working.
// So far it looks like an LLVM issue and it was reported:
// http://llvm.org/bugs/show_bug.cgi?id=19855
// Actually this issue is pretty common while compiling for armv7 iOS
// and in most cases it is simply solved by using --opt-level=2 (or -O)
//
// For this specific case unfortunately turning optimizations wasn't
// enough.
fn helper(input: libc::c_int, messages: Receiver<Req>, _: int) {
let mut set: c::fd_set = unsafe { mem::zeroed() };

let mut fd = FileDesc::new(input, true);
Expand Down Expand Up @@ -202,7 +215,9 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {

impl Timer {
pub fn new() -> IoResult<Timer> {
unsafe { HELPER.boot(|| {}, helper); }
// See notes above regarding using int return value
// instead of ()
unsafe { HELPER.boot(|| {0}, helper); }

static mut ID: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
let id = unsafe { ID.fetch_add(1, atomics::Relaxed) };
Expand Down
8 changes: 8 additions & 0 deletions src/librustc/back/arm.rs
Expand Up @@ -34,6 +34,14 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
-a0:0:64-n32".to_string()
}

abi::OsiOS => {
"e-p:32:32:32\
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-f32:32:32-f64:64:64\
-v64:64:64-v128:64:128\
-a0:0:64-n32".to_string()
}

abi::OsWin32 => {
"e-p:32:32:32\
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
Expand Down
70 changes: 48 additions & 22 deletions src/librustc/back/link.rs
Expand Up @@ -114,6 +114,13 @@ pub mod write {
// which are *far* more efficient. This is obviously undesirable in some
// cases, so if any sort of target feature is specified we don't append v7
// to the feature list.
//
// On iOS only armv7 and newer are supported. So it is useful to
// get all hardware potential via VFP3 (hardware floating point)
// and NEON (SIMD) instructions supported by LLVM.
// Note that without those flags various linking errors might
// arise as some of intrinsicts are converted into function calls
// and nobody provides implementations those functions
fn target_feature<'a>(sess: &'a Session) -> &'a str {
match sess.targ_cfg.os {
abi::OsAndroid => {
Expand All @@ -122,7 +129,10 @@ pub mod write {
} else {
sess.opts.cg.target_feature.as_slice()
}
}
},
abi::OsiOS if sess.targ_cfg.arch == abi::Arm => {
"+v7,+thumb2,+vfp3,+neon"
},
_ => sess.opts.cg.target_feature.as_slice()
}
}
Expand Down Expand Up @@ -827,15 +837,23 @@ pub fn filename_for_input(sess: &Session, crate_type: config::CrateType,
out_filename.with_filename(format!("lib{}.rlib", libname))
}
config::CrateTypeDylib => {
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),
};
out_filename.with_filename(format!("{}{}{}", prefix, libname,
suffix))
// 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))
}
}
config::CrateTypeStaticlib => {
out_filename.with_filename(format!("lib{}.a", libname))
Expand Down Expand Up @@ -886,7 +904,14 @@ fn link_binary_output(sess: &Session,
link_natively(sess, trans, false, &obj_filename, &out_filename);
}
config::CrateTypeDylib => {
link_natively(sess, trans, true, &obj_filename, &out_filename);
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);
}
}
}

Expand Down Expand Up @@ -991,7 +1016,7 @@ fn link_rlib<'a>(sess: &'a Session,
// symbol table of the archive. This currently dies on OSX (see
// #11162), and isn't necessary there anyway
match sess.targ_cfg.os {
abi::OsMacos => {}
abi::OsMacos | abi::OsiOS => {}
_ => { a.update_symbols(); }
}
}
Expand Down Expand Up @@ -1104,15 +1129,16 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,

// 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) {
match Command::new("dsymutil").arg(out_filename).status() {
Ok(..) => {}
Err(e) => {
sess.err(format!("failed to run dsymutil: {}", e).as_slice());
sess.abort_if_errors();
if (sess.targ_cfg.os == abi::OsMacos || sess.targ_cfg.os == abi::OsiOS)
&& (sess.opts.debuginfo != NoDebugInfo) {
match Command::new("dsymutil").arg(out_filename).status() {
Ok(..) => {}
Err(e) => {
sess.err(format!("failed to run dsymutil: {}", e).as_slice());
sess.abort_if_errors();
}
}
}
}
}

fn link_args(cmd: &mut Command,
Expand Down Expand Up @@ -1169,7 +1195,7 @@ fn link_args(cmd: &mut Command,
// already done the best it can do, and we also don't want to eliminate the
// metadata. If we're building an executable, however, --gc-sections drops
// the size of hello world from 1.8MB to 597K, a 67% reduction.
if !dylib && sess.targ_cfg.os != abi::OsMacos {
if !dylib && sess.targ_cfg.os != abi::OsMacos && sess.targ_cfg.os != abi::OsiOS {
cmd.arg("-Wl,--gc-sections");
}

Expand All @@ -1185,7 +1211,7 @@ fn link_args(cmd: &mut Command,
sess.opts.optimize == config::Aggressive {
cmd.arg("-Wl,-O1");
}
} else if sess.targ_cfg.os == abi::OsMacos {
} else if sess.targ_cfg.os == abi::OsMacos || sess.targ_cfg.os == abi::OsiOS {
// The dead_strip option to the linker specifies that functions and data
// unreachable by the entry point will be removed. This is quite useful
// with Rust's compilation model of compiling libraries at a time into
Expand Down Expand Up @@ -1348,7 +1374,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
// For those that support this, we ensure we pass the option if the library
// was flagged "static" (most defaults are dynamic) to ensure that if
// libfoo.a and libfoo.so both exist that the right one is chosen.
let takes_hints = sess.targ_cfg.os != abi::OsMacos;
let takes_hints = sess.targ_cfg.os != abi::OsMacos && sess.targ_cfg.os != abi::OsiOS;

for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
match kind {
Expand Down
8 changes: 8 additions & 0 deletions src/librustc/back/mips.rs
Expand Up @@ -29,6 +29,14 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
-a0:0:64-n32".to_string()
}

abi::OsiOS => {
"E-p:32:32:32\
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-f32:32:32-f64:64:64\
-v64:64:64-v128:64:128\
-a0:0:64-n32".to_string()
}

abi::OsWin32 => {
"E-p:32:32:32\
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
Expand Down

0 comments on commit a49b765

Please sign in to comment.