Auto merge of #42105 - Mark-Simulacrum:rollup, r=Mark-Simulacrum

Rollup of 17 pull requests

- Successful merges: #41870, #41910, #41958, #41971, #42006, #42024, #42037, #42056, #42067, #42070, #42079, #42080, #42082, #42089, #42092, #42096, #42100
- Failed merges:
This commit is contained in:
bors
2017-05-19 20:41:18 +00:00
71 changed files with 957 additions and 523 deletions

View File

@@ -398,13 +398,14 @@ class RustBuild(object):
sys.exit(ret) sys.exit(ret)
def output(self, args, env=None, cwd=None): def output(self, args, env=None, cwd=None):
default_encoding = sys.getdefaultencoding()
proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env, cwd=cwd) proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env, cwd=cwd)
(out, err) = proc.communicate() (out, err) = proc.communicate()
ret = proc.wait() ret = proc.wait()
if ret != 0: if ret != 0:
print(out) print(out)
sys.exit(ret) sys.exit(ret)
return out return out.decode(default_encoding)
def build_triple(self): def build_triple(self):
default_encoding = sys.getdefaultencoding() default_encoding = sys.getdefaultencoding()
@@ -570,10 +571,10 @@ class RustBuild(object):
for submod in submodules: for submod in submodules:
path, status = submod path, status = submod
if path.endswith(b"llvm") and \ if path.endswith('llvm') and \
(self.get_toml('llvm-config') or self.get_mk('CFG_LLVM_ROOT')): (self.get_toml('llvm-config') or self.get_mk('CFG_LLVM_ROOT')):
continue continue
if path.endswith(b"jemalloc") and \ if path.endswith('jemalloc') and \
(self.get_toml('jemalloc') or self.get_mk('CFG_JEMALLOC_ROOT')): (self.get_toml('jemalloc') or self.get_mk('CFG_JEMALLOC_ROOT')):
continue continue
submod_path = os.path.join(self.rust_root, path) submod_path = os.path.join(self.rust_root, path)

View File

@@ -21,8 +21,18 @@ use std::process::Command;
use Build; use Build;
use dist::{sanitize_sh, tmpdir}; use dist::{sanitize_sh, tmpdir};
/// Installs everything. pub struct Installer<'a> {
pub fn install(build: &Build, stage: u32, host: &str) { build: &'a Build,
prefix: PathBuf,
sysconfdir: PathBuf,
docdir: PathBuf,
bindir: PathBuf,
libdir: PathBuf,
mandir: PathBuf,
}
impl<'a> Installer<'a> {
pub fn new(build: &'a Build) -> Installer<'a> {
let prefix_default = PathBuf::from("/usr/local"); let prefix_default = PathBuf::from("/usr/local");
let sysconfdir_default = PathBuf::from("/etc"); let sysconfdir_default = PathBuf::from("/etc");
let docdir_default = PathBuf::from("share/doc/rust"); let docdir_default = PathBuf::from("share/doc/rust");
@@ -51,53 +61,70 @@ pub fn install(build: &Build, stage: u32, host: &str) {
let libdir = add_destdir(&libdir, &destdir); let libdir = add_destdir(&libdir, &destdir);
let mandir = add_destdir(&mandir, &destdir); let mandir = add_destdir(&mandir, &destdir);
let empty_dir = build.out.join("tmp/empty_dir"); Installer {
build,
prefix,
sysconfdir,
docdir,
bindir,
libdir,
mandir,
}
}
/// Installs everything.
pub fn install(&self, stage: u32, host: &str) {
let empty_dir = self.build.out.join("tmp/empty_dir");
t!(fs::create_dir_all(&empty_dir)); t!(fs::create_dir_all(&empty_dir));
if build.config.docs {
install_sh(&build, "docs", "rust-docs", &build.rust_package_vers(), if self.build.config.docs {
stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, self.install_sh("docs", "rust-docs", &self.build.rust_package_vers(),
&mandir, &empty_dir); stage, Some(host), &empty_dir);
} }
for target in build.config.target.iter() { for target in self.build.config.target.iter() {
install_sh(&build, "std", "rust-std", &build.rust_package_vers(), self.install_sh("std", "rust-std", &self.build.rust_package_vers(),
stage, target, &prefix, &sysconfdir, &docdir, &bindir, &libdir, stage, Some(target), &empty_dir);
&mandir, &empty_dir);
} }
if build.config.extended { if self.build.config.extended {
install_sh(&build, "cargo", "cargo", &build.cargo_package_vers(), self.install_sh("cargo", "cargo", &self.build.cargo_package_vers(),
stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, stage, Some(host), &empty_dir);
&mandir, &empty_dir); self.install_sh("rls", "rls", &self.build.rls_package_vers(),
install_sh(&build, "rls", "rls", &build.rls_package_vers(), stage, Some(host), &empty_dir);
stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, self.install_sh("analysis", "rust-analysis", &self.build.rust_package_vers(),
&mandir, &empty_dir); stage, Some(host), &empty_dir);
self.install_sh("src", "rust-src", &self.build.rust_package_vers(),
stage, None, &empty_dir);
} }
install_sh(&build, "rustc", "rustc", &build.rust_package_vers(), self.install_sh("rustc", "rustc", &self.build.rust_package_vers(),
stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, stage, Some(host), &empty_dir);
&mandir, &empty_dir);
t!(fs::remove_dir_all(&empty_dir)); t!(fs::remove_dir_all(&empty_dir));
} }
fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: &str, fn install_sh(&self, package: &str, name: &str, version: &str,
prefix: &Path, sysconfdir: &Path, docdir: &Path, bindir: &Path, libdir: &Path, stage: u32, host: Option<&str>, empty_dir: &Path) {
mandir: &Path, empty_dir: &Path) { println!("Install {} stage{} ({:?})", package, stage, host);
println!("Install {} stage{} ({})", package, stage, host); let package_name = if let Some(host) = host {
let package_name = format!("{}-{}-{}", name, version, host); format!("{}-{}-{}", name, version, host)
} else {
format!("{}-{}", name, version)
};
let mut cmd = Command::new("sh"); let mut cmd = Command::new("sh");
cmd.current_dir(empty_dir) cmd.current_dir(empty_dir)
.arg(sanitize_sh(&tmpdir(build).join(&package_name).join("install.sh"))) .arg(sanitize_sh(&tmpdir(self.build).join(&package_name).join("install.sh")))
.arg(format!("--prefix={}", sanitize_sh(prefix))) .arg(format!("--prefix={}", sanitize_sh(&self.prefix)))
.arg(format!("--sysconfdir={}", sanitize_sh(sysconfdir))) .arg(format!("--sysconfdir={}", sanitize_sh(&self.sysconfdir)))
.arg(format!("--docdir={}", sanitize_sh(docdir))) .arg(format!("--docdir={}", sanitize_sh(&self.docdir)))
.arg(format!("--bindir={}", sanitize_sh(bindir))) .arg(format!("--bindir={}", sanitize_sh(&self.bindir)))
.arg(format!("--libdir={}", sanitize_sh(libdir))) .arg(format!("--libdir={}", sanitize_sh(&self.libdir)))
.arg(format!("--mandir={}", sanitize_sh(mandir))) .arg(format!("--mandir={}", sanitize_sh(&self.mandir)))
.arg("--disable-ldconfig"); .arg("--disable-ldconfig");
build.run(&mut cmd); self.build.run(&mut cmd);
}
} }
fn add_destdir(path: &Path, destdir: &Option<PathBuf>) -> PathBuf { fn add_destdir(path: &Path, destdir: &Option<PathBuf>) -> PathBuf {

View File

@@ -761,7 +761,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
.run(move |s| dist::rls(build, s.stage, s.target)); .run(move |s| dist::rls(build, s.stage, s.target));
rules.dist("install", "path/to/nowhere") rules.dist("install", "path/to/nowhere")
.dep(|s| s.name("default:dist")) .dep(|s| s.name("default:dist"))
.run(move |s| install::install(build, s.stage, s.target)); .run(move |s| install::Installer::new(build).install(s.stage, s.target));
rules.dist("dist-cargo", "cargo") rules.dist("dist-cargo", "cargo")
.host(true) .host(true)
.only_host_build(true) .only_host_build(true)

View File

@@ -16,6 +16,12 @@ for example:
Images will output artifacts in an `obj` dir at the root of a repository. Images will output artifacts in an `obj` dir at the root of a repository.
## Filesystem layout
- Each directory, excluding `scripts` and `disabled`, corresponds to a docker image
- `scripts` contains files shared by docker images
- `disabled` contains images that are not build travis
## Cross toolchains ## Cross toolchains
A number of these images take quite a long time to compile as they're building A number of these images take quite a long time to compile as they're building

View File

@@ -2,52 +2,44 @@ FROM ubuntu:16.04
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
g++ \
make \
file \
curl \
ca-certificates \ ca-certificates \
python2.7 \
git \
cmake \ cmake \
unzip \ curl \
sudo \ file \
xz-utils \ g++ \
git \
libssl-dev \ libssl-dev \
pkg-config make \
pkg-config \
python2.7 \
sudo \
unzip \
xz-utils
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ # dumb-init
dpkg -i dumb-init_*.deb && \ COPY scripts/dumb-init.sh /scripts/
rm dumb-init_*.deb RUN sh /scripts/dumb-init.sh
RUN curl -o /usr/local/bin/sccache \ # ndk
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ COPY scripts/android-ndk.sh /scripts/
chmod +x /usr/local/bin/sccache RUN . /scripts/android-ndk.sh && \
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm 9
# Install NDK # sdk
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
# Install SDK
RUN dpkg --add-architecture i386 && \ RUN dpkg --add-architecture i386 && \
apt-get update && \ apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
openjdk-9-jre-headless \
tzdata \
libstdc++6:i386 \
libgl1-mesa-glx \ libgl1-mesa-glx \
libpulse0 libpulse0 \
libstdc++6:i386 \
openjdk-9-jre-headless \
tzdata
COPY install-sdk.sh /tmp COPY scripts/android-sdk.sh /scripts/
RUN . /tmp/install-sdk.sh && \ RUN . /scripts/android-sdk.sh && \
download_sdk tools_r25.2.5-linux.zip && \ download_and_create_avd tools_r25.2.5-linux.zip armeabi-v7a 18
download_sysimage armeabi-v7a 18 && \
create_avd armeabi-v7a 18
# Setup env # env
ENV PATH=$PATH:/android/sdk/tools ENV PATH=$PATH:/android/sdk/tools
ENV PATH=$PATH:/android/sdk/platform-tools ENV PATH=$PATH:/android/sdk/platform-tools
@@ -57,8 +49,12 @@ ENV RUST_CONFIGURE_ARGS \
--target=$TARGETS \ --target=$TARGETS \
--arm-linux-androideabi-ndk=/android/ndk/arm-9 --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 $TARGETS
# Entrypoint # sccache
COPY start-emulator.sh /android/ COPY scripts/sccache.sh /scripts/
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/android/start-emulator.sh"] RUN sh /scripts/sccache.sh
# init
COPY scripts/android-start-emulator.sh /scripts/
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/scripts/android-start-emulator.sh"]

View File

@@ -1,35 +0,0 @@
#!/bin/sh
# 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 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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.html
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
}

View File

@@ -31,7 +31,7 @@ WORKDIR /build
# The `vexpress_config` config file was a previously generated config file for # The `vexpress_config` config file was a previously generated config file for
# the kernel. This file was generated by running `make vexpress_defconfig` # the kernel. This file was generated by running `make vexpress_defconfig`
# followed by `make menuconfig` and then enabling the IPv6 protocol page. # followed by `make menuconfig` and then enabling the IPv6 protocol page.
COPY vexpress_config /build/.config COPY armhf-gnu/vexpress_config /build/.config
RUN curl https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.42.tar.xz | \ RUN curl https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.42.tar.xz | \
tar xJf - && \ tar xJf - && \
cd /build/linux-4.4.42 && \ cd /build/linux-4.4.42 && \
@@ -63,11 +63,11 @@ RUN curl http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-bas
# Copy over our init script, which starts up our test server and also a few # Copy over our init script, which starts up our test server and also a few
# other misc tasks. # other misc tasks.
COPY rcS rootfs/etc/init.d/rcS COPY armhf-gnu/rcS rootfs/etc/init.d/rcS
RUN chmod +x rootfs/etc/init.d/rcS RUN chmod +x rootfs/etc/init.d/rcS
# Helper to quickly fill the entropy pool in the kernel. # Helper to quickly fill the entropy pool in the kernel.
COPY addentropy.c /tmp/ COPY armhf-gnu/addentropy.c /tmp/
RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static
# TODO: What is this?! # TODO: What is this?!

View File

@@ -32,10 +32,10 @@ ENTRYPOINT ["/usr/bin/dumb-init", "--"]
WORKDIR /tmp WORKDIR /tmp
COPY build-rumprun.sh /tmp/ COPY cross/build-rumprun.sh /tmp/
RUN ./build-rumprun.sh RUN ./build-rumprun.sh
COPY build-arm-musl.sh /tmp/ COPY cross/build-arm-musl.sh /tmp/
RUN ./build-arm-musl.sh RUN ./build-arm-musl.sh
# originally from # originally from

View File

@@ -2,36 +2,30 @@ FROM ubuntu:16.04
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
g++ \
make \
file \
curl \
ca-certificates \ ca-certificates \
python2.7 \
git \
cmake \ cmake \
unzip \ curl \
sudo \ file \
xz-utils \ g++ \
git \
libssl-dev \ libssl-dev \
pkg-config make \
pkg-config \
python2.7 \
sudo \
unzip \
xz-utils
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ # dumb-init
dpkg -i dumb-init_*.deb && \ COPY scripts/dumb-init.sh /scripts/
rm dumb-init_*.deb RUN sh /scripts/dumb-init.sh
RUN curl -o /usr/local/bin/sccache \ # ndk
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ COPY scripts/android-ndk.sh /scripts/
chmod +x /usr/local/bin/sccache RUN . /scripts/android-ndk.sh && \
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm64 21
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
ENV PATH=$PATH:/android/ndk/arm64-21/bin ENV PATH=$PATH:/android/ndk/arm64-21/bin
ENV DEP_Z_ROOT=/android/ndk/arm64-21/sysroot/usr/ ENV DEP_Z_ROOT=/android/ndk/arm64-21/sysroot/usr/
@@ -47,3 +41,10 @@ ENV RUST_CONFIGURE_ARGS \
--enable-cargo-openssl-static --enable-cargo-openssl-static
ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS
# sccache
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
# init
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

View File

@@ -2,37 +2,36 @@ FROM ubuntu:16.04
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
g++ \
make \
file \
curl \
ca-certificates \ ca-certificates \
python2.7 \
git \
cmake \ cmake \
unzip \ curl \
sudo \ file \
xz-utils \ g++ \
git \
libssl-dev \ libssl-dev \
pkg-config make \
pkg-config \
python2.7 \
sudo \
unzip \
xz-utils
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ # dumb-init
dpkg -i dumb-init_*.deb && \ COPY scripts/dumb-init.sh /scripts/
rm dumb-init_*.deb RUN sh /scripts/dumb-init.sh
RUN curl -o /usr/local/bin/sccache \ # ndk
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ COPY scripts/android-ndk.sh /scripts/
chmod +x /usr/local/bin/sccache RUN . /scripts/android-ndk.sh && \
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
COPY android-ndk.sh /
RUN . /android-ndk.sh && \
download_ndk android-ndk-r13b-linux-x86_64.zip && \ download_ndk android-ndk-r13b-linux-x86_64.zip && \
make_standalone_toolchain arm 9 && \ make_standalone_toolchain arm 9 && \
make_standalone_toolchain arm 21 && \ make_standalone_toolchain arm 21 && \
remove_ndk remove_ndk
RUN chmod 777 /android/ndk && \
ln -s /android/ndk/arm-21 /android/ndk/arm
# env
ENV PATH=$PATH:/android/ndk/arm-9/bin ENV PATH=$PATH:/android/ndk/arm-9/bin
ENV DEP_Z_ROOT=/android/ndk/arm-9/sysroot/usr/ ENV DEP_Z_ROOT=/android/ndk/arm-9/sysroot/usr/
@@ -54,12 +53,16 @@ ENV RUST_CONFIGURE_ARGS \
# level 9), the default linker behavior is to generate an error, to allow the # 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 # build to finish we use --warn-unresolved-symbols. Note that the missing
# symbols does not affect std, only the compiler (llvm) and cargo (openssl). # 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 \ ENV SCRIPT \
python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \
(export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \
rm /android/ndk/arm && \ rm /android/ndk/arm && \
ln -s /android/ndk/arm-9 /android/ndk/arm && \ ln -s /android/ndk/arm-9 /android/ndk/arm && \
python2.7 ../x.py dist --host $HOSTS --target $HOSTS) python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
# sccache
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
# init
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

View File

@@ -2,37 +2,36 @@ FROM ubuntu:16.04
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
g++ \
make \
file \
curl \
ca-certificates \ ca-certificates \
python2.7 \
git \
cmake \ cmake \
unzip \ curl \
sudo \ file \
xz-utils \ g++ \
git \
libssl-dev \ libssl-dev \
pkg-config make \
pkg-config \
python2.7 \
sudo \
unzip \
xz-utils
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ # dumb-init
dpkg -i dumb-init_*.deb && \ COPY scripts/dumb-init.sh /scripts/
rm dumb-init_*.deb RUN sh /scripts/dumb-init.sh
RUN curl -o /usr/local/bin/sccache \ # ndk
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ COPY scripts/android-ndk.sh /scripts/
chmod +x /usr/local/bin/sccache RUN . /scripts/android-ndk.sh && \
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
COPY android-ndk.sh /
RUN . /android-ndk.sh && \
download_ndk android-ndk-r13b-linux-x86_64.zip && \ download_ndk android-ndk-r13b-linux-x86_64.zip && \
make_standalone_toolchain x86 9 && \ make_standalone_toolchain x86 9 && \
make_standalone_toolchain x86 21 && \ make_standalone_toolchain x86 21 && \
remove_ndk remove_ndk
RUN chmod 777 /android/ndk && \
ln -s /android/ndk/x86-21 /android/ndk/x86
# env
ENV PATH=$PATH:/android/ndk/x86-9/bin ENV PATH=$PATH:/android/ndk/x86-9/bin
ENV DEP_Z_ROOT=/android/ndk/x86-9/sysroot/usr/ ENV DEP_Z_ROOT=/android/ndk/x86-9/sysroot/usr/
@@ -54,12 +53,16 @@ ENV RUST_CONFIGURE_ARGS \
# level 9), the default linker behavior is to generate an error, to allow the # 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 # build to finish we use --warn-unresolved-symbols. Note that the missing
# symbols does not affect std, only the compiler (llvm) and cargo (openssl). # 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 \ ENV SCRIPT \
python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \
(export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \
rm /android/ndk/x86 && \ rm /android/ndk/x86 && \
ln -s /android/ndk/x86-9 /android/ndk/x86 && \ ln -s /android/ndk/x86-9 /android/ndk/x86 && \
python2.7 ../x.py dist --host $HOSTS --target $HOSTS) python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
# sccache
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
# init
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

View File

@@ -2,36 +2,30 @@ FROM ubuntu:16.04
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
g++ \
make \
file \
curl \
ca-certificates \ ca-certificates \
python2.7 \
git \
cmake \ cmake \
unzip \ curl \
sudo \ file \
xz-utils \ g++ \
git \
libssl-dev \ libssl-dev \
pkg-config make \
pkg-config \
python2.7 \
sudo \
unzip \
xz-utils
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ # dumb-init
dpkg -i dumb-init_*.deb && \ COPY scripts/dumb-init.sh /scripts/
rm dumb-init_*.deb RUN sh /scripts/dumb-init.sh
RUN curl -o /usr/local/bin/sccache \ # ndk
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ COPY scripts/android-ndk.sh /scripts/
chmod +x /usr/local/bin/sccache RUN . /scripts/android-ndk.sh && \
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip x86_64 21
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
ENV PATH=$PATH:/android/ndk/x86_64-21/bin ENV PATH=$PATH:/android/ndk/x86_64-21/bin
ENV DEP_Z_ROOT=/android/ndk/x86_64-21/sysroot/usr/ ENV DEP_Z_ROOT=/android/ndk/x86_64-21/sysroot/usr/
@@ -47,3 +41,10 @@ ENV RUST_CONFIGURE_ARGS \
--enable-cargo-openssl-static --enable-cargo-openssl-static
ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS
# sccache
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
# init
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

View File

@@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
USER rustbuild USER rustbuild
WORKDIR /tmp WORKDIR /tmp
COPY aarch64-linux-gnu.config build-toolchains.sh /tmp/ COPY dist-aarch64-linux/aarch64-linux-gnu.config dist-aarch64-linux/build-toolchains.sh /tmp/
RUN ./build-toolchains.sh RUN ./build-toolchains.sh
USER root USER root

View File

@@ -2,33 +2,27 @@ FROM ubuntu:16.04
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
g++ \
make \
file \
curl \
ca-certificates \ ca-certificates \
python2.7 \
git \
cmake \ cmake \
unzip \ curl \
sudo \ file \
xz-utils \ g++ \
git \
libssl-dev \ libssl-dev \
pkg-config make \
pkg-config \
python2.7 \
sudo \
unzip \
xz-utils
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ # dumb-init
dpkg -i dumb-init_*.deb && \ COPY scripts/dumb-init.sh /scripts/
rm dumb-init_*.deb RUN sh /scripts/dumb-init.sh
RUN curl -o /usr/local/bin/sccache \ # ndk
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ COPY scripts/android-ndk.sh /scripts/
chmod +x /usr/local/bin/sccache RUN . /scripts/android-ndk.sh && \
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 && \ download_ndk android-ndk-r13b-linux-x86_64.zip && \
make_standalone_toolchain arm 9 && \ make_standalone_toolchain arm 9 && \
make_standalone_toolchain x86 9 && \ make_standalone_toolchain x86 9 && \
@@ -36,6 +30,7 @@ RUN . /tmp/install-ndk.sh && \
make_standalone_toolchain x86_64 21 && \ make_standalone_toolchain x86_64 21 && \
remove_ndk remove_ndk
# env
ENV TARGETS=arm-linux-androideabi ENV TARGETS=arm-linux-androideabi
ENV TARGETS=$TARGETS,armv7-linux-androideabi ENV TARGETS=$TARGETS,armv7-linux-androideabi
ENV TARGETS=$TARGETS,i686-linux-android ENV TARGETS=$TARGETS,i686-linux-android
@@ -52,3 +47,10 @@ ENV RUST_CONFIGURE_ARGS \
--x86_64-linux-android-ndk=/android/ndk/x86_64-21 --x86_64-linux-android-ndk=/android/ndk/x86_64-21
ENV SCRIPT python2.7 ../x.py dist --target $TARGETS ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
# cache
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
# init
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

View File

@@ -1,35 +0,0 @@
#!/bin/sh
# 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 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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.html
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
}

View File

@@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
USER rustbuild USER rustbuild
WORKDIR /tmp WORKDIR /tmp
COPY arm-linux-gnueabi.config build-toolchains.sh /tmp/ COPY dist-arm-linux/arm-linux-gnueabi.config dist-arm-linux/build-toolchains.sh /tmp/
RUN ./build-toolchains.sh RUN ./build-toolchains.sh
USER root USER root

View File

@@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
USER rustbuild USER rustbuild
WORKDIR /tmp WORKDIR /tmp
COPY arm-linux-gnueabihf.config build-toolchains.sh /tmp/ COPY dist-armhf-linux/arm-linux-gnueabihf.config dist-armhf-linux/build-toolchains.sh /tmp/
RUN ./build-toolchains.sh RUN ./build-toolchains.sh
USER root USER root

View File

@@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
USER rustbuild USER rustbuild
WORKDIR /tmp WORKDIR /tmp
COPY build-toolchains.sh armv7-linux-gnueabihf.config /tmp/ COPY dist-armv7-linux/build-toolchains.sh dist-armv7-linux/armv7-linux-gnueabihf.config /tmp/
RUN ./build-toolchains.sh RUN ./build-toolchains.sh
USER root USER root

View File

@@ -21,7 +21,7 @@ RUN curl -L https://cmake.org/files/v3.8/cmake-3.8.0-rc1-Linux-x86_64.tar.gz | \
tar xzf - -C /usr/local --strip-components=1 tar xzf - -C /usr/local --strip-components=1
WORKDIR /tmp WORKDIR /tmp
COPY shared.sh build-toolchain.sh compiler-rt-dso-handle.patch /tmp/ COPY dist-fuchsia/shared.sh dist-fuchsia/build-toolchain.sh dist-fuchsia/compiler-rt-dso-handle.patch /tmp/
RUN /tmp/build-toolchain.sh RUN /tmp/build-toolchain.sh
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \

View File

@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config pkg-config
WORKDIR /build/ WORKDIR /build/
COPY musl-libunwind-patch.patch build-musl.sh /build/ COPY dist-i586-gnu-i686-musl/musl-libunwind-patch.patch dist-i586-gnu-i686-musl/build-musl.sh /build/
RUN sh /build/build-musl.sh && rm -rf /build RUN sh /build/build-musl.sh && rm -rf /build
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \

View File

@@ -16,7 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libssl-dev \ libssl-dev \
pkg-config pkg-config
COPY build-toolchain.sh /tmp/ COPY dist-i686-freebsd/build-toolchain.sh /tmp/
RUN /tmp/build-toolchain.sh i686 RUN /tmp/build-toolchain.sh i686
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \

View File

@@ -29,13 +29,13 @@ ENV PATH=/rustroot/bin:$PATH
ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib
ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig
WORKDIR /tmp WORKDIR /tmp
COPY shared.sh build-binutils.sh /tmp/ COPY dist-i686-linux/shared.sh dist-i686-linux/build-binutils.sh /tmp/
# We need a build of openssl which supports SNI to download artifacts from # We need a build of openssl which supports SNI to download artifacts from
# static.rust-lang.org. This'll be used to link into libcurl below (and used # static.rust-lang.org. This'll be used to link into libcurl below (and used
# later as well), so build a copy of OpenSSL with dynamic libraries into our # later as well), so build a copy of OpenSSL with dynamic libraries into our
# generic root. # generic root.
COPY build-openssl.sh /tmp/ COPY dist-i686-linux/build-openssl.sh /tmp/
RUN ./build-openssl.sh RUN ./build-openssl.sh
# The `curl` binary on CentOS doesn't support SNI which is needed for fetching # The `curl` binary on CentOS doesn't support SNI which is needed for fetching
@@ -44,7 +44,7 @@ RUN ./build-openssl.sh
# #
# Note that we also disable a bunch of optional features of curl that we don't # Note that we also disable a bunch of optional features of curl that we don't
# really need. # really need.
COPY build-curl.sh /tmp/ COPY dist-i686-linux/build-curl.sh /tmp/
RUN ./build-curl.sh RUN ./build-curl.sh
# binutils < 2.22 has a bug where the 32-bit executables it generates # binutils < 2.22 has a bug where the 32-bit executables it generates
@@ -54,26 +54,26 @@ RUN ./build-curl.sh
RUN ./build-binutils.sh RUN ./build-binutils.sh
# Need a newer version of gcc than centos has to compile LLVM nowadays # Need a newer version of gcc than centos has to compile LLVM nowadays
COPY build-gcc.sh /tmp/ COPY dist-i686-linux/build-gcc.sh /tmp/
RUN ./build-gcc.sh RUN ./build-gcc.sh
# CentOS 5.5 has Python 2.4 by default, but LLVM needs 2.7+ # CentOS 5.5 has Python 2.4 by default, but LLVM needs 2.7+
COPY build-python.sh /tmp/ COPY dist-i686-linux/build-python.sh /tmp/
RUN ./build-python.sh RUN ./build-python.sh
# Apparently CentOS 5.5 desn't have `git` in yum, but we're gonna need it for # Apparently CentOS 5.5 desn't have `git` in yum, but we're gonna need it for
# cloning, so download and build it here. # cloning, so download and build it here.
COPY build-git.sh /tmp/ COPY dist-i686-linux/build-git.sh /tmp/
RUN ./build-git.sh RUN ./build-git.sh
# libssh2 (a dependency of Cargo) requires cmake 2.8.11 or higher but CentOS # libssh2 (a dependency of Cargo) requires cmake 2.8.11 or higher but CentOS
# only has 2.6.4, so build our own # only has 2.6.4, so build our own
COPY build-cmake.sh /tmp/ COPY dist-i686-linux/build-cmake.sh /tmp/
RUN ./build-cmake.sh RUN ./build-cmake.sh
# for sanitizers, we need kernel headers files newer than the ones CentOS ships # for sanitizers, we need kernel headers files newer than the ones CentOS ships
# with so we install newer ones here # with so we install newer ones here
COPY build-headers.sh /tmp/ COPY dist-i686-linux/build-headers.sh /tmp/
RUN ./build-headers.sh RUN ./build-headers.sh
RUN curl -Lo /rustroot/dumb-init \ RUN curl -Lo /rustroot/dumb-init \

View File

@@ -56,8 +56,8 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
USER rustbuild USER rustbuild
WORKDIR /tmp WORKDIR /tmp
COPY patches/ /tmp/patches/ COPY dist-powerpc-linux/patches/ /tmp/patches/
COPY powerpc-linux-gnu.config build-powerpc-toolchain.sh /tmp/ COPY dist-powerpc-linux/powerpc-linux-gnu.config dist-powerpc-linux/build-powerpc-toolchain.sh /tmp/
RUN ./build-powerpc-toolchain.sh RUN ./build-powerpc-toolchain.sh
USER root USER root

View File

@@ -56,8 +56,8 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
USER rustbuild USER rustbuild
WORKDIR /tmp WORKDIR /tmp
COPY patches/ /tmp/patches/ COPY dist-powerpc64-linux/patches/ /tmp/patches/
COPY shared.sh powerpc64-linux-gnu.config build-powerpc64-toolchain.sh /tmp/ COPY dist-powerpc64-linux/shared.sh dist-powerpc64-linux/powerpc64-linux-gnu.config dist-powerpc64-linux/build-powerpc64-toolchain.sh /tmp/
RUN ./build-powerpc64-toolchain.sh RUN ./build-powerpc64-toolchain.sh
USER root USER root

View File

@@ -59,7 +59,7 @@ WORKDIR /tmp
USER root USER root
RUN apt-get install -y --no-install-recommends rpm2cpio cpio RUN apt-get install -y --no-install-recommends rpm2cpio cpio
COPY shared.sh build-powerpc64le-toolchain.sh /tmp/ COPY dist-powerpc64le-linux/shared.sh dist-powerpc64le-linux/build-powerpc64le-toolchain.sh /tmp/
RUN ./build-powerpc64le-toolchain.sh RUN ./build-powerpc64le-toolchain.sh
RUN curl -o /usr/local/bin/sccache \ RUN curl -o /usr/local/bin/sccache \

View File

@@ -56,8 +56,8 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
USER rustbuild USER rustbuild
WORKDIR /tmp WORKDIR /tmp
COPY patches/ /tmp/patches/ COPY dist-s390x-linux/patches/ /tmp/patches/
COPY s390x-linux-gnu.config build-s390x-toolchain.sh /tmp/ COPY dist-s390x-linux/s390x-linux-gnu.config dist-s390x-linux/build-s390x-toolchain.sh /tmp/
RUN ./build-s390x-toolchain.sh RUN ./build-s390x-toolchain.sh
USER root USER root

View File

@@ -16,7 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libssl-dev \ libssl-dev \
pkg-config pkg-config
COPY build-toolchain.sh /tmp/ COPY dist-x86_64-freebsd/build-toolchain.sh /tmp/
RUN /tmp/build-toolchain.sh x86_64 RUN /tmp/build-toolchain.sh x86_64
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \

View File

@@ -29,13 +29,13 @@ ENV PATH=/rustroot/bin:$PATH
ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib
ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig
WORKDIR /tmp WORKDIR /tmp
COPY shared.sh build-binutils.sh /tmp/ COPY dist-x86_64-linux/shared.sh dist-x86_64-linux/build-binutils.sh /tmp/
# We need a build of openssl which supports SNI to download artifacts from # We need a build of openssl which supports SNI to download artifacts from
# static.rust-lang.org. This'll be used to link into libcurl below (and used # static.rust-lang.org. This'll be used to link into libcurl below (and used
# later as well), so build a copy of OpenSSL with dynamic libraries into our # later as well), so build a copy of OpenSSL with dynamic libraries into our
# generic root. # generic root.
COPY build-openssl.sh /tmp/ COPY dist-x86_64-linux/build-openssl.sh /tmp/
RUN ./build-openssl.sh RUN ./build-openssl.sh
# The `curl` binary on CentOS doesn't support SNI which is needed for fetching # The `curl` binary on CentOS doesn't support SNI which is needed for fetching
@@ -44,7 +44,7 @@ RUN ./build-openssl.sh
# #
# Note that we also disable a bunch of optional features of curl that we don't # Note that we also disable a bunch of optional features of curl that we don't
# really need. # really need.
COPY build-curl.sh /tmp/ COPY dist-x86_64-linux/build-curl.sh /tmp/
RUN ./build-curl.sh RUN ./build-curl.sh
# binutils < 2.22 has a bug where the 32-bit executables it generates # binutils < 2.22 has a bug where the 32-bit executables it generates
@@ -54,26 +54,26 @@ RUN ./build-curl.sh
RUN ./build-binutils.sh RUN ./build-binutils.sh
# Need a newer version of gcc than centos has to compile LLVM nowadays # Need a newer version of gcc than centos has to compile LLVM nowadays
COPY build-gcc.sh /tmp/ COPY dist-x86_64-linux/build-gcc.sh /tmp/
RUN ./build-gcc.sh RUN ./build-gcc.sh
# CentOS 5.5 has Python 2.4 by default, but LLVM needs 2.7+ # CentOS 5.5 has Python 2.4 by default, but LLVM needs 2.7+
COPY build-python.sh /tmp/ COPY dist-x86_64-linux/build-python.sh /tmp/
RUN ./build-python.sh RUN ./build-python.sh
# Apparently CentOS 5.5 desn't have `git` in yum, but we're gonna need it for # Apparently CentOS 5.5 desn't have `git` in yum, but we're gonna need it for
# cloning, so download and build it here. # cloning, so download and build it here.
COPY build-git.sh /tmp/ COPY dist-x86_64-linux/build-git.sh /tmp/
RUN ./build-git.sh RUN ./build-git.sh
# libssh2 (a dependency of Cargo) requires cmake 2.8.11 or higher but CentOS # libssh2 (a dependency of Cargo) requires cmake 2.8.11 or higher but CentOS
# only has 2.6.4, so build our own # only has 2.6.4, so build our own
COPY build-cmake.sh /tmp/ COPY dist-x86_64-linux/build-cmake.sh /tmp/
RUN ./build-cmake.sh RUN ./build-cmake.sh
# for sanitizers, we need kernel headers files newer than the ones CentOS ships # for sanitizers, we need kernel headers files newer than the ones CentOS ships
# with so we install newer ones here # with so we install newer ones here
COPY build-headers.sh /tmp/ COPY dist-x86_64-linux/build-headers.sh /tmp/
RUN ./build-headers.sh RUN ./build-headers.sh
RUN curl -Lo /rustroot/dumb-init \ RUN curl -Lo /rustroot/dumb-init \

View File

@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config pkg-config
WORKDIR /build/ WORKDIR /build/
COPY build-musl.sh /build/ COPY dist-x86_64-musl/build-musl.sh /build/
RUN sh /build/build-musl.sh && rm -rf /build RUN sh /build/build-musl.sh && rm -rf /build
RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \

View File

@@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools
USER rustbuild USER rustbuild
WORKDIR /tmp WORKDIR /tmp
COPY build-netbsd-toolchain.sh /tmp/ COPY dist-x86_64-netbsd/build-netbsd-toolchain.sh /tmp/
RUN ./build-netbsd-toolchain.sh RUN ./build-netbsd-toolchain.sh
USER root USER root

View File

@@ -24,7 +24,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
ENTRYPOINT ["/usr/bin/dumb-init", "--"] ENTRYPOINT ["/usr/bin/dumb-init", "--"]
WORKDIR /tmp WORKDIR /tmp
COPY build-emscripten.sh /tmp/ COPY emscripten/build-emscripten.sh /tmp/
RUN ./build-emscripten.sh RUN ./build-emscripten.sh
ENV PATH=$PATH:/tmp/emsdk_portable ENV PATH=$PATH:/tmp/emsdk_portable
ENV PATH=$PATH:/tmp/emsdk_portable/clang/tag-e1.37.10/build_tag-e1.37.10_32/bin ENV PATH=$PATH:/tmp/emsdk_portable/clang/tag-e1.37.10/build_tag-e1.37.10_32/bin

View File

@@ -26,7 +26,8 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
build \ build \
--rm \ --rm \
-t rust-ci \ -t rust-ci \
"$docker_dir/$image" -f "$docker_dir/$image/Dockerfile" \
"$docker_dir"
elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then
if [ -n "$TRAVIS_OS_NAME" ]; then if [ -n "$TRAVIS_OS_NAME" ]; then
echo Cannot run disabled images on travis! echo Cannot run disabled images on travis!

View File

@@ -1,4 +1,3 @@
#!/bin/sh
# Copyright 2017 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 # file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT. # http://rust-lang.org/COPYRIGHT.
@@ -33,3 +32,9 @@ make_standalone_toolchain() {
remove_ndk() { remove_ndk() {
rm -rf /android/ndk/ndk rm -rf /android/ndk/ndk
} }
download_and_make_toolchain() {
download_ndk $1 && \
make_standalone_toolchain $2 $3 && \
remove_ndk
}

View File

@@ -1,4 +1,3 @@
#!/bin/sh
# Copyright 2017 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 # file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT. # http://rust-lang.org/COPYRIGHT.
@@ -47,3 +46,8 @@ create_avd() {
--abi $abi --abi $abi
} }
download_and_create_avd() {
download_sdk $1
download_sysimage $2 $3
create_avd $2 $3
}

View File

@@ -0,0 +1,15 @@
# 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 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
set -ex
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

View File

@@ -0,0 +1,16 @@
# 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 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
set -ex
curl -o /usr/local/bin/sccache \
https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl
chmod +x /usr/local/bin/sccache

View File

@@ -195,30 +195,34 @@ fn bench_contains_equal(b: &mut Bencher) {
}) })
} }
macro_rules! make_test_inner { macro_rules! make_test_inner {
($s:ident, $code:expr, $name:ident, $str:expr) => { ($s:ident, $code:expr, $name:ident, $str:expr, $iters:expr) => {
#[bench] #[bench]
fn $name(bencher: &mut Bencher) { fn $name(bencher: &mut Bencher) {
let mut $s = $str; let mut $s = $str;
black_box(&mut $s); black_box(&mut $s);
bencher.iter(|| $code); bencher.iter(|| for _ in 0..$iters { black_box($code); });
} }
} }
} }
macro_rules! make_test { macro_rules! make_test {
($name:ident, $s:ident, $code:expr) => { ($name:ident, $s:ident, $code:expr) => {
make_test!($name, $s, $code, 1);
};
($name:ident, $s:ident, $code:expr, $iters:expr) => {
mod $name { mod $name {
use test::Bencher; use test::Bencher;
use test::black_box; use test::black_box;
// Short strings: 65 bytes each // Short strings: 65 bytes each
make_test_inner!($s, $code, short_ascii, make_test_inner!($s, $code, short_ascii,
"Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!"); "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!", $iters);
make_test_inner!($s, $code, short_mixed, make_test_inner!($s, $code, short_mixed,
"ศไทย中华Việt Nam; Mary had a little lamb, Little lam!"); "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!", $iters);
make_test_inner!($s, $code, short_pile_of_poo, make_test_inner!($s, $code, short_pile_of_poo,
"💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!"); "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!", $iters);
make_test_inner!($s, $code, long_lorem_ipsum,"\ make_test_inner!($s, $code, long_lorem_ipsum,"\
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \ ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
@@ -253,7 +257,7 @@ Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas
feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \ feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \ vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \ leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
malesuada sollicitudin quam eu fermentum!"); malesuada sollicitudin quam eu fermentum!", $iters);
} }
} }
} }
@@ -288,6 +292,13 @@ make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}')); make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
make_test!(find_zzz_str, s, s.find("\u{1F4A4}")); make_test!(find_zzz_str, s, s.find("\u{1F4A4}"));
make_test!(starts_with_ascii_char, s, s.starts_with('/'), 1024);
make_test!(ends_with_ascii_char, s, s.ends_with('/'), 1024);
make_test!(starts_with_unichar, s, s.starts_with('\u{1F4A4}'), 1024);
make_test!(ends_with_unichar, s, s.ends_with('\u{1F4A4}'), 1024);
make_test!(starts_with_str, s, s.starts_with("💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩"), 1024);
make_test!(ends_with_str, s, s.ends_with("💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩"), 1024);
make_test!(split_space_char, s, s.split(' ').count()); make_test!(split_space_char, s, s.split(' ').count());
make_test!(split_terminator_space_char, s, s.split_terminator(' ').count()); make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());

View File

@@ -813,6 +813,7 @@ impl str {
/// assert!(!bananas.contains("apples")); /// assert!(!bananas.contains("apples"));
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool { pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
core_str::StrExt::contains(self, pat) core_str::StrExt::contains(self, pat)
} }
@@ -900,6 +901,7 @@ impl str {
/// assert_eq!(s.find(x), None); /// assert_eq!(s.find(x), None);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> { pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
core_str::StrExt::find(self, pat) core_str::StrExt::find(self, pat)
} }
@@ -944,6 +946,7 @@ impl str {
/// assert_eq!(s.rfind(x), None); /// assert_eq!(s.rfind(x), None);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
where P::Searcher: ReverseSearcher<'a> where P::Searcher: ReverseSearcher<'a>
{ {
@@ -1057,6 +1060,7 @@ impl str {
/// ///
/// [`split_whitespace`]: #method.split_whitespace /// [`split_whitespace`]: #method.split_whitespace
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> { pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
core_str::StrExt::split(self, pat) core_str::StrExt::split(self, pat)
} }
@@ -1106,6 +1110,7 @@ impl str {
/// assert_eq!(v, ["ghi", "def", "abc"]); /// assert_eq!(v, ["ghi", "def", "abc"]);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P> pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
where P::Searcher: ReverseSearcher<'a> where P::Searcher: ReverseSearcher<'a>
{ {
@@ -1152,6 +1157,7 @@ impl str {
/// assert_eq!(v, ["A", "", "B", ""]); /// assert_eq!(v, ["A", "", "B", ""]);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> { pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
core_str::StrExt::split_terminator(self, pat) core_str::StrExt::split_terminator(self, pat)
} }
@@ -1195,6 +1201,7 @@ impl str {
/// assert_eq!(v, ["", "B", "", "A"]); /// assert_eq!(v, ["", "B", "", "A"]);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P> pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
where P::Searcher: ReverseSearcher<'a> where P::Searcher: ReverseSearcher<'a>
{ {
@@ -1247,6 +1254,7 @@ impl str {
/// assert_eq!(v, ["abc", "defXghi"]); /// assert_eq!(v, ["abc", "defXghi"]);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> { pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
core_str::StrExt::splitn(self, n, pat) core_str::StrExt::splitn(self, n, pat)
} }
@@ -1294,6 +1302,7 @@ impl str {
/// assert_eq!(v, ["ghi", "abc1def"]); /// assert_eq!(v, ["ghi", "abc1def"]);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P> pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a> where P::Searcher: ReverseSearcher<'a>
{ {
@@ -1334,6 +1343,7 @@ impl str {
/// assert_eq!(v, ["1", "2", "3"]); /// assert_eq!(v, ["1", "2", "3"]);
/// ``` /// ```
#[stable(feature = "str_matches", since = "1.2.0")] #[stable(feature = "str_matches", since = "1.2.0")]
#[inline]
pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> { pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
core_str::StrExt::matches(self, pat) core_str::StrExt::matches(self, pat)
} }
@@ -1370,6 +1380,7 @@ impl str {
/// assert_eq!(v, ["3", "2", "1"]); /// assert_eq!(v, ["3", "2", "1"]);
/// ``` /// ```
#[stable(feature = "str_matches", since = "1.2.0")] #[stable(feature = "str_matches", since = "1.2.0")]
#[inline]
pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P> pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
where P::Searcher: ReverseSearcher<'a> where P::Searcher: ReverseSearcher<'a>
{ {
@@ -1415,6 +1426,7 @@ impl str {
/// assert_eq!(v, [(0, "aba")]); // only the first `aba` /// assert_eq!(v, [(0, "aba")]); // only the first `aba`
/// ``` /// ```
#[stable(feature = "str_match_indices", since = "1.5.0")] #[stable(feature = "str_match_indices", since = "1.5.0")]
#[inline]
pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> { pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
core_str::StrExt::match_indices(self, pat) core_str::StrExt::match_indices(self, pat)
} }
@@ -1457,6 +1469,7 @@ impl str {
/// assert_eq!(v, [(2, "aba")]); // only the last `aba` /// assert_eq!(v, [(2, "aba")]); // only the last `aba`
/// ``` /// ```
#[stable(feature = "str_match_indices", since = "1.5.0")] #[stable(feature = "str_match_indices", since = "1.5.0")]
#[inline]
pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P> pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
where P::Searcher: ReverseSearcher<'a> where P::Searcher: ReverseSearcher<'a>
{ {
@@ -1737,6 +1750,7 @@ impl str {
/// assert_eq!(s, s.replace("cookie monster", "little lamb")); /// assert_eq!(s, s.replace("cookie monster", "little lamb"));
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String { pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
let mut result = String::new(); let mut result = String::new();
let mut last_end = 0; let mut last_end = 0;

View File

@@ -429,7 +429,33 @@ impl<'a> DoubleEndedSearcher<'a> for CharSearcher<'a> {}
/// Searches for chars that are equal to a given char /// Searches for chars that are equal to a given char
impl<'a> Pattern<'a> for char { impl<'a> Pattern<'a> for char {
pattern_methods!(CharSearcher<'a>, CharEqPattern, CharSearcher); type Searcher = CharSearcher<'a>;
#[inline]
fn into_searcher(self, haystack: &'a str) -> Self::Searcher {
CharSearcher(CharEqPattern(self).into_searcher(haystack))
}
#[inline]
fn is_contained_in(self, haystack: &'a str) -> bool {
if (self as u32) < 128 {
haystack.as_bytes().contains(&(self as u8))
} else {
let mut buffer = [0u8; 4];
self.encode_utf8(&mut buffer).is_contained_in(haystack)
}
}
#[inline]
fn is_prefix_of(self, haystack: &'a str) -> bool {
CharEqPattern(self).is_prefix_of(haystack)
}
#[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool where Self::Searcher: ReverseSearcher<'a>
{
CharEqPattern(self).is_suffix_of(haystack)
}
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@@ -16,6 +16,7 @@
use hir; use hir;
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace}; use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace};
use ich::Fingerprint;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::stable_hasher::StableHasher;
@@ -34,7 +35,7 @@ use util::nodemap::NodeMap;
pub struct DefPathTable { pub struct DefPathTable {
index_to_key: [Vec<DefKey>; 2], index_to_key: [Vec<DefKey>; 2],
key_to_index: FxHashMap<DefKey, DefIndex>, key_to_index: FxHashMap<DefKey, DefIndex>,
def_path_hashes: [Vec<u64>; 2], def_path_hashes: [Vec<Fingerprint>; 2],
} }
// Unfortunately we have to provide a manual impl of Clone because of the // Unfortunately we have to provide a manual impl of Clone because of the
@@ -55,7 +56,7 @@ impl DefPathTable {
fn allocate(&mut self, fn allocate(&mut self,
key: DefKey, key: DefKey,
def_path_hash: u64, def_path_hash: Fingerprint,
address_space: DefIndexAddressSpace) address_space: DefIndexAddressSpace)
-> DefIndex { -> DefIndex {
let index = { let index = {
@@ -79,7 +80,7 @@ impl DefPathTable {
} }
#[inline(always)] #[inline(always)]
pub fn def_path_hash(&self, index: DefIndex) -> u64 { pub fn def_path_hash(&self, index: DefIndex) -> Fingerprint {
self.def_path_hashes[index.address_space().index()] self.def_path_hashes[index.address_space().index()]
[index.as_array_index()] [index.as_array_index()]
} }
@@ -146,8 +147,8 @@ impl Decodable for DefPathTable {
let index_to_key_lo: Vec<DefKey> = Decodable::decode(d)?; let index_to_key_lo: Vec<DefKey> = Decodable::decode(d)?;
let index_to_key_hi: Vec<DefKey> = Decodable::decode(d)?; let index_to_key_hi: Vec<DefKey> = Decodable::decode(d)?;
let def_path_hashes_lo: Vec<u64> = Decodable::decode(d)?; let def_path_hashes_lo: Vec<Fingerprint> = Decodable::decode(d)?;
let def_path_hashes_hi: Vec<u64> = Decodable::decode(d)?; let def_path_hashes_hi: Vec<Fingerprint> = Decodable::decode(d)?;
let index_to_key = [index_to_key_lo, index_to_key_hi]; let index_to_key = [index_to_key_lo, index_to_key_hi];
let def_path_hashes = [def_path_hashes_lo, def_path_hashes_hi]; let def_path_hashes = [def_path_hashes_lo, def_path_hashes_hi];
@@ -210,7 +211,7 @@ pub struct DefKey {
} }
impl DefKey { impl DefKey {
fn compute_stable_hash(&self, parent_hash: u64) -> u64 { fn compute_stable_hash(&self, parent_hash: Fingerprint) -> Fingerprint {
let mut hasher = StableHasher::new(); let mut hasher = StableHasher::new();
// We hash a 0u8 here to disambiguate between regular DefPath hashes, // We hash a 0u8 here to disambiguate between regular DefPath hashes,
@@ -221,7 +222,7 @@ impl DefKey {
hasher.finish() hasher.finish()
} }
fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> u64 { fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> Fingerprint {
let mut hasher = StableHasher::new(); let mut hasher = StableHasher::new();
// Disambiguate this from a regular DefPath hash, // Disambiguate this from a regular DefPath hash,
// see compute_stable_hash() above. // see compute_stable_hash() above.
@@ -396,7 +397,7 @@ impl Definitions {
} }
#[inline(always)] #[inline(always)]
pub fn def_path_hash(&self, index: DefIndex) -> u64 { pub fn def_path_hash(&self, index: DefIndex) -> Fingerprint {
self.table.def_path_hash(index) self.table.def_path_hash(index)
} }

View File

@@ -10,95 +10,75 @@
use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
use rustc_data_structures::stable_hasher; use rustc_data_structures::stable_hasher;
use rustc_data_structures::ToHex; use std::mem;
use std::slice;
const FINGERPRINT_LENGTH: usize = 16;
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
pub struct Fingerprint(pub [u8; FINGERPRINT_LENGTH]); pub struct Fingerprint(u64, u64);
impl Fingerprint { impl Fingerprint {
#[inline] #[inline]
pub fn zero() -> Fingerprint { pub fn zero() -> Fingerprint {
Fingerprint([0; FINGERPRINT_LENGTH]) Fingerprint(0, 0)
} }
#[inline]
pub fn from_smaller_hash(hash: u64) -> Fingerprint { pub fn from_smaller_hash(hash: u64) -> Fingerprint {
let mut result = Fingerprint::zero(); Fingerprint(hash, hash)
result.0[0] = (hash >> 0) as u8;
result.0[1] = (hash >> 8) as u8;
result.0[2] = (hash >> 16) as u8;
result.0[3] = (hash >> 24) as u8;
result.0[4] = (hash >> 32) as u8;
result.0[5] = (hash >> 40) as u8;
result.0[6] = (hash >> 48) as u8;
result.0[7] = (hash >> 56) as u8;
result
} }
#[inline]
pub fn to_smaller_hash(&self) -> u64 { pub fn to_smaller_hash(&self) -> u64 {
((self.0[0] as u64) << 0) | self.0
((self.0[1] as u64) << 8) |
((self.0[2] as u64) << 16) |
((self.0[3] as u64) << 24) |
((self.0[4] as u64) << 32) |
((self.0[5] as u64) << 40) |
((self.0[6] as u64) << 48) |
((self.0[7] as u64) << 56)
} }
pub fn to_hex(&self) -> String { pub fn to_hex(&self) -> String {
self.0.to_hex() format!("{:x}{:x}", self.0, self.1)
} }
} }
impl Encodable for Fingerprint { impl Encodable for Fingerprint {
#[inline] #[inline]
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
for &byte in &self.0 { s.emit_u64(self.0.to_le())?;
s.emit_u8(byte)?; s.emit_u64(self.1.to_le())
}
Ok(())
} }
} }
impl Decodable for Fingerprint { impl Decodable for Fingerprint {
#[inline] #[inline]
fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> { fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> {
let mut result = Fingerprint([0u8; FINGERPRINT_LENGTH]); let _0 = u64::from_le(d.read_u64()?);
for byte in &mut result.0 { let _1 = u64::from_le(d.read_u64()?);
*byte = d.read_u8()?; Ok(Fingerprint(_0, _1))
}
Ok(result)
} }
} }
impl ::std::fmt::Display for Fingerprint { impl ::std::fmt::Display for Fingerprint {
fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
for i in 0 .. self.0.len() { write!(formatter, "{:x}-{:x}", self.0, self.1)
if i > 0 {
write!(formatter, "::")?;
}
write!(formatter, "{}", self.0[i])?;
}
Ok(())
} }
} }
impl stable_hasher::StableHasherResult for Fingerprint { impl stable_hasher::StableHasherResult for Fingerprint {
fn finish(mut hasher: stable_hasher::StableHasher<Self>) -> Self { fn finish(mut hasher: stable_hasher::StableHasher<Self>) -> Self {
let mut fingerprint = Fingerprint::zero(); let hash_bytes: &[u8] = hasher.finalize();
fingerprint.0.copy_from_slice(hasher.finalize());
fingerprint assert!(hash_bytes.len() >= mem::size_of::<u64>() * 2);
let hash_bytes: &[u64] = unsafe {
slice::from_raw_parts(hash_bytes.as_ptr() as *const u64, 2)
};
// The bytes returned bytes the Blake2B hasher are always little-endian.
Fingerprint(u64::from_le(hash_bytes[0]), u64::from_le(hash_bytes[1]))
} }
} }
impl<CTX> stable_hasher::HashStable<CTX> for Fingerprint { impl<CTX> stable_hasher::HashStable<CTX> for Fingerprint {
#[inline]
fn hash_stable<W: stable_hasher::StableHasherResult>(&self, fn hash_stable<W: stable_hasher::StableHasherResult>(&self,
_: &mut CTX, _: &mut CTX,
hasher: &mut stable_hasher::StableHasher<W>) { hasher: &mut stable_hasher::StableHasher<W>) {
::std::hash::Hash::hash(&self.0, hasher); ::std::hash::Hash::hash(self, hasher);
} }
} }

View File

@@ -110,7 +110,7 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
} }
#[inline] #[inline]
pub fn def_path_hash(&mut self, def_id: DefId) -> u64 { pub fn def_path_hash(&mut self, def_id: DefId) -> ich::Fingerprint {
self.tcx.def_path_hash(def_id) self.tcx.def_path_hash(def_id)
} }

View File

@@ -282,7 +282,7 @@ pub trait CrateStore {
-> Option<DefId>; -> Option<DefId>;
fn def_key(&self, def: DefId) -> DefKey; fn def_key(&self, def: DefId) -> DefKey;
fn def_path(&self, def: DefId) -> hir_map::DefPath; fn def_path(&self, def: DefId) -> hir_map::DefPath;
fn def_path_hash(&self, def: DefId) -> u64; fn def_path_hash(&self, def: DefId) -> ich::Fingerprint;
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>; fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
fn item_children(&self, did: DefId) -> Vec<def::Export>; fn item_children(&self, did: DefId) -> Vec<def::Export>;
fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro; fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro;
@@ -414,7 +414,7 @@ impl CrateStore for DummyCrateStore {
fn def_path(&self, def: DefId) -> hir_map::DefPath { fn def_path(&self, def: DefId) -> hir_map::DefPath {
bug!("relative_def_path") bug!("relative_def_path")
} }
fn def_path_hash(&self, def: DefId) -> u64 { fn def_path_hash(&self, def: DefId) -> ich::Fingerprint {
bug!("wa") bug!("wa")
} }
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") } fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }

View File

@@ -824,9 +824,9 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
linker: Option<String> = (None, parse_opt_string, [UNTRACKED], linker: Option<String> = (None, parse_opt_string, [UNTRACKED],
"system linker to link outputs with"), "system linker to link outputs with"),
link_arg: Vec<String> = (vec![], parse_string_push, [UNTRACKED], link_arg: Vec<String> = (vec![], parse_string_push, [UNTRACKED],
"a single extra argument to pass to the linker (can be used several times)"), "a single extra argument to append to the linker invocation (can be used several times)"),
link_args: Option<Vec<String>> = (None, parse_opt_list, [UNTRACKED], link_args: Option<Vec<String>> = (None, parse_opt_list, [UNTRACKED],
"extra arguments to pass to the linker (space separated)"), "extra arguments to append to the linker invocation (space separated)"),
link_dead_code: bool = (false, parse_bool, [UNTRACKED], link_dead_code: bool = (false, parse_bool, [UNTRACKED],
"don't let linker strip dead code (turning it on can be used for code coverage)"), "don't let linker strip dead code (turning it on can be used for code coverage)"),
lto: bool = (false, parse_bool, [TRACKED], lto: bool = (false, parse_bool, [TRACKED],
@@ -1029,6 +1029,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"add a mapping target to the file path remapping config"), "add a mapping target to the file path remapping config"),
force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
"force all crates to be `rustc_private` unstable"), "force all crates to be `rustc_private` unstable"),
pre_link_arg: Vec<String> = (vec![], parse_string_push, [UNTRACKED],
"a single extra argument to prepend the linker invocation (can be used several times)"),
pre_link_args: Option<Vec<String>> = (None, parse_opt_list, [UNTRACKED],
"extra arguments to prepend to the linker invocation (space separated)"),
} }
pub fn default_lib_output() -> CrateType { pub fn default_lib_output() -> CrateType {

View File

@@ -159,10 +159,15 @@ pub fn get_or_default_sysroot() -> PathBuf {
}) })
} }
match canonicalize(env::current_exe().ok()) { match env::current_exe() {
Some(mut p) => { p.pop(); p.pop(); p } Ok(exe) => {
match canonicalize(Some(exe)) {
Some(mut p) => { p.pop(); p.pop(); return p; },
None => bug!("can't determine value for sysroot") None => bug!("can't determine value for sysroot")
} }
}
Err(ref e) => panic!(format!("failed to get current_exe: {}", e))
}
} }
// The name of the directory rustc expects libraries to be located. // The name of the directory rustc expects libraries to be located.

View File

@@ -19,7 +19,7 @@ use dep_graph::DepNode;
use hir::{map as hir_map, FreevarMap, TraitMap}; use hir::{map as hir_map, FreevarMap, TraitMap};
use hir::def::{Def, CtorKind, ExportMap}; use hir::def::{Def, CtorKind, ExportMap};
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use ich::StableHashingContext; use ich::{self, StableHashingContext};
use middle::const_val::ConstVal; use middle::const_val::ConstVal;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::privacy::AccessLevels; use middle::privacy::AccessLevels;
@@ -2248,7 +2248,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
} }
#[inline] #[inline]
pub fn def_path_hash(self, def_id: DefId) -> u64 { pub fn def_path_hash(self, def_id: DefId) -> ich::Fingerprint {
if def_id.is_local() { if def_id.is_local() {
self.hir.definitions().def_path_hash(def_id.index) self.hir.definitions().def_path_hash(def_id.index)
} else { } else {

View File

@@ -29,6 +29,7 @@ use util::nodemap::FxHashMap;
use serialize; use serialize;
use hir; use hir;
use ich;
use self::InferTy::*; use self::InferTy::*;
use self::TypeVariants::*; use self::TypeVariants::*;
@@ -849,7 +850,7 @@ impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> {
self.item_name // safe to skip the binder to access a name self.item_name // safe to skip the binder to access a name
} }
pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (u64, InternedString) { pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (ich::Fingerprint, InternedString) {
// We want something here that is stable across crate boundaries. // We want something here that is stable across crate boundaries.
// The DefId isn't but the `deterministic_hash` of the corresponding // The DefId isn't but the `deterministic_hash` of the corresponding
// DefPath is. // DefPath is.
@@ -884,7 +885,7 @@ impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> {
self.skip_binder().item_name() self.skip_binder().item_name()
} }
pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (u64, InternedString) { pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (ich::Fingerprint, InternedString) {
self.skip_binder().sort_key(tcx) self.skip_binder().sort_key(tcx)
} }

View File

@@ -9,6 +9,7 @@
// except according to those terms. // except according to those terms.
use hir::def_id::DefId; use hir::def_id::DefId;
use ich::Fingerprint;
use traits::specialization_graph; use traits::specialization_graph;
use ty::fast_reject; use ty::fast_reject;
use ty::fold::TypeFoldable; use ty::fold::TypeFoldable;
@@ -32,7 +33,7 @@ pub struct TraitDef {
/// The ICH of this trait's DefPath, cached here so it doesn't have to be /// The ICH of this trait's DefPath, cached here so it doesn't have to be
/// recomputed all the time. /// recomputed all the time.
pub def_path_hash: u64, pub def_path_hash: Fingerprint,
} }
// We don't store the list of impls in a flat list because each cached list of // We don't store the list of impls in a flat list because each cached list of
@@ -94,7 +95,7 @@ impl<'a, 'gcx, 'tcx> TraitDef {
unsafety: hir::Unsafety, unsafety: hir::Unsafety,
paren_sugar: bool, paren_sugar: bool,
has_default_impl: bool, has_default_impl: bool,
def_path_hash: u64) def_path_hash: Fingerprint)
-> TraitDef { -> TraitDef {
TraitDef { TraitDef {
def_id, def_id,

View File

@@ -1148,9 +1148,18 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
Registry::new(&all_errors) Registry::new(&all_errors)
} }
fn get_args() -> Vec<String> {
env::args_os().enumerate()
.map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| {
early_error(ErrorOutputType::default(),
&format!("Argument {} is not valid Unicode: {:?}", i, arg))
}))
.collect()
}
pub fn main() { pub fn main() {
env_logger::init().unwrap(); env_logger::init().unwrap();
let result = run(|| run_compiler(&env::args().collect::<Vec<_>>(), let result = run(|| run_compiler(&get_args(),
&mut RustcDefaultCalls, &mut RustcDefaultCalls,
None, None,
None)); None));

View File

@@ -224,7 +224,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
{ {
let tcx = self.hcx.tcx(); let tcx = self.hcx.tcx();
let mut impls: Vec<(u64, Fingerprint)> = krate let mut impls: Vec<(Fingerprint, Fingerprint)> = krate
.trait_impls .trait_impls
.iter() .iter()
.map(|(&trait_id, impls)| { .map(|(&trait_id, impls)| {

View File

@@ -17,6 +17,7 @@ use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind,
ExternCrate, NativeLibrary, MetadataLoader, LinkMeta, ExternCrate, NativeLibrary, MetadataLoader, LinkMeta,
LinkagePreference, LoadedMacro, EncodedMetadata}; LinkagePreference, LoadedMacro, EncodedMetadata};
use rustc::hir::def; use rustc::hir::def;
use rustc::ich;
use rustc::middle::lang_items; use rustc::middle::lang_items;
use rustc::session::Session; use rustc::session::Session;
use rustc::ty::{self, TyCtxt}; use rustc::ty::{self, TyCtxt};
@@ -337,7 +338,7 @@ impl CrateStore for cstore::CStore {
self.get_crate_data(def.krate).def_path(def.index) self.get_crate_data(def.krate).def_path(def.index)
} }
fn def_path_hash(&self, def: DefId) -> u64 { fn def_path_hash(&self, def: DefId) -> ich::Fingerprint {
self.get_crate_data(def.krate).def_path_hash(def.index) self.get_crate_data(def.krate).def_path_hash(def.index)
} }

View File

@@ -16,6 +16,7 @@ use schema::*;
use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind}; use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind};
use rustc::hir::map::{DefKey, DefPath, DefPathData}; use rustc::hir::map::{DefKey, DefPath, DefPathData};
use rustc::hir; use rustc::hir;
use rustc::ich;
use rustc::middle::cstore::LinkagePreference; use rustc::middle::cstore::LinkagePreference;
use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def::{self, Def, CtorKind};
@@ -1106,7 +1107,7 @@ impl<'a, 'tcx> CrateMetadata {
} }
#[inline] #[inline]
pub fn def_path_hash(&self, index: DefIndex) -> u64 { pub fn def_path_hash(&self, index: DefIndex) -> ich::Fingerprint {
self.def_path_table.def_path_hash(index) self.def_path_table.def_path_hash(index)
} }

View File

@@ -715,6 +715,10 @@ fn link_natively(sess: &Session,
if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) { if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) {
cmd.args(args); cmd.args(args);
} }
if let Some(ref args) = sess.opts.debugging_opts.pre_link_args {
cmd.args(args);
}
cmd.args(&sess.opts.debugging_opts.pre_link_arg);
let pre_link_objects = if crate_type == config::CrateTypeExecutable { let pre_link_objects = if crate_type == config::CrateTypeExecutable {
&sess.target.target.options.pre_link_objects_exe &sess.target.target.options.pre_link_objects_exe

View File

@@ -375,7 +375,10 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo { let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo {
let dctx = debuginfo::CrateDebugContext::new(llmod); let dctx = debuginfo::CrateDebugContext::new(llmod);
debuginfo::metadata::compile_unit_metadata(shared, &dctx, shared.tcx.sess); debuginfo::metadata::compile_unit_metadata(shared,
codegen_unit.name(),
&dctx,
shared.tcx.sess);
Some(dctx) Some(dctx)
} else { } else {
None None

View File

@@ -762,23 +762,30 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
} }
pub fn compile_unit_metadata(scc: &SharedCrateContext, pub fn compile_unit_metadata(scc: &SharedCrateContext,
codegen_unit_name: &str,
debug_context: &CrateDebugContext, debug_context: &CrateDebugContext,
sess: &Session) sess: &Session)
-> DIDescriptor { -> DIDescriptor {
let compile_unit_name = match sess.local_crate_source_file { let mut name_in_debuginfo = match sess.local_crate_source_file {
None => fallback_path(scc), Some(ref path) => path.clone(),
Some(ref path) => { None => scc.tcx().crate_name(LOCAL_CRATE).to_string(),
CString::new(&path[..]).unwrap()
}
}; };
debug!("compile_unit_metadata: {:?}", compile_unit_name); // The OSX linker has an idiosyncrasy where it will ignore some debuginfo
// if multiple object files with the same DW_AT_name are linked together.
// As a workaround we generate unique names for each object file. Those do
// not correspond to an actual source file but that should be harmless.
if scc.sess().target.target.options.is_like_osx {
name_in_debuginfo.push_str("@");
name_in_debuginfo.push_str(codegen_unit_name);
}
debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
// FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice. // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
let producer = format!("clang LLVM (rustc version {})", let producer = format!("clang LLVM (rustc version {})",
(option_env!("CFG_VERSION")).expect("CFG_VERSION")); (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
let compile_unit_name = compile_unit_name.as_ptr(); let name_in_debuginfo = CString::new(name_in_debuginfo).unwrap();
let work_dir = CString::new(&sess.working_dir.0[..]).unwrap(); let work_dir = CString::new(&sess.working_dir.0[..]).unwrap();
let producer = CString::new(producer).unwrap(); let producer = CString::new(producer).unwrap();
let flags = "\0"; let flags = "\0";
@@ -786,7 +793,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
unsafe { unsafe {
let file_metadata = llvm::LLVMRustDIBuilderCreateFile( let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
debug_context.builder, compile_unit_name, work_dir.as_ptr()); debug_context.builder, name_in_debuginfo.as_ptr(), work_dir.as_ptr());
return llvm::LLVMRustDIBuilderCreateCompileUnit( return llvm::LLVMRustDIBuilderCreateCompileUnit(
debug_context.builder, debug_context.builder,
@@ -798,10 +805,6 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
0, 0,
split_name.as_ptr() as *const _) split_name.as_ptr() as *const _)
}; };
fn fallback_path(scc: &SharedCrateContext) -> CString {
CString::new(scc.tcx().crate_name(LOCAL_CRATE).to_string()).unwrap()
}
} }
struct MetadataCreationResult { struct MetadataCreationResult {

View File

@@ -215,14 +215,14 @@
} else if (ev.target.tagName === 'SPAN' && hasClass(ev.target.parentNode, 'line-numbers')) { } else if (ev.target.tagName === 'SPAN' && hasClass(ev.target.parentNode, 'line-numbers')) {
var prev_id = 0; var prev_id = 0;
function set_fragment(name) { var set_fragment = function (name) {
if (browserSupportsHistoryApi()) { if (browserSupportsHistoryApi()) {
history.replaceState(null, null, '#' + name); history.replaceState(null, null, '#' + name);
window.hashchange(); window.hashchange();
} else { } else {
location.replace('#' + name); location.replace('#' + name);
} }
} };
var cur_id = parseInt(ev.target.id, 10); var cur_id = parseInt(ev.target.id, 10);
@@ -685,7 +685,7 @@
} }
function escape(content) { function escape(content) {
let h1 = document.createElement('h1'); var h1 = document.createElement('h1');
h1.textContent = content; h1.textContent = content;
return h1.innerHTML; return h1.innerHTML;
} }
@@ -1083,10 +1083,10 @@
code.innerHTML = structs[j]; code.innerHTML = structs[j];
var x = code.getElementsByTagName('a'); var x = code.getElementsByTagName('a');
for (var i = 0; i < x.length; i++) { for (var k = 0; k < x.length; k++) {
var href = x[i].href; var href = x[k].getAttribute('href');
if (href && href.indexOf('http') !== 0) { if (href && href.indexOf('http') !== 0) {
x[i].href = rootPath + href; x[k].setAttribute('href', rootPath + href);
} }
} }
var li = document.createElement('li'); var li = document.createElement('li');

View File

@@ -107,12 +107,19 @@ pub fn main() {
const STACK_SIZE: usize = 32_000_000; // 32MB const STACK_SIZE: usize = 32_000_000; // 32MB
env_logger::init().unwrap(); env_logger::init().unwrap();
let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || { let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || {
let s = env::args().collect::<Vec<_>>(); get_args().map(|args| main_args(&args)).unwrap_or(1)
main_args(&s)
}).unwrap().join().unwrap_or(101); }).unwrap().join().unwrap_or(101);
process::exit(res as i32); process::exit(res as i32);
} }
fn get_args() -> Option<Vec<String>> {
env::args_os().enumerate()
.map(|(i, arg)| arg.into_string().map_err(|arg| {
print_error(format!("Argument {} is not valid Unicode: {:?}", i, arg));
}).ok())
.collect()
}
fn stable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::stable(g) } fn stable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::stable(g) }
fn unstable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::unstable(g) } fn unstable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::unstable(g) }

View File

@@ -43,16 +43,19 @@ use sys::os as os_imp;
/// use std::env; /// use std::env;
/// ///
/// // We assume that we are in a valid directory. /// // We assume that we are in a valid directory.
/// let p = env::current_dir().unwrap(); /// let path = env::current_dir().unwrap();
/// println!("The current directory is {}", p.display()); /// println!("The current directory is {}", path.display());
/// ``` /// ```
#[stable(feature = "env", since = "1.0.0")] #[stable(feature = "env", since = "1.0.0")]
pub fn current_dir() -> io::Result<PathBuf> { pub fn current_dir() -> io::Result<PathBuf> {
os_imp::getcwd() os_imp::getcwd()
} }
/// Changes the current working directory to the specified path, returning /// Changes the current working directory to the specified path.
/// whether the change was completed successfully or not. ///
/// Returns an [`Err`] if the operation fails.
///
/// [`Err`]: ../../std/result/enum.Result.html#method.err
/// ///
/// # Examples /// # Examples
/// ///
@@ -65,8 +68,8 @@ pub fn current_dir() -> io::Result<PathBuf> {
/// println!("Successfully changed working directory to {}!", root.display()); /// println!("Successfully changed working directory to {}!", root.display());
/// ``` /// ```
#[stable(feature = "env", since = "1.0.0")] #[stable(feature = "env", since = "1.0.0")]
pub fn set_current_dir<P: AsRef<Path>>(p: P) -> io::Result<()> { pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
os_imp::chdir(p.as_ref()) os_imp::chdir(path.as_ref())
} }
/// An iterator over a snapshot of the environment variables of this process. /// An iterator over a snapshot of the environment variables of this process.
@@ -175,10 +178,10 @@ impl fmt::Debug for VarsOs {
/// ///
/// The returned result is [`Ok(s)`] if the environment variable is present and is /// The returned result is [`Ok(s)`] if the environment variable is present and is
/// valid unicode. If the environment variable is not present, or it is not /// valid unicode. If the environment variable is not present, or it is not
/// valid unicode, then [`Err`] will be returned. /// valid unicode, then [`VarError`] will be returned.
/// ///
/// [`Ok(s)`]: ../result/enum.Result.html#variant.Ok /// [`Ok(s)`]: ../result/enum.Result.html#variant.Ok
/// [`Err`]: ../result/enum.Result.html#variant.Err /// [`VarError`]: enum.VarError.html
/// ///
/// # Examples /// # Examples
/// ///
@@ -199,7 +202,7 @@ pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> {
fn _var(key: &OsStr) -> Result<String, VarError> { fn _var(key: &OsStr) -> Result<String, VarError> {
match var_os(key) { match var_os(key) {
Some(s) => s.into_string().map_err(VarError::NotUnicode), Some(s) => s.into_string().map_err(VarError::NotUnicode),
None => Err(VarError::NotPresent) None => Err(VarError::NotPresent),
} }
} }

View File

@@ -754,6 +754,13 @@ impl fmt::Debug for Stdio {
} }
/// Describes the result of a process after it has terminated. /// Describes the result of a process after it has terminated.
///
/// This `struct` is used to represent the exit status of a child process.
/// Child processes are created via the [`Command`] struct and their exit
/// status is exposed through the [`status`] method.
///
/// [`Command`]: struct.Command.html
/// [`status`]: struct.Command.html#method.status
#[derive(PartialEq, Eq, Clone, Copy, Debug)] #[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[stable(feature = "process", since = "1.0.0")] #[stable(feature = "process", since = "1.0.0")]
pub struct ExitStatus(imp::ExitStatus); pub struct ExitStatus(imp::ExitStatus);
@@ -788,6 +795,22 @@ impl ExitStatus {
/// On Unix, this will return `None` if the process was terminated /// On Unix, this will return `None` if the process was terminated
/// by a signal; `std::os::unix` provides an extension trait for /// by a signal; `std::os::unix` provides an extension trait for
/// extracting the signal and other details from the `ExitStatus`. /// extracting the signal and other details from the `ExitStatus`.
///
/// # Examples
///
/// ```no_run
/// use std::process::Command;
///
/// let status = Command::new("mkdir")
/// .arg("projects")
/// .status()
/// .expect("failed to execute mkdir");
///
/// match status.code() {
/// Some(code) => println!("Exited with status code: {}", code),
/// None => println!("Process terminated by signal")
/// }
/// ```
#[stable(feature = "process", since = "1.0.0")] #[stable(feature = "process", since = "1.0.0")]
pub fn code(&self) -> Option<i32> { pub fn code(&self) -> Option<i32> {
self.0.code() self.0.code()

View File

@@ -1067,7 +1067,7 @@ impl<T> Receiver<T> {
Receiver { inner: UnsafeCell::new(inner) } Receiver { inner: UnsafeCell::new(inner) }
} }
/// Attempts to return a pending value on this receiver without blocking /// Attempts to return a pending value on this receiver without blocking.
/// ///
/// This method will never block the caller in order to wait for data to /// This method will never block the caller in order to wait for data to
/// become available. Instead, this will always return immediately with a /// become available. Instead, this will always return immediately with a

View File

@@ -253,7 +253,12 @@ pub fn current_exe() -> io::Result<PathBuf> {
#[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))] #[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))]
pub fn current_exe() -> io::Result<PathBuf> { pub fn current_exe() -> io::Result<PathBuf> {
::fs::read_link("/proc/self/exe") let selfexe = PathBuf::from("/proc/self/exe");
if selfexe.exists() {
::fs::read_link(selfexe)
} else {
Err(io::Error::new(io::ErrorKind::Other, "no /proc/self/exe available. Is /proc mounted?"))
}
} }
#[cfg(any(target_os = "macos", target_os = "ios"))] #[cfg(any(target_os = "macos", target_os = "ios"))]

View File

@@ -26,8 +26,22 @@ pub trait OsStringExt {
/// Creates an `OsString` from a potentially ill-formed UTF-16 slice of /// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
/// 16-bit code units. /// 16-bit code units.
/// ///
/// This is lossless: calling `.encode_wide()` on the resulting string /// This is lossless: calling [`encode_wide`] on the resulting string
/// will always return the original code units. /// will always return the original code units.
///
/// # Examples
///
/// ```
/// use std::ffi::OsString;
/// use std::os::windows::prelude::*;
///
/// // UTF-16 encoding for "Unicode".
/// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065];
///
/// let string = OsString::from_wide(&source[..]);
/// ```
///
/// [`encode_wide`]: ./trait.OsStrExt.html#tymethod.encode_wide
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn from_wide(wide: &[u16]) -> Self; fn from_wide(wide: &[u16]) -> Self;
} }
@@ -42,11 +56,29 @@ impl OsStringExt for OsString {
/// Windows-specific extensions to `OsStr`. /// Windows-specific extensions to `OsStr`.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStrExt { pub trait OsStrExt {
/// Re-encodes an `OsStr` as a wide character sequence, /// Re-encodes an `OsStr` as a wide character sequence, i.e. potentially
/// i.e. potentially ill-formed UTF-16. /// ill-formed UTF-16.
/// ///
/// This is lossless. Note that the encoding does not include a final /// This is lossless: calling [`OsString::from_wide`] and then
/// null. /// `encode_wide` on the result will yield the original code units.
/// Note that the encoding does not add a final null terminator.
///
/// # Examples
///
/// ```
/// use std::ffi::OsString;
/// use std::os::windows::prelude::*;
///
/// // UTF-16 encoding for "Unicode".
/// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065];
///
/// let string = OsString::from_wide(&source[..]);
///
/// let result: Vec<u16> = string.encode_wide().collect();
/// assert_eq!(&source[..], &result[..]);
/// ```
///
/// [`OsString::from_wide`]: ./trait.OsStringExt.html#tymethod.from_wide
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn encode_wide(&self) -> EncodeWide; fn encode_wide(&self) -> EncodeWide;
} }

View File

@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//! Windows-specific extensions for the primitives in `std::fs` //! Windows-specific extensions for the primitives in the `std::fs` module.
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]
@@ -18,7 +18,9 @@ use path::Path;
use sys; use sys;
use sys_common::{AsInnerMut, AsInner}; use sys_common::{AsInnerMut, AsInner};
/// Windows-specific extensions to `File` /// Windows-specific extensions to [`File`].
///
/// [`File`]: ../../../fs/struct.File.html
#[stable(feature = "file_offset", since = "1.15.0")] #[stable(feature = "file_offset", since = "1.15.0")]
pub trait FileExt { pub trait FileExt {
/// Seeks to a given position and reads a number of bytes. /// Seeks to a given position and reads a number of bytes.
@@ -35,6 +37,24 @@ pub trait FileExt {
/// Note that similar to `File::read`, it is not an error to return with a /// Note that similar to `File::read`, it is not an error to return with a
/// short read. When returning from such a short read, the file pointer is /// short read. When returning from such a short read, the file pointer is
/// still updated. /// still updated.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::fs::File;
/// use std::os::windows::prelude::*;
///
/// # fn foo() -> io::Result<()> {
/// let mut file = File::open("foo.txt")?;
/// let mut buffer = [0; 10];
///
/// // Read 10 bytes, starting 72 bytes from the
/// // start of the file.
/// file.seek_read(&mut buffer[..], 72)?;
/// # Ok(())
/// # }
/// ```
#[stable(feature = "file_offset", since = "1.15.0")] #[stable(feature = "file_offset", since = "1.15.0")]
fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>; fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
@@ -52,6 +72,22 @@ pub trait FileExt {
/// Note that similar to `File::write`, it is not an error to return a /// Note that similar to `File::write`, it is not an error to return a
/// short write. When returning from such a short write, the file pointer /// short write. When returning from such a short write, the file pointer
/// is still updated. /// is still updated.
///
/// # Examples
///
/// ```no_run
/// use std::fs::File;
/// use std::os::windows::prelude::*;
///
/// # fn foo() -> std::io::Result<()> {
/// let mut buffer = File::create("foo.txt")?;
///
/// // Write a byte string starting 72 bytes from
/// // the start of the file.
/// buffer.seek_write(b"some bytes", 72)?;
/// # Ok(())
/// # }
/// ```
#[stable(feature = "file_offset", since = "1.15.0")] #[stable(feature = "file_offset", since = "1.15.0")]
fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize>; fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
} }
@@ -67,81 +103,94 @@ impl FileExt for fs::File {
} }
} }
/// Windows-specific extensions to `OpenOptions` /// Windows-specific extensions to [`OpenOptions`].
///
/// [`OpenOptions`]: ../../../fs/struct.OpenOptions.html
#[stable(feature = "open_options_ext", since = "1.10.0")] #[stable(feature = "open_options_ext", since = "1.10.0")]
pub trait OpenOptionsExt { pub trait OpenOptionsExt {
/// Overrides the `dwDesiredAccess` argument to the call to `CreateFile` /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`]
/// with the specified value. /// with the specified value.
/// ///
/// This will override the `read`, `write`, and `append` flags on the /// This will override the `read`, `write`, and `append` flags on the
/// `OpenOptions` structure. This method provides fine-grained control over /// `OpenOptions` structure. This method provides fine-grained control over
/// the permissions to read, write and append data, attributes (like hidden /// the permissions to read, write and append data, attributes (like hidden
/// and system) and extended attributes. /// and system), and extended attributes.
/// ///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// use std::fs::OpenOptions; /// use std::fs::OpenOptions;
/// use std::os::windows::fs::OpenOptionsExt; /// use std::os::windows::prelude::*;
/// ///
/// // Open without read and write permission, for example if you only need /// // Open without read and write permission, for example if you only need
/// // to call `stat()` on the file /// // to call `stat` on the file
/// let file = OpenOptions::new().access_mode(0).open("foo.txt"); /// let file = OpenOptions::new().access_mode(0).open("foo.txt");
/// ``` /// ```
///
/// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
#[stable(feature = "open_options_ext", since = "1.10.0")] #[stable(feature = "open_options_ext", since = "1.10.0")]
fn access_mode(&mut self, access: u32) -> &mut Self; fn access_mode(&mut self, access: u32) -> &mut Self;
/// Overrides the `dwShareMode` argument to the call to `CreateFile` with /// Overrides the `dwShareMode` argument to the call to [`CreateFile`] with
/// the specified value. /// the specified value.
/// ///
/// By default `share_mode` is set to /// By default `share_mode` is set to
/// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. Specifying /// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. This allows
/// less permissions denies others to read from, write to and/or delete the /// other processes to to read, write, and delete/rename the same file
/// file while it is open. /// while it is open. Removing any of the flags will prevent other
/// processes from performing the corresponding operation until the file
/// handle is closed.
/// ///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// use std::fs::OpenOptions; /// use std::fs::OpenOptions;
/// use std::os::windows::fs::OpenOptionsExt; /// use std::os::windows::prelude::*;
/// ///
/// // Do not allow others to read or modify this file while we have it open /// // Do not allow others to read or modify this file while we have it open
/// // for writing /// // for writing.
/// let file = OpenOptions::new().write(true) /// let file = OpenOptions::new()
/// .write(true)
/// .share_mode(0) /// .share_mode(0)
/// .open("foo.txt"); /// .open("foo.txt");
/// ``` /// ```
///
/// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
#[stable(feature = "open_options_ext", since = "1.10.0")] #[stable(feature = "open_options_ext", since = "1.10.0")]
fn share_mode(&mut self, val: u32) -> &mut Self; fn share_mode(&mut self, val: u32) -> &mut Self;
/// Sets extra flags for the `dwFileFlags` argument to the call to /// Sets extra flags for the `dwFileFlags` argument to the call to
/// `CreateFile2` (or combines it with `attributes` and `security_qos_flags` /// [`CreateFile2`] to the specified value (or combines it with
/// to set the `dwFlagsAndAttributes` for `CreateFile`). /// `attributes` and `security_qos_flags` to set the `dwFlagsAndAttributes`
/// for [`CreateFile`]).
/// ///
/// Custom flags can only set flags, not remove flags set by Rusts options. /// Custom flags can only set flags, not remove flags set by Rust's options.
/// This options overwrites any previously set custom flags. /// This option overwrites any previously set custom flags.
/// ///
/// # Examples /// # Examples
/// ///
/// ```rust,ignore /// ```ignore
/// extern crate winapi; /// extern crate winapi;
/// use std::fs::OpenOptions;
/// use std::os::windows::fs::OpenOptionsExt;
/// ///
/// let mut options = OpenOptions::new(); /// use std::fs::OpenOptions;
/// options.create(true).write(true); /// use std::os::windows::prelude::*;
/// if cfg!(windows) { ///
/// options.custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE); /// let file = OpenOptions::new()
/// } /// .create(true)
/// let file = options.open("foo.txt"); /// .write(true)
/// .custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE)
/// .open("foo.txt");
/// ``` /// ```
///
/// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
/// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
#[stable(feature = "open_options_ext", since = "1.10.0")] #[stable(feature = "open_options_ext", since = "1.10.0")]
fn custom_flags(&mut self, flags: u32) -> &mut Self; fn custom_flags(&mut self, flags: u32) -> &mut Self;
/// Sets the `dwFileAttributes` argument to the call to `CreateFile2` to /// Sets the `dwFileAttributes` argument to the call to [`CreateFile2`] to
/// the specified value (or combines it with `custom_flags` and /// the specified value (or combines it with `custom_flags` and
/// `security_qos_flags` to set the `dwFlagsAndAttributes` for /// `security_qos_flags` to set the `dwFlagsAndAttributes` for
/// `CreateFile`). /// [`CreateFile`]).
/// ///
/// If a _new_ file is created because it does not yet exist and /// If a _new_ file is created because it does not yet exist and
/// `.create(true)` or `.create_new(true)` are specified, the new file is /// `.create(true)` or `.create_new(true)` are specified, the new file is
@@ -155,21 +204,52 @@ pub trait OpenOptionsExt {
/// ///
/// # Examples /// # Examples
/// ///
/// ```rust,ignore /// ```ignore
/// extern crate winapi; /// extern crate winapi;
/// use std::fs::OpenOptions;
/// use std::os::windows::fs::OpenOptionsExt;
/// ///
/// let file = OpenOptions::new().write(true).create(true) /// use std::fs::OpenOptions;
/// use std::os::windows::prelude::*;
///
/// let file = OpenOptions::new()
/// .write(true)
/// .create(true)
/// .attributes(winapi::FILE_ATTRIBUTE_HIDDEN) /// .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
/// .open("foo.txt"); /// .open("foo.txt");
/// ``` /// ```
///
/// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
/// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
#[stable(feature = "open_options_ext", since = "1.10.0")] #[stable(feature = "open_options_ext", since = "1.10.0")]
fn attributes(&mut self, val: u32) -> &mut Self; fn attributes(&mut self, val: u32) -> &mut Self;
/// Sets the `dwSecurityQosFlags` argument to the call to `CreateFile2` to /// Sets the `dwSecurityQosFlags` argument to the call to [`CreateFile2`] to
/// the specified value (or combines it with `custom_flags` and `attributes` /// the specified value (or combines it with `custom_flags` and `attributes`
/// to set the `dwFlagsAndAttributes` for `CreateFile`). /// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
///
/// By default, `security_qos_flags` is set to `SECURITY_ANONYMOUS`. For
/// information about possible values, see [Impersonation Levels] on the
/// Windows Dev Center site.
///
/// # Examples
///
/// ```no_run
/// use std::fs::OpenOptions;
/// use std::os::windows::prelude::*;
///
/// let file = OpenOptions::new()
/// .write(true)
/// .create(true)
///
/// // Sets the flag value to `SecurityIdentification`.
/// .security_qos_flags(1)
///
/// .open("foo.txt");
/// ```
///
/// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
/// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
/// [Impersonation Levels]:
/// https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572.aspx
#[stable(feature = "open_options_ext", since = "1.10.0")] #[stable(feature = "open_options_ext", since = "1.10.0")]
fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions; fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions;
} }
@@ -197,35 +277,136 @@ impl OpenOptionsExt for OpenOptions {
} }
} }
/// Extension methods for `fs::Metadata` to access the raw fields contained /// Extension methods for [`fs::Metadata`] to access the raw fields contained
/// within. /// within.
///
/// The data members that this trait exposes correspond to the members
/// of the [`BY_HANDLE_FILE_INFORMATION`] structure.
///
/// [`fs::Metadata`]: ../../../fs/struct.Metadata.html
/// [`BY_HANDLE_FILE_INFORMATION`]:
/// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788.aspx
#[stable(feature = "metadata_ext", since = "1.1.0")] #[stable(feature = "metadata_ext", since = "1.1.0")]
pub trait MetadataExt { pub trait MetadataExt {
/// Returns the value of the `dwFileAttributes` field of this metadata. /// Returns the value of the `dwFileAttributes` field of this metadata.
/// ///
/// This field contains the file system attribute information for a file /// This field contains the file system attribute information for a file
/// or directory. /// or directory. For possible values and their descriptions, see
/// [File Attribute Constants] in the Windows Dev Center.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::fs;
/// use std::os::windows::prelude::*;
///
/// # fn foo() -> io::Result<()> {
/// let metadata = fs::metadata("foo.txt")?;
/// let attributes = metadata.file_attributes();
/// # Ok(())
/// # }
/// ```
///
/// [File Attribute Constants]:
/// https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx
#[stable(feature = "metadata_ext", since = "1.1.0")] #[stable(feature = "metadata_ext", since = "1.1.0")]
fn file_attributes(&self) -> u32; fn file_attributes(&self) -> u32;
/// Returns the value of the `ftCreationTime` field of this metadata. /// Returns the value of the `ftCreationTime` field of this metadata.
/// ///
/// The returned 64-bit value represents the number of 100-nanosecond /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
/// intervals since January 1, 1601 (UTC). /// which represents the number of 100-nanosecond intervals since
/// January 1, 1601 (UTC). The struct is automatically
/// converted to a `u64` value, as that is the recommended way
/// to use it.
///
/// If the underlying filesystem does not support creation time, the
/// returned value is 0.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::fs;
/// use std::os::windows::prelude::*;
///
/// # fn foo() -> io::Result<()> {
/// let metadata = fs::metadata("foo.txt")?;
/// let creation_time = metadata.creation_time();
/// # Ok(())
/// # }
/// ```
///
/// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
#[stable(feature = "metadata_ext", since = "1.1.0")] #[stable(feature = "metadata_ext", since = "1.1.0")]
fn creation_time(&self) -> u64; fn creation_time(&self) -> u64;
/// Returns the value of the `ftLastAccessTime` field of this metadata. /// Returns the value of the `ftLastAccessTime` field of this metadata.
/// ///
/// The returned 64-bit value represents the number of 100-nanosecond /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
/// intervals since January 1, 1601 (UTC). /// which represents the number of 100-nanosecond intervals since
/// January 1, 1601 (UTC). The struct is automatically
/// converted to a `u64` value, as that is the recommended way
/// to use it.
///
/// For a file, the value specifies the last time that a file was read
/// from or written to. For a directory, the value specifies when
/// the directory was created. For both files and directories, the
/// specified date is correct, but the time of day is always set to
/// midnight.
///
/// If the underlying filesystem does not support last access time, the
/// returned value is 0.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::fs;
/// use std::os::windows::prelude::*;
///
/// # fn foo() -> io::Result<()> {
/// let metadata = fs::metadata("foo.txt")?;
/// let last_access_time = metadata.last_access_time();
/// # Ok(())
/// # }
/// ```
///
/// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
#[stable(feature = "metadata_ext", since = "1.1.0")] #[stable(feature = "metadata_ext", since = "1.1.0")]
fn last_access_time(&self) -> u64; fn last_access_time(&self) -> u64;
/// Returns the value of the `ftLastWriteTime` field of this metadata. /// Returns the value of the `ftLastWriteTime` field of this metadata.
/// ///
/// The returned 64-bit value represents the number of 100-nanosecond /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
/// intervals since January 1, 1601 (UTC). /// which represents the number of 100-nanosecond intervals since
/// January 1, 1601 (UTC). The struct is automatically
/// converted to a `u64` value, as that is the recommended way
/// to use it.
///
/// For a file, the value specifies the last time that a file was written
/// to. For a directory, the structure specifies when the directory was
/// created.
///
/// If the underlying filesystem does not support the last write time
/// time, the returned value is 0.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::fs;
/// use std::os::windows::prelude::*;
///
/// # fn foo() -> io::Result<()> {
/// let metadata = fs::metadata("foo.txt")?;
/// let last_write_time = metadata.last_write_time();
/// # Ok(())
/// # }
/// ```
///
/// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
#[stable(feature = "metadata_ext", since = "1.1.0")] #[stable(feature = "metadata_ext", since = "1.1.0")]
fn last_write_time(&self) -> u64; fn last_write_time(&self) -> u64;
@@ -233,6 +414,20 @@ pub trait MetadataExt {
/// metadata. /// metadata.
/// ///
/// The returned value does not have meaning for directories. /// The returned value does not have meaning for directories.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::fs;
/// use std::os::windows::prelude::*;
///
/// # fn foo() -> io::Result<()> {
/// let metadata = fs::metadata("foo.txt")?;
/// let file_size = metadata.file_size();
/// # Ok(())
/// # }
/// ```
#[stable(feature = "metadata_ext", since = "1.1.0")] #[stable(feature = "metadata_ext", since = "1.1.0")]
fn file_size(&self) -> u64; fn file_size(&self) -> u64;
} }
@@ -253,7 +448,7 @@ impl MetadataExt for Metadata {
/// ///
/// # Examples /// # Examples
/// ///
/// ```ignore /// ```no_run
/// use std::os::windows::fs; /// use std::os::windows::fs;
/// ///
/// # fn foo() -> std::io::Result<()> { /// # fn foo() -> std::io::Result<()> {
@@ -274,7 +469,7 @@ pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
/// ///
/// # Examples /// # Examples
/// ///
/// ```ignore /// ```no_run
/// use std::os::windows::fs; /// use std::os::windows::fs;
/// ///
/// # fn foo() -> std::io::Result<()> { /// # fn foo() -> std::io::Result<()> {

View File

@@ -8,11 +8,13 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//! Experimental extensions to `std` for Windows. //! Platform-specific extensions to `std` for Windows.
//! //!
//! For now, this module is limited to extracting handles, file //! Provides access to platform-level information for Windows, and exposes
//! descriptors, and sockets, but its functionality will grow over //! Windows-specific idioms that would otherwise be inappropriate as part
//! time. //! the core `std` library. These extensions allow developers to use
//! `std` types and idioms with Windows in a way that the normal
//! platform-agnostic idioms would not normally support.
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]

View File

@@ -750,6 +750,7 @@ impl<'a> Iterator for Wtf8CodePoints<'a> {
} }
} }
/// Generates a wide character sequence for potentially ill-formed UTF-16.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)] #[derive(Clone)]
pub struct EncodeWide<'a> { pub struct EncodeWide<'a> {

View File

@@ -700,7 +700,7 @@ impl<'a> ExtCtxt<'a> {
/// Returns span for the macro which originally caused the current expansion to happen. /// Returns span for the macro which originally caused the current expansion to happen.
/// ///
/// Stops backtracing at include! boundary. /// Stops backtracing at include! boundary.
pub fn expansion_cause(&self) -> Span { pub fn expansion_cause(&self) -> Option<Span> {
let mut ctxt = self.backtrace(); let mut ctxt = self.backtrace();
let mut last_macro = None; let mut last_macro = None;
loop { loop {
@@ -716,7 +716,7 @@ impl<'a> ExtCtxt<'a> {
break break
} }
} }
last_macro.expect("missing expansion backtrace") last_macro
} }
pub fn struct_span_warn(&self, pub fn struct_span_warn(&self,

View File

@@ -35,7 +35,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-> Box<base::MacResult+'static> { -> Box<base::MacResult+'static> {
base::check_zero_tts(cx, sp, tts, "line!"); base::check_zero_tts(cx, sp, tts, "line!");
let topmost = cx.expansion_cause(); let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.codemap().lookup_char_pos(topmost.lo); let loc = cx.codemap().lookup_char_pos(topmost.lo);
base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32)) base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
@@ -46,7 +46,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-> Box<base::MacResult+'static> { -> Box<base::MacResult+'static> {
base::check_zero_tts(cx, sp, tts, "column!"); base::check_zero_tts(cx, sp, tts, "column!");
let topmost = cx.expansion_cause(); let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.codemap().lookup_char_pos(topmost.lo); let loc = cx.codemap().lookup_char_pos(topmost.lo);
base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32)) base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
@@ -59,7 +59,7 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-> Box<base::MacResult+'static> { -> Box<base::MacResult+'static> {
base::check_zero_tts(cx, sp, tts, "file!"); base::check_zero_tts(cx, sp, tts, "file!");
let topmost = cx.expansion_cause(); let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.codemap().lookup_char_pos(topmost.lo); let loc = cx.codemap().lookup_char_pos(topmost.lo);
base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name))) base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name)))
} }

View File

@@ -542,6 +542,7 @@ struct ConsoleTestState<T> {
passed: usize, passed: usize,
failed: usize, failed: usize,
ignored: usize, ignored: usize,
filtered_out: usize,
measured: usize, measured: usize,
metrics: MetricMap, metrics: MetricMap,
failures: Vec<(TestDesc, Vec<u8>)>, failures: Vec<(TestDesc, Vec<u8>)>,
@@ -570,6 +571,7 @@ impl<T: Write> ConsoleTestState<T> {
passed: 0, passed: 0,
failed: 0, failed: 0,
ignored: 0, ignored: 0,
filtered_out: 0,
measured: 0, measured: 0,
metrics: MetricMap::new(), metrics: MetricMap::new(),
failures: Vec::new(), failures: Vec::new(),
@@ -775,11 +777,12 @@ impl<T: Write> ConsoleTestState<T> {
} else { } else {
self.write_pretty("FAILED", term::color::RED)?; self.write_pretty("FAILED", term::color::RED)?;
} }
let s = format!(". {} passed; {} failed; {} ignored; {} measured\n\n", let s = format!(". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
self.passed, self.passed,
self.failed, self.failed,
self.ignored, self.ignored,
self.measured); self.measured,
self.filtered_out);
self.write_plain(&s)?; self.write_plain(&s)?;
return Ok(success); return Ok(success);
} }
@@ -875,6 +878,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
fn callback<T: Write>(event: &TestEvent, st: &mut ConsoleTestState<T>) -> io::Result<()> { fn callback<T: Write>(event: &TestEvent, st: &mut ConsoleTestState<T>) -> io::Result<()> {
match (*event).clone() { match (*event).clone() {
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()), TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
TeFilteredOut(filtered_out) => Ok(st.filtered_out = filtered_out),
TeWait(ref test, padding) => st.write_test_start(test, padding), TeWait(ref test, padding) => st.write_test_start(test, padding),
TeTimeout(ref test) => st.write_timeout(test), TeTimeout(ref test) => st.write_timeout(test),
TeResult(test, result, stdout) => { TeResult(test, result, stdout) => {
@@ -957,6 +961,7 @@ fn should_sort_failures_before_printing_them() {
passed: 0, passed: 0,
failed: 0, failed: 0,
ignored: 0, ignored: 0,
filtered_out: 0,
measured: 0, measured: 0,
max_name_len: 10, max_name_len: 10,
metrics: MetricMap::new(), metrics: MetricMap::new(),
@@ -1017,6 +1022,7 @@ pub enum TestEvent {
TeWait(TestDesc, NamePadding), TeWait(TestDesc, NamePadding),
TeResult(TestDesc, TestResult, Vec<u8>), TeResult(TestDesc, TestResult, Vec<u8>),
TeTimeout(TestDesc), TeTimeout(TestDesc),
TeFilteredOut(usize),
} }
pub type MonitorMsg = (TestDesc, TestResult, Vec<u8>); pub type MonitorMsg = (TestDesc, TestResult, Vec<u8>);
@@ -1028,11 +1034,16 @@ pub fn run_tests<F>(opts: &TestOpts, tests: Vec<TestDescAndFn>, mut callback: F)
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::mpsc::RecvTimeoutError; use std::sync::mpsc::RecvTimeoutError;
let tests_len = tests.len();
let mut filtered_tests = filter_tests(opts, tests); let mut filtered_tests = filter_tests(opts, tests);
if !opts.bench_benchmarks { if !opts.bench_benchmarks {
filtered_tests = convert_benchmarks_to_tests(filtered_tests); filtered_tests = convert_benchmarks_to_tests(filtered_tests);
} }
let filtered_out = tests_len - filtered_tests.len();
callback(TeFilteredOut(filtered_out))?;
let filtered_descs = filtered_tests.iter() let filtered_descs = filtered_tests.iter()
.map(|t| t.desc.clone()) .map(|t| t.desc.clone())
.collect(); .collect();

View File

@@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
include!(line!()); //~ ERROR argument must be a string literal
}

View File

@@ -0,0 +1,67 @@
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// This test case makes sure that we get proper break points for binaries
// compiled with multiple codegen units. (see #39160)
// min-lldb-version: 310
// compile-flags:-g -Ccodegen-units=2
// === GDB TESTS ===============================================================
// gdb-command:run
// gdb-command:print xxx
// gdb-check:$1 = 12345
// gdb-command:continue
// gdb-command:print yyy
// gdb-check:$2 = 67890
// gdb-command:continue
// === LLDB TESTS ==============================================================
// lldb-command:run
// lldb-command:print xxx
// lldb-check:[...]$0 = 12345
// lldb-command:continue
// lldb-command:print yyy
// lldb-check:[...]$1 = 67890
// lldb-command:continue
#![feature(omit_gdb_pretty_printer_section)]
#![omit_gdb_pretty_printer_section]
mod a {
pub fn foo(xxx: u32) {
super::_zzz(); // #break
}
}
mod b {
pub fn bar(yyy: u64) {
super::_zzz(); // #break
}
}
fn main() {
a::foo(12345);
b::bar(67890);
}
#[inline(never)]
fn _zzz() {}