From 061b56bd5ca2d3a49bebdd6a174995e1b3ec6a5b Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 13:47:39 +0200 Subject: [PATCH 01/14] Add a link to `park` in the `park_timeout` doc. Part of #29378 --- src/libstd/thread/mod.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 8e7eaa77cd709..dbc8562ea39fd 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -585,9 +585,9 @@ pub fn park() { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to `park()` except that the -/// thread will be blocked for roughly no longer than `ms`. This method -/// should not be used for precise timing due to anomalies such as +/// The semantics of this function are equivalent to [`park()`][[park] except +/// that the thread will be blocked for roughly no longer than `dur`. This +/// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `ms` long. /// @@ -595,6 +595,7 @@ pub fn park() { /// /// [thread]: index.html /// [park_timeout]: fn.park_timeout.html +/// [park]: fn.park.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")] pub fn park_timeout_ms(ms: u32) { @@ -604,9 +605,9 @@ pub fn park_timeout_ms(ms: u32) { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to `park()` except that the -/// thread will be blocked for roughly no longer than `dur`. This method -/// should not be used for precise timing due to anomalies such as +/// The semantics of this function are equivalent to [`park()`][[park] except +/// that the thread will be blocked for roughly no longer than `dur`. This +/// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `dur` long. /// @@ -635,6 +636,8 @@ pub fn park_timeout_ms(ms: u32) { /// park_timeout(timeout); /// } /// ``` +/// +/// [park]: fn.park.html #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { let thread = current(); From c158962169e3cf0686cb70652282bcdf20772926 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 13:50:23 +0200 Subject: [PATCH 02/14] Add link to the module doc in `park_timeout`. Part of #29378 --- src/libstd/thread/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index dbc8562ea39fd..1857f81a33967 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -611,7 +611,7 @@ pub fn park_timeout_ms(ms: u32) { /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `dur` long. /// -/// See the module doc for more detail. +/// See the [module doc][thread] for more detail. /// /// # Platform behavior /// @@ -637,6 +637,7 @@ pub fn park_timeout_ms(ms: u32) { /// } /// ``` /// +/// [thread]: index.html /// [park]: fn.park.html #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { From d9628f9389319c1075d4a54a0a490226539cea81 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 13:54:06 +0200 Subject: [PATCH 03/14] Add `park` info to `unpark`. - Adds an explanantion of what `park` does in the `unpark` documentation. - Adds a link to the module doc. --- src/libstd/thread/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 1857f81a33967..bdf7b1134bfe7 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -768,7 +768,11 @@ impl Thread { /// Atomically makes the handle's token available if it is not already. /// - /// See the module doc for more detail. + /// Every thread is equipped with some basic low-level blocking support, via + /// the [`park()`][park] function and the `unpark` method. These can be + /// used as a more CPU-efficient implementation of a spinlock. + /// + /// See the [module doc][thread] for more detail. /// /// # Examples /// @@ -784,6 +788,9 @@ impl Thread { /// /// handler.join().unwrap(); /// ``` + /// + /// [thread]: index.html + /// [park]: fn.park.html #[stable(feature = "rust1", since = "1.0.0")] pub fn unpark(&self) { let mut guard = self.inner.lock.lock().unwrap(); From 5573c4709cba7b3d5dc15c47239d1b1f32af4753 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 16:01:47 +0200 Subject: [PATCH 04/14] Better example for `thread::unpark`. Part of #29378 --- src/libstd/thread/mod.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index bdf7b1134bfe7..94a2c91858ea7 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -769,7 +769,7 @@ impl Thread { /// Atomically makes the handle's token available if it is not already. /// /// Every thread is equipped with some basic low-level blocking support, via - /// the [`park()`][park] function and the `unpark` method. These can be + /// the [`park()`][park] function and the `unpark()` method. These can be /// used as a more CPU-efficient implementation of a spinlock. /// /// See the [module doc][thread] for more detail. @@ -779,14 +779,21 @@ impl Thread { /// ``` /// use std::thread; /// - /// let handler = thread::Builder::new() + /// let parked_thread = thread::Builder::new() /// .spawn(|| { - /// let thread = thread::current(); - /// thread.unpark(); + /// println!("Parking thread"); + /// thread::park(); + /// println!("Thread unparked"); /// }) /// .unwrap(); /// - /// handler.join().unwrap(); + /// // Let some time pass for the thread to be spawned. + /// thread::sleep(Duration::from_millis(10)); + /// + /// println!("Unpark the thread"); + /// parked_thread.thread().unpark(); + /// + /// parked_thread.join().unwrap(); /// ``` /// /// [thread]: index.html From c0d475ad7b44c153b4999709ff08a9275160ea1c Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 16:22:13 +0200 Subject: [PATCH 05/14] fix typo --- src/libstd/thread/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 94a2c91858ea7..9c15857edf693 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -585,7 +585,7 @@ pub fn park() { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park()`][[park] except +/// The semantics of this function are equivalent to [`park()`][park] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum @@ -605,7 +605,7 @@ pub fn park_timeout_ms(ms: u32) { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park()`][[park] except +/// The semantics of this function are equivalent to [`park()`][park] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum From fa0cdaa63f575c81c7cc87239f7dfcc677362c78 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 18:55:20 +0200 Subject: [PATCH 06/14] Inline `thread::park` documentation. Part of #29378 - Moves the module documentation into `park`. - Add the same example as the one from `unpark` to `park`. --- src/libstd/thread/mod.rs | 114 +++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 9c15857edf693..5373bf273d4de 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -96,41 +96,6 @@ //! The [`thread::current`] function is available even for threads not spawned //! by the APIs of this module. //! -//! ## Blocking support: park and unpark -//! -//! Every thread is equipped with some basic low-level blocking support, via the -//! [`thread::park`][`park`] function and [`thread::Thread::unpark()`][`unpark`] -//! method. [`park`] blocks the current thread, which can then be resumed from -//! another thread by calling the [`unpark`] method on the blocked thread's handle. -//! -//! Conceptually, each [`Thread`] handle has an associated token, which is -//! initially not present: -//! -//! * The [`thread::park`][`park`] function blocks the current thread unless or until -//! the token is available for its thread handle, at which point it atomically -//! consumes the token. It may also return *spuriously*, without consuming the -//! token. [`thread::park_timeout`] does the same, but allows specifying a -//! maximum time to block the thread for. -//! -//! * The [`unpark`] method on a [`Thread`] atomically makes the token available -//! if it wasn't already. -//! -//! In other words, each [`Thread`] acts a bit like a semaphore with initial count -//! 0, except that the semaphore is *saturating* (the count cannot go above 1), -//! and can return spuriously. -//! -//! The API is typically used by acquiring a handle to the current thread, -//! placing that handle in a shared data structure so that other threads can -//! find it, and then `park`ing. When some desired condition is met, another -//! thread calls [`unpark`] on the handle. -//! -//! The motivation for this design is twofold: -//! -//! * It avoids the need to allocate mutexes and condvars when building new -//! synchronization primitives; the threads already provide basic blocking/signaling. -//! -//! * It can be implemented very efficiently on many platforms. -//! //! ## Thread-local storage //! //! This module also provides an implementation of thread-local storage for Rust @@ -547,23 +512,71 @@ pub fn sleep(dur: Duration) { /// Blocks unless or until the current thread's token is made available. /// -/// Every thread is equipped with some basic low-level blocking support, via -/// the `park()` function and the [`unpark`][unpark] method. These can be -/// used as a more CPU-efficient implementation of a spinlock. +/// A call to `park` does not guarantee that the thread will remain parked +/// forever, and callers should be prepared for this possibility. +/// +/// # park and unpark +/// +/// Every thread is equipped with some basic low-level blocking support, via the +/// [`thread::park`][`park`] function and [`thread::Thread::unpark()`][`unpark`] +/// method. [`park`] blocks the current thread, which can then be resumed from +/// another thread by calling the [`unpark`] method on the blocked thread's +/// handle. +/// +/// Conceptually, each [`Thread`] handle has an associated token, which is +/// initially not present: +/// +/// * The [`thread::park`][`park`] function blocks the current thread unless or +/// until the token is available for its thread handle, at which point it +/// atomically consumes the token. It may also return *spuriously*, without +/// consuming the token. [`thread::park_timeout`] does the same, but allows +/// specifying a maximum time to block the thread for. +/// +/// * The [`unpark`] method on a [`Thread`] atomically makes the token available +/// if it wasn't already. /// -/// [unpark]: struct.Thread.html#method.unpark +/// In other words, each [`Thread`] acts a bit like a spinlock that can be +/// locked and unlocked using `park` and `unpark`. /// /// The API is typically used by acquiring a handle to the current thread, /// placing that handle in a shared data structure so that other threads can -/// find it, and then parking (in a loop with a check for the token actually -/// being acquired). +/// find it, and then `park`ing. When some desired condition is met, another +/// thread calls [`unpark`] on the handle. /// -/// A call to `park` does not guarantee that the thread will remain parked -/// forever, and callers should be prepared for this possibility. +/// The motivation for this design is twofold: +/// +/// * It avoids the need to allocate mutexes and condvars when building new +/// synchronization primitives; the threads already provide basic +/// blocking/signaling. /// -/// See the [module documentation][thread] for more detail. +/// * It can be implemented very efficiently on many platforms. +/// +/// # Examples /// -/// [thread]: index.html +/// ``` +/// use std::thread; +/// +/// let parked_thread = thread::Builder::new() +/// .spawn(|| { +/// println!("Parking thread"); +/// thread::park(); +/// println!("Thread unparked"); +/// }) +/// .unwrap(); +/// +/// // Let some time pass for the thread to be spawned. +/// thread::sleep(Duration::from_millis(10)); +/// +/// println!("Unpark the thread"); +/// parked_thread.thread().unpark(); +/// +/// parked_thread.join().unwrap(); +/// ``` +/// +/// [`Thread`]: ../../std/thread/struct.Thread.html +/// [`park`]: ../../std/thread/fn.park.html +/// [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark +/// [`thread::park_timeout`]: ../../std/thread/fn.park_timeout.html // // The implementation currently uses the trivial strategy of a Mutex+Condvar // with wakeup flag, which does not actually allow spurious wakeups. In the @@ -591,11 +604,10 @@ pub fn park() { /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `ms` long. /// -/// See the [module documentation][thread] for more detail. +/// See the [park documentation][park] for more detail. /// -/// [thread]: index.html /// [park_timeout]: fn.park_timeout.html -/// [park]: fn.park.html +/// [park]: ../../std/thread/fn.park.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")] pub fn park_timeout_ms(ms: u32) { @@ -611,7 +623,7 @@ pub fn park_timeout_ms(ms: u32) { /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `dur` long. /// -/// See the [module doc][thread] for more detail. +/// See the [park dococumentation][park] for more details. /// /// # Platform behavior /// @@ -637,7 +649,6 @@ pub fn park_timeout_ms(ms: u32) { /// } /// ``` /// -/// [thread]: index.html /// [park]: fn.park.html #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { @@ -772,7 +783,7 @@ impl Thread { /// the [`park()`][park] function and the `unpark()` method. These can be /// used as a more CPU-efficient implementation of a spinlock. /// - /// See the [module doc][thread] for more detail. + /// See the [park documentation][park] for more details. /// /// # Examples /// @@ -796,7 +807,6 @@ impl Thread { /// parked_thread.join().unwrap(); /// ``` /// - /// [thread]: index.html /// [park]: fn.park.html #[stable(feature = "rust1", since = "1.0.0")] pub fn unpark(&self) { From 03c9510525c986715af1f1f98c2bc06248c747e8 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 21:43:46 +0200 Subject: [PATCH 07/14] Fix typos in `thread::park` documentation. --- src/libstd/thread/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 5373bf273d4de..4d931682676e1 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -518,7 +518,7 @@ pub fn sleep(dur: Duration) { /// # park and unpark /// /// Every thread is equipped with some basic low-level blocking support, via the -/// [`thread::park`][`park`] function and [`thread::Thread::unpark()`][`unpark`] +/// [`thread::park`][`park`] function and [`thread::Thread::unpark`][`unpark`] /// method. [`park`] blocks the current thread, which can then be resumed from /// another thread by calling the [`unpark`] method on the blocked thread's /// handle. @@ -555,6 +555,7 @@ pub fn sleep(dur: Duration) { /// /// ``` /// use std::thread; +/// use std::time::Duration; /// /// let parked_thread = thread::Builder::new() /// .spawn(|| { @@ -598,7 +599,7 @@ pub fn park() { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park()`][park] except +/// The semantics of this function are equivalent to [`park`][park] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum @@ -617,7 +618,7 @@ pub fn park_timeout_ms(ms: u32) { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park()`][park] except +/// The semantics of this function are equivalent to [`park`][park] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum @@ -780,7 +781,7 @@ impl Thread { /// Atomically makes the handle's token available if it is not already. /// /// Every thread is equipped with some basic low-level blocking support, via - /// the [`park()`][park] function and the `unpark()` method. These can be + /// the [`park`][park] function and the `unpark()` method. These can be /// used as a more CPU-efficient implementation of a spinlock. /// /// See the [park documentation][park] for more details. @@ -789,6 +790,7 @@ impl Thread { /// /// ``` /// use std::thread; + /// use std::time::Duration; /// /// let parked_thread = thread::Builder::new() /// .spawn(|| { From 2f6744c5fc086fcedd6515240fce15ed641f2846 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 25 Apr 2017 11:24:06 -0400 Subject: [PATCH 08/14] Improve docs on Arc and Send/Sync This is something I always forget, so let's actually explain in the docs. --- src/liballoc/arc.rs | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 6d85183faf75d..27ecefe043b1e 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -54,16 +54,33 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// exception. If you need to mutate through an `Arc`, use [`Mutex`][mutex], /// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types. /// -/// `Arc` uses atomic operations for reference counting, so `Arc`s can be -/// sent between threads. In other words, `Arc` implements [`Send`] -/// as long as `T` implements [`Send`] and [`Sync`][sync]. The disadvantage is -/// that atomic operations are more expensive than ordinary memory accesses. -/// If you are not sharing reference-counted values between threads, consider -/// using [`rc::Rc`][`Rc`] for lower overhead. [`Rc`] is a safe default, because -/// the compiler will catch any attempt to send an [`Rc`] between threads. -/// However, a library might choose `Arc` in order to give library consumers +/// ## Thread Safety +/// +/// Unlike [`Rc`], `Arc` uses atomic operations for its reference +/// counting This means that it is thread-safe. The disadvantage is that +/// atomic operations are more expensive than ordinary memory accesses. If you +/// are not sharing reference-counted values between threads, consider using +/// [`Rc`] for lower overhead. [`Rc`] is a safe default, because the +/// compiler will catch any attempt to send an [`Rc`] between threads. +/// However, a library might choose `Arc` in order to give library consumers /// more flexibility. /// +/// `Arc` will implement [`Send`] and [`Sync`] as long as the `T` implements +/// [`Send`] and [`Sync`]. Why can't you put a non-thread-safe type `T` in an +/// `Arc` to make it thread-safe? This may be a bit counter-intuitive at +/// first: after all, isn't the point of `Arc` thread safety? The key is +/// this: `Arc` makes it thread safe to have multiple ownership of the same +/// data, but it doesn't add thread safety to its data. Consider +/// `Arc>`. `RefCell` isn't [`Sync`], and if `Arc` was always +/// [`Send`], `Arc>` would be as well. But then we'd have a problem: +/// `RefCell` is not thread safe; it keeps track of the borrowing count using +/// non-atomic operations. +/// +/// In the end, this means that you may need to pair `Arc` with some sort of +/// `std::sync` type, usually `Mutex`. +/// +/// ## Breaking cycles with `Weak` +/// /// The [`downgrade`][downgrade] method can be used to create a non-owning /// [`Weak`][weak] pointer. A [`Weak`][weak] pointer can be [`upgrade`][upgrade]d /// to an `Arc`, but this will return [`None`] if the value has already been @@ -74,6 +91,8 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// strong `Arc` pointers from parent nodes to children, and [`Weak`][weak] /// pointers from children back to their parents. /// +/// ## `Deref` behavior +/// /// `Arc` automatically dereferences to `T` (via the [`Deref`][deref] trait), /// so you can call `T`'s methods on a value of type `Arc`. To avoid name /// clashes with `T`'s methods, the methods of `Arc` itself are [associated @@ -91,13 +110,13 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// /// [arc]: struct.Arc.html /// [weak]: struct.Weak.html -/// [`Rc`]: ../../std/rc/struct.Rc.html +/// [`Rc`]: ../../std/rc/struct.Rc.html /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone /// [mutex]: ../../std/sync/struct.Mutex.html /// [rwlock]: ../../std/sync/struct.RwLock.html /// [atomic]: ../../std/sync/atomic/index.html /// [`Send`]: ../../std/marker/trait.Send.html -/// [sync]: ../../std/marker/trait.Sync.html +/// [`Sync`]: ../../std/marker/trait.Sync.html /// [deref]: ../../std/ops/trait.Deref.html /// [downgrade]: struct.Arc.html#method.downgrade /// [upgrade]: struct.Weak.html#method.upgrade From afe74c3900aa00373a0d5edd2bd433870822c40a Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Tue, 9 May 2017 19:02:43 +0200 Subject: [PATCH 09/14] Fix link --- src/libstd/thread/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 4d931682676e1..9a7239d297c4d 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -594,21 +594,21 @@ pub fn park() { *guard = false; } -/// Use [park_timeout]. +/// Use [`park_timeout`]. /// /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park`][park] except +/// The semantics of this function are equivalent to [`park`] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `ms` long. /// -/// See the [park documentation][park] for more detail. +/// See the [park documentation][`park`] for more detail. /// -/// [park_timeout]: fn.park_timeout.html -/// [park]: ../../std/thread/fn.park.html +/// [`park_timeout`]: fn.park_timeout.html +/// [`park`]: ../../std/thread/fn.park.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")] pub fn park_timeout_ms(ms: u32) { From 49f793ac17b66c2f81c19e310523a0f11e03d92a Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Fri, 5 May 2017 21:46:16 -0300 Subject: [PATCH 10/14] ci: Update android ndk and sdk --- src/ci/docker/arm-android/Dockerfile | 58 +++++++++++++------- src/ci/docker/arm-android/accept-licenses.sh | 15 ----- src/ci/docker/arm-android/install-ndk.sh | 36 ++++++------ src/ci/docker/arm-android/install-sdk.sh | 50 +++++++++++------ src/ci/docker/arm-android/start-emulator.sh | 9 ++- src/ci/docker/dist-android/Dockerfile | 37 +++++++------ src/ci/docker/dist-android/install-ndk.sh | 51 +++++++---------- src/tools/compiletest/src/runtest.rs | 2 +- 8 files changed, 139 insertions(+), 119 deletions(-) delete mode 100755 src/ci/docker/arm-android/accept-licenses.sh diff --git a/src/ci/docker/arm-android/Dockerfile b/src/ci/docker/arm-android/Dockerfile index 04ca6d76c557b..86f0cc5d467d7 100644 --- a/src/ci/docker/arm-android/Dockerfile +++ b/src/ci/docker/arm-android/Dockerfile @@ -1,7 +1,6 @@ FROM ubuntu:16.04 -RUN dpkg --add-architecture i386 && \ - apt-get update && \ +RUN apt-get update && \ apt-get install -y --no-install-recommends \ g++ \ make \ @@ -12,35 +11,54 @@ RUN dpkg --add-architecture i386 && \ git \ cmake \ unzip \ - expect \ - openjdk-9-jre-headless \ sudo \ - libstdc++6:i386 \ xz-utils \ libssl-dev \ pkg-config -WORKDIR /android/ -ENV PATH=$PATH:/android/ndk-arm-9/bin:/android/sdk/tools:/android/sdk/platform-tools - -COPY install-ndk.sh install-sdk.sh accept-licenses.sh /android/ -RUN sh /android/install-ndk.sh -RUN sh /android/install-sdk.sh - RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ dpkg -i dumb-init_*.deb && \ rm dumb-init_*.deb -COPY start-emulator.sh /android/ +RUN curl -o /usr/local/bin/sccache \ + https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \ + chmod +x /usr/local/bin/sccache -ENTRYPOINT ["/usr/bin/dumb-init", "--", "/android/start-emulator.sh"] +# Install NDK +COPY install-ndk.sh /tmp +RUN . /tmp/install-ndk.sh && \ + download_ndk android-ndk-r13b-linux-x86_64.zip && \ + make_standalone_toolchain arm 9 && \ + remove_ndk -RUN curl -o /usr/local/bin/sccache \ - https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-02-24-sccache-x86_64-unknown-linux-gnu && \ - chmod +x /usr/local/bin/sccache +# Install SDK +RUN dpkg --add-architecture i386 && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + openjdk-9-jre-headless \ + tzdata \ + libstdc++6:i386 \ + libgl1-mesa-glx \ + libpulse0 + +COPY install-sdk.sh /tmp +RUN . /tmp/install-sdk.sh && \ + download_sdk tools_r25.2.5-linux.zip && \ + download_sysimage armeabi-v7a 18 && \ + create_avd armeabi-v7a 18 + +# Setup env +ENV PATH=$PATH:/android/sdk/tools +ENV PATH=$PATH:/android/sdk/platform-tools + +ENV TARGETS=arm-linux-androideabi ENV RUST_CONFIGURE_ARGS \ - --target=arm-linux-androideabi \ - --arm-linux-androideabi-ndk=/android/ndk-arm-9 + --target=$TARGETS \ + --arm-linux-androideabi-ndk=/android/ndk/arm-9 + +ENV SCRIPT python2.7 ../x.py test --target $TARGETS --verbose -ENV SCRIPT python2.7 ../x.py test --target arm-linux-androideabi +# Entrypoint +COPY start-emulator.sh /android/ +ENTRYPOINT ["/usr/bin/dumb-init", "--", "/android/start-emulator.sh"] diff --git a/src/ci/docker/arm-android/accept-licenses.sh b/src/ci/docker/arm-android/accept-licenses.sh deleted file mode 100755 index 8d8f60a5ec260..0000000000000 --- a/src/ci/docker/arm-android/accept-licenses.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/expect -f -# ignore-license - -set timeout 1800 -set cmd [lindex $argv 0] -set licenses [lindex $argv 1] - -spawn {*}$cmd -expect { - "Do you accept the license '*'*" { - exp_send "y\r" - exp_continue - } - eof -} diff --git a/src/ci/docker/arm-android/install-ndk.sh b/src/ci/docker/arm-android/install-ndk.sh index 389ec062110e0..8081872119983 100644 --- a/src/ci/docker/arm-android/install-ndk.sh +++ b/src/ci/docker/arm-android/install-ndk.sh @@ -11,23 +11,25 @@ set -ex -cpgdb() { - cp android-ndk-r11c/prebuilt/linux-x86_64/bin/gdb /android/$1/bin/$2-gdb - cp android-ndk-r11c/prebuilt/linux-x86_64/bin/gdb-orig /android/$1/bin/gdb-orig - cp -r android-ndk-r11c/prebuilt/linux-x86_64/share /android/$1/share +URL=https://dl.google.com/android/repository + +download_ndk() { + mkdir -p /android/ndk + cd /android/ndk + curl -O $URL/$1 + unzip -q $1 + rm $1 + mv android-ndk-* ndk } -# Prep the Android NDK -# -# See https://github.com/servo/servo/wiki/Building-for-Android -curl -O https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip -unzip -q android-ndk-r11c-linux-x86_64.zip -bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \ - --platform=android-9 \ - --toolchain=arm-linux-androideabi-4.9 \ - --install-dir=/android/ndk-arm-9 \ - --ndk-dir=/android/android-ndk-r11c \ - --arch=arm -cpgdb ndk-arm-9 arm-linux-androideabi +make_standalone_toolchain() { + # See https://developer.android.com/ndk/guides/standalone_toolchain.html + python2.7 /android/ndk/ndk/build/tools/make_standalone_toolchain.py \ + --install-dir /android/ndk/$1-$2 \ + --arch $1 \ + --api $2 +} -rm -rf ./android-ndk-r11c-linux-x86_64.zip ./android-ndk-r11c +remove_ndk() { + rm -rf /android/ndk/ndk +} diff --git a/src/ci/docker/arm-android/install-sdk.sh b/src/ci/docker/arm-android/install-sdk.sh index 2db1d46ba2273..258fc47a7a692 100644 --- a/src/ci/docker/arm-android/install-sdk.sh +++ b/src/ci/docker/arm-android/install-sdk.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright 2016 The Rust Project Developers. See the COPYRIGHT +# Copyright 2017 The Rust Project Developers. See the COPYRIGHT # file at the top-level directory of this distribution and at # http://rust-lang.org/COPYRIGHT. # @@ -11,23 +11,39 @@ set -ex -# Prep the SDK and emulator -# -# Note that the update process requires that we accept a bunch of licenses, and -# we can't just pipe `yes` into it for some reason, so we take the same strategy -# located in https://github.com/appunite/docker by just wrapping it in a script -# which apparently magically accepts the licenses. +URL=https://dl.google.com/android/repository + +download_sdk() { + mkdir -p /android/sdk + cd /android/sdk + curl -O $URL/$1 + unzip -q $1 + rm -rf $1 +} + +download_sysimage() { + # See https://developer.android.com/studio/tools/help/android.html + abi=$1 + api=$2 + + filter="platform-tools,android-$api" + filter="$filter,sys-img-$abi-android-$api" -mkdir sdk -curl https://dl.google.com/android/android-sdk_r24.4-linux.tgz | \ - tar xzf - -C sdk --strip-components=1 + # Keep printing yes to accept the licenses + while true; do echo yes; sleep 10; done | \ + /android/sdk/tools/android update sdk -a --no-ui \ + --filter "$filter" +} -filter="platform-tools,android-18" -filter="$filter,sys-img-armeabi-v7a-android-18" +create_avd() { + # See https://developer.android.com/studio/tools/help/android.html + abi=$1 + api=$2 -./accept-licenses.sh "android - update sdk -a --no-ui --filter $filter" + echo no | \ + /android/sdk/tools/android create avd \ + --name $abi-$api \ + --target android-$api \ + --abi $abi +} -echo "no" | android create avd \ - --name arm-18 \ - --target android-18 \ - --abi armeabi-v7a diff --git a/src/ci/docker/arm-android/start-emulator.sh b/src/ci/docker/arm-android/start-emulator.sh index 4a73637e9ddbf..cd3369d5eaddc 100755 --- a/src/ci/docker/arm-android/start-emulator.sh +++ b/src/ci/docker/arm-android/start-emulator.sh @@ -14,5 +14,12 @@ set -ex # Setting SHELL to a file instead on a symlink helps android # emulator identify the system export SHELL=/bin/bash -nohup nohup emulator @arm-18 -no-window -partition-size 2047 0<&- &>/dev/null & + +# Using the default qemu2 engine makes time::tests::since_epoch fails because +# the emulator date is set to unix epoch (in armeabi-v7a-18 image). Using +# classic engine the emulator starts with the current date and the tests run +# fine. If another image is used, this need to be evaluated again. +nohup nohup emulator @armeabi-v7a-18 \ + -engine classic -no-window -partition-size 2047 0<&- &>/dev/null & + exec "$@" diff --git a/src/ci/docker/dist-android/Dockerfile b/src/ci/docker/dist-android/Dockerfile index 1dd97fd4e0471..a3658225bc47c 100644 --- a/src/ci/docker/dist-android/Dockerfile +++ b/src/ci/docker/dist-android/Dockerfile @@ -1,7 +1,6 @@ FROM ubuntu:16.04 -RUN dpkg --add-architecture i386 && \ - apt-get update && \ +RUN apt-get update && \ apt-get install -y --no-install-recommends \ g++ \ make \ @@ -12,28 +11,30 @@ RUN dpkg --add-architecture i386 && \ git \ cmake \ unzip \ - expect \ - openjdk-9-jre \ sudo \ - libstdc++6:i386 \ xz-utils \ libssl-dev \ pkg-config -WORKDIR /android/ -ENV PATH=$PATH:/android/ndk-arm-9/bin:/android/sdk/tools:/android/sdk/platform-tools - -COPY install-ndk.sh /android/ -RUN sh /android/install-ndk.sh - RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ dpkg -i dumb-init_*.deb && \ rm dumb-init_*.deb -ENTRYPOINT ["/usr/bin/dumb-init", "--"] RUN curl -o /usr/local/bin/sccache \ https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \ - chmod +x /usr/local/bin/sccache + chmod +x /usr/local/bin/sccache + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] + +# Install NDK +COPY install-ndk.sh /tmp +RUN . /tmp/install-ndk.sh && \ + download_ndk android-ndk-r13b-linux-x86_64.zip && \ + make_standalone_toolchain arm 9 && \ + make_standalone_toolchain x86 9 && \ + make_standalone_toolchain arm64 21 && \ + make_standalone_toolchain x86_64 21 && \ + remove_ndk ENV TARGETS=arm-linux-androideabi ENV TARGETS=$TARGETS,armv7-linux-androideabi @@ -44,10 +45,10 @@ ENV TARGETS=$TARGETS,x86_64-linux-android ENV RUST_CONFIGURE_ARGS \ --target=$TARGETS \ --enable-extended \ - --arm-linux-androideabi-ndk=/android/ndk-arm-9 \ - --armv7-linux-androideabi-ndk=/android/ndk-arm-9 \ - --i686-linux-android-ndk=/android/ndk-x86-9 \ - --aarch64-linux-android-ndk=/android/ndk-arm64-21 \ - --x86_64-linux-android-ndk=/android/ndk-x86_64-21 + --arm-linux-androideabi-ndk=/android/ndk/arm-9 \ + --armv7-linux-androideabi-ndk=/android/ndk/arm-9 \ + --i686-linux-android-ndk=/android/ndk/x86-9 \ + --aarch64-linux-android-ndk=/android/ndk/arm64-21 \ + --x86_64-linux-android-ndk=/android/ndk/x86_64-21 ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/ci/docker/dist-android/install-ndk.sh b/src/ci/docker/dist-android/install-ndk.sh index d3a2d31754543..8081872119983 100644 --- a/src/ci/docker/dist-android/install-ndk.sh +++ b/src/ci/docker/dist-android/install-ndk.sh @@ -11,34 +11,25 @@ set -ex -# Prep the Android NDK -# -# See https://github.com/servo/servo/wiki/Building-for-Android -curl -O https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip -unzip -q android-ndk-r11c-linux-x86_64.zip -bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \ - --platform=android-9 \ - --toolchain=arm-linux-androideabi-4.9 \ - --install-dir=/android/ndk-arm-9 \ - --ndk-dir=/android/android-ndk-r11c \ - --arch=arm -bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \ - --platform=android-21 \ - --toolchain=aarch64-linux-android-4.9 \ - --install-dir=/android/ndk-arm64-21 \ - --ndk-dir=/android/android-ndk-r11c \ - --arch=arm64 -bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \ - --platform=android-9 \ - --toolchain=x86-4.9 \ - --install-dir=/android/ndk-x86-9 \ - --ndk-dir=/android/android-ndk-r11c \ - --arch=x86 -bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \ - --platform=android-21 \ - --toolchain=x86_64-4.9 \ - --install-dir=/android/ndk-x86_64-21 \ - --ndk-dir=/android/android-ndk-r11c \ - --arch=x86_64 +URL=https://dl.google.com/android/repository + +download_ndk() { + mkdir -p /android/ndk + cd /android/ndk + curl -O $URL/$1 + unzip -q $1 + rm $1 + mv android-ndk-* ndk +} + +make_standalone_toolchain() { + # See https://developer.android.com/ndk/guides/standalone_toolchain.html + python2.7 /android/ndk/ndk/build/tools/make_standalone_toolchain.py \ + --install-dir /android/ndk/$1-$2 \ + --arch $1 \ + --api $2 +} -rm -rf ./android-ndk-r11c-linux-x86_64.zip ./android-ndk-r11c +remove_ndk() { + rm -rf /android/ndk/ndk +} diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index a044282666da0..7fe8c1041a729 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -570,7 +570,7 @@ actual:\n\ format!("-command={}", debugger_script.to_str().unwrap())]; let mut gdb_path = tool_path; - gdb_path.push_str(&format!("/bin/{}-gdb", self.config.target)); + gdb_path.push_str("/bin/gdb"); let procsrv::Result { out, err, From cc4afe0f6504136ed2adc8cbada32e5429e04757 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 9 May 2017 20:51:18 +0200 Subject: [PATCH 11/14] Improve E0477 error message --- src/librustc/infer/error_reporting/note.rs | 11 +++++++++-- src/test/ui/static-lifetime.rs | 16 ++++++++++++++++ src/test/ui/static-lifetime.stderr | 10 ++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/static-lifetime.rs create mode 100644 src/test/ui/static-lifetime.stderr diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index 49952d81cbb0b..963c14c48c829 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -9,7 +9,7 @@ // except according to those terms. use infer::{self, InferCtxt, SubregionOrigin}; -use ty::Region; +use ty::{self, Region}; use ty::error::TypeError; use errors::DiagnosticBuilder; @@ -262,7 +262,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { "the type `{}` does not fulfill the required \ lifetime", self.ty_to_string(ty)); - self.tcx.note_and_explain_region(&mut err, "type must outlive ", sub, ""); + match *sub { + ty::ReStatic => { + self.tcx.note_and_explain_region(&mut err, "type must satisfy ", sub, "") + } + _ => { + self.tcx.note_and_explain_region(&mut err, "type must outlive ", sub, "") + } + } err } infer::RelateRegionParamBound(span) => { diff --git a/src/test/ui/static-lifetime.rs b/src/test/ui/static-lifetime.rs new file mode 100644 index 0000000000000..7b1887b2d1a29 --- /dev/null +++ b/src/test/ui/static-lifetime.rs @@ -0,0 +1,16 @@ +// Copyright 2016 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. + +pub trait Arbitrary: Sized + 'static {} + +impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} + +fn main() { +} \ No newline at end of file diff --git a/src/test/ui/static-lifetime.stderr b/src/test/ui/static-lifetime.stderr new file mode 100644 index 0000000000000..f73dff4f73d0e --- /dev/null +++ b/src/test/ui/static-lifetime.stderr @@ -0,0 +1,10 @@ +error[E0477]: the type `std::borrow::Cow<'a, A>` does not fulfill the required lifetime + --> $DIR/static-lifetime.rs:13:20 + | +13 | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} + | ^^^^^^^^^ + | + = note: type must satisfy the static lifetime + +error: aborting due to previous error + From 2e509d2410e89ad8961a792a203cfa24ed8a6901 Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Fri, 5 May 2017 17:19:18 -0300 Subject: [PATCH 12/14] Add disabled android host builders --- src/ci/docker/android-ndk.sh | 35 ++++++++++ .../disabled/dist-aarch64-android/Dockerfile | 49 ++++++++++++++ .../disabled/dist-armv7-android/Dockerfile | 65 +++++++++++++++++++ .../disabled/dist-i686-android/Dockerfile | 65 +++++++++++++++++++ .../disabled/dist-x86_64-android/Dockerfile | 49 ++++++++++++++ src/ci/docker/run.sh | 26 ++++++-- 6 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 src/ci/docker/android-ndk.sh create mode 100644 src/ci/docker/disabled/dist-aarch64-android/Dockerfile create mode 100644 src/ci/docker/disabled/dist-armv7-android/Dockerfile create mode 100644 src/ci/docker/disabled/dist-i686-android/Dockerfile create mode 100644 src/ci/docker/disabled/dist-x86_64-android/Dockerfile diff --git a/src/ci/docker/android-ndk.sh b/src/ci/docker/android-ndk.sh new file mode 100644 index 0000000000000..4849f84300729 --- /dev/null +++ b/src/ci/docker/android-ndk.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# Copyright 2017 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. + +set -ex + +URL=https://dl.google.com/android/repository + +download_ndk() { + mkdir -p /android/ndk + cd /android/ndk + curl -O $URL/$1 + unzip -q $1 + rm $1 + mv android-ndk-* ndk +} + +make_standalone_toolchain() { + # See https://developer.android.com/ndk/guides/standalone_toolchain.htm + python2.7 /android/ndk/ndk/build/tools/make_standalone_toolchain.py \ + --install-dir /android/ndk/$1-$2 \ + --arch $1 \ + --api $2 +} + +remove_ndk() { + rm -rf /android/ndk/ndk +} diff --git a/src/ci/docker/disabled/dist-aarch64-android/Dockerfile b/src/ci/docker/disabled/dist-aarch64-android/Dockerfile new file mode 100644 index 0000000000000..34e112a1f4f41 --- /dev/null +++ b/src/ci/docker/disabled/dist-aarch64-android/Dockerfile @@ -0,0 +1,49 @@ +FROM ubuntu:16.04 + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + g++ \ + make \ + file \ + curl \ + ca-certificates \ + python2.7 \ + git \ + cmake \ + unzip \ + sudo \ + xz-utils \ + libssl-dev \ + pkg-config + +RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ + dpkg -i dumb-init_*.deb && \ + rm dumb-init_*.deb + +RUN curl -o /usr/local/bin/sccache \ + https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \ + chmod +x /usr/local/bin/sccache + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] + +COPY android-ndk.sh / +RUN . /android-ndk.sh && \ + download_ndk android-ndk-r13b-linux-x86_64.zip && \ + make_standalone_toolchain arm64 21 && \ + remove_ndk + +ENV PATH=$PATH:/android/ndk/arm64-21/bin + +ENV DEP_Z_ROOT=/android/ndk/arm64-21/sysroot/usr/ + +ENV HOSTS=aarch64-linux-android + +ENV RUST_CONFIGURE_ARGS \ + --host=$HOSTS \ + --target=$HOSTS \ + --aarch64-linux-android-ndk=/android/ndk/arm64-21 \ + --disable-rpath \ + --enable-extended \ + --enable-cargo-openssl-static + +ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS diff --git a/src/ci/docker/disabled/dist-armv7-android/Dockerfile b/src/ci/docker/disabled/dist-armv7-android/Dockerfile new file mode 100644 index 0000000000000..34468969b88eb --- /dev/null +++ b/src/ci/docker/disabled/dist-armv7-android/Dockerfile @@ -0,0 +1,65 @@ +FROM ubuntu:16.04 + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + g++ \ + make \ + file \ + curl \ + ca-certificates \ + python2.7 \ + git \ + cmake \ + unzip \ + sudo \ + xz-utils \ + libssl-dev \ + pkg-config + +RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ + dpkg -i dumb-init_*.deb && \ + rm dumb-init_*.deb + +RUN curl -o /usr/local/bin/sccache \ + https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \ + chmod +x /usr/local/bin/sccache + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] + +COPY android-ndk.sh / +RUN . /android-ndk.sh && \ + download_ndk android-ndk-r13b-linux-x86_64.zip && \ + make_standalone_toolchain arm 9 && \ + make_standalone_toolchain arm 21 && \ + remove_ndk + +ENV PATH=$PATH:/android/ndk/arm-9/bin + +ENV DEP_Z_ROOT=/android/ndk/arm-9/sysroot/usr/ + +ENV HOSTS=armv7-linux-androideabi + +ENV RUST_CONFIGURE_ARGS \ + --host=$HOSTS \ + --target=$HOSTS \ + --armv7-linux-androideabi-ndk=/android/ndk/arm \ + --disable-rpath \ + --enable-extended \ + --enable-cargo-openssl-static + +# We support api level 9, but api level 21 is required to build llvm. To +# overcome this problem we use a ndk with api level 21 to build llvm and then +# switch to a ndk with api level 9 to complete the build. When the linker is +# invoked there are missing symbols (like sigsetempty, not available with api +# level 9), the default linker behavior is to generate an error, to allow the +# build to finish we use --warn-unresolved-symbols. Note that the missing +# symbols does not affect std, only the compiler (llvm) and cargo (openssl). +RUN chmod 777 /android/ndk && \ + ln -s /android/ndk/arm-21 /android/ndk/arm + +ENV SCRIPT \ + python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ + (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ + rm /android/ndk/arm && \ + ln -s /android/ndk/arm-9 /android/ndk/arm && \ + python2.7 ../x.py dist --host $HOSTS --target $HOSTS) diff --git a/src/ci/docker/disabled/dist-i686-android/Dockerfile b/src/ci/docker/disabled/dist-i686-android/Dockerfile new file mode 100644 index 0000000000000..cb9c76b22818c --- /dev/null +++ b/src/ci/docker/disabled/dist-i686-android/Dockerfile @@ -0,0 +1,65 @@ +FROM ubuntu:16.04 + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + g++ \ + make \ + file \ + curl \ + ca-certificates \ + python2.7 \ + git \ + cmake \ + unzip \ + sudo \ + xz-utils \ + libssl-dev \ + pkg-config + +RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ + dpkg -i dumb-init_*.deb && \ + rm dumb-init_*.deb + +RUN curl -o /usr/local/bin/sccache \ + https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \ + chmod +x /usr/local/bin/sccache + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] + +COPY android-ndk.sh / +RUN . /android-ndk.sh && \ + download_ndk android-ndk-r13b-linux-x86_64.zip && \ + make_standalone_toolchain x86 9 && \ + make_standalone_toolchain x86 21 && \ + remove_ndk + +ENV PATH=$PATH:/android/ndk/x86-9/bin + +ENV DEP_Z_ROOT=/android/ndk/x86-9/sysroot/usr/ + +ENV HOSTS=i686-linux-android + +ENV RUST_CONFIGURE_ARGS \ + --host=$HOSTS \ + --target=$HOSTS \ + --i686-linux-android-ndk=/android/ndk/x86 \ + --disable-rpath \ + --enable-extended \ + --enable-cargo-openssl-static + +# We support api level 9, but api level 21 is required to build llvm. To +# overcome this problem we use a ndk with api level 21 to build llvm and then +# switch to a ndk with api level 9 to complete the build. When the linker is +# invoked there are missing symbols (like sigsetempty, not available with api +# level 9), the default linker behavior is to generate an error, to allow the +# build to finish we use --warn-unresolved-symbols. Note that the missing +# symbols does not affect std, only the compiler (llvm) and cargo (openssl). +RUN chmod 777 /android/ndk && \ + ln -s /android/ndk/x86-21 /android/ndk/x86 + +ENV SCRIPT \ + python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ + (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ + rm /android/ndk/x86 && \ + ln -s /android/ndk/x86-9 /android/ndk/x86 && \ + python2.7 ../x.py dist --host $HOSTS --target $HOSTS) diff --git a/src/ci/docker/disabled/dist-x86_64-android/Dockerfile b/src/ci/docker/disabled/dist-x86_64-android/Dockerfile new file mode 100644 index 0000000000000..11a80abf8f9fc --- /dev/null +++ b/src/ci/docker/disabled/dist-x86_64-android/Dockerfile @@ -0,0 +1,49 @@ +FROM ubuntu:16.04 + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + g++ \ + make \ + file \ + curl \ + ca-certificates \ + python2.7 \ + git \ + cmake \ + unzip \ + sudo \ + xz-utils \ + libssl-dev \ + pkg-config + +RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ + dpkg -i dumb-init_*.deb && \ + rm dumb-init_*.deb + +RUN curl -o /usr/local/bin/sccache \ + https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-29-sccache-x86_64-unknown-linux-musl && \ + chmod +x /usr/local/bin/sccache + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] + +COPY android-ndk.sh / +RUN . /android-ndk.sh && \ + download_ndk android-ndk-r13b-linux-x86_64.zip && \ + make_standalone_toolchain x86_64 21 && \ + remove_ndk + +ENV PATH=$PATH:/android/ndk/x86_64-21/bin + +ENV DEP_Z_ROOT=/android/ndk/x86_64-21/sysroot/usr/ + +ENV HOSTS=x86_64-linux-android + +ENV RUST_CONFIGURE_ARGS \ + --host=$HOSTS \ + --target=$HOSTS \ + --x86_64-linux-android-ndk=/android/ndk/x86_64-21 \ + --disable-rpath \ + --enable-extended \ + --enable-cargo-openssl-static + +ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 59b93b784b2f6..6abbf0530afa6 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -21,11 +21,27 @@ root_dir="`dirname $src_dir`" source "$ci_dir/shared.sh" -retry docker \ - build \ - --rm \ - -t rust-ci \ - "`dirname "$script"`/$image" +if [ -f "$docker_dir/$image/Dockerfile" ]; then + retry docker \ + build \ + --rm \ + -t rust-ci \ + "$docker_dir/$image" +elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then + if [ -n "$TRAVIS_OS_NAME" ]; then + echo Cannot run disabled images on travis! + exit 1 + fi + retry docker \ + build \ + --rm \ + -t rust-ci \ + -f "$docker_dir/disabled/$image/Dockerfile" \ + "$docker_dir" +else + echo Invalid image: $image + exit 1 +fi objdir=$root_dir/obj From 84a40c14430566b94a238d5399929bc16867f519 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 10 May 2017 11:00:08 +0200 Subject: [PATCH 13/14] ICH: Handle case of removed FileMaps. --- src/librustc_incremental/persist/hash.rs | 6 +++- .../remove_source_file/auxiliary/mod.rs | 13 ++++++++ .../incremental/remove_source_file/main.rs | 31 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/test/incremental/remove_source_file/auxiliary/mod.rs create mode 100644 src/test/incremental/remove_source_file/main.rs diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs index 5bc442deafa2b..2f727a80f016e 100644 --- a/src/librustc_incremental/persist/hash.rs +++ b/src/librustc_incremental/persist/hash.rs @@ -79,7 +79,11 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { DepNode::FileMap(def_id, ref name) => { if def_id.is_local() { - Some(self.incremental_hashes_map[dep_node]) + // We will have been able to retrace the DefId (which is + // always the local CRATE_DEF_INDEX), but the file with the + // given name might have been removed, so we use get() in + // order to allow for that case. + self.incremental_hashes_map.get(dep_node).map(|x| *x) } else { Some(self.metadata_hash(DepNode::FileMap(def_id, name.clone()), def_id.krate, diff --git a/src/test/incremental/remove_source_file/auxiliary/mod.rs b/src/test/incremental/remove_source_file/auxiliary/mod.rs new file mode 100644 index 0000000000000..a2cea65a309ce --- /dev/null +++ b/src/test/incremental/remove_source_file/auxiliary/mod.rs @@ -0,0 +1,13 @@ +// Copyright 2017 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. + +pub fn print_hello() { + println!("hello"); +} diff --git a/src/test/incremental/remove_source_file/main.rs b/src/test/incremental/remove_source_file/main.rs new file mode 100644 index 0000000000000..4ba33f3bb3d62 --- /dev/null +++ b/src/test/incremental/remove_source_file/main.rs @@ -0,0 +1,31 @@ +// Copyright 2017 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. + +// This test case makes sure that the compiler doesn't crash due to a failing +// table lookup when a source file is removed. + +// revisions:rpass1 rpass2 + +// Note that we specify -g so that the FileMaps actually get referenced by the +// incr. comp. cache: +// compile-flags: -Z query-dep-graph -g + +#[cfg(rpass1)] +mod auxiliary; + +#[cfg(rpass1)] +fn main() { + auxiliary::print_hello(); +} + +#[cfg(rpass2)] +fn main() { + println!("hello"); +} From d23a65077add9da538e7ba2c2d3c3baae7a8597e Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 10 May 2017 14:37:29 +0300 Subject: [PATCH 14/14] compiletest: force GDB to print values in the Rust format. --- src/tools/compiletest/src/runtest.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index a044282666da0..461cb59bf7dfa 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -647,6 +647,11 @@ actual:\n\ exe_file.to_str().unwrap() .replace(r"\", r"\\"))); + // Force GDB to print values in the Rust format. + if self.config.gdb_native_rust { + script_str.push_str("set language rust\n"); + } + // Add line breakpoints for line in &breakpoint_lines { script_str.push_str(&format!("break '{}':{}\n",