Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade Android SDK to API level 17 #71123

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 12 additions & 0 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
4 changes: 2 additions & 2 deletions src/ci/docker/arm-android/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 && \
Expand All @@ -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

Expand Down
14 changes: 7 additions & 7 deletions src/ci/docker/disabled/dist-armv7-android/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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/
Expand Down
12 changes: 6 additions & 6 deletions src/ci/docker/disabled/dist-i686-android/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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/
Expand Down
12 changes: 6 additions & 6 deletions src/ci/docker/dist-android/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
32 changes: 13 additions & 19 deletions src/libstd/sys/unix/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand All @@ -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();
Expand Down
96 changes: 4 additions & 92 deletions src/libstd/sys/unix/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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<ssize_t> {
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<ssize_t> {
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<ssize_t> {
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<ssize_t> {
cvt(pwrite(fd, buf, count, offset))
}
16 changes: 4 additions & 12 deletions src/libstd/sys/unix/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,15 @@ impl FileDesc {
}

pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
#[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<isize> {
#[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))
}
Expand Down Expand Up @@ -127,19 +123,15 @@ impl FileDesc {
}

pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
#[cfg(target_os = "android")]
use super::android::cvt_pwrite64;

#[cfg(not(target_os = "android"))]
unsafe fn cvt_pwrite64(
Copy link
Member

Choose a reason for hiding this comment

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

If you'll forgive the drive-by-comment, a lot of the organization in these idioms isn't necessary any longer now that the #[cfg] switch is gone, so you can probably clean these all up by inlining functions instead of declaring inline functions or inline blocks. Not critical of course, but just a thought!

Copy link
Member Author

Choose a reason for hiding this comment

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

That absolutely makes sense, drive-by comment happily taken.
First I need to get it working, then I can make it nice.

fd: c_int,
buf: *const c_void,
count: usize,
offset: i64,
) -> io::Result<isize> {
#[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))
}
Expand Down
8 changes: 2 additions & 6 deletions src/libstd/sys/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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 =
Expand Down