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:
commit
3d2ffa06ea
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -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
1
.gitignore
vendored
@ -98,3 +98,4 @@ tmp.*.rs
|
||||
version.md
|
||||
version.ml
|
||||
version.texi
|
||||
.cargo
|
||||
|
@ -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
1
configure
vendored
@ -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"
|
||||
|
@ -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
69
src/Cargo.lock
generated
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
# =============================================================================
|
||||
|
@ -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
|
||||
|
@ -460,6 +460,9 @@ impl Build {
|
||||
if self.config.rust_optimize {
|
||||
cargo.arg("--release");
|
||||
}
|
||||
if self.config.vendor {
|
||||
cargo.arg("--frozen");
|
||||
}
|
||||
return cargo
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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) {
|
||||
|
@ -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") {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
@ -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
1
src/vendor/cmake/.cargo-checksum.json
vendored
Normal 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
0
src/vendor/cmake/.cargo-ok
vendored
Normal file
2
src/vendor/cmake/.gitignore
vendored
Normal file
2
src/vendor/cmake/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/target
|
||||
/Cargo.lock
|
19
src/vendor/cmake/.travis.yml
vendored
Normal file
19
src/vendor/cmake/.travis.yml
vendored
Normal 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
17
src/vendor/cmake/Cargo.toml
vendored
Normal 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
201
src/vendor/cmake/LICENSE-APACHE
vendored
Normal 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
25
src/vendor/cmake/LICENSE-MIT
vendored
Normal 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
22
src/vendor/cmake/README.md
vendored
Normal 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
522
src/vendor/cmake/src/lib.rs
vendored
Normal 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(¶llel_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
84
src/vendor/cmake/src/registry.rs
vendored
Normal 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); }
|
||||
}
|
||||
}
|
1
src/vendor/env_logger/.cargo-checksum.json
vendored
Normal file
1
src/vendor/env_logger/.cargo-checksum.json
vendored
Normal 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
0
src/vendor/env_logger/.cargo-ok
vendored
Normal file
23
src/vendor/env_logger/Cargo.toml
vendored
Normal file
23
src/vendor/env_logger/Cargo.toml
vendored
Normal 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
623
src/vendor/env_logger/src/lib.rs
vendored
Normal 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
28
src/vendor/env_logger/src/regex.rs
vendored
Normal 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
21
src/vendor/env_logger/src/string.rs
vendored
Normal 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)
|
||||
}
|
||||
}
|
51
src/vendor/env_logger/tests/regexp_filter.rs
vendored
Normal file
51
src/vendor/env_logger/tests/regexp_filter.rs
vendored
Normal 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");
|
||||
}
|
1
src/vendor/filetime/.cargo-checksum.json
vendored
Normal file
1
src/vendor/filetime/.cargo-checksum.json
vendored
Normal 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
0
src/vendor/filetime/.cargo-ok
vendored
Normal file
2
src/vendor/filetime/.gitignore
vendored
Normal file
2
src/vendor/filetime/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
target
|
||||
Cargo.lock
|
26
src/vendor/filetime/.travis.yml
vendored
Normal file
26
src/vendor/filetime/.travis.yml
vendored
Normal 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
19
src/vendor/filetime/Cargo.toml
vendored
Normal 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
201
src/vendor/filetime/LICENSE-APACHE
vendored
Normal 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
25
src/vendor/filetime/LICENSE-MIT
vendored
Normal 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
25
src/vendor/filetime/README.md
vendored
Normal 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
17
src/vendor/filetime/appveyor.yml
vendored
Normal 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
305
src/vendor/filetime/src/lib.rs
vendored
Normal 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
1
src/vendor/gcc/.cargo-checksum.json
vendored
Normal 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
0
src/vendor/gcc/.cargo-ok
vendored
Normal file
2
src/vendor/gcc/.gitignore
vendored
Normal file
2
src/vendor/gcc/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
target
|
||||
Cargo.lock
|
40
src/vendor/gcc/.travis.yml
vendored
Normal file
40
src/vendor/gcc/.travis.yml
vendored
Normal 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
23
src/vendor/gcc/Cargo.toml
vendored
Normal 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
201
src/vendor/gcc/LICENSE-APACHE
vendored
Normal 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
25
src/vendor/gcc/LICENSE-MIT
vendored
Normal 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
161
src/vendor/gcc/README.md
vendored
Normal 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
35
src/vendor/gcc/appveyor.yml
vendored
Normal 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
23
src/vendor/gcc/src/bin/gcc-shim.rs
vendored
Normal 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
959
src/vendor/gcc/src/lib.rs
vendored
Normal 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
169
src/vendor/gcc/src/registry.rs
vendored
Normal 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
425
src/vendor/gcc/src/windows_registry.rs
vendored
Normal 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
49
src/vendor/gcc/tests/cc_env.rs
vendored
Normal 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
111
src/vendor/gcc/tests/support/mod.rs
vendored
Normal 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
207
src/vendor/gcc/tests/test.rs
vendored
Normal 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");
|
||||
}
|
1
src/vendor/getopts/.cargo-checksum.json
vendored
Normal file
1
src/vendor/getopts/.cargo-checksum.json
vendored
Normal 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
0
src/vendor/getopts/.cargo-ok
vendored
Normal file
2
src/vendor/getopts/.gitignore
vendored
Normal file
2
src/vendor/getopts/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/target
|
||||
/Cargo.lock
|
20
src/vendor/getopts/.travis.yml
vendored
Normal file
20
src/vendor/getopts/.travis.yml
vendored
Normal 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
16
src/vendor/getopts/Cargo.toml
vendored
Normal 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
201
src/vendor/getopts/LICENSE-APACHE
vendored
Normal 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
25
src/vendor/getopts/LICENSE-MIT
vendored
Normal 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
23
src/vendor/getopts/README.md
vendored
Normal 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
17
src/vendor/getopts/appveyor.yml
vendored
Normal 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
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
8
src/vendor/getopts/tests/smoke.rs
vendored
Normal 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
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
0
src/vendor/libc/.cargo-ok
vendored
Normal file
3
src/vendor/libc/.gitignore
vendored
Normal file
3
src/vendor/libc/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
target
|
||||
Cargo.lock
|
||||
*~
|
125
src/vendor/libc/.travis.yml
vendored
Normal file
125
src/vendor/libc/.travis.yml
vendored
Normal 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
21
src/vendor/libc/Cargo.toml
vendored
Normal 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
201
src/vendor/libc/LICENSE-APACHE
vendored
Normal 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
25
src/vendor/libc/LICENSE-MIT
vendored
Normal 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
137
src/vendor/libc/README.md
vendored
Normal 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
25
src/vendor/libc/appveyor.yml
vendored
Normal 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
203
src/vendor/libc/ci/README.md
vendored
Normal 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!
|
||||
|
7
src/vendor/libc/ci/docker/aarch64-unknown-linux-gnu/Dockerfile
vendored
Normal file
7
src/vendor/libc/ci/docker/aarch64-unknown-linux-gnu/Dockerfile
vendored
Normal 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
|
4
src/vendor/libc/ci/docker/arm-linux-androideabi/Dockerfile
vendored
Normal file
4
src/vendor/libc/ci/docker/arm-linux-androideabi/Dockerfile
vendored
Normal 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"]
|
7
src/vendor/libc/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile
vendored
Normal file
7
src/vendor/libc/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile
vendored
Normal 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
|
5
src/vendor/libc/ci/docker/i686-unknown-linux-gnu/Dockerfile
vendored
Normal file
5
src/vendor/libc/ci/docker/i686-unknown-linux-gnu/Dockerfile
vendored
Normal 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
|
22
src/vendor/libc/ci/docker/i686-unknown-linux-musl/Dockerfile
vendored
Normal file
22
src/vendor/libc/ci/docker/i686-unknown-linux-musl/Dockerfile
vendored
Normal 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
|
10
src/vendor/libc/ci/docker/mips-unknown-linux-gnu/Dockerfile
vendored
Normal file
10
src/vendor/libc/ci/docker/mips-unknown-linux-gnu/Dockerfile
vendored
Normal 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
|
14
src/vendor/libc/ci/docker/mips-unknown-linux-musl/Dockerfile
vendored
Normal file
14
src/vendor/libc/ci/docker/mips-unknown-linux-musl/Dockerfile
vendored
Normal 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
|
11
src/vendor/libc/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile
vendored
Normal file
11
src/vendor/libc/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile
vendored
Normal 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
|
14
src/vendor/libc/ci/docker/mipsel-unknown-linux-musl/Dockerfile
vendored
Normal file
14
src/vendor/libc/ci/docker/mipsel-unknown-linux-musl/Dockerfile
vendored
Normal 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
|
10
src/vendor/libc/ci/docker/powerpc-unknown-linux-gnu/Dockerfile
vendored
Normal file
10
src/vendor/libc/ci/docker/powerpc-unknown-linux-gnu/Dockerfile
vendored
Normal 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
|
11
src/vendor/libc/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile
vendored
Normal file
11
src/vendor/libc/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile
vendored
Normal 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
|
6
src/vendor/libc/ci/docker/x86_64-rumprun-netbsd/Dockerfile
vendored
Normal file
6
src/vendor/libc/ci/docker/x86_64-rumprun-netbsd/Dockerfile
vendored
Normal 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
|
13
src/vendor/libc/ci/docker/x86_64-unknown-freebsd/Dockerfile
vendored
Normal file
13
src/vendor/libc/ci/docker/x86_64-unknown-freebsd/Dockerfile
vendored
Normal 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
|
5
src/vendor/libc/ci/docker/x86_64-unknown-linux-gnu/Dockerfile
vendored
Normal file
5
src/vendor/libc/ci/docker/x86_64-unknown-linux-gnu/Dockerfile
vendored
Normal 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
|
13
src/vendor/libc/ci/docker/x86_64-unknown-linux-musl/Dockerfile
vendored
Normal file
13
src/vendor/libc/ci/docker/x86_64-unknown-linux-musl/Dockerfile
vendored
Normal 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
|
8
src/vendor/libc/ci/docker/x86_64-unknown-openbsd/Dockerfile
vendored
Normal file
8
src/vendor/libc/ci/docker/x86_64-unknown-openbsd/Dockerfile
vendored
Normal 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
33
src/vendor/libc/ci/dox.sh
vendored
Normal 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
|
3
src/vendor/libc/ci/landing-page-footer.html
vendored
Normal file
3
src/vendor/libc/ci/landing-page-footer.html
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
7
src/vendor/libc/ci/landing-page-head.html
vendored
Normal file
7
src/vendor/libc/ci/landing-page-head.html
vendored
Normal 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
Loading…
Reference in New Issue
Block a user