Rollup merge of #37524 - alexcrichton:vendor, r=brson

Vendor all rustbuild dependencies in this repo

This commit vendors all crates.io dependencies into the rust-lang/rust repository using the `cargo-vendor` tool. This is done in an effort to make rustbuild distro-ready by ensuring that our source tarballs are self-contained units which don't need extraneous network downloads.

A new `src/vendor` directory is created with all vendored crates, and Cargo, when using rustbuild, is configured to use this directory. Over time we can deduplicate this directory with the actual src tree (e.g. src/librustc_serialize, src/liblibc, src/libgetopts, ...). For now though that's left to a separate commit.
This commit is contained in:
Eduard-Mihai Burtescu 2016-11-09 20:51:17 +02:00 committed by GitHub
commit 3d2ffa06ea
354 changed files with 40230 additions and 168 deletions

1
.gitattributes vendored
View File

@ -7,3 +7,4 @@
src/etc/pkg/rust-logo.ico binary
src/etc/pkg/rust-logo.png binary
*.woff binary
src/vendor/* binary

1
.gitignore vendored
View File

@ -98,3 +98,4 @@ tmp.*.rs
version.md
version.ml
version.texi
.cargo

View File

@ -15,7 +15,7 @@ before_install:
script:
- docker run -v `pwd`:/build rust
sh -c "
./configure --enable-rustbuild --llvm-root=/usr/lib/llvm-3.7 --enable-quiet-tests &&
./configure --enable-vendor --enable-rustbuild --llvm-root=/usr/lib/llvm-3.7 --enable-quiet-tests &&
make tidy &&
make check -j4
"

1
configure vendored
View File

@ -634,6 +634,7 @@ opt rustbuild 0 "use the rust and cargo based build system"
opt codegen-tests 1 "run the src/test/codegen tests"
opt option-checking 1 "complain about unrecognized options in this configure script"
opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)"
opt vendor 0 "enable usage of vendored Rust crates"
# Optimization and debugging options. These may be overridden by the release channel, etc.
opt_nosave optimize 1 "build optimized rust code"

View File

@ -65,7 +65,8 @@ PKG_FILES := \
stage0.txt \
rust-installer \
tools \
test) \
test \
vendor) \
$(PKG_GITMODULES) \
$(filter-out config.stamp, \
$(MKFILES_FOR_TARBALL))

69
src/Cargo.lock generated
View File

@ -44,13 +44,11 @@ dependencies = [
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -149,25 +147,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "graphviz"
version = "0.0.0"
[[package]]
name = "idna"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.0.0"
@ -183,9 +162,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "linkchecker"
version = "0.1.0"
dependencies = [
"url 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
@ -196,11 +172,6 @@ name = "log"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "matches"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "md5"
version = "0.1.1"
@ -705,55 +676,15 @@ dependencies = [
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0e5bcf27e097a184c1df4437654ed98df3d7a516e8508a6ba45d8b092bbdf283"
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
"checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
"checksum gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5"
"checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8"
"checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
"checksum matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc3ad8109fa4b522f9b0cd81440422781f564aaf8c195de6b9d6642177ad0dd"
"checksum md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5539a8dee9b4ae308c9c406a379838b435a8f2c84cf9fedc6d5a576be9888db"
"checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3"
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
"checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
"checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
"checksum url 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "48ccf7bd87a81b769cf84ad556e034541fb90e1cd6d4bc375c822ed9500cd9d7"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"

View File

@ -27,10 +27,6 @@ num_cpus = "0.2"
toml = "0.1"
getopts = "0.2"
rustc-serialize = "0.3"
gcc = "0.3.36"
gcc = "0.3.38"
libc = "0.2"
md5 = "0.1"
[target.'cfg(windows)'.dependencies]
winapi = "0.2"
kernel32-sys = "0.2"

View File

@ -259,9 +259,11 @@ class RustBuild(object):
env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib")
env["PATH"] = os.path.join(self.bin_root(), "bin") + \
os.pathsep + env["PATH"]
self.run([self.cargo(), "build", "--manifest-path",
os.path.join(self.rust_root, "src/bootstrap/Cargo.toml")],
env)
args = [self.cargo(), "build", "--manifest-path",
os.path.join(self.rust_root, "src/bootstrap/Cargo.toml")]
if self.use_vendored_sources:
args.append("--frozen")
self.run(args, env)
def run(self, args, env):
proc = subprocess.Popen(args, env=env)
@ -400,6 +402,25 @@ def main():
except:
pass
rb.use_vendored_sources = '\nvendor = true' in rb.config_toml or \
'CFG_ENABLE_VENDOR' in rb.config_mk
if rb.use_vendored_sources:
if not os.path.exists('.cargo'):
os.makedirs('.cargo')
f = open('.cargo/config','w')
f.write("""
[source.crates-io]
replace-with = 'vendored-sources'
registry = 'https://example.com'
[source.vendored-sources]
directory = '{}/src/vendor'
""".format(rb.rust_root))
f.close()
else:
if os.path.exists('.cargo'):
shutil.rmtree('.cargo')
data = stage0_data(rb.rust_root)
rb._rustc_channel, rb._rustc_date = data['rustc'].split('-', 1)
rb._cargo_channel, rb._cargo_date = data['cargo'].split('-', 1)

View File

@ -44,6 +44,7 @@ pub struct Config {
pub submodules: bool,
pub compiler_docs: bool,
pub docs: bool,
pub vendor: bool,
pub target_config: HashMap<String, Target>,
// llvm codegen options
@ -126,6 +127,7 @@ struct Build {
docs: Option<bool>,
submodules: Option<bool>,
gdb: Option<String>,
vendor: Option<bool>,
}
/// TOML representation of how the LLVM build is configured.
@ -234,6 +236,7 @@ impl Config {
set(&mut config.compiler_docs, build.compiler_docs);
set(&mut config.docs, build.docs);
set(&mut config.submodules, build.submodules);
set(&mut config.vendor, build.vendor);
if let Some(ref llvm) = toml.llvm {
set(&mut config.ccache, llvm.ccache);
@ -347,6 +350,7 @@ impl Config {
("LOCAL_REBUILD", self.local_rebuild),
("NINJA", self.ninja),
("CODEGEN_TESTS", self.codegen_tests),
("VENDOR", self.vendor),
}
match key {

View File

@ -82,6 +82,9 @@
# The path to (or name of) the GDB executable to use
#gdb = "gdb"
# Indicate whether the vendored sources are used for Rust dependencies or not
#vendor = false
# =============================================================================
# Options for compiling Rust code itself
# =============================================================================

View File

@ -37,15 +37,82 @@
//! Note that this module has a #[cfg(windows)] above it as none of this logic
//! is required on Unix.
extern crate kernel32;
extern crate winapi;
#![allow(bad_style, dead_code)]
use std::env;
use std::io;
use std::mem;
use self::winapi::*;
use self::kernel32::*;
type HANDLE = *mut u8;
type BOOL = i32;
type DWORD = u32;
type LPHANDLE = *mut HANDLE;
type LPVOID = *mut u8;
type JOBOBJECTINFOCLASS = i32;
type SIZE_T = usize;
type LARGE_INTEGER = i64;
type ULONG_PTR = usize;
type ULONGLONG = u64;
const FALSE: BOOL = 0;
const DUPLICATE_SAME_ACCESS: DWORD = 0x2;
const PROCESS_DUP_HANDLE: DWORD = 0x40;
const JobObjectExtendedLimitInformation: JOBOBJECTINFOCLASS = 9;
const JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: DWORD = 0x2000;
extern "system" {
fn CreateJobObjectW(lpJobAttributes: *mut u8, lpName: *const u8) -> HANDLE;
fn CloseHandle(hObject: HANDLE) -> BOOL;
fn GetCurrentProcess() -> HANDLE;
fn OpenProcess(dwDesiredAccess: DWORD,
bInheritHandle: BOOL,
dwProcessId: DWORD) -> HANDLE;
fn DuplicateHandle(hSourceProcessHandle: HANDLE,
hSourceHandle: HANDLE,
hTargetProcessHandle: HANDLE,
lpTargetHandle: LPHANDLE,
dwDesiredAccess: DWORD,
bInheritHandle: BOOL,
dwOptions: DWORD) -> BOOL;
fn AssignProcessToJobObject(hJob: HANDLE, hProcess: HANDLE) -> BOOL;
fn SetInformationJobObject(hJob: HANDLE,
JobObjectInformationClass: JOBOBJECTINFOCLASS,
lpJobObjectInformation: LPVOID,
cbJobObjectInformationLength: DWORD) -> BOOL;
}
#[repr(C)]
struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
BasicLimitInformation: JOBOBJECT_BASIC_LIMIT_INFORMATION,
IoInfo: IO_COUNTERS,
ProcessMemoryLimit: SIZE_T,
JobMemoryLimit: SIZE_T,
PeakProcessMemoryUsed: SIZE_T,
PeakJobMemoryUsed: SIZE_T,
}
#[repr(C)]
struct IO_COUNTERS {
ReadOperationCount: ULONGLONG,
WriteOperationCount: ULONGLONG,
OtherOperationCount: ULONGLONG,
ReadTransferCount: ULONGLONG,
WriteTransferCount: ULONGLONG,
OtherTransferCount: ULONGLONG,
}
#[repr(C)]
struct JOBOBJECT_BASIC_LIMIT_INFORMATION {
PerProcessUserTimeLimit: LARGE_INTEGER,
PerJobUserTimeLimit: LARGE_INTEGER,
LimitFlags: DWORD,
MinimumWorkingsetSize: SIZE_T,
MaximumWorkingsetSize: SIZE_T,
ActiveProcessLimit: DWORD,
Affinity: ULONG_PTR,
PriorityClass: DWORD,
SchedulingClass: DWORD,
}
pub unsafe fn setup() {
// Create a new job object for us to use

View File

@ -460,6 +460,9 @@ impl Build {
if self.config.rust_optimize {
cargo.arg("--release");
}
if self.config.vendor {
cargo.arg("--frozen");
}
return cargo
}

View File

@ -3,9 +3,6 @@ name = "linkchecker"
version = "0.1.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
[dependencies]
url = "1.2"
[[bin]]
name = "linkchecker"
path = "main.rs"

View File

@ -24,17 +24,13 @@
//! A few whitelisted exceptions are allowed as there's known bugs in rustdoc,
//! but this should catch the majority of "broken link" cases.
extern crate url;
use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::path::{Path, PathBuf, Component};
use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry;
use url::Url;
use Redirect::*;
macro_rules! t {
@ -47,9 +43,8 @@ macro_rules! t {
fn main() {
let docs = env::args().nth(1).unwrap();
let docs = env::current_dir().unwrap().join(docs);
let mut url = Url::from_file_path(&docs).unwrap();
let mut errors = false;
walk(&mut HashMap::new(), &docs, &docs, &mut url, &mut errors);
walk(&mut HashMap::new(), &docs, &docs, &mut errors);
if errors {
panic!("found some broken links");
}
@ -88,15 +83,14 @@ impl FileEntry {
}
}
fn walk(cache: &mut Cache, root: &Path, dir: &Path, url: &mut Url, errors: &mut bool) {
fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) {
for entry in t!(dir.read_dir()).map(|e| t!(e)) {
let path = entry.path();
let kind = t!(entry.file_type());
url.path_segments_mut().unwrap().push(entry.file_name().to_str().unwrap());
if kind.is_dir() {
walk(cache, root, &path, url, errors);
walk(cache, root, &path, errors);
} else {
let pretty_path = check(cache, root, &path, url, errors);
let pretty_path = check(cache, root, &path, errors);
if let Some(pretty_path) = pretty_path {
let entry = cache.get_mut(&pretty_path).unwrap();
// we don't need the source anymore,
@ -104,14 +98,12 @@ fn walk(cache: &mut Cache, root: &Path, dir: &Path, url: &mut Url, errors: &mut
entry.source = String::new();
}
}
url.path_segments_mut().unwrap().pop();
}
}
fn check(cache: &mut Cache,
root: &Path,
file: &Path,
base: &Url,
errors: &mut bool)
-> Option<PathBuf> {
// ignore js files as they are not prone to errors as the rest of the
@ -157,19 +149,28 @@ fn check(cache: &mut Cache,
url.starts_with("irc:") || url.starts_with("data:") {
return;
}
let mut parts = url.splitn(2, "#");
let url = parts.next().unwrap();
if url.is_empty() {
return
}
let fragment = parts.next();
let mut parts = url.splitn(2, "?");
let url = parts.next().unwrap();
// Once we've plucked out the URL, parse it using our base url and
// then try to extract a file path.
let (parsed_url, path) = match url_to_file_path(&base, url) {
Some((url, path)) => (url, PathBuf::from(path)),
None => {
*errors = true;
println!("{}:{}: invalid link - {}",
pretty_file.display(),
i + 1,
url);
return;
let mut path = file.to_path_buf();
path.pop();
for part in Path::new(url).components() {
match part {
Component::Prefix(_) |
Component::RootDir => panic!(),
Component::CurDir => {}
Component::ParentDir => { path.pop(); }
Component::Normal(s) => { path.push(s); }
}
};
}
// Alright, if we've found a file name then this file had better
// exist! If it doesn't then we register and print an error.
@ -200,7 +201,7 @@ fn check(cache: &mut Cache,
Err(LoadError::IsRedirect) => unreachable!(),
};
if let Some(ref fragment) = parsed_url.fragment() {
if let Some(ref fragment) = fragment {
// Fragments like `#1-6` are most likely line numbers to be
// interpreted by javascript, so we're ignoring these
if fragment.splitn(2, '-')
@ -231,7 +232,7 @@ fn check(cache: &mut Cache,
fn load_file(cache: &mut Cache,
root: &Path,
file: PathBuf,
mut file: PathBuf,
redirect: Redirect)
-> Result<(PathBuf, String), LoadError> {
let mut contents = String::new();
@ -266,10 +267,9 @@ fn load_file(cache: &mut Cache,
maybe
}
};
let base = Url::from_file_path(&file).unwrap();
match maybe_redirect.and_then(|url| url_to_file_path(&base, &url)) {
Some((_, redirect_file)) => {
file.pop();
match maybe_redirect.map(|url| file.join(url)) {
Some(redirect_file) => {
let path = PathBuf::from(redirect_file);
load_file(cache, root, path, FromRedirect(true))
}
@ -293,12 +293,6 @@ fn maybe_redirect(source: &str) -> Option<String> {
})
}
fn url_to_file_path(parser: &Url, url: &str) -> Option<(Url, PathBuf)> {
parser.join(url)
.ok()
.and_then(|parsed_url| parsed_url.to_file_path().ok().map(|f| (parsed_url, f)))
}
fn with_attrs_in_source<F: FnMut(&str, usize)>(contents: &str, attr: &str, mut f: F) {
for (i, mut line) in contents.lines().enumerate() {
while let Some(j) = line.find(attr) {

View File

@ -20,6 +20,9 @@ use std::fs::File;
use std::path::Path;
pub fn check(path: &Path, bad: &mut bool) {
if path.ends_with("vendor") {
return
}
for entry in t!(path.read_dir(), path).map(|e| t!(e)) {
// Look for `Cargo.toml` with a sibling `src/lib.rs` or `lib.rs`
if entry.file_name().to_str() == Some("Cargo.toml") {

View File

@ -1,45 +0,0 @@
// 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.
use std::path::Path;
use std::ffi::OsStr;
const CARGO_LOCK: &'static str = "Cargo.lock";
pub fn check(path: &Path, bad: &mut bool) {
use std::process::Command;
super::walk(path,
&mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
&mut |file| {
if let Some(CARGO_LOCK) = file.file_name().and_then(OsStr::to_str) {
let rel_path = file.strip_prefix(path).unwrap();
let git_friendly_path = rel_path.to_str().unwrap().replace("\\", "/");
let ret_code = Command::new("git")
.arg("diff")
.arg("--exit-code")
.arg("--patch")
.arg("HEAD")
.arg(&git_friendly_path)
.current_dir(path)
.status()
.unwrap_or_else(|e| {
panic!("could not run git diff-index: {}", e);
});
if !ret_code.success() {
let parent_path = file.parent().unwrap().join("Cargo.toml");
print!("dirty lock file found at {} ", rel_path.display());
println!("please commit your changes or update the lock file by running:");
println!("\n\tcargo update --manifest-path {}", parent_path.display());
*bad = true;
}
}
});
}

View File

@ -35,7 +35,6 @@ mod style;
mod errors;
mod features;
mod cargo;
mod cargo_lock;
mod pal;
fn main() {
@ -48,7 +47,6 @@ fn main() {
errors::check(&path, &mut bad);
cargo::check(&path, &mut bad);
features::check(&path, &mut bad);
cargo_lock::check(&path, &mut bad);
pal::check(&path, &mut bad);
if bad {
@ -66,6 +64,7 @@ fn filter_dirs(path: &Path) -> bool {
"src/rustllvm",
"src/rust-installer",
"src/liblibc",
"src/vendor",
];
skip.iter().any(|p| path.ends_with(p))
}

1
src/vendor/cmake/.cargo-checksum.json vendored Normal file
View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"5d83ed1ae0b80cd6cebfc6a25b1fdb58c893ead400f0f84cd0ebf08d9ad48b28","Cargo.toml":"2266412ecb4504137a90d378ebdbf3a41f0e8b7188858cfb149da54792f7f8d9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"8ca528d20639506546044c676ff9069e3e850937b02bff4194dcf9e5c3c50d64","src/lib.rs":"dae5d93c005bf8d16427e29eb3bfb50c5527a1ec7c39a383d0694a8e8e38af90","src/registry.rs":"ca16433f51b5e3aedb0560bba41370b0c42de9238926a5118d1c0a3a072b64b2"},"package":"0e5bcf27e097a184c1df4437654ed98df3d7a516e8508a6ba45d8b092bbdf283"}

0
src/vendor/cmake/.cargo-ok vendored Normal file
View File

2
src/vendor/cmake/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
/Cargo.lock

19
src/vendor/cmake/.travis.yml vendored Normal file
View File

@ -0,0 +1,19 @@
language: rust
rust:
- stable
- beta
- nightly
sudo: false
before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
script:
- cargo test --verbose
- cargo doc --no-deps
after_success:
- travis-cargo --only nightly doc-upload
env:
global:
secure: WSQJRyheeMf7eRdivHextSEQzyFnTIw2yeemO2+ZkHVftp0XYsTXQVca3RGlQNsVmjI0RP8lbDVe7HG23uwbTMeRgm+9hzSwNMa0ndJZ06TNMpPM6nqcXFUaNGeuf7EqU370xcgVBO+ZA0cSh55pJkOBg5ALd9bfRWbjEAjHkx8=
notifications:
email:
on_success: never

17
src/vendor/cmake/Cargo.toml vendored Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "cmake"
version = "0.1.18"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
license = "MIT/Apache-2.0"
readme = "README.md"
keywords = ["build-dependencies"]
repository = "https://github.com/alexcrichton/cmake-rs"
homepage = "https://github.com/alexcrichton/cmake-rs"
documentation = "http://alexcrichton.com/cmake-rs"
description = """
A build dependency for running `cmake` to build a native library
"""
[dependencies]
gcc = "0.3.17"

201
src/vendor/cmake/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
src/vendor/cmake/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

22
src/vendor/cmake/README.md vendored Normal file
View File

@ -0,0 +1,22 @@
# cmake
[![Build Status](https://travis-ci.org/alexcrichton/cmake-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/cmake-rs)
[Documentation](http://alexcrichton.com/cmake-rs)
A build dependency for running the `cmake` build tool to compile a native
library.
```toml
# Cargo.toml
[build-dependencies]
cmake = "0.2"
```
# License
`cmake-rs` is primarily distributed under the terms of both the MIT license and
the Apache License (Version 2.0), with portions covered by various BSD-like
licenses.
See LICENSE-APACHE, and LICENSE-MIT for details.

522
src/vendor/cmake/src/lib.rs vendored Normal file
View File

@ -0,0 +1,522 @@
//! A build dependency for running `cmake` to build a native library
//!
//! This crate provides some necessary boilerplate and shim support for running
//! the system `cmake` command to build a native library. It will add
//! appropriate cflags for building code to link into Rust, handle cross
//! compilation, and use the necessary generator for the platform being
//! targeted.
//!
//! The builder-style configuration allows for various variables and such to be
//! passed down into the build as well.
//!
//! ## Installation
//!
//! Add this to your `Cargo.toml`:
//!
//! ```toml
//! [build-dependencies]
//! cmake = "0.1"
//! ```
//!
//! ## Examples
//!
//! ```no_run
//! use cmake;
//!
//! // Builds the project in the directory located in `libfoo`, installing it
//! // into $OUT_DIR
//! let dst = cmake::build("libfoo");
//!
//! println!("cargo:rustc-link-search=native={}", dst.display());
//! println!("cargo:rustc-link-lib=static=foo");
//! ```
//!
//! ```no_run
//! use cmake::Config;
//!
//! let dst = Config::new("libfoo")
//! .define("FOO", "BAR")
//! .cflag("-foo")
//! .build();
//! println!("cargo:rustc-link-search=native={}", dst.display());
//! println!("cargo:rustc-link-lib=static=foo");
//! ```
#![deny(missing_docs)]
extern crate gcc;
use std::env;
use std::ffi::{OsString, OsStr};
use std::fs::{self, File};
use std::io::ErrorKind;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::process::Command;
#[cfg(windows)]
mod registry;
/// Builder style configuration for a pending CMake build.
pub struct Config {
path: PathBuf,
generator: Option<OsString>,
cflags: OsString,
cxxflags: OsString,
defines: Vec<(OsString, OsString)>,
deps: Vec<String>,
target: Option<String>,
host: Option<String>,
out_dir: Option<PathBuf>,
profile: Option<String>,
build_args: Vec<OsString>,
cmake_target: Option<String>,
}
/// Builds the native library rooted at `path` with the default cmake options.
/// This will return the directory in which the library was installed.
///
/// # Examples
///
/// ```no_run
/// use cmake;
///
/// // Builds the project in the directory located in `libfoo`, installing it
/// // into $OUT_DIR
/// let dst = cmake::build("libfoo");
///
/// println!("cargo:rustc-link-search=native={}", dst.display());
/// println!("cargo:rustc-link-lib=static=foo");
/// ```
///
pub fn build<P: AsRef<Path>>(path: P) -> PathBuf {
Config::new(path.as_ref()).build()
}
impl Config {
/// Creates a new blank set of configuration to build the project specified
/// at the path `path`.
pub fn new<P: AsRef<Path>>(path: P) -> Config {
Config {
path: env::current_dir().unwrap().join(path),
generator: None,
cflags: OsString::new(),
cxxflags: OsString::new(),
defines: Vec::new(),
deps: Vec::new(),
profile: None,
out_dir: None,
target: None,
host: None,
build_args: Vec::new(),
cmake_target: None,
}
}
/// Sets the build-tool generator (`-G`) for this compilation.
pub fn generator<T: AsRef<OsStr>>(&mut self, generator: T) -> &mut Config {
self.generator = Some(generator.as_ref().to_owned());
self
}
/// Adds a custom flag to pass down to the C compiler, supplementing those
/// that this library already passes.
pub fn cflag<P: AsRef<OsStr>>(&mut self, flag: P) -> &mut Config {
self.cflags.push(" ");
self.cflags.push(flag.as_ref());
self
}
/// Adds a custom flag to pass down to the C++ compiler, supplementing those
/// that this library already passes.
pub fn cxxflag<P: AsRef<OsStr>>(&mut self, flag: P) -> &mut Config {
self.cxxflags.push(" ");
self.cxxflags.push(flag.as_ref());
self
}
/// Adds a new `-D` flag to pass to cmake during the generation step.
pub fn define<K, V>(&mut self, k: K, v: V) -> &mut Config
where K: AsRef<OsStr>, V: AsRef<OsStr>
{
self.defines.push((k.as_ref().to_owned(), v.as_ref().to_owned()));
self
}
/// Registers a dependency for this compilation on the native library built
/// by Cargo previously.
///
/// This registration will modify the `CMAKE_PREFIX_PATH` environment
/// variable for the build system generation step.
pub fn register_dep(&mut self, dep: &str) -> &mut Config {
self.deps.push(dep.to_string());
self
}
/// Sets the target triple for this compilation.
///
/// This is automatically scraped from `$TARGET` which is set for Cargo
/// build scripts so it's not necessary to call this from a build script.
pub fn target(&mut self, target: &str) -> &mut Config {
self.target = Some(target.to_string());
self
}
/// Sets the host triple for this compilation.
///
/// This is automatically scraped from `$HOST` which is set for Cargo
/// build scripts so it's not necessary to call this from a build script.
pub fn host(&mut self, host: &str) -> &mut Config {
self.host = Some(host.to_string());
self
}
/// Sets the output directory for this compilation.
///
/// This is automatically scraped from `$OUT_DIR` which is set for Cargo
/// build scripts so it's not necessary to call this from a build script.
pub fn out_dir<P: AsRef<Path>>(&mut self, out: P) -> &mut Config {
self.out_dir = Some(out.as_ref().to_path_buf());
self
}
/// Sets the profile for this compilation.
///
/// This is automatically scraped from `$PROFILE` which is set for Cargo
/// build scripts so it's not necessary to call this from a build script.
pub fn profile(&mut self, profile: &str) -> &mut Config {
self.profile = Some(profile.to_string());
self
}
/// Add an argument to the final `cmake` build step
pub fn build_arg<A: AsRef<OsStr>>(&mut self, arg: A) -> &mut Config {
self.build_args.push(arg.as_ref().to_owned());
self
}
/// Sets the build target for the final `cmake` build step, this will
/// default to "install" if not specified.
pub fn build_target(&mut self, target: &str) -> &mut Config {
self.cmake_target = Some(target.to_string());
self
}
/// Run this configuration, compiling the library with all the configured
/// options.
///
/// This will run both the build system generator command as well as the
/// command to build the library.
pub fn build(&mut self) -> PathBuf {
let target = self.target.clone().unwrap_or_else(|| {
getenv_unwrap("TARGET")
});
let host = self.host.clone().unwrap_or_else(|| {
getenv_unwrap("HOST")
});
let msvc = target.contains("msvc");
let c_compiler = gcc::Config::new().cargo_metadata(false)
.opt_level(0)
.debug(false)
.target(&target)
.host(&host)
.get_compiler();
let cxx_compiler = gcc::Config::new().cargo_metadata(false)
.cpp(true)
.opt_level(0)
.debug(false)
.target(&target)
.host(&host)
.get_compiler();
let dst = self.out_dir.clone().unwrap_or_else(|| {
PathBuf::from(getenv_unwrap("OUT_DIR"))
});
let build = dst.join("build");
self.maybe_clear(&build);
let _ = fs::create_dir(&build);
// Add all our dependencies to our cmake paths
let mut cmake_prefix_path = Vec::new();
for dep in &self.deps {
if let Some(root) = env::var_os(&format!("DEP_{}_ROOT", dep)) {
cmake_prefix_path.push(PathBuf::from(root));
}
}
let system_prefix = env::var_os("CMAKE_PREFIX_PATH")
.unwrap_or(OsString::new());
cmake_prefix_path.extend(env::split_paths(&system_prefix)
.map(|s| s.to_owned()));
let cmake_prefix_path = env::join_paths(&cmake_prefix_path).unwrap();
// Build up the first cmake command to build the build system.
let mut cmd = Command::new("cmake");
cmd.arg(&self.path)
.current_dir(&build);
if target.contains("windows-gnu") {
if host.contains("windows") {
// On MinGW we need to coerce cmake to not generate a visual
// studio build system but instead use makefiles that MinGW can
// use to build.
if self.generator.is_none() {
cmd.arg("-G").arg("MSYS Makefiles");
}
} else {
// If we're cross compiling onto windows, then set some
// variables which will hopefully get things to succeed. Some
// systems may need the `windres` or `dlltool` variables set, so
// set them if possible.
if !self.defined("CMAKE_SYSTEM_NAME") {
cmd.arg("-DCMAKE_SYSTEM_NAME=Windows");
}
if !self.defined("CMAKE_RC_COMPILER") {
let exe = find_exe(c_compiler.path());
if let Some(name) = exe.file_name().unwrap().to_str() {
let name = name.replace("gcc", "windres");
let windres = exe.with_file_name(name);
if windres.is_file() {
let mut arg = OsString::from("-DCMAKE_RC_COMPILER=");
arg.push(&windres);
cmd.arg(arg);
}
}
}
}
} else if msvc {
// If we're on MSVC we need to be sure to use the right generator or
// otherwise we won't get 32/64 bit correct automatically.
if self.generator.is_none() {
cmd.arg("-G").arg(self.visual_studio_generator(&target));
}
}
if let Some(ref generator) = self.generator {
cmd.arg("-G").arg(generator);
}
let profile = self.profile.clone().unwrap_or_else(|| {
match &getenv_unwrap("PROFILE")[..] {
"bench" | "release" => "Release",
// currently we need to always use the same CRT for MSVC
_ if msvc => "Release",
_ => "Debug",
}.to_string()
});
for &(ref k, ref v) in &self.defines {
let mut os = OsString::from("-D");
os.push(k);
os.push("=");
os.push(v);
cmd.arg(os);
}
if !self.defined("CMAKE_INSTALL_PREFIX") {
let mut dstflag = OsString::from("-DCMAKE_INSTALL_PREFIX=");
dstflag.push(&dst);
cmd.arg(dstflag);
}
{
let mut set_compiler = |kind: &str,
compiler: &gcc::Tool,
extra: &OsString| {
let flag_var = format!("CMAKE_{}_FLAGS", kind);
let tool_var = format!("CMAKE_{}_COMPILER", kind);
if !self.defined(&flag_var) {
let mut flagsflag = OsString::from("-D");
flagsflag.push(&flag_var);
flagsflag.push("=");
flagsflag.push(extra);
for arg in compiler.args() {
flagsflag.push(" ");
flagsflag.push(arg);
}
cmd.arg(flagsflag);
}
// Apparently cmake likes to have an absolute path to the
// compiler as otherwise it sometimes thinks that this variable
// changed as it thinks the found compiler, /usr/bin/cc,
// differs from the specified compiler, cc. Not entirely sure
// what's up, but at least this means cmake doesn't get
// confused?
//
// Also don't specify this on Windows as it's not needed for
// MSVC and for MinGW it doesn't really vary.
if !self.defined("CMAKE_TOOLCHAIN_FILE")
&& !self.defined(&tool_var)
&& env::consts::FAMILY != "windows" {
let mut ccompiler = OsString::from("-D");
ccompiler.push(&tool_var);
ccompiler.push("=");
ccompiler.push(find_exe(compiler.path()));
cmd.arg(ccompiler);
}
};
set_compiler("C", &c_compiler, &self.cflags);
set_compiler("CXX", &cxx_compiler, &self.cxxflags);
}
if !self.defined("CMAKE_BUILD_TYPE") {
cmd.arg(&format!("-DCMAKE_BUILD_TYPE={}", profile));
}
if !self.defined("CMAKE_TOOLCHAIN_FILE") {
if let Ok(s) = env::var("CMAKE_TOOLCHAIN_FILE") {
cmd.arg(&format!("-DCMAKE_TOOLCHAIN_FILE={}", s));
}
}
run(cmd.env("CMAKE_PREFIX_PATH", cmake_prefix_path), "cmake");
let mut parallel_args = Vec::new();
if fs::metadata(&dst.join("build/Makefile")).is_ok() {
if let Ok(s) = env::var("NUM_JOBS") {
parallel_args.push(format!("-j{}", s));
}
}
// And build!
let target = self.cmake_target.clone().unwrap_or("install".to_string());
run(Command::new("cmake")
.arg("--build").arg(".")
.arg("--target").arg(target)
.arg("--config").arg(profile)
.arg("--").args(&self.build_args)
.args(&parallel_args)
.current_dir(&build), "cmake");
println!("cargo:root={}", dst.display());
return dst
}
fn visual_studio_generator(&self, target: &str) -> String {
let base = match std::env::var("VisualStudioVersion") {
Ok(version) => {
match &version[..] {
"15.0" => "Visual Studio 15",
"14.0" => "Visual Studio 14 2015",
"12.0" => "Visual Studio 12 2013",
vers => panic!("\n\n\
unsupported or unknown VisualStudio version: {}\n\
if another version is installed consider running \
the appropriate vcvars script before building this \
crate\n\
", vers),
}
}
_ => {
// Check for the presense of a specific registry key
// that indicates visual studio is installed.
if self.has_msbuild_version("15.0") {
"Visual Studio 15"
} else if self.has_msbuild_version("14.0") {
"Visual Studio 14 2015"
} else if self.has_msbuild_version("12.0") {
"Visual Studio 12 2013"
} else {
panic!("\n\n\
couldn't determine visual studio generator\n\
if VisualStudio is installed, however, consider \
running the appropriate vcvars script before building \
this crate\n\
");
}
}
};
if target.contains("i686") {
base.to_string()
} else if target.contains("x86_64") {
format!("{} Win64", base)
} else {
panic!("unsupported msvc target: {}", target);
}
}
#[cfg(not(windows))]
fn has_msbuild_version(&self, _version: &str) -> bool {
false
}
#[cfg(windows)]
fn has_msbuild_version(&self, version: &str) -> bool {
let key = format!("SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\{}",
version);
registry::LOCAL_MACHINE.open(key.as_ref()).is_ok()
}
fn defined(&self, var: &str) -> bool {
self.defines.iter().any(|&(ref a, _)| a == var)
}
// If a cmake project has previously been built (e.g. CMakeCache.txt already
// exists), then cmake will choke if the source directory for the original
// project being built has changed. Detect this situation through the
// `CMAKE_HOME_DIRECTORY` variable that cmake emits and if it doesn't match
// we blow away the build directory and start from scratch (the recommended
// solution apparently [1]).
//
// [1]: https://cmake.org/pipermail/cmake/2012-August/051545.html
fn maybe_clear(&self, dir: &Path) {
// CMake will apparently store canonicalized paths which normally
// isn't relevant to us but we canonicalize it here to ensure
// we're both checking the same thing.
let path = fs::canonicalize(&self.path).unwrap_or(self.path.clone());
let src = match path.to_str() {
Some(src) => src,
None => return,
};
let mut f = match File::open(dir.join("CMakeCache.txt")) {
Ok(f) => f,
Err(..) => return,
};
let mut u8contents = Vec::new();
match f.read_to_end(&mut u8contents) {
Ok(f) => f,
Err(..) => return,
};
let contents = String::from_utf8_lossy(&u8contents);
drop(f);
for line in contents.lines() {
if line.contains("CMAKE_HOME_DIRECTORY") && !line.contains(src) {
println!("detected home dir change, cleaning out entire build \
directory");
fs::remove_dir_all(dir).unwrap();
break
}
}
}
}
fn run(cmd: &mut Command, program: &str) {
println!("running: {:?}", cmd);
let status = match cmd.status() {
Ok(status) => status,
Err(ref e) if e.kind() == ErrorKind::NotFound => {
fail(&format!("failed to execute command: {}\nis `{}` not installed?",
e, program));
}
Err(e) => fail(&format!("failed to execute command: {}", e)),
};
if !status.success() {
fail(&format!("command did not execute successfully, got: {}", status));
}
}
fn find_exe(path: &Path) -> PathBuf {
env::split_paths(&env::var_os("PATH").unwrap_or(OsString::new()))
.map(|p| p.join(path))
.find(|p| fs::metadata(p).is_ok())
.unwrap_or(path.to_owned())
}
fn getenv_unwrap(v: &str) -> String {
match env::var(v) {
Ok(s) => s,
Err(..) => fail(&format!("environment variable `{}` not defined", v)),
}
}
fn fail(s: &str) -> ! {
panic!("\n{}\n\nbuild script failed, must exit now", s)
}

84
src/vendor/cmake/src/registry.rs vendored Normal file
View File

@ -0,0 +1,84 @@
// Copyright 2015 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.
use std::ffi::OsStr;
use std::io;
use std::os::raw;
use std::os::windows::prelude::*;
pub struct RegistryKey(Repr);
type HKEY = *mut u8;
type DWORD = u32;
type LPDWORD = *mut DWORD;
type LPCWSTR = *const u16;
type LPWSTR = *mut u16;
type LONG = raw::c_long;
type PHKEY = *mut HKEY;
type PFILETIME = *mut u8;
type LPBYTE = *mut u8;
type REGSAM = u32;
const ERROR_SUCCESS: DWORD = 0;
const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY;
const KEY_READ: DWORD = 0x20019;
const KEY_WOW64_32KEY: DWORD = 0x200;
#[link(name = "advapi32")]
extern "system" {
fn RegOpenKeyExW(key: HKEY,
lpSubKey: LPCWSTR,
ulOptions: DWORD,
samDesired: REGSAM,
phkResult: PHKEY) -> LONG;
fn RegCloseKey(hKey: HKEY) -> LONG;
}
struct OwnedKey(HKEY);
enum Repr {
Const(HKEY),
Owned(OwnedKey),
}
unsafe impl Sync for Repr {}
unsafe impl Send for Repr {}
pub static LOCAL_MACHINE: RegistryKey =
RegistryKey(Repr::Const(HKEY_LOCAL_MACHINE));
impl RegistryKey {
fn raw(&self) -> HKEY {
match self.0 {
Repr::Const(val) => val,
Repr::Owned(ref val) => val.0,
}
}
pub fn open(&self, key: &OsStr) -> io::Result<RegistryKey> {
let key = key.encode_wide().chain(Some(0)).collect::<Vec<_>>();
let mut ret = 0 as *mut _;
let err = unsafe {
RegOpenKeyExW(self.raw(), key.as_ptr(), 0,
KEY_READ | KEY_WOW64_32KEY, &mut ret)
};
if err == ERROR_SUCCESS as LONG {
Ok(RegistryKey(Repr::Owned(OwnedKey(ret))))
} else {
Err(io::Error::from_raw_os_error(err as i32))
}
}
}
impl Drop for OwnedKey {
fn drop(&mut self) {
unsafe { RegCloseKey(self.0); }
}
}

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"4af0565a97a599bba727315d9aff1f57a350dcfee7d9f00986c851e54a24b4ca","src/lib.rs":"484cec14a5f18a25b71d7b1842f7b184f0530165021b71b36dde9fc57b7fc15a","src/regex.rs":"d8e2a6958d4ed8084867063aae4b5c77ffc5d271dc2e17909d56c5a5e1552034","src/string.rs":"26ede9ab41a2673c3ad6001bc1802c005ce9a4f190f55860a24aa66b6b71bbc7","tests/regexp_filter.rs":"a3f9c01623e90e54b247a62c53b25caf5f502d054f28c0bdf92abbea486a95b5"},"package":"15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"}

0
src/vendor/env_logger/.cargo-ok vendored Normal file
View File

23
src/vendor/env_logger/Cargo.toml vendored Normal file
View File

@ -0,0 +1,23 @@
[package]
name = "env_logger"
version = "0.3.5"
authors = ["The Rust Project Developers"]
license = "MIT/Apache-2.0"
repository = "https://github.com/rust-lang/log"
documentation = "http://doc.rust-lang.org/log/env_logger"
homepage = "https://github.com/rust-lang/log"
description = """
An logging implementation for `log` which is configured via an environment
variable.
"""
[dependencies]
log = { version = "0.3", path = ".." }
regex = { version = "0.1", optional = true }
[[test]]
name = "regexp_filter"
harness = false
[features]
default = ["regex"]

623
src/vendor/env_logger/src/lib.rs vendored Normal file
View File

@ -0,0 +1,623 @@
// Copyright 2014-2015 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.
//! A logger configured via an environment variable which writes to standard
//! error.
//!
//! ## Example
//!
//! ```
//! #[macro_use] extern crate log;
//! extern crate env_logger;
//!
//! use log::LogLevel;
//!
//! fn main() {
//! env_logger::init().unwrap();
//!
//! debug!("this is a debug {}", "message");
//! error!("this is printed by default");
//!
//! if log_enabled!(LogLevel::Info) {
//! let x = 3 * 4; // expensive computation
//! info!("the answer was: {}", x);
//! }
//! }
//! ```
//!
//! Assumes the binary is `main`:
//!
//! ```{.bash}
//! $ RUST_LOG=error ./main
//! ERROR:main: this is printed by default
//! ```
//!
//! ```{.bash}
//! $ RUST_LOG=info ./main
//! ERROR:main: this is printed by default
//! INFO:main: the answer was: 12
//! ```
//!
//! ```{.bash}
//! $ RUST_LOG=debug ./main
//! DEBUG:main: this is a debug message
//! ERROR:main: this is printed by default
//! INFO:main: the answer was: 12
//! ```
//!
//! You can also set the log level on a per module basis:
//!
//! ```{.bash}
//! $ RUST_LOG=main=info ./main
//! ERROR:main: this is printed by default
//! INFO:main: the answer was: 12
//! ```
//!
//! And enable all logging:
//!
//! ```{.bash}
//! $ RUST_LOG=main ./main
//! DEBUG:main: this is a debug message
//! ERROR:main: this is printed by default
//! INFO:main: the answer was: 12
//! ```
//!
//! See the documentation for the log crate for more information about its API.
//!
//! ## Enabling logging
//!
//! Log levels are controlled on a per-module basis, and by default all logging
//! is disabled except for `error!`. Logging is controlled via the `RUST_LOG`
//! environment variable. The value of this environment variable is a
//! comma-separated list of logging directives. A logging directive is of the
//! form:
//!
//! ```text
//! path::to::module=log_level
//! ```
//!
//! The path to the module is rooted in the name of the crate it was compiled
//! for, so if your program is contained in a file `hello.rs`, for example, to
//! turn on logging for this file you would use a value of `RUST_LOG=hello`.
//! Furthermore, this path is a prefix-search, so all modules nested in the
//! specified module will also have logging enabled.
//!
//! The actual `log_level` is optional to specify. If omitted, all logging will
//! be enabled. If specified, it must be one of the strings `debug`, `error`,
//! `info`, `warn`, or `trace`.
//!
//! As the log level for a module is optional, the module to enable logging for
//! is also optional. If only a `log_level` is provided, then the global log
//! level for all modules is set to this value.
//!
//! Some examples of valid values of `RUST_LOG` are:
//!
//! * `hello` turns on all logging for the 'hello' module
//! * `info` turns on all info logging
//! * `hello=debug` turns on debug logging for 'hello'
//! * `hello,std::option` turns on hello, and std's option logging
//! * `error,hello=warn` turn on global error logging and also warn for hello
//!
//! ## Filtering results
//!
//! A RUST_LOG directive may include a regex filter. The syntax is to append `/`
//! followed by a regex. Each message is checked against the regex, and is only
//! logged if it matches. Note that the matching is done after formatting the
//! log string but before adding any logging meta-data. There is a single filter
//! for all modules.
//!
//! Some examples:
//!
//! * `hello/foo` turns on all logging for the 'hello' module where the log
//! message includes 'foo'.
//! * `info/f.o` turns on all info logging where the log message includes 'foo',
//! 'f1o', 'fao', etc.
//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the log
//! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc.
//! * `error,hello=warn/[0-9] scopes` turn on global error logging and also
//! warn for hello. In both cases the log message must include a single digit
//! number followed by 'scopes'.
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/env_logger/")]
#![cfg_attr(test, deny(warnings))]
extern crate log;
use std::env;
use std::io::prelude::*;
use std::io;
use std::mem;
use log::{Log, LogLevel, LogLevelFilter, LogRecord, SetLoggerError, LogMetadata};
#[cfg(feature = "regex")]
#[path = "regex.rs"]
mod filter;
#[cfg(not(feature = "regex"))]
#[path = "string.rs"]
mod filter;
/// The logger.
pub struct Logger {
directives: Vec<LogDirective>,
filter: Option<filter::Filter>,
format: Box<Fn(&LogRecord) -> String + Sync + Send>,
}
/// LogBuilder acts as builder for initializing the Logger.
/// It can be used to customize the log format, change the enviromental variable used
/// to provide the logging directives and also set the default log level filter.
///
/// ## Example
///
/// ```
/// #[macro_use]
/// extern crate log;
/// extern crate env_logger;
///
/// use std::env;
/// use log::{LogRecord, LogLevelFilter};
/// use env_logger::LogBuilder;
///
/// fn main() {
/// let format = |record: &LogRecord| {
/// format!("{} - {}", record.level(), record.args())
/// };
///
/// let mut builder = LogBuilder::new();
/// builder.format(format).filter(None, LogLevelFilter::Info);
///
/// if env::var("RUST_LOG").is_ok() {
/// builder.parse(&env::var("RUST_LOG").unwrap());
/// }
///
/// builder.init().unwrap();
///
/// error!("error message");
/// info!("info message");
/// }
/// ```
pub struct LogBuilder {
directives: Vec<LogDirective>,
filter: Option<filter::Filter>,
format: Box<Fn(&LogRecord) -> String + Sync + Send>,
}
impl LogBuilder {
/// Initializes the log builder with defaults
pub fn new() -> LogBuilder {
LogBuilder {
directives: Vec::new(),
filter: None,
format: Box::new(|record: &LogRecord| {
format!("{}:{}: {}", record.level(),
record.location().module_path(), record.args())
}),
}
}
/// Adds filters to the logger
///
/// The given module (if any) will log at most the specified level provided.
/// If no module is provided then the filter will apply to all log messages.
pub fn filter(&mut self,
module: Option<&str>,
level: LogLevelFilter) -> &mut Self {
self.directives.push(LogDirective {
name: module.map(|s| s.to_string()),
level: level,
});
self
}
/// Sets the format function for formatting the log output.
///
/// This function is called on each record logged to produce a string which
/// is actually printed out.
pub fn format<F: 'static>(&mut self, format: F) -> &mut Self
where F: Fn(&LogRecord) -> String + Sync + Send
{
self.format = Box::new(format);
self
}
/// Parses the directives string in the same form as the RUST_LOG
/// environment variable.
///
/// See the module documentation for more details.
pub fn parse(&mut self, filters: &str) -> &mut Self {
let (directives, filter) = parse_logging_spec(filters);
self.filter = filter;
for directive in directives {
self.directives.push(directive);
}
self
}
/// Initializes the global logger with an env logger.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization
/// attempts will return an error.
pub fn init(&mut self) -> Result<(), SetLoggerError> {
log::set_logger(|max_level| {
let logger = self.build();
max_level.set(logger.filter());
Box::new(logger)
})
}
/// Build an env logger.
pub fn build(&mut self) -> Logger {
if self.directives.is_empty() {
// Adds the default filter if none exist
self.directives.push(LogDirective {
name: None,
level: LogLevelFilter::Error,
});
} else {
// Sort the directives by length of their name, this allows a
// little more efficient lookup at runtime.
self.directives.sort_by(|a, b| {
let alen = a.name.as_ref().map(|a| a.len()).unwrap_or(0);
let blen = b.name.as_ref().map(|b| b.len()).unwrap_or(0);
alen.cmp(&blen)
});
}
Logger {
directives: mem::replace(&mut self.directives, Vec::new()),
filter: mem::replace(&mut self.filter, None),
format: mem::replace(&mut self.format, Box::new(|_| String::new())),
}
}
}
impl Logger {
pub fn new() -> Logger {
let mut builder = LogBuilder::new();
if let Ok(s) = env::var("RUST_LOG") {
builder.parse(&s);
}
builder.build()
}
pub fn filter(&self) -> LogLevelFilter {
self.directives.iter()
.map(|d| d.level).max()
.unwrap_or(LogLevelFilter::Off)
}
fn enabled(&self, level: LogLevel, target: &str) -> bool {
// Search for the longest match, the vector is assumed to be pre-sorted.
for directive in self.directives.iter().rev() {
match directive.name {
Some(ref name) if !target.starts_with(&**name) => {},
Some(..) | None => {
return level <= directive.level
}
}
}
false
}
}
impl Log for Logger {
fn enabled(&self, metadata: &LogMetadata) -> bool {
self.enabled(metadata.level(), metadata.target())
}
fn log(&self, record: &LogRecord) {
if !Log::enabled(self, record.metadata()) {
return;
}
if let Some(filter) = self.filter.as_ref() {
if !filter.is_match(&*record.args().to_string()) {
return;
}
}
let _ = writeln!(&mut io::stderr(), "{}", (self.format)(record));
}
}
struct LogDirective {
name: Option<String>,
level: LogLevelFilter,
}
/// Initializes the global logger with an env logger.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
pub fn init() -> Result<(), SetLoggerError> {
let mut builder = LogBuilder::new();
if let Ok(s) = env::var("RUST_LOG") {
builder.parse(&s);
}
builder.init()
}
/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=error/foo")
/// and return a vector with log directives.
fn parse_logging_spec(spec: &str) -> (Vec<LogDirective>, Option<filter::Filter>) {
let mut dirs = Vec::new();
let mut parts = spec.split('/');
let mods = parts.next();
let filter = parts.next();
if parts.next().is_some() {
println!("warning: invalid logging spec '{}', \
ignoring it (too many '/'s)", spec);
return (dirs, None);
}
mods.map(|m| { for s in m.split(',') {
if s.len() == 0 { continue }
let mut parts = s.split('=');
let (log_level, name) = match (parts.next(), parts.next().map(|s| s.trim()), parts.next()) {
(Some(part0), None, None) => {
// if the single argument is a log-level string or number,
// treat that as a global fallback
match part0.parse() {
Ok(num) => (num, None),
Err(_) => (LogLevelFilter::max(), Some(part0)),
}
}
(Some(part0), Some(""), None) => (LogLevelFilter::max(), Some(part0)),
(Some(part0), Some(part1), None) => {
match part1.parse() {
Ok(num) => (num, Some(part0)),
_ => {
println!("warning: invalid logging spec '{}', \
ignoring it", part1);
continue
}
}
},
_ => {
println!("warning: invalid logging spec '{}', \
ignoring it", s);
continue
}
};
dirs.push(LogDirective {
name: name.map(|s| s.to_string()),
level: log_level,
});
}});
let filter = filter.map_or(None, |filter| {
match filter::Filter::new(filter) {
Ok(re) => Some(re),
Err(e) => {
println!("warning: invalid regex filter - {}", e);
None
}
}
});
return (dirs, filter);
}
#[cfg(test)]
mod tests {
use log::{LogLevel, LogLevelFilter};
use super::{LogBuilder, Logger, LogDirective, parse_logging_spec};
fn make_logger(dirs: Vec<LogDirective>) -> Logger {
let mut logger = LogBuilder::new().build();
logger.directives = dirs;
logger
}
#[test]
fn filter_info() {
let logger = LogBuilder::new().filter(None, LogLevelFilter::Info).build();
assert!(logger.enabled(LogLevel::Info, "crate1"));
assert!(!logger.enabled(LogLevel::Debug, "crate1"));
}
#[test]
fn filter_beginning_longest_match() {
let logger = LogBuilder::new()
.filter(Some("crate2"), LogLevelFilter::Info)
.filter(Some("crate2::mod"), LogLevelFilter::Debug)
.filter(Some("crate1::mod1"), LogLevelFilter::Warn)
.build();
assert!(logger.enabled(LogLevel::Debug, "crate2::mod1"));
assert!(!logger.enabled(LogLevel::Debug, "crate2"));
}
#[test]
fn parse_default() {
let logger = LogBuilder::new().parse("info,crate1::mod1=warn").build();
assert!(logger.enabled(LogLevel::Warn, "crate1::mod1"));
assert!(logger.enabled(LogLevel::Info, "crate2::mod2"));
}
#[test]
fn match_full_path() {
let logger = make_logger(vec![
LogDirective {
name: Some("crate2".to_string()),
level: LogLevelFilter::Info
},
LogDirective {
name: Some("crate1::mod1".to_string()),
level: LogLevelFilter::Warn
}
]);
assert!(logger.enabled(LogLevel::Warn, "crate1::mod1"));
assert!(!logger.enabled(LogLevel::Info, "crate1::mod1"));
assert!(logger.enabled(LogLevel::Info, "crate2"));
assert!(!logger.enabled(LogLevel::Debug, "crate2"));
}
#[test]
fn no_match() {
let logger = make_logger(vec![
LogDirective { name: Some("crate2".to_string()), level: LogLevelFilter::Info },
LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Warn }
]);
assert!(!logger.enabled(LogLevel::Warn, "crate3"));
}
#[test]
fn match_beginning() {
let logger = make_logger(vec![
LogDirective { name: Some("crate2".to_string()), level: LogLevelFilter::Info },
LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Warn }
]);
assert!(logger.enabled(LogLevel::Info, "crate2::mod1"));
}
#[test]
fn match_beginning_longest_match() {
let logger = make_logger(vec![
LogDirective { name: Some("crate2".to_string()), level: LogLevelFilter::Info },
LogDirective { name: Some("crate2::mod".to_string()), level: LogLevelFilter::Debug },
LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Warn }
]);
assert!(logger.enabled(LogLevel::Debug, "crate2::mod1"));
assert!(!logger.enabled(LogLevel::Debug, "crate2"));
}
#[test]
fn match_default() {
let logger = make_logger(vec![
LogDirective { name: None, level: LogLevelFilter::Info },
LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Warn }
]);
assert!(logger.enabled(LogLevel::Warn, "crate1::mod1"));
assert!(logger.enabled(LogLevel::Info, "crate2::mod2"));
}
#[test]
fn zero_level() {
let logger = make_logger(vec![
LogDirective { name: None, level: LogLevelFilter::Info },
LogDirective { name: Some("crate1::mod1".to_string()), level: LogLevelFilter::Off }
]);
assert!(!logger.enabled(LogLevel::Error, "crate1::mod1"));
assert!(logger.enabled(LogLevel::Info, "crate2::mod2"));
}
#[test]
fn parse_logging_spec_valid() {
let (dirs, filter) = parse_logging_spec("crate1::mod1=error,crate1::mod2,crate2=debug");
assert_eq!(dirs.len(), 3);
assert_eq!(dirs[0].name, Some("crate1::mod1".to_string()));
assert_eq!(dirs[0].level, LogLevelFilter::Error);
assert_eq!(dirs[1].name, Some("crate1::mod2".to_string()));
assert_eq!(dirs[1].level, LogLevelFilter::max());
assert_eq!(dirs[2].name, Some("crate2".to_string()));
assert_eq!(dirs[2].level, LogLevelFilter::Debug);
assert!(filter.is_none());
}
#[test]
fn parse_logging_spec_invalid_crate() {
// test parse_logging_spec with multiple = in specification
let (dirs, filter) = parse_logging_spec("crate1::mod1=warn=info,crate2=debug");
assert_eq!(dirs.len(), 1);
assert_eq!(dirs[0].name, Some("crate2".to_string()));
assert_eq!(dirs[0].level, LogLevelFilter::Debug);
assert!(filter.is_none());
}
#[test]
fn parse_logging_spec_invalid_log_level() {
// test parse_logging_spec with 'noNumber' as log level
let (dirs, filter) = parse_logging_spec("crate1::mod1=noNumber,crate2=debug");
assert_eq!(dirs.len(), 1);
assert_eq!(dirs[0].name, Some("crate2".to_string()));
assert_eq!(dirs[0].level, LogLevelFilter::Debug);
assert!(filter.is_none());
}
#[test]
fn parse_logging_spec_string_log_level() {
// test parse_logging_spec with 'warn' as log level
let (dirs, filter) = parse_logging_spec("crate1::mod1=wrong,crate2=warn");
assert_eq!(dirs.len(), 1);
assert_eq!(dirs[0].name, Some("crate2".to_string()));
assert_eq!(dirs[0].level, LogLevelFilter::Warn);
assert!(filter.is_none());
}
#[test]
fn parse_logging_spec_empty_log_level() {
// test parse_logging_spec with '' as log level
let (dirs, filter) = parse_logging_spec("crate1::mod1=wrong,crate2=");
assert_eq!(dirs.len(), 1);
assert_eq!(dirs[0].name, Some("crate2".to_string()));
assert_eq!(dirs[0].level, LogLevelFilter::max());
assert!(filter.is_none());
}
#[test]
fn parse_logging_spec_global() {
// test parse_logging_spec with no crate
let (dirs, filter) = parse_logging_spec("warn,crate2=debug");
assert_eq!(dirs.len(), 2);
assert_eq!(dirs[0].name, None);
assert_eq!(dirs[0].level, LogLevelFilter::Warn);
assert_eq!(dirs[1].name, Some("crate2".to_string()));
assert_eq!(dirs[1].level, LogLevelFilter::Debug);
assert!(filter.is_none());
}
#[test]
fn parse_logging_spec_valid_filter() {
let (dirs, filter) = parse_logging_spec("crate1::mod1=error,crate1::mod2,crate2=debug/abc");
assert_eq!(dirs.len(), 3);
assert_eq!(dirs[0].name, Some("crate1::mod1".to_string()));
assert_eq!(dirs[0].level, LogLevelFilter::Error);
assert_eq!(dirs[1].name, Some("crate1::mod2".to_string()));
assert_eq!(dirs[1].level, LogLevelFilter::max());
assert_eq!(dirs[2].name, Some("crate2".to_string()));
assert_eq!(dirs[2].level, LogLevelFilter::Debug);
assert!(filter.is_some() && filter.unwrap().to_string() == "abc");
}
#[test]
fn parse_logging_spec_invalid_crate_filter() {
let (dirs, filter) = parse_logging_spec("crate1::mod1=error=warn,crate2=debug/a.c");
assert_eq!(dirs.len(), 1);
assert_eq!(dirs[0].name, Some("crate2".to_string()));
assert_eq!(dirs[0].level, LogLevelFilter::Debug);
assert!(filter.is_some() && filter.unwrap().to_string() == "a.c");
}
#[test]
fn parse_logging_spec_empty_with_filter() {
let (dirs, filter) = parse_logging_spec("crate1/a*c");
assert_eq!(dirs.len(), 1);
assert_eq!(dirs[0].name, Some("crate1".to_string()));
assert_eq!(dirs[0].level, LogLevelFilter::max());
assert!(filter.is_some() && filter.unwrap().to_string() == "a*c");
}
}

28
src/vendor/env_logger/src/regex.rs vendored Normal file
View File

@ -0,0 +1,28 @@
extern crate regex;
use std::fmt;
use self::regex::Regex;
pub struct Filter {
inner: Regex,
}
impl Filter {
pub fn new(spec: &str) -> Result<Filter, String> {
match Regex::new(spec){
Ok(r) => Ok(Filter { inner: r }),
Err(e) => Err(e.to_string()),
}
}
pub fn is_match(&self, s: &str) -> bool {
self.inner.is_match(s)
}
}
impl fmt::Display for Filter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}

21
src/vendor/env_logger/src/string.rs vendored Normal file
View File

@ -0,0 +1,21 @@
use std::fmt;
pub struct Filter {
inner: String,
}
impl Filter {
pub fn new(spec: &str) -> Result<Filter, String> {
Ok(Filter { inner: spec.to_string() })
}
pub fn is_match(&self, s: &str) -> bool {
s.contains(&self.inner)
}
}
impl fmt::Display for Filter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}

View File

@ -0,0 +1,51 @@
#[macro_use] extern crate log;
extern crate env_logger;
use std::process;
use std::env;
use std::str;
fn main() {
if env::var("LOG_REGEXP_TEST").ok() == Some(String::from("1")) {
child_main();
} else {
parent_main()
}
}
fn child_main() {
env_logger::init().unwrap();
info!("XYZ Message");
}
fn run_child(rust_log: String) -> bool {
let exe = env::current_exe().unwrap();
let out = process::Command::new(exe)
.env("LOG_REGEXP_TEST", "1")
.env("RUST_LOG", rust_log)
.output()
.unwrap_or_else(|e| panic!("Unable to start child process: {}", e));
str::from_utf8(out.stderr.as_ref()).unwrap().contains("XYZ Message")
}
fn assert_message_printed(rust_log: &str) {
if !run_child(rust_log.to_string()) {
panic!("RUST_LOG={} should allow the test log message", rust_log)
}
}
fn assert_message_not_printed(rust_log: &str) {
if run_child(rust_log.to_string()) {
panic!("RUST_LOG={} should not allow the test log message", rust_log)
}
}
fn parent_main() {
// test normal log severity levels
assert_message_printed("info");
assert_message_not_printed("warn");
// test of regular expression filters
assert_message_printed("info/XYZ");
assert_message_not_printed("info/XXX");
}

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"c8cfe2c700e7b1d6500d0ad8084694be7009095e9572aaf54bf695c1fe7822d6","Cargo.toml":"4e414fe72ef2afcae81fb5a89f39e59ec40844272b589381746623f612333305","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"fef1998633eb2f460e6b12bc1133a21f5674e0b53ae5914ba1e53f1b63a185c3","appveyor.yml":"da991211b72fa6f231af7adb84c9fb72f5a9131d1c0a3d47b8ceffe5a82c8542","src/lib.rs":"8fa03e69ab113e5a30c742f60b6beddc0b77ef41a1eb45e82f9df867c9265815"},"package":"5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"}

0
src/vendor/filetime/.cargo-ok vendored Normal file
View File

2
src/vendor/filetime/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
Cargo.lock

26
src/vendor/filetime/.travis.yml vendored Normal file
View File

@ -0,0 +1,26 @@
language: rust
rust:
- stable
- beta
- nightly
sudo: false
script:
- cargo build --verbose
- cargo test --verbose
- cargo doc --no-deps
after_success: |
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
echo '<meta http-equiv=refresh content=0;url=filetime/index.html>' > target/doc/index.html &&
pip install ghp-import --user $USER &&
$HOME/.local/bin/ghp-import -n target/doc &&
git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
notifications:
email:
on_success: never
env:
global:
secure: dsIj09BQvGF872zKmqzG+WwCl7gfqwsnxcm3GZlAMgyLYm4juvHOwCRhIERCN3BCxPvdlSRKhe9Rwmp1RkiKuqTK3ITUTAy29Maf2vuL1T+zcdpZE0t6JSCU1gbEwzCA2foB1jzgy7Q47EzeJusmGNwibscjYmXKlH6JCFwTobM=
os:
- linux
- osx

19
src/vendor/filetime/Cargo.toml vendored Normal file
View File

@ -0,0 +1,19 @@
[package]
name = "filetime"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
version = "0.1.10"
license = "MIT/Apache-2.0"
readme = "README.md"
keywords = ["timestamp", "mtime"]
repository = "https://github.com/alexcrichton/filetime"
homepage = "https://github.com/alexcrichton/filetime"
documentation = "http://alexcrichton.com/filetime"
description = """
Platform-agnostic accessors of timestamps in File metadata
"""
[dependencies]
libc = "0.2"
[dev-dependencies]
tempdir = "0.3"

201
src/vendor/filetime/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
src/vendor/filetime/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

25
src/vendor/filetime/README.md vendored Normal file
View File

@ -0,0 +1,25 @@
# filetime
[![Build Status](https://travis-ci.org/alexcrichton/filetime.svg?branch=master)](https://travis-ci.org/alexcrichton/filetime)
[![Build status](https://ci.appveyor.com/api/projects/status/9tatexq47i3ee13k?svg=true)](https://ci.appveyor.com/project/alexcrichton/filetime)
[Documentation](http://alexcrichton.com/filetime/filetime/index.html)
A helper library for inspecting the various timestamps of files in Rust. This
library takes into account cross-platform differences in terms of where the
timestamps are located, what they are called, and how to convert them into a
platform-independent representation.
```toml
# Cargo.toml
[dependencies]
filetime = "0.1"
```
# License
`filetime` is primarily distributed under the terms of both the MIT license and
the Apache License (Version 2.0), with portions covered by various BSD-like
licenses.
See LICENSE-APACHE, and LICENSE-MIT for details.

17
src/vendor/filetime/appveyor.yml vendored Normal file
View File

@ -0,0 +1,17 @@
environment:
matrix:
- TARGET: x86_64-pc-windows-msvc
- TARGET: i686-pc-windows-msvc
- TARGET: i686-pc-windows-gnu
install:
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
- rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
- SET PATH=%PATH%;C:\MinGW\bin
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --verbose

305
src/vendor/filetime/src/lib.rs vendored Normal file
View File

@ -0,0 +1,305 @@
//! Timestamps for files in Rust
//!
//! This library provides platform-agnostic inspection of the various timestamps
//! present in the standard `fs::Metadata` structure.
//!
//! # Installation
//!
//! Add this to you `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! filetime = "0.1"
//! ```
//!
//! # Usage
//!
//! ```no_run
//! use std::fs;
//! use filetime::FileTime;
//!
//! let metadata = fs::metadata("foo.txt").unwrap();
//!
//! let mtime = FileTime::from_last_modification_time(&metadata);
//! println!("{}", mtime);
//!
//! let atime = FileTime::from_last_access_time(&metadata);
//! assert!(mtime < atime);
//!
//! // Inspect values that can be interpreted across platforms
//! println!("{}", mtime.seconds_relative_to_1970());
//! println!("{}", mtime.nanoseconds());
//!
//! // Print the platform-specific value of seconds
//! println!("{}", mtime.seconds());
//! ```
extern crate libc;
#[cfg(unix)] use std::os::unix::prelude::*;
#[cfg(windows)] use std::os::windows::prelude::*;
use std::fmt;
use std::fs;
use std::io;
use std::path::Path;
/// A helper structure to represent a timestamp for a file.
///
/// The actual value contined within is platform-specific and does not have the
/// same meaning across platforms, but comparisons and stringification can be
/// significant among the same platform.
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone, Hash)]
pub struct FileTime {
seconds: u64,
nanos: u32,
}
impl FileTime {
/// Creates a new timestamp representing a 0 time.
///
/// Useful for creating the base of a cmp::max chain of times.
pub fn zero() -> FileTime {
FileTime { seconds: 0, nanos: 0 }
}
/// Creates a new instance of `FileTime` with a number of seconds and
/// nanoseconds relative to January 1, 1970.
///
/// Note that this is typically the relative point that Unix time stamps are
/// from, but on Windows the native time stamp is relative to January 1,
/// 1601 so the return value of `seconds` from the returned `FileTime`
/// instance may not be the same as that passed in.
pub fn from_seconds_since_1970(seconds: u64, nanos: u32) -> FileTime {
FileTime {
seconds: seconds + if cfg!(windows) {11644473600} else {0},
nanos: nanos,
}
}
/// Creates a new timestamp from the last modification time listed in the
/// specified metadata.
///
/// The returned value corresponds to the `mtime` field of `stat` on Unix
/// platforms and the `ftLastWriteTime` field on Windows platforms.
pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime {
#[cfg(unix)]
fn imp(meta: &fs::Metadata) -> FileTime {
FileTime::from_os_repr(meta.mtime() as u64, meta.mtime_nsec() as u32)
}
#[cfg(windows)]
fn imp(meta: &fs::Metadata) -> FileTime {
FileTime::from_os_repr(meta.last_write_time())
}
imp(meta)
}
/// Creates a new timestamp from the last access time listed in the
/// specified metadata.
///
/// The returned value corresponds to the `atime` field of `stat` on Unix
/// platforms and the `ftLastAccessTime` field on Windows platforms.
pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime {
#[cfg(unix)]
fn imp(meta: &fs::Metadata) -> FileTime {
FileTime::from_os_repr(meta.atime() as u64, meta.atime_nsec() as u32)
}
#[cfg(windows)]
fn imp(meta: &fs::Metadata) -> FileTime {
FileTime::from_os_repr(meta.last_access_time())
}
imp(meta)
}
/// Creates a new timestamp from the creation time listed in the specified
/// metadata.
///
/// The returned value corresponds to the `birthtime` field of `stat` on
/// Unix platforms and the `ftCreationTime` field on Windows platforms. Note
/// that not all Unix platforms have this field available and may return
/// `None` in some circumstances.
pub fn from_creation_time(meta: &fs::Metadata) -> Option<FileTime> {
macro_rules! birthtim {
($(($e:expr, $i:ident)),*) => {
#[cfg(any($(target_os = $e),*))]
fn imp(meta: &fs::Metadata) -> Option<FileTime> {
$(
#[cfg(target_os = $e)]
use std::os::$i::fs::MetadataExt;
)*
let raw = meta.as_raw_stat();
Some(FileTime::from_os_repr(raw.st_birthtime as u64,
raw.st_birthtime_nsec as u32))
}
#[cfg(all(not(windows),
$(not(target_os = $e)),*))]
fn imp(_meta: &fs::Metadata) -> Option<FileTime> {
None
}
}
}
birthtim! {
("bitrig", bitrig),
("freebsd", freebsd),
("ios", ios),
("macos", macos),
("openbsd", openbsd)
}
#[cfg(windows)]
fn imp(meta: &fs::Metadata) -> Option<FileTime> {
Some(FileTime::from_os_repr(meta.last_access_time()))
}
imp(meta)
}
#[cfg(windows)]
fn from_os_repr(time: u64) -> FileTime {
// Windows write times are in 100ns intervals, so do a little math to
// get it into the right representation.
FileTime {
seconds: time / (1_000_000_000 / 100),
nanos: ((time % (1_000_000_000 / 100)) * 100) as u32,
}
}
#[cfg(unix)]
fn from_os_repr(seconds: u64, nanos: u32) -> FileTime {
FileTime { seconds: seconds, nanos: nanos }
}
/// Returns the whole number of seconds represented by this timestamp.
///
/// Note that this value's meaning is **platform specific**. On Unix
/// platform time stamps are typically relative to January 1, 1970, but on
/// Windows platforms time stamps are relative to January 1, 1601.
pub fn seconds(&self) -> u64 { self.seconds }
/// Returns the whole number of seconds represented by this timestamp,
/// relative to the Unix epoch start of January 1, 1970.
///
/// Note that this does not return the same value as `seconds` for Windows
/// platforms as seconds are relative to a different date there.
pub fn seconds_relative_to_1970(&self) -> u64 {
self.seconds - if cfg!(windows) {11644473600} else {0}
}
/// Returns the nanosecond precision of this timestamp.
///
/// The returned value is always less than one billion and represents a
/// portion of a second forward from the seconds returned by the `seconds`
/// method.
pub fn nanoseconds(&self) -> u32 { self.nanos }
}
impl fmt::Display for FileTime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}.{:09}s", self.seconds, self.nanos)
}
}
/// Set the last access and modification times for a file on the filesystem.
///
/// This function will set the `atime` and `mtime` metadata fields for a file
/// on the local filesystem, returning any error encountered.
pub fn set_file_times<P>(p: P, atime: FileTime, mtime: FileTime)
-> io::Result<()> where P: AsRef<Path> {
set_file_times_(p.as_ref(), atime, mtime)
}
#[cfg(unix)]
fn set_file_times_(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
use std::ffi::CString;
use libc::{timeval, time_t, suseconds_t, utimes};
let times = [to_timeval(&atime), to_timeval(&mtime)];
let p = try!(CString::new(p.as_os_str().as_bytes()));
return unsafe {
if utimes(p.as_ptr() as *const _, times.as_ptr()) == 0 {
Ok(())
} else {
Err(io::Error::last_os_error())
}
};
fn to_timeval(ft: &FileTime) -> timeval {
timeval {
tv_sec: ft.seconds() as time_t,
tv_usec: (ft.nanoseconds() / 1000) as suseconds_t,
}
}
}
#[cfg(windows)]
#[allow(bad_style)]
fn set_file_times_(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
use std::fs::OpenOptions;
type BOOL = i32;
type HANDLE = *mut u8;
type DWORD = u32;
#[repr(C)]
struct FILETIME {
dwLowDateTime: u32,
dwHighDateTime: u32,
}
extern "system" {
fn SetFileTime(hFile: HANDLE,
lpCreationTime: *const FILETIME,
lpLastAccessTime: *const FILETIME,
lpLastWriteTime: *const FILETIME) -> BOOL;
}
let f = try!(OpenOptions::new().write(true).open(p));
let atime = to_filetime(&atime);
let mtime = to_filetime(&mtime);
return unsafe {
let ret = SetFileTime(f.as_raw_handle() as *mut _,
0 as *const _,
&atime, &mtime);
if ret != 0 {
Ok(())
} else {
Err(io::Error::last_os_error())
}
};
fn to_filetime(ft: &FileTime) -> FILETIME {
let intervals = ft.seconds() * (1_000_000_000 / 100) +
((ft.nanoseconds() as u64) / 100);
FILETIME {
dwLowDateTime: intervals as DWORD,
dwHighDateTime: (intervals >> 32) as DWORD,
}
}
}
#[cfg(test)]
mod tests {
extern crate tempdir;
use std::fs::{self, File};
use self::tempdir::TempDir;
use super::{FileTime, set_file_times};
#[test]
fn set_file_times_test() {
let td = TempDir::new("filetime").unwrap();
let path = td.path().join("foo.txt");
File::create(&path).unwrap();
let metadata = fs::metadata(&path).unwrap();
let mtime = FileTime::from_last_modification_time(&metadata);
let atime = FileTime::from_last_access_time(&metadata);
set_file_times(&path, atime, mtime).unwrap();
let new_mtime = FileTime::from_seconds_since_1970(10_000, 0);
set_file_times(&path, atime, new_mtime).unwrap();
let metadata = fs::metadata(&path).unwrap();
let mtime = FileTime::from_last_modification_time(&metadata);
assert_eq!(mtime, new_mtime);
}
}

1
src/vendor/gcc/.cargo-checksum.json vendored Normal file
View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"5cee7774cf6d876246a0ae0f8362cceeecec5924b751049c945faac9342565ff","Cargo.toml":"2634dedd87889b33a794e31b41a8d8d4713ef40382be3d464229707679bd83da","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ecb2d93f4c81edbd48d8742ff7887dc0a4530a5890967839090bbc972d49bebe","appveyor.yml":"46c77d913eaa45871296942c2cd96ef092c9dcaf19201cb5c500a5107faeb06f","src/bin/gcc-shim.rs":"11edfe1fc6f932bd42ffffda5145833302bc163e0b87dc0d54f4bd0997ad4708","src/lib.rs":"5eb0e311367226ed0420f5e2dac10cc35fc0a3be639a612b6e8ea6d24f646634","src/registry.rs":"3e2a42581ebb82e325dd5600c6571cef937b35003b2927dc618967f5238a2058","src/windows_registry.rs":"906653c020ffe9d572e435f3fc3a8892d9e0a13240ba297db01ce0a288e08cdb","tests/cc_env.rs":"d92c5e3d3d43ac244e63b2cd2c93a521fcf124bf1ccf8d4c6bfa7f8333d88976","tests/support/mod.rs":"d11ed0db4dda5ecf5fb970c9b0c56428cd47421a2742f07032e2cc6b0a0f07e2","tests/test.rs":"164220f11be2eebc20315826513999970660a82feff8cc4b15b4e9d73d98324e"},"package":"553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5"}

0
src/vendor/gcc/.cargo-ok vendored Normal file
View File

2
src/vendor/gcc/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
Cargo.lock

40
src/vendor/gcc/.travis.yml vendored Normal file
View File

@ -0,0 +1,40 @@
language: rust
rust:
- stable
- beta
- nightly
sudo: false
install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then OS=unknown-linux-gnu; else OS=apple-darwin; fi
- export TARGET=$ARCH-$OS
- curl https://static.rust-lang.org/rustup.sh |
sh -s -- --add-target=$TARGET --disable-sudo -y --prefix=`rustc --print sysroot`
before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
script:
- cargo build --verbose
- cargo test --verbose
- cargo test --verbose --features parallel
- cargo test --manifest-path gcc-test/Cargo.toml --target $TARGET
- cargo test --manifest-path gcc-test/Cargo.toml --target $TARGET --features parallel
- cargo test --manifest-path gcc-test/Cargo.toml --target $TARGET --release
- cargo doc
- rustdoc --test README.md -L target/debug -L target/debug/deps
after_success:
- travis-cargo --only nightly doc-upload
env:
global:
secure: ilbcq9zX+UaiBcwqkBGldeanbEQus9npLsi0/nF1PUxKbQsoWSVtVOehAD8Hy92D3hX2npIRyNL8GxBn85XEcBYc1h7DiWUhLcXfZie79v8Ly/qboHCfZLXlB1ofbypbyQfouEdOE9zHf0ZILYVpAgUkliv6KuVShsrKNlbn4QE=
matrix:
- ARCH=x86_64
- ARCH=i686
notifications:
email:
on_success: never
os:
- linux
- osx
addons:
apt:
packages:
- g++-multilib

23
src/vendor/gcc/Cargo.toml vendored Normal file
View File

@ -0,0 +1,23 @@
[package]
name = "gcc"
version = "0.3.38"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
license = "MIT/Apache-2.0"
repository = "https://github.com/alexcrichton/gcc-rs"
documentation = "http://alexcrichton.com/gcc-rs"
description = """
A build-time dependency for Cargo build scripts to assist in invoking the native
C compiler to compile native C code into a static archive to be linked into Rust
code.
"""
keywords = ["build-dependencies"]
[dependencies]
rayon = { version = "0.4", optional = true }
[features]
parallel = ["rayon"]
[dev-dependencies]
tempdir = "0.3"

201
src/vendor/gcc/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
src/vendor/gcc/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

161
src/vendor/gcc/README.md vendored Normal file
View File

@ -0,0 +1,161 @@
# gcc-rs
A library to compile C/C++ code into a Rust library/application.
[![Build Status](https://travis-ci.org/alexcrichton/gcc-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/gcc-rs)
[![Build status](https://ci.appveyor.com/api/projects/status/onu270iw98h81nwv?svg=true)](https://ci.appveyor.com/project/alexcrichton/gcc-rs)
[Documentation](http://alexcrichton.com/gcc-rs)
A simple library meant to be used as a build dependency with Cargo packages in
order to build a set of C/C++ files into a static archive. Note that while this
crate is called "gcc", it actually calls out to the most relevant compile for
a platform, for example using `cl` on MSVC. That is, this crate does indeed work
on MSVC!
## Using gcc-rs
First, you'll want to both add a build script for your crate (`build.rs`) and
also add this crate to your `Cargo.toml` via:
```toml
[package]
# ...
build = "build.rs"
[build-dependencies]
gcc = "0.3"
```
Next up, you'll want to write a build script like so:
```rust,no_run
// build.rs
extern crate gcc;
fn main() {
gcc::compile_library("libfoo.a", &["foo.c", "bar.c"]);
}
```
And that's it! Running `cargo build` should take care of the rest and your Rust
application will now have the C files `foo.c` and `bar.c` compiled into it. You
can call the functions in Rust by declaring functions in your Rust code like so:
```
extern {
fn foo_function();
fn bar_function();
}
pub fn call() {
unsafe {
foo_function();
bar_function();
}
}
fn main() {
// ...
}
```
## External configuration via environment variables
To control the programs and flags used for building, the builder can set a
number of different environment variables.
* `CFLAGS` - a series of space separated flags passed to "gcc". Note that
individual flags cannot currently contain spaces, so doing
something like: "-L=foo\ bar" is not possible.
* `CC` - the actual C compiler used. Note that this is used as an exact
executable name, so (for example) no extra flags can be passed inside
this variable, and the builder must ensure that there aren't any
trailing spaces. This compiler must understand the `-c` flag. For
certain `TARGET`s, it also is assumed to know about other flags (most
common is `-fPIC`).
* `AR` - the `ar` (archiver) executable to use to build the static library.
Each of these variables can also be supplied with certain prefixes and suffixes,
in the following prioritized order:
1. `<var>_<target>` - for example, `CC_x86_64-unknown-linux-gnu`
2. `<var>_<target_with_underscores>` - for example, `CC_x86_64_unknown_linux_gnu`
3. `<build-kind>_<var>` - for example, `HOST_CC` or `TARGET_CFLAGS`
4. `<var>` - a plain `CC`, `AR` as above.
If none of these variables exist, gcc-rs uses built-in defaults
In addition to the the above optional environment variables, `gcc-rs` has some
functions with hard requirements on some variables supplied by [cargo's
build-script driver][cargo] that it has the `TARGET`, `OUT_DIR`, `OPT_LEVEL`,
and `HOST` variables.
[cargo]: http://doc.crates.io/build-script.html#inputs-to-the-build-script
## Optional features
Currently gcc-rs supports parallel compilation (think `make -jN`) but this
feature is turned off by default. To enable gcc-rs to compile C/C++ in parallel,
you can change your dependency to:
```toml
[build-dependencies]
gcc = { version = "0.3", features = ["parallel"] }
```
By default gcc-rs will limit parallelism to `$NUM_JOBS`, or if not present it
will limit it to the number of cpus on the machine.
## Compile-time Requirements
To work properly this crate needs access to a C compiler when the build script
is being run. This crate does not ship a C compiler with it. The compiler
required varies per platform, but there are three broad categories:
* Unix platforms require `cc` to be the C compiler. This can be found by
installing gcc/clang on Linux distributions and Xcode on OSX, for example.
* Windows platforms targeting MSVC (e.g. your target triple ends in `-msvc`)
require `cl.exe` to be available and in `PATH`. This is typically found in
standard Visual Studio installations and the `PATH` can be set up by running
the appropriate developer tools shell.
* Windows platforms targeting MinGW (e.g. your target triple ends in `-gnu`)
require `gcc` to be available in `PATH`. We recommend the
[MinGW-w64](http://mingw-w64.org) distribution, which is using the
[Win-builds](http://win-builds.org) installation system.
You may also acquire it via
[MSYS2](http://msys2.github.io), as explained [here][msys2-help]. Make sure
to install the appropriate architecture corresponding to your installation of
rustc. GCC from older [MinGW](http://www.mingw.org) project is compatible
only with 32-bit rust compiler.
[msys2-help]: http://github.com/rust-lang/rust#building-on-windows
## C++ support
`gcc-rs` supports C++ libraries compilation by using the `cpp` method on
`Config`:
```rust,no_run
extern crate gcc;
fn main() {
gcc::Config::new()
.cpp(true) // Switch to C++ library compilation.
.file("foo.cpp")
.compile("libfoo.a");
}
```
When using C++ library compilation switch, the `CXX` and `CXXFLAGS` env
variables are used instead of `CC` and `CFLAGS` and the C++ standard library is
linked to the crate target.
## License
`gcc-rs` is primarily distributed under the terms of both the MIT license and
the Apache License (Version 2.0), with portions covered by various BSD-like
licenses.
See LICENSE-APACHE, and LICENSE-MIT for details.

35
src/vendor/gcc/appveyor.yml vendored Normal file
View File

@ -0,0 +1,35 @@
environment:
matrix:
- TARGET: x86_64-pc-windows-msvc
ARCH: amd64
VS: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat
- TARGET: x86_64-pc-windows-msvc
ARCH: amd64
VS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
- TARGET: i686-pc-windows-msvc
ARCH: x86
VS: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat
- TARGET: i686-pc-windows-msvc
ARCH: x86
VS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
- TARGET: x86_64-pc-windows-gnu
MSYS_BITS: 64
- TARGET: i686-pc-windows-gnu
MSYS_BITS: 32
install:
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
- rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
- if defined VS call "%VS%" %ARCH%
- set PATH=%PATH%;C:\Program Files (x86)\Rust\bin
- if defined MSYS_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS_BITS%\bin
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --target %TARGET%
- cargo test --features parallel --target %TARGET%
- cargo test --manifest-path gcc-test/Cargo.toml --target %TARGET%
- cargo test --manifest-path gcc-test/Cargo.toml --features parallel --target %TARGET%
- cargo test --manifest-path gcc-test/Cargo.toml --release --target %TARGET%

23
src/vendor/gcc/src/bin/gcc-shim.rs vendored Normal file
View File

@ -0,0 +1,23 @@
#![cfg_attr(test, allow(dead_code))]
use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
fn main() {
let out_dir = PathBuf::from(env::var_os("GCCTEST_OUT_DIR").unwrap());
for i in 0.. {
let candidate = out_dir.join(format!("out{}", i));
if candidate.exists() {
continue
}
let mut f = File::create(candidate).unwrap();
for arg in env::args().skip(1) {
writeln!(f, "{}", arg).unwrap();
}
File::create(out_dir.join("libfoo.a")).unwrap();
break
}
}

959
src/vendor/gcc/src/lib.rs vendored Normal file
View File

@ -0,0 +1,959 @@
//! A library for build scripts to compile custom C code
//!
//! This library is intended to be used as a `build-dependencies` entry in
//! `Cargo.toml`:
//!
//! ```toml
//! [build-dependencies]
//! gcc = "0.3"
//! ```
//!
//! The purpose of this crate is to provide the utility functions necessary to
//! compile C code into a static archive which is then linked into a Rust crate.
//! The top-level `compile_library` function serves as a convenience and more
//! advanced configuration is available through the `Config` builder.
//!
//! This crate will automatically detect situations such as cross compilation or
//! other environment variables set by Cargo and will build code appropriately.
//!
//! # Examples
//!
//! Use the default configuration:
//!
//! ```no_run
//! extern crate gcc;
//!
//! fn main() {
//! gcc::compile_library("libfoo.a", &["src/foo.c"]);
//! }
//! ```
//!
//! Use more advanced configuration:
//!
//! ```no_run
//! extern crate gcc;
//!
//! fn main() {
//! gcc::Config::new()
//! .file("src/foo.c")
//! .define("FOO", Some("bar"))
//! .include("src")
//! .compile("libfoo.a");
//! }
//! ```
#![doc(html_root_url = "http://alexcrichton.com/gcc-rs")]
#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]
#[cfg(feature = "parallel")]
extern crate rayon;
use std::env;
use std::ffi::{OsString, OsStr};
use std::fs;
use std::io;
use std::path::{PathBuf, Path};
use std::process::{Command, Stdio};
use std::io::{BufReader, BufRead, Write};
#[cfg(windows)]
mod registry;
pub mod windows_registry;
/// Extra configuration to pass to gcc.
pub struct Config {
include_directories: Vec<PathBuf>,
definitions: Vec<(String, Option<String>)>,
objects: Vec<PathBuf>,
flags: Vec<String>,
files: Vec<PathBuf>,
cpp: bool,
cpp_link_stdlib: Option<Option<String>>,
cpp_set_stdlib: Option<String>,
target: Option<String>,
host: Option<String>,
out_dir: Option<PathBuf>,
opt_level: Option<String>,
debug: Option<bool>,
env: Vec<(OsString, OsString)>,
compiler: Option<PathBuf>,
archiver: Option<PathBuf>,
cargo_metadata: bool,
pic: Option<bool>,
}
/// Configuration used to represent an invocation of a C compiler.
///
/// This can be used to figure out what compiler is in use, what the arguments
/// to it are, and what the environment variables look like for the compiler.
/// This can be used to further configure other build systems (e.g. forward
/// along CC and/or CFLAGS) or the `to_command` method can be used to run the
/// compiler itself.
pub struct Tool {
path: PathBuf,
args: Vec<OsString>,
env: Vec<(OsString, OsString)>,
}
/// Compile a library from the given set of input C files.
///
/// This will simply compile all files into object files and then assemble them
/// into the output. This will read the standard environment variables to detect
/// cross compilations and such.
///
/// This function will also print all metadata on standard output for Cargo.
///
/// # Example
///
/// ```no_run
/// gcc::compile_library("libfoo.a", &["foo.c", "bar.c"]);
/// ```
pub fn compile_library(output: &str, files: &[&str]) {
let mut c = Config::new();
for f in files.iter() {
c.file(*f);
}
c.compile(output)
}
impl Config {
/// Construct a new instance of a blank set of configuration.
///
/// This builder is finished with the `compile` function.
pub fn new() -> Config {
Config {
include_directories: Vec::new(),
definitions: Vec::new(),
objects: Vec::new(),
flags: Vec::new(),
files: Vec::new(),
cpp: false,
cpp_link_stdlib: None,
cpp_set_stdlib: None,
target: None,
host: None,
out_dir: None,
opt_level: None,
debug: None,
env: Vec::new(),
compiler: None,
archiver: None,
cargo_metadata: true,
pic: None,
}
}
/// Add a directory to the `-I` or include path for headers
pub fn include<P: AsRef<Path>>(&mut self, dir: P) -> &mut Config {
self.include_directories.push(dir.as_ref().to_path_buf());
self
}
/// Specify a `-D` variable with an optional value.
pub fn define(&mut self, var: &str, val: Option<&str>) -> &mut Config {
self.definitions.push((var.to_string(), val.map(|s| s.to_string())));
self
}
/// Add an arbitrary object file to link in
pub fn object<P: AsRef<Path>>(&mut self, obj: P) -> &mut Config {
self.objects.push(obj.as_ref().to_path_buf());
self
}
/// Add an arbitrary flag to the invocation of the compiler
pub fn flag(&mut self, flag: &str) -> &mut Config {
self.flags.push(flag.to_string());
self
}
/// Add a file which will be compiled
pub fn file<P: AsRef<Path>>(&mut self, p: P) -> &mut Config {
self.files.push(p.as_ref().to_path_buf());
self
}
/// Set C++ support.
///
/// The other `cpp_*` options will only become active if this is set to
/// `true`.
pub fn cpp(&mut self, cpp: bool) -> &mut Config {
self.cpp = cpp;
self
}
/// Set the standard library to link against when compiling with C++
/// support.
///
/// The default value of this property depends on the current target: On
/// OS X `Some("c++")` is used, when compiling for a Visual Studio based
/// target `None` is used and for other targets `Some("stdc++")` is used.
///
/// A value of `None` indicates that no automatic linking should happen,
/// otherwise cargo will link against the specified library.
///
/// The given library name must not contain the `lib` prefix.
pub fn cpp_link_stdlib(&mut self, cpp_link_stdlib: Option<&str>)
-> &mut Config {
self.cpp_link_stdlib = Some(cpp_link_stdlib.map(|s| s.into()));
self
}
/// Force the C++ compiler to use the specified standard library.
///
/// Setting this option will automatically set `cpp_link_stdlib` to the same
/// value.
///
/// The default value of this option is always `None`.
///
/// This option has no effect when compiling for a Visual Studio based
/// target.
///
/// This option sets the `-stdlib` flag, which is only supported by some
/// compilers (clang, icc) but not by others (gcc). The library will not
/// detect which compiler is used, as such it is the responsibility of the
/// caller to ensure that this option is only used in conjuction with a
/// compiler which supports the `-stdlib` flag.
///
/// A value of `None` indicates that no specific C++ standard library should
/// be used, otherwise `-stdlib` is added to the compile invocation.
///
/// The given library name must not contain the `lib` prefix.
pub fn cpp_set_stdlib(&mut self, cpp_set_stdlib: Option<&str>)
-> &mut Config {
self.cpp_set_stdlib = cpp_set_stdlib.map(|s| s.into());
self.cpp_link_stdlib(cpp_set_stdlib);
self
}
/// Configures the target this configuration will be compiling for.
///
/// This option is automatically scraped from the `TARGET` environment
/// variable by build scripts, so it's not required to call this function.
pub fn target(&mut self, target: &str) -> &mut Config {
self.target = Some(target.to_string());
self
}
/// Configures the host assumed by this configuration.
///
/// This option is automatically scraped from the `HOST` environment
/// variable by build scripts, so it's not required to call this function.
pub fn host(&mut self, host: &str) -> &mut Config {
self.host = Some(host.to_string());
self
}
/// Configures the optimization level of the generated object files.
///
/// This option is automatically scraped from the `OPT_LEVEL` environment
/// variable by build scripts, so it's not required to call this function.
pub fn opt_level(&mut self, opt_level: u32) -> &mut Config {
self.opt_level = Some(opt_level.to_string());
self
}
/// Configures the optimization level of the generated object files.
///
/// This option is automatically scraped from the `OPT_LEVEL` environment
/// variable by build scripts, so it's not required to call this function.
pub fn opt_level_str(&mut self, opt_level: &str) -> &mut Config {
self.opt_level = Some(opt_level.to_string());
self
}
/// Configures whether the compiler will emit debug information when
/// generating object files.
///
/// This option is automatically scraped from the `PROFILE` environment
/// variable by build scripts (only enabled when the profile is "debug"), so
/// it's not required to call this function.
pub fn debug(&mut self, debug: bool) -> &mut Config {
self.debug = Some(debug);
self
}
/// Configures the output directory where all object files and static
/// libraries will be located.
///
/// This option is automatically scraped from the `OUT_DIR` environment
/// variable by build scripts, so it's not required to call this function.
pub fn out_dir<P: AsRef<Path>>(&mut self, out_dir: P) -> &mut Config {
self.out_dir = Some(out_dir.as_ref().to_owned());
self
}
/// Configures the compiler to be used to produce output.
///
/// This option is automatically determined from the target platform or a
/// number of environment variables, so it's not required to call this
/// function.
pub fn compiler<P: AsRef<Path>>(&mut self, compiler: P) -> &mut Config {
self.compiler = Some(compiler.as_ref().to_owned());
self
}
/// Configures the tool used to assemble archives.
///
/// This option is automatically determined from the target platform or a
/// number of environment variables, so it's not required to call this
/// function.
pub fn archiver<P: AsRef<Path>>(&mut self, archiver: P) -> &mut Config {
self.archiver = Some(archiver.as_ref().to_owned());
self
}
/// Define whether metadata should be emitted for cargo allowing it to
/// automatically link the binary. Defaults to `true`.
pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Config {
self.cargo_metadata = cargo_metadata;
self
}
/// Configures whether the compiler will emit position independent code.
///
/// This option defaults to `false` for `i686` and `windows-gnu` targets and to `true` for all
/// other targets.
pub fn pic(&mut self, pic: bool) -> &mut Config {
self.pic = Some(pic);
self
}
#[doc(hidden)]
pub fn __set_env<A, B>(&mut self, a: A, b: B) -> &mut Config
where A: AsRef<OsStr>, B: AsRef<OsStr>
{
self.env.push((a.as_ref().to_owned(), b.as_ref().to_owned()));
self
}
/// Run the compiler, generating the file `output`
///
/// The name `output` must begin with `lib` and end with `.a`
pub fn compile(&self, output: &str) {
assert!(output.starts_with("lib"));
assert!(output.ends_with(".a"));
let lib_name = &output[3..output.len() - 2];
let dst = self.get_out_dir();
let mut objects = Vec::new();
let mut src_dst = Vec::new();
for file in self.files.iter() {
let obj = dst.join(file).with_extension("o");
let obj = if !obj.starts_with(&dst) {
dst.join(obj.file_name().unwrap())
} else {
obj
};
fs::create_dir_all(&obj.parent().unwrap()).unwrap();
src_dst.push((file.to_path_buf(), obj.clone()));
objects.push(obj);
}
self.compile_objects(&src_dst);
self.assemble(lib_name, &dst.join(output), &objects);
self.print(&format!("cargo:rustc-link-lib=static={}",
&output[3..output.len() - 2]));
self.print(&format!("cargo:rustc-link-search=native={}", dst.display()));
// Add specific C++ libraries, if enabled.
if self.cpp {
if let Some(stdlib) = self.get_cpp_link_stdlib() {
self.print(&format!("cargo:rustc-link-lib={}", stdlib));
}
}
}
#[cfg(feature = "parallel")]
fn compile_objects(&self, objs: &[(PathBuf, PathBuf)]) {
use self::rayon::prelude::*;
let mut cfg = rayon::Configuration::new();
if let Ok(amt) = env::var("NUM_JOBS") {
if let Ok(amt) = amt.parse() {
cfg = cfg.set_num_threads(amt);
}
}
drop(rayon::initialize(cfg));
objs.par_iter().weight_max().for_each(|&(ref src, ref dst)| {
self.compile_object(src, dst)
})
}
#[cfg(not(feature = "parallel"))]
fn compile_objects(&self, objs: &[(PathBuf, PathBuf)]) {
for &(ref src, ref dst) in objs {
self.compile_object(src, dst);
}
}
fn compile_object(&self, file: &Path, dst: &Path) {
let is_asm = file.extension().and_then(|s| s.to_str()) == Some("asm");
let msvc = self.get_target().contains("msvc");
let (mut cmd, name) = if msvc && is_asm {
self.msvc_macro_assembler()
} else {
let compiler = self.get_compiler();
let mut cmd = compiler.to_command();
for &(ref a, ref b) in self.env.iter() {
cmd.env(a, b);
}
(cmd, compiler.path.file_name().unwrap()
.to_string_lossy().into_owned())
};
if msvc && is_asm {
cmd.arg("/Fo").arg(dst);
} else if msvc {
let mut s = OsString::from("/Fo");
s.push(&dst);
cmd.arg(s);
} else {
cmd.arg("-o").arg(&dst);
}
cmd.arg(if msvc {"/c"} else {"-c"});
cmd.arg(file);
run(&mut cmd, &name);
}
/// Get the compiler that's in use for this configuration.
///
/// This function will return a `Tool` which represents the culmination
/// of this configuration at a snapshot in time. The returned compiler can
/// be inspected (e.g. the path, arguments, environment) to forward along to
/// other tools, or the `to_command` method can be used to invoke the
/// compiler itself.
///
/// This method will take into account all configuration such as debug
/// information, optimization level, include directories, defines, etc.
/// Additionally, the compiler binary in use follows the standard
/// conventions for this path, e.g. looking at the explicitly set compiler,
/// environment variables (a number of which are inspected here), and then
/// falling back to the default configuration.
pub fn get_compiler(&self) -> Tool {
let opt_level = self.get_opt_level();
let debug = self.get_debug();
let target = self.get_target();
let msvc = target.contains("msvc");
self.print(&format!("debug={} opt-level={}", debug, opt_level));
let mut cmd = self.get_base_compiler();
let nvcc = cmd.path.to_str()
.map(|path| path.contains("nvcc"))
.unwrap_or(false);
if msvc {
cmd.args.push("/nologo".into());
cmd.args.push("/MD".into()); // link against msvcrt.dll for now
match &opt_level[..] {
"z" | "s" => cmd.args.push("/Os".into()),
"2" => cmd.args.push("/O2".into()),
"1" => cmd.args.push("/O1".into()),
_ => {}
}
if target.contains("i686") {
cmd.args.push("/SAFESEH".into());
} else if target.contains("i586") {
cmd.args.push("/SAFESEH".into());
cmd.args.push("/ARCH:IA32".into());
}
} else if nvcc {
cmd.args.push(format!("-O{}", opt_level).into());
} else {
cmd.args.push(format!("-O{}", opt_level).into());
cmd.args.push("-ffunction-sections".into());
cmd.args.push("-fdata-sections".into());
}
for arg in self.envflags(if self.cpp {"CXXFLAGS"} else {"CFLAGS"}) {
cmd.args.push(arg.into());
}
if debug {
cmd.args.push(if msvc {"/Z7"} else {"-g"}.into());
}
if target.contains("-ios") {
self.ios_flags(&mut cmd);
} else if !msvc {
if target.contains("i686") || target.contains("i586") {
cmd.args.push("-m32".into());
} else if target.contains("x86_64") || target.contains("powerpc64") {
cmd.args.push("-m64".into());
}
if !nvcc && self.pic.unwrap_or(!target.contains("i686") && !target.contains("windows-gnu")) {
cmd.args.push("-fPIC".into());
} else if nvcc && self.pic.unwrap_or(false) {
cmd.args.push("-Xcompiler".into());
cmd.args.push("\'-fPIC\'".into());
}
if target.contains("musl") {
cmd.args.push("-static".into());
}
if target.starts_with("armv7-unknown-linux-") {
cmd.args.push("-march=armv7-a".into());
}
if target.starts_with("armv7-linux-androideabi") {
cmd.args.push("-march=armv7-a".into());
cmd.args.push("-mfpu=vfpv3-d16".into());
}
if target.starts_with("arm-unknown-linux-") {
cmd.args.push("-march=armv6".into());
cmd.args.push("-marm".into());
}
if target.starts_with("i586-unknown-linux-") {
cmd.args.push("-march=pentium".into());
}
if target.starts_with("i686-unknown-linux-") {
cmd.args.push("-march=i686".into());
}
if target.starts_with("thumb") {
cmd.args.push("-mthumb".into());
if target.ends_with("eabihf") {
cmd.args.push("-mfloat-abi=hard".into())
}
}
if target.starts_with("thumbv6m") {
cmd.args.push("-march=armv6-m".into());
}
if target.starts_with("thumbv7em") {
cmd.args.push("-march=armv7e-m".into());
}
if target.starts_with("thumbv7m") {
cmd.args.push("-march=armv7-m".into());
}
}
if self.cpp && !msvc {
if let Some(ref stdlib) = self.cpp_set_stdlib {
cmd.args.push(format!("-stdlib=lib{}", stdlib).into());
}
}
for directory in self.include_directories.iter() {
cmd.args.push(if msvc {"/I"} else {"-I"}.into());
cmd.args.push(directory.into());
}
for flag in self.flags.iter() {
cmd.args.push(flag.into());
}
for &(ref key, ref value) in self.definitions.iter() {
let lead = if msvc {"/"} else {"-"};
if let &Some(ref value) = value {
cmd.args.push(format!("{}D{}={}", lead, key, value).into());
} else {
cmd.args.push(format!("{}D{}", lead, key).into());
}
}
cmd
}
fn msvc_macro_assembler(&self) -> (Command, String) {
let target = self.get_target();
let tool = if target.contains("x86_64") {"ml64.exe"} else {"ml.exe"};
let mut cmd = windows_registry::find(&target, tool).unwrap_or_else(|| {
self.cmd(tool)
});
for directory in self.include_directories.iter() {
cmd.arg("/I").arg(directory);
}
for &(ref key, ref value) in self.definitions.iter() {
if let &Some(ref value) = value {
cmd.arg(&format!("/D{}={}", key, value));
} else {
cmd.arg(&format!("/D{}", key));
}
}
if target.contains("i686") || target.contains("i586") {
cmd.arg("/safeseh");
}
for flag in self.flags.iter() {
cmd.arg(flag);
}
(cmd, tool.to_string())
}
fn assemble(&self, lib_name: &str, dst: &Path, objects: &[PathBuf]) {
// Delete the destination if it exists as the `ar` tool at least on Unix
// appends to it, which we don't want.
let _ = fs::remove_file(&dst);
let target = self.get_target();
if target.contains("msvc") {
let mut cmd = match self.archiver {
Some(ref s) => self.cmd(s),
None => windows_registry::find(&target, "lib.exe")
.unwrap_or(self.cmd("lib.exe")),
};
let mut out = OsString::from("/OUT:");
out.push(dst);
run(cmd.arg(out).arg("/nologo")
.args(objects)
.args(&self.objects), "lib.exe");
// The Rust compiler will look for libfoo.a and foo.lib, but the
// MSVC linker will also be passed foo.lib, so be sure that both
// exist for now.
let lib_dst = dst.with_file_name(format!("{}.lib", lib_name));
let _ = fs::remove_file(&lib_dst);
fs::hard_link(&dst, &lib_dst).or_else(|_| {
//if hard-link fails, just copy (ignoring the number of bytes written)
fs::copy(&dst, &lib_dst).map(|_| ())
}).ok().expect("Copying from {:?} to {:?} failed.");;
} else {
let ar = self.get_ar();
let cmd = ar.file_name().unwrap().to_string_lossy();
run(self.cmd(&ar).arg("crs")
.arg(dst)
.args(objects)
.args(&self.objects), &cmd);
}
}
fn ios_flags(&self, cmd: &mut Tool) {
enum ArchSpec {
Device(&'static str),
Simulator(&'static str),
}
let target = self.get_target();
let arch = target.split('-').nth(0).unwrap();
let arch = match arch {
"arm" | "armv7" | "thumbv7" => ArchSpec::Device("armv7"),
"armv7s" | "thumbv7s" => ArchSpec::Device("armv7s"),
"arm64" | "aarch64" => ArchSpec::Device("arm64"),
"i386" | "i686" => ArchSpec::Simulator("-m32"),
"x86_64" => ArchSpec::Simulator("-m64"),
_ => fail("Unknown arch for iOS target")
};
let sdk = match arch {
ArchSpec::Device(arch) => {
cmd.args.push("-arch".into());
cmd.args.push(arch.into());
cmd.args.push("-miphoneos-version-min=7.0".into());
"iphoneos"
},
ArchSpec::Simulator(arch) => {
cmd.args.push(arch.into());
cmd.args.push("-mios-simulator-version-min=7.0".into());
"iphonesimulator"
}
};
self.print(&format!("Detecting iOS SDK path for {}", sdk));
let sdk_path = self.cmd("xcrun")
.arg("--show-sdk-path")
.arg("--sdk")
.arg(sdk)
.stderr(Stdio::inherit())
.output()
.unwrap()
.stdout;
let sdk_path = String::from_utf8(sdk_path).unwrap();
cmd.args.push("-isysroot".into());
cmd.args.push(sdk_path.trim().into());
}
fn cmd<P: AsRef<OsStr>>(&self, prog: P) -> Command {
let mut cmd = Command::new(prog);
for &(ref a, ref b) in self.env.iter() {
cmd.env(a, b);
}
return cmd
}
fn get_base_compiler(&self) -> Tool {
if let Some(ref c) = self.compiler {
return Tool::new(c.clone())
}
let host = self.get_host();
let target = self.get_target();
let (env, msvc, gnu, default) = if self.cpp {
("CXX", "cl.exe", "g++", "c++")
} else {
("CC", "cl.exe", "gcc", "cc")
};
self.env_tool(env).map(|(tool, args)| {
let mut t = Tool::new(PathBuf::from(tool));
for arg in args {
t.args.push(arg.into());
}
return t
}).or_else(|| {
if target.contains("emscripten") {
if self.cpp {
Some(Tool::new(PathBuf::from("em++")))
} else {
Some(Tool::new(PathBuf::from("emcc")))
}
} else {
None
}
}).or_else(|| {
windows_registry::find_tool(&target, "cl.exe")
}).unwrap_or_else(|| {
let compiler = if host.contains("windows") &&
target.contains("windows") {
if target.contains("msvc") {
msvc.to_string()
} else {
format!("{}.exe", gnu)
}
} else if target.contains("android") {
format!("{}-{}", target, gnu)
} else if self.get_host() != target {
// CROSS_COMPILE is of the form: "arm-linux-gnueabi-"
let cc_env = self.getenv("CROSS_COMPILE");
let cross_compile = cc_env.as_ref().map(|s| s.trim_right_matches('-'));
let prefix = cross_compile.or(match &target[..] {
"aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu"),
"arm-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"),
"arm-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
"arm-unknown-linux-musleabi" => Some("arm-linux-musleabi"),
"arm-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
"arm-unknown-netbsdelf-eabi" => Some("arm--netbsdelf-eabi"),
"armv6-unknown-netbsdelf-eabihf" => Some("armv6--netbsdelf-eabihf"),
"armv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
"armv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
"armv7-unknown-netbsdelf-eabihf" => Some("armv7--netbsdelf-eabihf"),
"i686-pc-windows-gnu" => Some("i686-w64-mingw32"),
"i686-unknown-linux-musl" => Some("musl"),
"i686-unknown-netbsdelf" => Some("i486--netbsdelf"),
"mips-unknown-linux-gnu" => Some("mips-linux-gnu"),
"mipsel-unknown-linux-gnu" => Some("mipsel-linux-gnu"),
"mips64-unknown-linux-gnuabi64" => Some("mips64-linux-gnuabi64"),
"mips64el-unknown-linux-gnuabi64" => Some("mips64el-linux-gnuabi64"),
"powerpc-unknown-linux-gnu" => Some("powerpc-linux-gnu"),
"powerpc-unknown-netbsd" => Some("powerpc--netbsd"),
"powerpc64-unknown-linux-gnu" => Some("powerpc-linux-gnu"),
"powerpc64le-unknown-linux-gnu" => Some("powerpc64le-linux-gnu"),
"s390x-unknown-linux-gnu" => Some("s390x-linux-gnu"),
"thumbv6m-none-eabi" => Some("arm-none-eabi"),
"thumbv7em-none-eabi" => Some("arm-none-eabi"),
"thumbv7em-none-eabihf" => Some("arm-none-eabi"),
"thumbv7m-none-eabi" => Some("arm-none-eabi"),
"x86_64-pc-windows-gnu" => Some("x86_64-w64-mingw32"),
"x86_64-rumprun-netbsd" => Some("x86_64-rumprun-netbsd"),
"x86_64-unknown-linux-musl" => Some("musl"),
"x86_64-unknown-netbsd" => Some("x86_64--netbsd"),
_ => None,
});
match prefix {
Some(prefix) => format!("{}-{}", prefix, gnu),
None => default.to_string(),
}
} else {
default.to_string()
};
Tool::new(PathBuf::from(compiler))
})
}
fn get_var(&self, var_base: &str) -> Result<String, String> {
let target = self.get_target();
let host = self.get_host();
let kind = if host == target {"HOST"} else {"TARGET"};
let target_u = target.replace("-", "_");
let res = self.getenv(&format!("{}_{}", var_base, target))
.or_else(|| self.getenv(&format!("{}_{}", var_base, target_u)))
.or_else(|| self.getenv(&format!("{}_{}", kind, var_base)))
.or_else(|| self.getenv(var_base));
match res {
Some(res) => Ok(res),
None => Err("could not get environment variable".to_string()),
}
}
fn envflags(&self, name: &str) -> Vec<String> {
self.get_var(name).unwrap_or(String::new())
.split(|c: char| c.is_whitespace()).filter(|s| !s.is_empty())
.map(|s| s.to_string())
.collect()
}
fn env_tool(&self, name: &str) -> Option<(String, Vec<String>)> {
self.get_var(name).ok().map(|tool| {
let whitelist = ["ccache", "distcc"];
for t in whitelist.iter() {
if tool.starts_with(t) && tool[t.len()..].starts_with(" ") {
return (t.to_string(),
vec![tool[t.len()..].trim_left().to_string()])
}
}
(tool, Vec::new())
})
}
/// Returns the default C++ standard library for the current target: `libc++`
/// for OS X and `libstdc++` for anything else.
fn get_cpp_link_stdlib(&self) -> Option<String> {
self.cpp_link_stdlib.clone().unwrap_or_else(|| {
let target = self.get_target();
if target.contains("msvc") {
None
} else if target.contains("darwin") {
Some("c++".to_string())
} else {
Some("stdc++".to_string())
}
})
}
fn get_ar(&self) -> PathBuf {
self.archiver.clone().or_else(|| {
self.get_var("AR").map(PathBuf::from).ok()
}).unwrap_or_else(|| {
if self.get_target().contains("android") {
PathBuf::from(format!("{}-ar", self.get_target()))
} else if self.get_target().contains("emscripten") {
PathBuf::from("emar")
} else {
PathBuf::from("ar")
}
})
}
fn get_target(&self) -> String {
self.target.clone().unwrap_or_else(|| self.getenv_unwrap("TARGET"))
}
fn get_host(&self) -> String {
self.host.clone().unwrap_or_else(|| self.getenv_unwrap("HOST"))
}
fn get_opt_level(&self) -> String {
self.opt_level.as_ref().cloned().unwrap_or_else(|| {
self.getenv_unwrap("OPT_LEVEL")
})
}
fn get_debug(&self) -> bool {
self.debug.unwrap_or_else(|| self.getenv_unwrap("PROFILE") == "debug")
}
fn get_out_dir(&self) -> PathBuf {
self.out_dir.clone().unwrap_or_else(|| {
env::var_os("OUT_DIR").map(PathBuf::from).unwrap()
})
}
fn getenv(&self, v: &str) -> Option<String> {
let r = env::var(v).ok();
self.print(&format!("{} = {:?}", v, r));
r
}
fn getenv_unwrap(&self, v: &str) -> String {
match self.getenv(v) {
Some(s) => s,
None => fail(&format!("environment variable `{}` not defined", v)),
}
}
fn print(&self, s: &str) {
if self.cargo_metadata {
println!("{}", s);
}
}
}
impl Tool {
fn new(path: PathBuf) -> Tool {
Tool {
path: path,
args: Vec::new(),
env: Vec::new(),
}
}
/// Converts this compiler into a `Command` that's ready to be run.
///
/// This is useful for when the compiler needs to be executed and the
/// command returned will already have the initial arguments and environment
/// variables configured.
pub fn to_command(&self) -> Command {
let mut cmd = Command::new(&self.path);
cmd.args(&self.args);
for &(ref k, ref v) in self.env.iter() {
cmd.env(k, v);
}
return cmd
}
/// Returns the path for this compiler.
///
/// Note that this may not be a path to a file on the filesystem, e.g. "cc",
/// but rather something which will be resolved when a process is spawned.
pub fn path(&self) -> &Path {
&self.path
}
/// Returns the default set of arguments to the compiler needed to produce
/// executables for the target this compiler generates.
pub fn args(&self) -> &[OsString] {
&self.args
}
/// Returns the set of environment variables needed for this compiler to
/// operate.
///
/// This is typically only used for MSVC compilers currently.
pub fn env(&self) -> &[(OsString, OsString)] {
&self.env
}
}
fn run(cmd: &mut Command, program: &str) {
println!("running: {:?}", cmd);
// Capture the standard error coming from these programs, and write it out
// with cargo:warning= prefixes. Note that this is a bit wonky to avoid
// requiring the output to be UTF-8, we instead just ship bytes from one
// location to another.
let spawn_result = match cmd.stderr(Stdio::piped()).spawn() {
Ok(mut child) => {
let stderr = BufReader::new(child.stderr.take().unwrap());
for line in stderr.split(b'\n').filter_map(|l| l.ok()) {
print!("cargo:warning=");
std::io::stdout().write_all(&line).unwrap();
println!("");
}
child.wait()
}
Err(e) => Err(e),
};
let status = match spawn_result {
Ok(status) => status,
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
let extra = if cfg!(windows) {
" (see https://github.com/alexcrichton/gcc-rs#compile-time-requirements \
for help)"
} else {
""
};
fail(&format!("failed to execute command: {}\nIs `{}` \
not installed?{}", e, program, extra));
}
Err(e) => fail(&format!("failed to execute command: {}", e)),
};
println!("{:?}", status);
if !status.success() {
fail(&format!("command did not execute successfully, got: {}", status));
}
}
fn fail(s: &str) -> ! {
println!("\n\n{}\n\n", s);
panic!()
}

169
src/vendor/gcc/src/registry.rs vendored Normal file
View File

@ -0,0 +1,169 @@
// Copyright 2015 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.
use std::ffi::{OsString, OsStr};
use std::io;
use std::ops::RangeFrom;
use std::os::raw;
use std::os::windows::prelude::*;
pub struct RegistryKey(Repr);
type HKEY = *mut u8;
type DWORD = u32;
type LPDWORD = *mut DWORD;
type LPCWSTR = *const u16;
type LPWSTR = *mut u16;
type LONG = raw::c_long;
type PHKEY = *mut HKEY;
type PFILETIME = *mut u8;
type LPBYTE = *mut u8;
type REGSAM = u32;
const ERROR_SUCCESS: DWORD = 0;
const ERROR_NO_MORE_ITEMS: DWORD = 259;
const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY;
const REG_SZ: DWORD = 1;
const KEY_READ: DWORD = 0x20019;
const KEY_WOW64_32KEY: DWORD = 0x200;
#[link(name = "advapi32")]
extern "system" {
fn RegOpenKeyExW(key: HKEY,
lpSubKey: LPCWSTR,
ulOptions: DWORD,
samDesired: REGSAM,
phkResult: PHKEY) -> LONG;
fn RegEnumKeyExW(key: HKEY,
dwIndex: DWORD,
lpName: LPWSTR,
lpcName: LPDWORD,
lpReserved: LPDWORD,
lpClass: LPWSTR,
lpcClass: LPDWORD,
lpftLastWriteTime: PFILETIME) -> LONG;
fn RegQueryValueExW(hKey: HKEY,
lpValueName: LPCWSTR,
lpReserved: LPDWORD,
lpType: LPDWORD,
lpData: LPBYTE,
lpcbData: LPDWORD) -> LONG;
fn RegCloseKey(hKey: HKEY) -> LONG;
}
struct OwnedKey(HKEY);
enum Repr {
Const(HKEY),
Owned(OwnedKey),
}
pub struct Iter<'a> {
idx: RangeFrom<DWORD>,
key: &'a RegistryKey,
}
unsafe impl Sync for Repr {}
unsafe impl Send for Repr {}
pub static LOCAL_MACHINE: RegistryKey =
RegistryKey(Repr::Const(HKEY_LOCAL_MACHINE));
impl RegistryKey {
fn raw(&self) -> HKEY {
match self.0 {
Repr::Const(val) => val,
Repr::Owned(ref val) => val.0,
}
}
pub fn open(&self, key: &OsStr) -> io::Result<RegistryKey> {
let key = key.encode_wide().chain(Some(0)).collect::<Vec<_>>();
let mut ret = 0 as *mut _;
let err = unsafe {
RegOpenKeyExW(self.raw(), key.as_ptr(), 0,
KEY_READ | KEY_WOW64_32KEY, &mut ret)
};
if err == ERROR_SUCCESS as LONG {
Ok(RegistryKey(Repr::Owned(OwnedKey(ret))))
} else {
Err(io::Error::from_raw_os_error(err as i32))
}
}
pub fn iter(&self) -> Iter {
Iter { idx: 0.., key: self }
}
pub fn query_str(&self, name: &str) -> io::Result<OsString> {
let name: &OsStr = name.as_ref();
let name = name.encode_wide().chain(Some(0)).collect::<Vec<_>>();
let mut len = 0;
let mut kind = 0;
unsafe {
let err = RegQueryValueExW(self.raw(), name.as_ptr(), 0 as *mut _,
&mut kind, 0 as *mut _, &mut len);
if err != ERROR_SUCCESS as LONG {
return Err(io::Error::from_raw_os_error(err as i32))
}
if kind != REG_SZ {
return Err(io::Error::new(io::ErrorKind::Other,
"registry key wasn't a string"))
}
// The length here is the length in bytes, but we're using wide
// characters so we need to be sure to halve it for the capacity
// passed in.
let mut v = Vec::with_capacity(len as usize / 2);
let err = RegQueryValueExW(self.raw(), name.as_ptr(), 0 as *mut _,
0 as *mut _, v.as_mut_ptr() as *mut _,
&mut len);
if err != ERROR_SUCCESS as LONG {
return Err(io::Error::from_raw_os_error(err as i32))
}
v.set_len(len as usize / 2);
// Some registry keys may have a terminating nul character, but
// we're not interested in that, so chop it off if it's there.
if v[v.len() - 1] == 0 {
v.pop();
}
Ok(OsString::from_wide(&v))
}
}
}
impl Drop for OwnedKey {
fn drop(&mut self) {
unsafe { RegCloseKey(self.0); }
}
}
impl<'a> Iterator for Iter<'a> {
type Item = io::Result<OsString>;
fn next(&mut self) -> Option<io::Result<OsString>> {
self.idx.next().and_then(|i| unsafe {
let mut v = Vec::with_capacity(256);
let mut len = v.capacity() as DWORD;
let ret = RegEnumKeyExW(self.key.raw(), i, v.as_mut_ptr(), &mut len,
0 as *mut _, 0 as *mut _, 0 as *mut _,
0 as *mut _);
if ret == ERROR_NO_MORE_ITEMS as LONG {
None
} else if ret != ERROR_SUCCESS as LONG {
Some(Err(io::Error::from_raw_os_error(ret as i32)))
} else {
v.set_len(len as usize);
Some(Ok(OsString::from_wide(&v)))
}
})
}
}

425
src/vendor/gcc/src/windows_registry.rs vendored Normal file
View File

@ -0,0 +1,425 @@
// Copyright 2015 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.
//! A helper module to probe the Windows Registry when looking for
//! windows-specific tools.
use std::process::Command;
use Tool;
macro_rules! otry {
($expr:expr) => (match $expr {
Some(val) => val,
None => return None,
})
}
/// Attempts to find a tool within an MSVC installation using the Windows
/// registry as a point to search from.
///
/// The `target` argument is the target that the tool should work for (e.g.
/// compile or link for) and the `tool` argument is the tool to find (e.g.
/// `cl.exe` or `link.exe`).
///
/// This function will return `None` if the tool could not be found, or it will
/// return `Some(cmd)` which represents a command that's ready to execute the
/// tool with the appropriate environment variables set.
///
/// Note that this function always returns `None` for non-MSVC targets.
pub fn find(target: &str, tool: &str) -> Option<Command> {
find_tool(target, tool).map(|c| c.to_command())
}
/// Similar to the `find` function above, this function will attempt the same
/// operation (finding a MSVC tool in a local install) but instead returns a
/// `Tool` which may be introspected.
#[cfg(not(windows))]
pub fn find_tool(_target: &str, _tool: &str) -> Option<Tool> {
None
}
/// Documented above.
#[cfg(windows)]
pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
use std::env;
use std::ffi::OsString;
use std::mem;
use std::path::{Path, PathBuf};
use registry::{RegistryKey, LOCAL_MACHINE};
struct MsvcTool {
tool: PathBuf,
libs: Vec<PathBuf>,
path: Vec<PathBuf>,
include: Vec<PathBuf>,
}
impl MsvcTool {
fn new(tool: PathBuf) -> MsvcTool {
MsvcTool {
tool: tool,
libs: Vec::new(),
path: Vec::new(),
include: Vec::new(),
}
}
fn into_tool(self) -> Tool {
let MsvcTool { tool, libs, path, include } = self;
let mut tool = Tool::new(tool.into());
add_env(&mut tool, "LIB", libs);
add_env(&mut tool, "PATH", path);
add_env(&mut tool, "INCLUDE", include);
return tool
}
}
// This logic is all tailored for MSVC, if we're not that then bail out
// early.
if !target.contains("msvc") {
return None
}
// Looks like msbuild isn't located in the same location as other tools like
// cl.exe and lib.exe. To handle this we probe for it manually with
// dedicated registry keys.
if tool.contains("msbuild") {
return find_msbuild(target)
}
// If VCINSTALLDIR is set, then someone's probably already run vcvars and we
// should just find whatever that indicates.
if env::var_os("VCINSTALLDIR").is_some() {
return env::var_os("PATH").and_then(|path| {
env::split_paths(&path).map(|p| p.join(tool)).find(|p| p.exists())
}).map(|path| {
Tool::new(path.into())
})
}
// Ok, if we're here, now comes the fun part of the probing. Default shells
// or shells like MSYS aren't really configured to execute `cl.exe` and the
// various compiler tools shipped as part of Visual Studio. Here we try to
// first find the relevant tool, then we also have to be sure to fill in
// environment variables like `LIB`, `INCLUDE`, and `PATH` to ensure that
// the tool is actually usable.
return find_msvc_latest(tool, target, "15.0").or_else(|| {
find_msvc_latest(tool, target, "14.0")
}).or_else(|| {
find_msvc_12(tool, target)
}).or_else(|| {
find_msvc_11(tool, target)
});
// For MSVC 14 or newer we need to find the Universal CRT as well as either
// the Windows 10 SDK or Windows 8.1 SDK.
fn find_msvc_latest(tool: &str, target: &str, ver: &str) -> Option<Tool> {
let vcdir = otry!(get_vc_dir(ver));
let mut tool = otry!(get_tool(tool, &vcdir, target));
let sub = otry!(lib_subdir(target));
let (ucrt, ucrt_version) = otry!(get_ucrt_dir());
let ucrt_include = ucrt.join("include").join(&ucrt_version);
tool.include.push(ucrt_include.join("ucrt"));
let ucrt_lib = ucrt.join("lib").join(&ucrt_version);
tool.libs.push(ucrt_lib.join("ucrt").join(sub));
if let Some((sdk, version)) = get_sdk10_dir() {
tool.path.push(sdk.join("bin").join(sub));
let sdk_lib = sdk.join("lib").join(&version);
tool.libs.push(sdk_lib.join("um").join(sub));
let sdk_include = sdk.join("include").join(&version);
tool.include.push(sdk_include.join("um"));
tool.include.push(sdk_include.join("winrt"));
tool.include.push(sdk_include.join("shared"));
} else if let Some(sdk) = get_sdk81_dir() {
tool.path.push(sdk.join("bin").join(sub));
let sdk_lib = sdk.join("lib").join("winv6.3");
tool.libs.push(sdk_lib.join("um").join(sub));
let sdk_include = sdk.join("include");
tool.include.push(sdk_include.join("um"));
tool.include.push(sdk_include.join("winrt"));
tool.include.push(sdk_include.join("shared"));
} else {
return None
}
Some(tool.into_tool())
}
// For MSVC 12 we need to find the Windows 8.1 SDK.
fn find_msvc_12(tool: &str, target: &str) -> Option<Tool> {
let vcdir = otry!(get_vc_dir("12.0"));
let mut tool = otry!(get_tool(tool, &vcdir, target));
let sub = otry!(lib_subdir(target));
let sdk81 = otry!(get_sdk81_dir());
tool.path.push(sdk81.join("bin").join(sub));
let sdk_lib = sdk81.join("lib").join("winv6.3");
tool.libs.push(sdk_lib.join("um").join(sub));
let sdk_include = sdk81.join("include");
tool.include.push(sdk_include.join("shared"));
tool.include.push(sdk_include.join("um"));
tool.include.push(sdk_include.join("winrt"));
Some(tool.into_tool())
}
// For MSVC 11 we need to find the Windows 8 SDK.
fn find_msvc_11(tool: &str, target: &str) -> Option<Tool> {
let vcdir = otry!(get_vc_dir("11.0"));
let mut tool = otry!(get_tool(tool, &vcdir, target));
let sub = otry!(lib_subdir(target));
let sdk8 = otry!(get_sdk8_dir());
tool.path.push(sdk8.join("bin").join(sub));
let sdk_lib = sdk8.join("lib").join("win8");
tool.libs.push(sdk_lib.join("um").join(sub));
let sdk_include = sdk8.join("include");
tool.include.push(sdk_include.join("shared"));
tool.include.push(sdk_include.join("um"));
tool.include.push(sdk_include.join("winrt"));
Some(tool.into_tool())
}
fn add_env(tool: &mut Tool, env: &str, paths: Vec<PathBuf>) {
let prev = env::var_os(env).unwrap_or(OsString::new());
let prev = env::split_paths(&prev);
let new = paths.into_iter().chain(prev);
tool.env.push((env.to_string().into(), env::join_paths(new).unwrap()));
}
// Given a possible MSVC installation directory, we look for the linker and
// then add the MSVC library path.
fn get_tool(tool: &str, path: &Path, target: &str) -> Option<MsvcTool> {
bin_subdir(target).into_iter().map(|(sub, host)| {
(path.join("bin").join(sub).join(tool),
path.join("bin").join(host))
}).filter(|&(ref path, _)| {
path.is_file()
}).map(|(path, host)| {
let mut tool = MsvcTool::new(path);
tool.path.push(host);
tool
}).filter_map(|mut tool| {
let sub = otry!(vc_lib_subdir(target));
tool.libs.push(path.join("lib").join(sub));
tool.include.push(path.join("include"));
Some(tool)
}).next()
}
// To find MSVC we look in a specific registry key for the version we are
// trying to find.
fn get_vc_dir(ver: &str) -> Option<PathBuf> {
let key = r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
let path = otry!(key.query_str(ver).ok());
Some(path.into())
}
// To find the Universal CRT we look in a specific registry key for where
// all the Universal CRTs are located and then sort them asciibetically to
// find the newest version. While this sort of sorting isn't ideal, it is
// what vcvars does so that's good enough for us.
//
// Returns a pair of (root, version) for the ucrt dir if found
fn get_ucrt_dir() -> Option<(PathBuf, String)> {
let key = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
let root = otry!(key.query_str("KitsRoot10").ok());
let readdir = otry!(Path::new(&root).join("lib").read_dir().ok());
let max_libdir = otry!(readdir.filter_map(|dir| {
dir.ok()
}).map(|dir| {
dir.path()
}).filter(|dir| {
dir.components().last().and_then(|c| {
c.as_os_str().to_str()
}).map(|c| {
c.starts_with("10.") && dir.join("ucrt").is_dir()
}).unwrap_or(false)
}).max());
let version = max_libdir.components().last().unwrap();
let version = version.as_os_str().to_str().unwrap().to_string();
Some((root.into(), version))
}
// Vcvars finds the correct version of the Windows 10 SDK by looking
// for the include `um\Windows.h` because sometimes a given version will
// only have UCRT bits without the rest of the SDK. Since we only care about
// libraries and not includes, we instead look for `um\x64\kernel32.lib`.
// Since the 32-bit and 64-bit libraries are always installed together we
// only need to bother checking x64, making this code a tiny bit simpler.
// Like we do for the Universal CRT, we sort the possibilities
// asciibetically to find the newest one as that is what vcvars does.
fn get_sdk10_dir() -> Option<(PathBuf, String)> {
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
let root = otry!(key.query_str("InstallationFolder").ok());
let readdir = otry!(Path::new(&root).join("lib").read_dir().ok());
let mut dirs = readdir.filter_map(|dir| dir.ok())
.map(|dir| dir.path())
.collect::<Vec<_>>();
dirs.sort();
let dir = otry!(dirs.into_iter().rev().filter(|dir| {
dir.join("um").join("x64").join("kernel32.lib").is_file()
}).next());
let version = dir.components().last().unwrap();
let version = version.as_os_str().to_str().unwrap().to_string();
Some((root.into(), version))
}
// Interestingly there are several subdirectories, `win7` `win8` and
// `winv6.3`. Vcvars seems to only care about `winv6.3` though, so the same
// applies to us. Note that if we were targetting kernel mode drivers
// instead of user mode applications, we would care.
fn get_sdk81_dir() -> Option<PathBuf> {
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
let root = otry!(key.query_str("InstallationFolder").ok());
Some(root.into())
}
fn get_sdk8_dir() -> Option<PathBuf> {
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
let root = otry!(key.query_str("InstallationFolder").ok());
Some(root.into())
}
const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0;
const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9;
const X86: u16 = PROCESSOR_ARCHITECTURE_INTEL;
const X86_64: u16 = PROCESSOR_ARCHITECTURE_AMD64;
// When choosing the tool to use, we have to choose the one which matches
// the target architecture. Otherwise we end up in situations where someone
// on 32-bit Windows is trying to cross compile to 64-bit and it tries to
// invoke the native 64-bit compiler which won't work.
//
// For the return value of this function, the first member of the tuple is
// the folder of the tool we will be invoking, while the second member is
// the folder of the host toolchain for that tool which is essential when
// using a cross linker. We return a Vec since on x64 there are often two
// linkers that can target the architecture we desire. The 64-bit host
// linker is preferred, and hence first, due to 64-bit allowing it more
// address space to work with and potentially being faster.
fn bin_subdir(target: &str) -> Vec<(&'static str, &'static str)> {
let arch = target.split('-').next().unwrap();
match (arch, host_arch()) {
("i586", X86) |
("i686", X86) => vec![("", "")],
("i586", X86_64) |
("i686", X86_64) => vec![("amd64_x86", "amd64"), ("", "")],
("x86_64", X86) => vec![("x86_amd64", "")],
("x86_64", X86_64) => vec![("amd64", "amd64"), ("x86_amd64", "")],
("arm", X86) => vec![("x86_arm", "")],
("arm", X86_64) => vec![("amd64_arm", "amd64"), ("x86_arm", "")],
_ => vec![],
}
}
fn lib_subdir(target: &str) -> Option<&'static str> {
let arch = target.split('-').next().unwrap();
match arch {
"i586" | "i686" => Some("x86"),
"x86_64" => Some("x64"),
"arm" => Some("arm"),
_ => None,
}
}
// MSVC's x86 libraries are not in a subfolder
fn vc_lib_subdir(target: &str) -> Option<&'static str> {
let arch = target.split('-').next().unwrap();
match arch {
"i586" | "i686" => Some(""),
"x86_64" => Some("amd64"),
"arm" => Some("arm"),
_ => None,
}
}
#[allow(bad_style)]
fn host_arch() -> u16 {
type DWORD = u32;
type WORD = u16;
type LPVOID = *mut u8;
type DWORD_PTR = usize;
#[repr(C)]
struct SYSTEM_INFO {
wProcessorArchitecture: WORD,
_wReserved: WORD,
_dwPageSize: DWORD,
_lpMinimumApplicationAddress: LPVOID,
_lpMaximumApplicationAddress: LPVOID,
_dwActiveProcessorMask: DWORD_PTR,
_dwNumberOfProcessors: DWORD,
_dwProcessorType: DWORD,
_dwAllocationGranularity: DWORD,
_wProcessorLevel: WORD,
_wProcessorRevision: WORD,
}
extern "system" {
fn GetNativeSystemInfo(lpSystemInfo: *mut SYSTEM_INFO);
}
unsafe {
let mut info = mem::zeroed();
GetNativeSystemInfo(&mut info);
info.wProcessorArchitecture
}
}
// Given a registry key, look at all the sub keys and find the one which has
// the maximal numeric value.
//
// Returns the name of the maximal key as well as the opened maximal key.
fn max_version(key: &RegistryKey) -> Option<(OsString, RegistryKey)> {
let mut max_vers = 0;
let mut max_key = None;
for subkey in key.iter().filter_map(|k| k.ok()) {
let val = subkey.to_str().and_then(|s| {
s.trim_left_matches("v").replace(".", "").parse().ok()
});
let val = match val {
Some(s) => s,
None => continue,
};
if val > max_vers {
if let Ok(k) = key.open(&subkey) {
max_vers = val;
max_key = Some((subkey, k));
}
}
}
return max_key
}
// see http://stackoverflow.com/questions/328017/path-to-msbuild
fn find_msbuild(target: &str) -> Option<Tool> {
let key = r"SOFTWARE\Microsoft\MSBuild\ToolsVersions";
LOCAL_MACHINE.open(key.as_ref()).ok().and_then(|key| {
max_version(&key).and_then(|(_vers, key)| {
key.query_str("MSBuildToolsPath").ok()
})
}).map(|path| {
let mut path = PathBuf::from(path);
path.push("MSBuild.exe");
let mut tool = Tool::new(path);
if target.contains("x86_64") {
tool.env.push(("Platform".into(), "X64".into()));
}
tool
})
}
}

49
src/vendor/gcc/tests/cc_env.rs vendored Normal file
View File

@ -0,0 +1,49 @@
extern crate tempdir;
extern crate gcc;
use std::env;
mod support;
use support::Test;
#[test]
fn main() {
ccache();
distcc();
ccache_spaces();
}
fn ccache() {
let test = Test::gnu();
test.shim("ccache");
env::set_var("CC", "ccache lol-this-is-not-a-compiler foo");
test.gcc().file("foo.c").compile("libfoo.a");
test.cmd(0)
.must_have("lol-this-is-not-a-compiler foo")
.must_have("foo.c")
.must_not_have("ccache");
}
fn ccache_spaces() {
let test = Test::gnu();
test.shim("ccache");
env::set_var("CC", "ccache lol-this-is-not-a-compiler foo");
test.gcc().file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("lol-this-is-not-a-compiler foo");
}
fn distcc() {
let test = Test::gnu();
test.shim("distcc");
env::set_var("CC", "distcc lol-this-is-not-a-compiler foo");
test.gcc().file("foo.c").compile("libfoo.a");
test.cmd(0)
.must_have("lol-this-is-not-a-compiler foo")
.must_have("foo.c")
.must_not_have("distcc");
}

111
src/vendor/gcc/tests/support/mod.rs vendored Normal file
View File

@ -0,0 +1,111 @@
#![allow(dead_code)]
use std::env;
use std::ffi::OsStr;
use std::fs::{self, File};
use std::io::prelude::*;
use std::path::PathBuf;
use gcc;
use tempdir::TempDir;
pub struct Test {
pub td: TempDir,
pub gcc: PathBuf,
pub msvc: bool,
}
pub struct Execution {
args: Vec<String>,
}
impl Test {
pub fn new() -> Test {
let mut gcc = PathBuf::from(env::current_exe().unwrap());
gcc.pop();
gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX));
Test {
td: TempDir::new("gcc-test").unwrap(),
gcc: gcc,
msvc: false,
}
}
pub fn gnu() -> Test {
let t = Test::new();
t.shim("cc").shim("ar");
return t
}
pub fn msvc() -> Test {
let mut t = Test::new();
t.shim("cl").shim("lib.exe");
t.msvc = true;
return t
}
pub fn shim(&self, name: &str) -> &Test {
let fname = format!("{}{}", name, env::consts::EXE_SUFFIX);
fs::hard_link(&self.gcc, self.td.path().join(&fname)).or_else(|_| {
fs::copy(&self.gcc, self.td.path().join(&fname)).map(|_| ())
}).unwrap();
self
}
pub fn gcc(&self) -> gcc::Config {
let mut cfg = gcc::Config::new();
let mut path = env::split_paths(&env::var_os("PATH").unwrap())
.collect::<Vec<_>>();
path.insert(0, self.td.path().to_owned());
let target = if self.msvc {
"x86_64-pc-windows-msvc"
} else {
"x86_64-unknown-linux-gnu"
};
cfg.target(target).host(target)
.opt_level(2)
.debug(false)
.out_dir(self.td.path())
.__set_env("PATH", env::join_paths(path).unwrap())
.__set_env("GCCTEST_OUT_DIR", self.td.path());
if self.msvc {
cfg.compiler(self.td.path().join("cl"));
cfg.archiver(self.td.path().join("lib.exe"));
}
return cfg
}
pub fn cmd(&self, i: u32) -> Execution {
let mut s = String::new();
File::open(self.td.path().join(format!("out{}", i))).unwrap()
.read_to_string(&mut s).unwrap();
Execution {
args: s.lines().map(|s| s.to_string()).collect(),
}
}
}
impl Execution {
pub fn must_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
if !self.has(p.as_ref()) {
panic!("didn't find {:?} in {:?}", p.as_ref(), self.args);
} else {
self
}
}
pub fn must_not_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
if self.has(p.as_ref()) {
panic!("found {:?}", p.as_ref());
} else {
self
}
}
pub fn has(&self, p: &OsStr) -> bool {
self.args.iter().any(|arg| {
OsStr::new(arg) == p
})
}
}

207
src/vendor/gcc/tests/test.rs vendored Normal file
View File

@ -0,0 +1,207 @@
extern crate gcc;
extern crate tempdir;
use support::Test;
mod support;
#[test]
fn gnu_smoke() {
let test = Test::gnu();
test.gcc()
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("-O2")
.must_have("foo.c")
.must_not_have("-g")
.must_have("-c")
.must_have("-ffunction-sections")
.must_have("-fdata-sections");
test.cmd(1).must_have(test.td.path().join("foo.o"));
}
#[test]
fn gnu_opt_level_1() {
let test = Test::gnu();
test.gcc()
.opt_level(1)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("-O1")
.must_not_have("-O2");
}
#[test]
fn gnu_opt_level_s() {
let test = Test::gnu();
test.gcc()
.opt_level_str("s")
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("-Os")
.must_not_have("-O1")
.must_not_have("-O2")
.must_not_have("-O3")
.must_not_have("-Oz");
}
#[test]
fn gnu_debug() {
let test = Test::gnu();
test.gcc()
.debug(true)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("-g");
}
#[test]
fn gnu_x86_64() {
for vendor in &["unknown-linux-gnu", "apple-darwin"] {
let target = format!("x86_64-{}", vendor);
let test = Test::gnu();
test.gcc()
.target(&target)
.host(&target)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("-fPIC")
.must_have("-m64");
}
}
#[test]
fn gnu_x86_64_no_pic() {
for vendor in &["unknown-linux-gnu", "apple-darwin"] {
let target = format!("x86_64-{}", vendor);
let test = Test::gnu();
test.gcc()
.pic(false)
.target(&target)
.host(&target)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_not_have("-fPIC");
}
}
#[test]
fn gnu_i686() {
for vendor in &["unknown-linux-gnu", "apple-darwin"] {
let target = format!("i686-{}", vendor);
let test = Test::gnu();
test.gcc()
.target(&target)
.host(&target)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_not_have("-fPIC")
.must_have("-m32");
}
}
#[test]
fn gnu_i686_pic() {
for vendor in &["unknown-linux-gnu", "apple-darwin"] {
let target = format!("i686-{}", vendor);
let test = Test::gnu();
test.gcc()
.pic(true)
.target(&target)
.host(&target)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("-fPIC");
}
}
#[test]
fn gnu_set_stdlib() {
let test = Test::gnu();
test.gcc()
.cpp_set_stdlib(Some("foo"))
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_not_have("-stdlib=foo");
}
#[test]
fn gnu_include() {
let test = Test::gnu();
test.gcc()
.include("foo/bar")
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("-I").must_have("foo/bar");
}
#[test]
fn gnu_define() {
let test = Test::gnu();
test.gcc()
.define("FOO", Some("bar"))
.define("BAR", None)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
}
#[test]
fn gnu_compile_assembly() {
let test = Test::gnu();
test.gcc()
.file("foo.S").compile("libfoo.a");
test.cmd(0).must_have("foo.S");
}
#[test]
fn msvc_smoke() {
let test = Test::msvc();
test.gcc()
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("/O2")
.must_have("foo.c")
.must_not_have("/Z7")
.must_have("/c");
test.cmd(1).must_have(test.td.path().join("foo.o"));
}
#[test]
fn msvc_opt_level_0() {
let test = Test::msvc();
test.gcc()
.opt_level(0)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_not_have("/O2");
}
#[test]
fn msvc_debug() {
let test = Test::msvc();
test.gcc()
.debug(true)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("/Z7");
}
#[test]
fn msvc_include() {
let test = Test::msvc();
test.gcc()
.include("foo/bar")
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("/I").must_have("foo/bar");
}
#[test]
fn msvc_define() {
let test = Test::msvc();
test.gcc()
.define("FOO", Some("bar"))
.define("BAR", None)
.file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR");
}

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"f01015154ac55bebd8ff25742496135c40395959f772005bdf7c63bc9b373c12","Cargo.toml":"a027aa6d21622b42c545707ba04f78341cc28079b46da775827ab1ec37fe3ca7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"4002d78e71c4e1fb82c77590eddb999371f40dce037d895f96e6d6df42c728d3","appveyor.yml":"da991211b72fa6f231af7adb84c9fb72f5a9131d1c0a3d47b8ceffe5a82c8542","src/lib.rs":"9512dd4ec1053c9fc61f630d869053ca50c55e0839e3ab7091246a8654423bf0","tests/smoke.rs":"26a95ac42e42b766ae752fe8531fb740fd147d5cdff352dec0763d175ce91806"},"package":"d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"}

0
src/vendor/getopts/.cargo-ok vendored Normal file
View File

2
src/vendor/getopts/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
/Cargo.lock

20
src/vendor/getopts/.travis.yml vendored Normal file
View File

@ -0,0 +1,20 @@
language: rust
rust:
- 1.0.0
- beta
- nightly
sudo: false
before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
script:
- cargo build --verbose
- cargo test --verbose
- cargo doc --no-deps
after_success:
- travis-cargo --only nightly doc-upload
env:
global:
secure: by+Jo/boBPbcF5c1N6RNCA008oJm2aRFE5T0SUc3OIfTXxY08dZc0WCBJCHrplp44VjpeKRp/89Y+k1CKncIeU8LiS6ZgsKqaQcCglE2O1KS90B6FYB7+rBqT3ib25taq1nW38clnBHYHV9nz4gOElSdKGRxCcBy+efQ5ZXr2tY=
notifications:
email:
on_success: never

16
src/vendor/getopts/Cargo.toml vendored Normal file
View File

@ -0,0 +1,16 @@
[package]
name = "getopts"
version = "0.2.14"
authors = ["The Rust Project Developers"]
license = "MIT/Apache-2.0"
readme = "README.md"
repository = "https://github.com/rust-lang/getopts"
documentation = "http://doc.rust-lang.org/getopts"
homepage = "https://github.com/rust-lang/getopts"
description = """
getopts-like option parsing.
"""
[dev-dependencies]
log = "0.3"

201
src/vendor/getopts/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
src/vendor/getopts/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

23
src/vendor/getopts/README.md vendored Normal file
View File

@ -0,0 +1,23 @@
getopts
===
A Rust library for option parsing for CLI utilities.
[![Build Status](https://travis-ci.org/rust-lang/getopts.svg?branch=master)](https://travis-ci.org/rust-lang/getopts)
[Documentation](http://doc.rust-lang.org/getopts)
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
getopts = "0.2.4"
```
and this to your crate root:
```rust
extern crate getopts;
```

17
src/vendor/getopts/appveyor.yml vendored Normal file
View File

@ -0,0 +1,17 @@
environment:
matrix:
- TARGET: x86_64-pc-windows-msvc
- TARGET: i686-pc-windows-msvc
- TARGET: i686-pc-windows-gnu
install:
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
- rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
- SET PATH=%PATH%;C:\MinGW\bin
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --verbose

1831
src/vendor/getopts/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff

8
src/vendor/getopts/tests/smoke.rs vendored Normal file
View File

@ -0,0 +1,8 @@
extern crate getopts;
use std::env;
#[test]
fn main() {
getopts::Options::new().parse(env::args()).unwrap();
}

1
src/vendor/libc/.cargo-checksum.json vendored Normal file

File diff suppressed because one or more lines are too long

0
src/vendor/libc/.cargo-ok vendored Normal file
View File

3
src/vendor/libc/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
target
Cargo.lock
*~

125
src/vendor/libc/.travis.yml vendored Normal file
View File

@ -0,0 +1,125 @@
language: rust
sudo: required
dist: trusty
services:
- docker
install:
- curl https://static.rust-lang.org/rustup.sh |
sh -s -- --add-target=$TARGET --disable-sudo -y --prefix=`rustc --print sysroot`
script:
- cargo build
- cargo build --no-default-features
- cargo generate-lockfile --manifest-path libc-test/Cargo.toml
- if [[ $TRAVIS_OS_NAME = "linux" ]]; then
sh ci/run-docker.sh $TARGET;
else
export CARGO_TARGET_DIR=`pwd`/target;
sh ci/run.sh $TARGET;
fi
- rustc ci/style.rs && ./style src
osx_image: xcode7.3
env:
global:
secure: eIDEoQdTyglcsTD13zSGotAX2HDhRSXIaaTnVZTThqLSrySOc3/6KY3qmOc2Msf7XaBqfFy9QA+alk7OwfePp253eiy1Kced67ffjjFOytEcRT7FlQiYpcYQD6WNHZEj62/bJBO4LTM9sGtWNCTJVEDKW0WM8mUK7qNuC+honPM=
matrix:
include:
# 1.0.0 compat
- os: linux
env: TARGET=x86_64-unknown-linux-gnu
rust: 1.0.0
script: cargo build
install:
# build documentation
- os: linux
env: TARGET=x86_64-unknown-linux-gnu
rust: stable
script: sh ci/dox.sh
# stable compat
- os: linux
env: TARGET=x86_64-unknown-linux-gnu
rust: stable
- os: linux
env: TARGET=i686-unknown-linux-gnu
rust: stable
- os: osx
env: TARGET=x86_64-apple-darwin
rust: stable
- os: osx
env: TARGET=i686-apple-darwin
rust: stable
- os: linux
env: TARGET=arm-linux-androideabi
rust: stable
- os: linux
env: TARGET=x86_64-unknown-linux-musl
rust: stable
- os: linux
env: TARGET=i686-unknown-linux-musl
rust: stable
- os: linux
env: TARGET=arm-unknown-linux-gnueabihf
rust: stable
- os: linux
env: TARGET=aarch64-unknown-linux-gnu
rust: stable
- os: osx
env: TARGET=i386-apple-ios
rust: stable
- os: osx
env: TARGET=x86_64-apple-ios
rust: stable
- os: linux
env: TARGET=x86_64-rumprun-netbsd
rust: stable
- os: linux
env: TARGET=powerpc-unknown-linux-gnu
rust: stable
- os: linux
env: TARGET=powerpc64-unknown-linux-gnu
rust: stable
- os: linux
env: TARGET=mips-unknown-linux-musl
rust: stable
- os: linux
env: TARGET=mipsel-unknown-linux-musl
rust: stable
- os: linux
env: TARGET=mips64-unknown-linux-gnuabi64
rust: nightly
# beta
- os: linux
env: TARGET=x86_64-unknown-linux-gnu
rust: beta
- os: osx
env: TARGET=x86_64-apple-darwin
rust: beta
# nightly
- os: linux
env: TARGET=x86_64-unknown-linux-gnu
rust: nightly
- os: osx
env: TARGET=x86_64-apple-darwin
rust: nightly
- os: linux
env: TARGET=mips-unknown-linux-gnu
# not sure why this has to be nightly...
rust: nightly
# QEMU based targets that compile in an emulator
- os: linux
env: TARGET=x86_64-unknown-freebsd
rust: stable
- os: linux
env: TARGET=x86_64-unknown-openbsd QEMU=openbsd.qcow2
rust: stable
script: sh ci/run-docker.sh $TARGET
install:
notifications:
email:
on_success: never
webhooks: https://buildbot.rust-lang.org/homu/travis

21
src/vendor/libc/Cargo.toml vendored Normal file
View File

@ -0,0 +1,21 @@
[package]
name = "libc"
version = "0.2.17"
authors = ["The Rust Project Developers"]
license = "MIT/Apache-2.0"
readme = "README.md"
repository = "https://github.com/rust-lang/libc"
homepage = "https://github.com/rust-lang/libc"
documentation = "http://doc.rust-lang.org/libc"
description = """
A library for types and bindings to native C functions often found in libc or
other common platform libraries.
"""
[features]
default = ["use_std"]
use_std = []
[workspace]
members = ["libc-test", "libc-test/generate-files"]

201
src/vendor/libc/LICENSE-APACHE vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
src/vendor/libc/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

137
src/vendor/libc/README.md vendored Normal file
View File

@ -0,0 +1,137 @@
libc
====
A Rust library with native bindings to the types and functions commonly found on
various systems, including libc.
[![Build Status](https://travis-ci.org/rust-lang/libc.svg?branch=master)](https://travis-ci.org/rust-lang/libc)
[![Build status](https://ci.appveyor.com/api/projects/status/34csq3uurnw7c0rl?svg=true)](https://ci.appveyor.com/project/alexcrichton/libc)
[Documentation](#platforms-and-documentation)
## Usage
First, add the following to your `Cargo.toml`:
```toml
[dependencies]
libc = "0.2"
```
Next, add this to your crate root:
```rust
extern crate libc;
```
Currently libc by default links to the standard library, but if you would
instead like to use libc in a `#![no_std]` situation or crate you can request
this via:
```toml
[dependencies]
libc = { version = "0.2", default-features = false }
```
## What is libc?
The primary purpose of this crate is to provide all of the definitions necessary
to easily interoperate with C code (or "C-like" code) on each of the platforms
that Rust supports. This includes type definitions (e.g. `c_int`), constants
(e.g. `EINVAL`) as well as function headers (e.g. `malloc`).
This crate does not strive to have any form of compatibility across platforms,
but rather it is simply a straight binding to the system libraries on the
platform in question.
## Public API
This crate exports all underlying platform types, functions, and constants under
the crate root, so all items are accessible as `libc::foo`. The types and values
of all the exported APIs match the platform that libc is compiled for.
More detailed information about the design of this library can be found in its
[associated RFC][rfc].
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1291-promote-libc.md
## Adding an API
Want to use an API which currently isn't bound in `libc`? It's quite easy to add
one!
The internal structure of this crate is designed to minimize the number of
`#[cfg]` attributes in order to easily be able to add new items which apply
to all platforms in the future. As a result, the crate is organized
hierarchically based on platform. Each module has a number of `#[cfg]`'d
children, but only one is ever actually compiled. Each module then reexports all
the contents of its children.
This means that for each platform that libc supports, the path from a
leaf module to the root will contain all bindings for the platform in question.
Consequently, this indicates where an API should be added! Adding an API at a
particular level in the hierarchy means that it is supported on all the child
platforms of that level. For example, when adding a Unix API it should be added
to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to
`src/unix/notbsd/linux/mod.rs`.
If you're not 100% sure at what level of the hierarchy an API should be added
at, fear not! This crate has CI support which tests any binding against all
platforms supported, so you'll see failures if an API is added at the wrong
level or has different signatures across platforms.
With that in mind, the steps for adding a new API are:
1. Determine where in the module hierarchy your API should be added.
2. Add the API.
3. Send a PR to this repo.
4. Wait for CI to pass, fixing errors.
5. Wait for a merge!
### Test before you commit
We have two automated tests running on [Travis](https://travis-ci.org/rust-lang/libc):
1. [`libc-test`](https://github.com/alexcrichton/ctest)
- `cd libc-test && cargo run`
- Use the `skip_*()` functions in `build.rs` if you really need a workaround.
2. Style checker
- `rustc ci/style.rs && ./style src`
## Platforms and Documentation
The following platforms are currently tested and have documentation available:
Tested:
* [`i686-pc-windows-msvc`](https://doc.rust-lang.org/libc/i686-pc-windows-msvc/libc/)
* [`x86_64-pc-windows-msvc`](https://doc.rust-lang.org/libc/x86_64-pc-windows-msvc/libc/)
(Windows)
* [`i686-pc-windows-gnu`](https://doc.rust-lang.org/libc/i686-pc-windows-gnu/libc/)
* [`x86_64-pc-windows-gnu`](https://doc.rust-lang.org/libc/x86_64-pc-windows-gnu/libc/)
* [`i686-apple-darwin`](https://doc.rust-lang.org/libc/i686-apple-darwin/libc/)
* [`x86_64-apple-darwin`](https://doc.rust-lang.org/libc/x86_64-apple-darwin/libc/)
(OSX)
* `i686-apple-ios`
* `x86_64-apple-ios`
* [`i686-unknown-linux-gnu`](https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/)
* [`x86_64-unknown-linux-gnu`](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/)
(Linux)
* [`x86_64-unknown-linux-musl`](https://doc.rust-lang.org/libc/x86_64-unknown-linux-musl/libc/)
(Linux MUSL)
* [`aarch64-unknown-linux-gnu`](https://doc.rust-lang.org/libc/aarch64-unknown-linux-gnu/libc/)
* [`mips-unknown-linux-gnu`](https://doc.rust-lang.org/libc/mips-unknown-linux-gnu/libc/)
* [`arm-unknown-linux-gnueabihf`](https://doc.rust-lang.org/libc/arm-unknown-linux-gnueabihf/libc/)
* [`arm-linux-androideabi`](https://doc.rust-lang.org/libc/arm-linux-androideabi/libc/)
(Android)
* [`x86_64-unknown-freebsd`](https://doc.rust-lang.org/libc/x86_64-unknown-freebsd/libc/)
* [`x86_64-unknown-openbsd`](https://doc.rust-lang.org/libc/x86_64-unknown-openbsd/libc/)
* [`x86_64-rumprun-netbsd`](https://doc.rust-lang.org/libc/x86_64-unknown-netbsd/libc/)
The following may be supported, but are not guaranteed to always work:
* `i686-unknown-freebsd`
* [`x86_64-unknown-bitrig`](https://doc.rust-lang.org/libc/x86_64-unknown-bitrig/libc/)
* [`x86_64-unknown-dragonfly`](https://doc.rust-lang.org/libc/x86_64-unknown-dragonfly/libc/)
* `i686-unknown-haiku`
* `x86_64-unknown-haiku`
* [`x86_64-unknown-netbsd`](https://doc.rust-lang.org/libc/x86_64-unknown-netbsd/libc/)

25
src/vendor/libc/appveyor.yml vendored Normal file
View File

@ -0,0 +1,25 @@
environment:
matrix:
- TARGET: x86_64-pc-windows-gnu
MSYS2_BITS: 64
- TARGET: i686-pc-windows-gnu
MSYS2_BITS: 32
- TARGET: x86_64-pc-windows-msvc
- TARGET: i686-pc-windows-msvc
install:
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
- rustup-init.exe -y --default-host %TARGET%
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- if defined MSYS2_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS2_BITS%\bin
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --target %TARGET%
- cargo run --manifest-path libc-test/Cargo.toml --target %TARGET%
cache:
- target
- C:\Users\appveyor\.cargo\registry

203
src/vendor/libc/ci/README.md vendored Normal file
View File

@ -0,0 +1,203 @@
The goal of the libc crate is to have CI running everywhere to have the
strongest guarantees about the definitions that this library contains, and as a
result the CI is pretty complicated and also pretty large! Hopefully this can
serve as a guide through the sea of scripts in this directory and elsewhere in
this project.
# Files
First up, let's talk about the files in this directory:
* `run-travis.sh` - a shell script run by all Travis builders, this is
responsible for setting up the rest of the environment such as installing new
packages, downloading Rust target libraries, etc.
* `run.sh` - the actual script which runs tests for a particular architecture.
Called from the `run-travis.sh` script this will run all tests for the target
specified.
* `cargo-config` - Cargo configuration of linkers to use copied into place by
the `run-travis.sh` script before builds are run.
* `dox.sh` - script called from `run-travis.sh` on only the linux 64-bit nightly
Travis bots to build documentation for this crate.
* `landing-page-*.html` - used by `dox.sh` to generate a landing page for all
architectures' documentation.
* `run-qemu.sh` - see discussion about QEMU below
* `mips`, `rumprun` - instructions to build the docker image for each respective
CI target
# CI Systems
Currently this repository leverages a combination of Travis CI and AppVeyor for
running tests. The triples tested are:
* AppVeyor
* `{i686,x86_64}-pc-windows-{msvc,gnu}`
* Travis
* `{i686,x86_64,mips,aarch64}-unknown-linux-gnu`
* `x86_64-unknown-linux-musl`
* `arm-unknown-linux-gnueabihf`
* `arm-linux-androideabi`
* `{i686,x86_64}-apple-{darwin,ios}`
* `x86_64-rumprun-netbsd`
* `x86_64-unknown-freebsd`
* `x86_64-unknown-openbsd`
The Windows triples are all pretty standard, they just set up their environment
then run tests, no need for downloading any extra target libs (we just download
the right installer). The Intel Linux/OSX builds are similar in that we just
download the right target libs and run tests. Note that the Intel Linux/OSX
builds are run on stable/beta/nightly, but are the only ones that do so.
The remaining architectures look like:
* Android runs in a [docker image][android-docker] with an emulator, the NDK,
and the SDK already set up. The entire build happens within the docker image.
* The MIPS, ARM, and AArch64 builds all use the QEMU userspace emulator to run
the generated binary to actually verify the tests pass.
* The MUSL build just has to download a MUSL compiler and target libraries and
then otherwise runs tests normally.
* iOS builds need an extra linker flag currently, but beyond that they're built
as standard as everything else.
* The rumprun target builds an entire kernel from the test suite and then runs
it inside QEMU using the serial console to test whether it succeeded or
failed.
* The BSD builds, currently OpenBSD and FreeBSD, use QEMU to boot up a system
and compile/run tests. More information on that below.
[android-docker]: https://github.com/rust-lang/rust-buildbot/blob/master/slaves/android/Dockerfile
## QEMU
Lots of the architectures tested here use QEMU in the tests, so it's worth going
over all the crazy capabilities QEMU has and the various flavors in which we use
it!
First up, QEMU has userspace emulation where it doesn't boot a full kernel, it
just runs a binary from another architecture (using the `qemu-<arch>` wrappers).
We provide it the runtime path for the dynamically loaded system libraries,
however. This strategy is used for all Linux architectures that aren't intel.
Note that one downside of this QEMU system is that threads are barely
implemented, so we're careful to not spawn many threads.
For the rumprun target the only output is a kernel image, so we just use that
plus the `rumpbake` command to create a full kernel image which is then run from
within QEMU.
Finally, the fun part, the BSDs. Quite a few hoops are jumped through to get CI
working for these platforms, but the gist of it looks like:
* Cross compiling from Linux to any of the BSDs seems to be quite non-standard.
We may be able to get it working but it might be difficult at that point to
ensure that the libc definitions align with what you'd get on the BSD itself.
As a result, we try to do compiles within the BSD distro.
* On Travis we can't run a VM-in-a-VM, so we resort to userspace emulation
(QEMU).
* Unfortunately on Travis we also can't use KVM, so the emulation is super slow.
With all that in mind, the way BSD is tested looks like:
1. Download a pre-prepared image for the OS being tested.
2. Generate the tests for the OS being tested. This involves running the `ctest`
library over libc to generate a Rust file and a C file which will then be
compiled into the final test.
3. Generate a disk image which will later be mounted by the OS being tested.
This image is mostly just the libc directory, but some modifications are made
to compile the generated files from step 2.
4. The kernel is booted in QEMU, and it is configured to detect the libc-test
image being available, run the test script, and then shut down afterwards.
5. Look for whether the tests passed in the serial console output of the kernel.
There's some pretty specific instructions for setting up each image (detailed
below), but the main gist of this is that we must avoid a vanilla `cargo run`
inside of the `libc-test` directory (which is what it's intended for) because
that would compile `syntex_syntax`, a large library, with userspace emulation.
This invariably times out on Travis, so we can't do that.
Once all those hoops are jumped through, however, we can be happy that we're
testing almost everything!
Below are some details of how to set up the initial OS images which are
downloaded. Each image must be enabled have input/output over the serial
console, log in automatically at the serial console, detect if a second drive in
QEMU is available, and if so mount it, run a script (it'll specifically be
`run-qemu.sh` in this folder which is copied into the generated image talked
about above), and then shut down.
### QEMU setup - FreeBSD
1. Download CD installer (most minimal is fine)
2. `qemu-img create -f qcow2 foo.qcow2 2G`
3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user`
4. run installer
5. `echo 'console="comconsole"' >> /boot/loader.conf`
6. `echo 'autoboot_delay="0"' >> /boot/loader.conf`
7. look at /etc/ttys, see what getty argument is for ttyu0
8. edit /etc/gettytab, look for ttyu0 argument, prepend `:al=root` to line
beneath
(note that the current image has a `freebsd` user, but this isn't really
necessary)
Once that's done, arrange for this script to run at login:
```
#!/bin/sh
sudo kldload ext2fs
[ -e /dev/vtbd1 ] || exit 0
sudo mount -t ext2fs /dev/vtbd1 /mnt
sh /mnt/run.sh /mnt
sudo poweroff
```
Helpful links
* https://en.wikibooks.org/wiki/QEMU/Images
* https://blog.nekoconeko.nl/blog/2015/06/04/creating-an-openstack-freebsd-image.html
* https://www.freebsd.org/doc/handbook/serialconsole-setup.html
### QEMU setup - OpenBSD
1. Download CD installer
2. `qemu-img create -f qcow2 foo.qcow2 2G`
3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user`
4. run installer
5. `echo 'set tty com0' >> /etc/boot.conf`
6. `echo 'boot' >> /etc/boot.conf`
7. Modify /etc/ttys, change the `tty00` at the end from 'unknown off' to
'vt220 on secure'
8. Modify same line in /etc/ttys to have `"/root/foo.sh"` as the shell
9. Add this script to `/root/foo.sh`
```
#!/bin/sh
exec 1>/dev/tty00
exec 2>&1
if mount -t ext2fs /dev/sd1c /mnt; then
sh /mnt/run.sh /mnt
shutdown -ph now
fi
# limited shell...
exec /bin/sh < /dev/tty00
```
10. `chmod +x /root/foo.sh`
Helpful links:
* https://en.wikibooks.org/wiki/QEMU/Images
* http://www.openbsd.org/faq/faq7.html#SerCon
# Questions?
Hopefully that's at least somewhat of an introduction to everything going on
here, and feel free to ping @alexcrichton with questions!

View File

@ -0,0 +1,7 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev ca-certificates \
gcc-aarch64-linux-gnu libc6-dev-arm64-cross qemu-user
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
PATH=$PATH:/rust/bin

View File

@ -0,0 +1,4 @@
FROM alexcrichton/rust-slave-android:2015-11-22
ENV CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \
PATH=$PATH:/rust/bin
ENTRYPOINT ["sh"]

View File

@ -0,0 +1,7 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev ca-certificates \
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user
ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \
PATH=$PATH:/rust/bin

View File

@ -0,0 +1,5 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc-multilib libc6-dev ca-certificates
ENV PATH=$PATH:/rust/bin

View File

@ -0,0 +1,22 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc make libc6-dev git curl ca-certificates
# Below we're cross-compiling musl for i686 using the system compiler on an
# x86_64 system. This is an awkward thing to be doing and so we have to jump
# through a couple hoops to get musl to be happy. In particular:
#
# * We specifically pass -m32 in CFLAGS and override CC when running ./configure,
# since otherwise the script will fail to find a compiler.
# * We manually unset CROSS_COMPILE when running make; otherwise the makefile
# will call the non-existent binary 'i686-ar'.
RUN curl https://www.musl-libc.org/releases/musl-1.1.15.tar.gz | \
tar xzf - && \
cd musl-1.1.15 && \
CC=gcc CFLAGS=-m32 ./configure --prefix=/musl-i686 --disable-shared --target=i686 && \
make CROSS_COMPILE= install -j4 && \
cd .. && \
rm -rf musl-1.1.15
ENV PATH=$PATH:/musl-i686/bin:/rust/bin \
CC_i686_unknown_linux_musl=musl-gcc

View File

@ -0,0 +1,10 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev qemu-user ca-certificates \
gcc-mips-linux-gnu libc6-dev-mips-cross \
qemu-system-mips
ENV CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER=mips-linux-gnu-gcc \
PATH=$PATH:/rust/bin

View File

@ -0,0 +1,14 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev qemu-user ca-certificates qemu-system-mips curl \
bzip2
RUN mkdir /toolchain
RUN curl -L https://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/OpenWrt-SDK-ar71xx-generic_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 | \
tar xjf - -C /toolchain --strip-components=1
ENV PATH=$PATH:/rust/bin:/toolchain/staging_dir/toolchain-mips_34kc_gcc-5.3.0_musl-1.1.15/bin \
CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \
CARGO_TARGET_MIPS_UNKNOWN_LINUX_MUSL_LINKER=mips-openwrt-linux-gcc

View File

@ -0,0 +1,11 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev qemu-user ca-certificates \
gcc-mips64-linux-gnuabi64 libc6-dev-mips64-cross \
qemu-system-mips64
ENV CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_LINKER=mips64-linux-gnuabi64-gcc \
CC_mips64_unknown_linux_gnuabi64=mips64-linux-gnuabi64-gcc \
PATH=$PATH:/rust/bin

View File

@ -0,0 +1,14 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev qemu-user ca-certificates qemu-system-mips curl \
bzip2
RUN mkdir /toolchain
RUN curl -L https://downloads.openwrt.org/snapshots/trunk/malta/generic/OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 | \
tar xjf - -C /toolchain --strip-components=2
ENV PATH=$PATH:/rust/bin:/toolchain/bin \
CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_MUSL_LINKER=mipsel-openwrt-linux-gcc

View File

@ -0,0 +1,10 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev qemu-user ca-certificates \
gcc-powerpc-linux-gnu libc6-dev-powerpc-cross \
qemu-system-ppc
ENV CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_LINKER=powerpc-linux-gnu-gcc \
PATH=$PATH:/rust/bin

View File

@ -0,0 +1,11 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev qemu-user ca-certificates \
gcc-powerpc64-linux-gnu libc6-dev-ppc64-cross \
qemu-system-ppc
ENV CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_LINKER=powerpc64-linux-gnu-gcc \
CC=powerpc64-linux-gnu-gcc \
PATH=$PATH:/rust/bin

View File

@ -0,0 +1,6 @@
FROM mato/rumprun-toolchain-hw-x86_64
USER root
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
qemu
ENV PATH=$PATH:/rust/bin

View File

@ -0,0 +1,13 @@
FROM alexcrichton/rust-slave-linux-cross:2016-04-15
USER root
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
qemu genext2fs
ENTRYPOINT ["sh"]
ENV PATH=$PATH:/rust/bin \
QEMU=freebsd.qcow2.gz \
CAN_CROSS=1 \
CARGO_TARGET_X86_64_UNKNOWN_FREEBSD_LINKER=x86_64-unknown-freebsd10-gcc

View File

@ -0,0 +1,5 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev ca-certificates
ENV PATH=$PATH:/rust/bin

View File

@ -0,0 +1,13 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc make libc6-dev git curl ca-certificates
RUN curl https://www.musl-libc.org/releases/musl-1.1.15.tar.gz | \
tar xzf - && \
cd musl-1.1.15 && \
./configure --prefix=/musl-x86_64 && \
make install -j4 && \
cd .. && \
rm -rf musl-1.1.15
ENV PATH=$PATH:/musl-x86_64/bin:/rust/bin

View File

@ -0,0 +1,8 @@
FROM ubuntu:16.10
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
gcc libc6-dev qemu curl ca-certificates \
genext2fs
ENV PATH=$PATH:/rust/bin \
QEMU=2016-09-07/openbsd-6.0-without-pkgs.qcow2

33
src/vendor/libc/ci/dox.sh vendored Normal file
View File

@ -0,0 +1,33 @@
#!/bin/sh
# Builds documentation for all target triples that we have a registered URL for
# in liblibc. This scrapes the list of triples to document from `src/lib.rs`
# which has a bunch of `html_root_url` directives we pick up.
set -e
TARGETS=`grep html_root_url src/lib.rs | sed 's/.*".*\/\(.*\)"/\1/'`
rm -rf target/doc
mkdir -p target/doc
cp ci/landing-page-head.html target/doc/index.html
for target in $TARGETS; do
echo documenting $target
rustdoc -o target/doc/$target --target $target src/lib.rs --cfg dox \
--crate-name libc
echo "<li><a href="/libc/$target/libc/index.html">$target</a></li>" \
>> target/doc/index.html
done
cat ci/landing-page-footer.html >> target/doc/index.html
# If we're on travis, not a PR, and on the right branch, publish!
if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_BRANCH" = "master" ]; then
pip install ghp-import --user $USER
$HOME/.local/bin/ghp-import -n target/doc
git push -qf https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
fi

View File

@ -0,0 +1,3 @@
</ul>
</body>
</html>

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<ul>

Some files were not shown because too many files have changed in this diff Show More