diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 31bbd92cd620..6bddc8c8f648 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -796,6 +796,18 @@ impl Build { base.push(format!("-fdebug-prefix-map={}", map)); } } + + // For Android we're building against API level 17 (Android 4.2). + // Due to unified headers and the NDK-shipped compilers being cross-compilers + // we need to explictely say so. + // + // Also see: + // * https://source.android.com/setup/start/build-numbers + // * https://android.googlesource.com/platform/ndk.git/+/master/docs/UnifiedHeaders.md + if target.contains("android") { + base.push("-D__ANDROID_API__=17".into()); + } + base } diff --git a/src/ci/docker/arm-android/Dockerfile b/src/ci/docker/arm-android/Dockerfile index 775148481670..9ebb905e50c0 100644 --- a/src/ci/docker/arm-android/Dockerfile +++ b/src/ci/docker/arm-android/Dockerfile @@ -5,7 +5,7 @@ RUN sh /scripts/android-base-apt-get.sh COPY scripts/android-ndk.sh /scripts/ RUN . /scripts/android-ndk.sh && \ - download_and_make_toolchain android-ndk-r15c-linux-x86_64.zip arm 14 + download_and_make_toolchain android-ndk-r19c-linux-x86_64.zip arm 17 RUN dpkg --add-architecture i386 && \ apt-get update && \ @@ -29,7 +29,7 @@ ENV PATH=$PATH:/android/sdk/platform-tools ENV TARGETS=arm-linux-androideabi -ENV RUST_CONFIGURE_ARGS --arm-linux-androideabi-ndk=/android/ndk/arm-14 +ENV RUST_CONFIGURE_ARGS --arm-linux-androideabi-ndk=/android/ndk/arm-17 ENV SCRIPT python3 ../x.py test --target $TARGETS diff --git a/src/ci/docker/disabled/dist-armv7-android/Dockerfile b/src/ci/docker/disabled/dist-armv7-android/Dockerfile index 7227c41ccca9..347af1c72531 100644 --- a/src/ci/docker/disabled/dist-armv7-android/Dockerfile +++ b/src/ci/docker/disabled/dist-armv7-android/Dockerfile @@ -6,16 +6,16 @@ RUN sh /scripts/android-base-apt-get.sh COPY scripts/android-ndk.sh /scripts/ RUN . /scripts/android-ndk.sh && \ download_ndk android-ndk-r15c-linux-x86_64.zip && \ - make_standalone_toolchain arm 14 && \ + make_standalone_toolchain arm 17 && \ make_standalone_toolchain arm 21 && \ remove_ndk RUN chmod 777 /android/ndk && \ ln -s /android/ndk/arm-21 /android/ndk/arm -ENV PATH=$PATH:/android/ndk/arm-14/bin +ENV PATH=$PATH:/android/ndk/arm-17/bin -ENV DEP_Z_ROOT=/android/ndk/arm-14/sysroot/usr/ +ENV DEP_Z_ROOT=/android/ndk/arm-17/sysroot/usr/ ENV HOSTS=armv7-linux-androideabi @@ -25,18 +25,18 @@ ENV RUST_CONFIGURE_ARGS \ --enable-extended \ --enable-cargo-openssl-static -# We support api level 14, but api level 21 is required to build llvm. To +# We support api level 17, 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 14 to complete the build. When the linker is +# switch to a ndk with api level 17 to complete the build. When the linker is # invoked there are missing symbols (like sigsetempty, not available with api -# level 14), the default linker behavior is to generate an error, to allow the +# level 17), 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). ENV SCRIPT \ python3 ../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-14 /android/ndk/arm && \ + ln -s /android/ndk/arm-17 /android/ndk/arm && \ python3 ../x.py dist --host $HOSTS --target $HOSTS) COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/docker/disabled/dist-i686-android/Dockerfile b/src/ci/docker/disabled/dist-i686-android/Dockerfile index b74dcefa3516..14ed86c585a9 100644 --- a/src/ci/docker/disabled/dist-i686-android/Dockerfile +++ b/src/ci/docker/disabled/dist-i686-android/Dockerfile @@ -13,9 +13,9 @@ RUN . /scripts/android-ndk.sh && \ RUN chmod 777 /android/ndk && \ ln -s /android/ndk/x86-21 /android/ndk/x86 -ENV PATH=$PATH:/android/ndk/x86-14/bin +ENV PATH=$PATH:/android/ndk/x86-16/bin -ENV DEP_Z_ROOT=/android/ndk/x86-14/sysroot/usr/ +ENV DEP_Z_ROOT=/android/ndk/x86-16/sysroot/usr/ ENV HOSTS=i686-linux-android @@ -25,18 +25,18 @@ ENV RUST_CONFIGURE_ARGS \ --enable-extended \ --enable-cargo-openssl-static -# We support api level 14, but api level 21 is required to build llvm. To +# We support api level 16, 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 14 to complete the build. When the linker is +# switch to a ndk with api level 16 to complete the build. When the linker is # invoked there are missing symbols (like sigsetempty, not available with api -# level 14), the default linker behavior is to generate an error, to allow the +# level 16), 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). ENV SCRIPT \ python3 ../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-14 /android/ndk/x86 && \ + ln -s /android/ndk/x86-16 /android/ndk/x86 && \ python3 ../x.py dist --host $HOSTS --target $HOSTS) COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/docker/dist-android/Dockerfile b/src/ci/docker/dist-android/Dockerfile index 6d38e199564b..a01043e134ca 100644 --- a/src/ci/docker/dist-android/Dockerfile +++ b/src/ci/docker/dist-android/Dockerfile @@ -7,8 +7,8 @@ RUN sh /scripts/android-base-apt-get.sh COPY scripts/android-ndk.sh /scripts/ RUN . /scripts/android-ndk.sh && \ download_ndk android-ndk-r15c-linux-x86_64.zip && \ - make_standalone_toolchain arm 14 && \ - make_standalone_toolchain x86 14 && \ + make_standalone_toolchain arm 17 && \ + make_standalone_toolchain x86 17 && \ make_standalone_toolchain arm64 21 && \ make_standalone_toolchain x86_64 21 && \ remove_ndk @@ -24,10 +24,10 @@ ENV TARGETS=$TARGETS,x86_64-linux-android ENV RUST_CONFIGURE_ARGS \ --enable-extended \ --enable-profiler \ - --arm-linux-androideabi-ndk=/android/ndk/arm-14 \ - --armv7-linux-androideabi-ndk=/android/ndk/arm-14 \ - --thumbv7neon-linux-androideabi-ndk=/android/ndk/arm-14 \ - --i686-linux-android-ndk=/android/ndk/x86-14 \ + --arm-linux-androideabi-ndk=/android/ndk/arm-17 \ + --armv7-linux-androideabi-ndk=/android/ndk/arm-17 \ + --thumbv7neon-linux-androideabi-ndk=/android/ndk/arm-17 \ + --i686-linux-android-ndk=/android/ndk/x86-17 \ --aarch64-linux-android-ndk=/android/ndk/arm64-21 \ --x86_64-linux-android-ndk=/android/ndk/x86_64-21 \ --disable-docs diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs index 8e193935460e..db6272dbe013 100644 --- a/src/libstd/sys/unix/alloc.rs +++ b/src/libstd/sys/unix/alloc.rs @@ -52,22 +52,21 @@ unsafe impl GlobalAlloc for System { } } -#[cfg(any( - target_os = "android", - target_os = "illumos", - target_os = "redox", - target_os = "solaris" -))] +#[cfg(any(target_os = "illumos", target_os = "redox", target_os = "solaris"))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { - // On android we currently target API level 9 which unfortunately - // doesn't have the `posix_memalign` API used below. Instead we use - // `memalign`, but this unfortunately has the property on some systems - // where the memory returned cannot be deallocated by `free`! + // On platforms where `posix_memalign` is unavailable, we use `memalign`. // - // Upon closer inspection, however, this appears to work just fine with - // Android, so for this platform we should be fine to call `memalign` - // (which is present in API level 9). Some helpful references could + // This was previously a workaround for old Android version, + // it also has been applied to other systems now. + // + // This _might_ unfortunately have the property on some platforms + // that the memory returned cannot be deallocated by `free`! + // + // However, this appears to work just fine with the covered platforms, + // so for these platforms we should be fine to call `memalign`. + // + // Some helpful references could // possibly be chromium using memalign [1], attempts at documenting that // memalign + free is ok [2] [3], or the current source of chromium // which still uses memalign on android [4]. @@ -80,12 +79,7 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { libc::memalign(layout.align(), layout.size()) as *mut u8 } -#[cfg(not(any( - target_os = "android", - target_os = "illumos", - target_os = "redox", - target_os = "solaris" -)))] +#[cfg(not(any(target_os = "illumos", target_os = "redox", target_os = "solaris")))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); diff --git a/src/libstd/sys/unix/android.rs b/src/libstd/sys/unix/android.rs index 8fc2599f0d76..61aab892b9d6 100644 --- a/src/libstd/sys/unix/android.rs +++ b/src/libstd/sys/unix/android.rs @@ -5,8 +5,8 @@ //! always work with the most recent version of Android, but we also want to //! work with older versions of Android for whenever projects need to. //! -//! Our current minimum supported Android version is `android-9`, e.g., Android -//! with API level 9. We then in theory want to work on that and all future +//! Our current minimum supported Android version is `android-16`, e.g., Android +//! with API level 16. We then in theory want to work on that and all future //! versions of Android! //! //! Some of the detection here is done at runtime via `dlopen` and @@ -18,11 +18,7 @@ #![cfg(target_os = "android")] -use libc::{c_int, c_void, sighandler_t, size_t, ssize_t}; -use libc::{ftruncate, pread, pwrite}; - -use super::{cvt, cvt_r}; -use crate::io; +use libc::{c_int, sighandler_t}; // The `log2` and `log2f` functions apparently appeared in android-18, or at // least you can see they're not present in the android-17 header [1] and they @@ -63,7 +59,7 @@ pub fn log2f64(f: f64) -> f64 { // removed [3]. // // Basically this means that if we want to be binary compatible with multiple -// Android releases (oldest being 9 and newest being 21) then we need to check +// Android releases (oldest supported being 16) then we need to check // for both symbols and not actually link against either. // // [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms @@ -81,87 +77,3 @@ pub unsafe fn signal(signum: c_int, handler: sighandler_t) -> sighandler_t { let f = f.expect("neither `signal` nor `bsd_signal` symbols found"); f(signum, handler) } - -// The `ftruncate64` symbol apparently appeared in android-12, so we do some -// dynamic detection to see if we can figure out whether `ftruncate64` exists. -// -// If it doesn't we just fall back to `ftruncate`, generating an error for -// too-large values. -#[cfg(target_pointer_width = "32")] -pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> { - weak!(fn ftruncate64(c_int, i64) -> c_int); - - unsafe { - match ftruncate64.get() { - Some(f) => cvt_r(|| f(fd, size as i64)).map(drop), - None => { - if size > i32::max_value() as u64 { - Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot truncate >2GB")) - } else { - cvt_r(|| ftruncate(fd, size as i32)).map(drop) - } - } - } - } -} - -#[cfg(target_pointer_width = "64")] -pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> { - unsafe { cvt_r(|| ftruncate(fd, size as i64)).map(drop) } -} - -#[cfg(target_pointer_width = "32")] -pub unsafe fn cvt_pread64( - fd: c_int, - buf: *mut c_void, - count: size_t, - offset: i64, -) -> io::Result { - use crate::convert::TryInto; - weak!(fn pread64(c_int, *mut c_void, size_t, i64) -> ssize_t); - pread64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| { - if let Ok(o) = offset.try_into() { - cvt(pread(fd, buf, count, o)) - } else { - Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot pread >2GB")) - } - }) -} - -#[cfg(target_pointer_width = "32")] -pub unsafe fn cvt_pwrite64( - fd: c_int, - buf: *const c_void, - count: size_t, - offset: i64, -) -> io::Result { - use crate::convert::TryInto; - weak!(fn pwrite64(c_int, *const c_void, size_t, i64) -> ssize_t); - pwrite64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| { - if let Ok(o) = offset.try_into() { - cvt(pwrite(fd, buf, count, o)) - } else { - Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot pwrite >2GB")) - } - }) -} - -#[cfg(target_pointer_width = "64")] -pub unsafe fn cvt_pread64( - fd: c_int, - buf: *mut c_void, - count: size_t, - offset: i64, -) -> io::Result { - cvt(pread(fd, buf, count, offset)) -} - -#[cfg(target_pointer_width = "64")] -pub unsafe fn cvt_pwrite64( - fd: c_int, - buf: *const c_void, - count: size_t, - offset: i64, -) -> io::Result { - cvt(pwrite(fd, buf, count, offset)) -} diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 1ef7ffacfcf1..ed110ba1f871 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -75,19 +75,15 @@ impl FileDesc { } pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { - #[cfg(target_os = "android")] - use super::android::cvt_pread64; - - #[cfg(not(target_os = "android"))] unsafe fn cvt_pread64( fd: c_int, buf: *mut c_void, count: usize, offset: i64, ) -> io::Result { - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "android")))] use libc::pread as pread64; - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "android"))] use libc::pread64; cvt(pread64(fd, buf, count, offset)) } @@ -127,19 +123,15 @@ impl FileDesc { } pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { - #[cfg(target_os = "android")] - use super::android::cvt_pwrite64; - - #[cfg(not(target_os = "android"))] unsafe fn cvt_pwrite64( fd: c_int, buf: *const c_void, count: usize, offset: i64, ) -> io::Result { - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "android")))] use libc::pwrite as pwrite64; - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "android"))] use libc::pwrite64; cvt(pwrite64(fd, buf, count, offset)) } diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 80cf6a5dbc27..af42189ac802 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -30,8 +30,8 @@ use libc::fstatat64; use libc::readdir_r as readdir64_r; #[cfg(target_os = "android")] use libc::{ - dirent as dirent64, fstat as fstat64, fstatat as fstatat64, lseek64, lstat as lstat64, - open as open64, stat as stat64, + dirent as dirent64, fstat as fstat64, fstatat as fstatat64, ftruncate64, lseek64, + lstat as lstat64, off64_t, open as open64, stat as stat64, }; #[cfg(not(any( target_os = "linux", @@ -812,10 +812,6 @@ impl File { } pub fn truncate(&self, size: u64) -> io::Result<()> { - #[cfg(target_os = "android")] - return crate::sys::android::ftruncate64(self.0.raw(), size); - - #[cfg(not(target_os = "android"))] { use crate::convert::TryInto; let size: off64_t =