Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Basic iOS support
  • Loading branch information
vhbit committed Jun 12, 2014
commit a49b765f9a5b5926e338da30fcaae59ff1ae5c02
13 changes: 13 additions & 0 deletions src/liblibc/lib.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems highly suspicious. I would rather not have this code at all, and leave the unreachable!() below. Can you structure the linkage phase such that it ignore calling this function for ios with dylib outputs?

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);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this if/else is necessary any more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange, I'm pretty sure I've deleted it, will fix

}
}

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
Original file line number Diff line number Diff line change
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
Loading