mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1716518 - Upgrade cc to v1.0.68. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D117771
This commit is contained in:
parent
3177d195f4
commit
cf1e29b146
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -506,9 +506,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.59"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381"
|
||||
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
]
|
||||
|
2
third_party/rust/cc/.cargo-checksum.json
vendored
2
third_party/rust/cc/.cargo-checksum.json
vendored
@ -1 +1 @@
|
||||
{"files":{"Cargo.lock":"bd34a585a35969291c78b96b1f239fa09f1f9dbeee48474989695def1ed64052","Cargo.toml":"cb73923110f764c2a6da0fde98db8f5f7c7194bd56e96e2f302da9ba29cba0a8","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"68fe1bc9f8aab4d8d195e8bc39fe76562742dc392f5c490e5404e01463100277","src/bin/gcc-shim.rs":"b77907875029494b6288841c3aed2e4939ed40708c7f597fca5c9e2570490ca6","src/com.rs":"bcdaf1c28b71e6ef889c6b08d1ce9d7c0761344a677f523bc4c3cd297957f804","src/lib.rs":"96f4782c70e0bd8d9ab7ce3efcc2091d2591c3276c0ed672e2379748bb3930aa","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"7014103587d3382eac599cb76f016e2609b8140970861b2237982d1db24af265","src/winapi.rs":"ea8b7edbb9ff87957254f465c2334e714c5d6b3b19a8d757c48ea7ca0881c50c","src/windows_registry.rs":"52afe8554f577c87841c48ddee3ba7ffe70a00129e1d6eeb2ec0efb3d2b9aa11","tests/cc_env.rs":"e02b3b0824ad039b47e4462c5ef6dbe6c824c28e7953af94a0f28f7b5158042e","tests/cflags.rs":"57f06eb5ce1557e5b4a032d0c4673e18fbe6f8d26c1deb153126e368b96b41b3","tests/cxxflags.rs":"c2c6c6d8a0d7146616fa1caed26876ee7bc9fcfffd525eb4743593cade5f3371","tests/support/mod.rs":"16274867f23871e9b07614eda4c7344da13d1751fed63d4f633857e40be86394","tests/test.rs":"65c073e0e2cf4aa0433066102788e9f57442719e6f32f5ad5248aa7132bb4597"},"package":"66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381"}
|
||||
{"files":{"Cargo.lock":"24720bf62cfad67ca24dfc9192a8f1c11a0f262655c087795605f188cee5c5f0","Cargo.toml":"84ef3b052c7b9ba469573df3ee45d89d426f2cd30d350f43198f115b9c5691fc","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"9916275542d23bfa0815b1f48d4546e514739fadc79775500de6a81cf17aac09","src/bin/gcc-shim.rs":"b77907875029494b6288841c3aed2e4939ed40708c7f597fca5c9e2570490ca6","src/com.rs":"bcdaf1c28b71e6ef889c6b08d1ce9d7c0761344a677f523bc4c3cd297957f804","src/lib.rs":"20d349f8528f191a4cf04a5a42daaaa8085c4e00885c78456ebada92dc39b7fb","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"7014103587d3382eac599cb76f016e2609b8140970861b2237982d1db24af265","src/vs_instances.rs":"2d3f8278a803b0e7052f4eeb1979b29f963dd0143f4458e2cb5f33c4e5f0963b","src/winapi.rs":"ea8b7edbb9ff87957254f465c2334e714c5d6b3b19a8d757c48ea7ca0881c50c","src/windows_registry.rs":"090b5de68e19dab9e1884175dc2a6866f697bd043d6b3a0d4b3836c9d6812569","tests/cc_env.rs":"e02b3b0824ad039b47e4462c5ef6dbe6c824c28e7953af94a0f28f7b5158042e","tests/cflags.rs":"57f06eb5ce1557e5b4a032d0c4673e18fbe6f8d26c1deb153126e368b96b41b3","tests/cxxflags.rs":"c2c6c6d8a0d7146616fa1caed26876ee7bc9fcfffd525eb4743593cade5f3371","tests/support/mod.rs":"16274867f23871e9b07614eda4c7344da13d1751fed63d4f633857e40be86394","tests/test.rs":"65c073e0e2cf4aa0433066102788e9f57442719e6f32f5ad5248aa7132bb4597"},"package":"4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"}
|
14
third_party/rust/cc/Cargo.lock
generated
vendored
14
third_party/rust/cc/Cargo.lock
generated
vendored
@ -2,7 +2,7 @@
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.59"
|
||||
version = "1.0.68"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"tempfile",
|
||||
@ -16,9 +16,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.14"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
@ -36,15 +36,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.74"
|
||||
version = "0.2.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
|
||||
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.8"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
|
||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
|
4
third_party/rust/cc/Cargo.toml
vendored
4
third_party/rust/cc/Cargo.toml
vendored
@ -13,9 +13,9 @@
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "cc"
|
||||
version = "1.0.59"
|
||||
version = "1.0.68"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
exclude = ["/.travis.yml", "/appveyor.yml"]
|
||||
exclude = ["/.github", "/.travis.yml", "/appveyor.yml"]
|
||||
description = "A build-time dependency for Cargo build scripts to assist in invoking the native\nC compiler to compile native C code into a static archive to be linked into Rust\ncode.\n"
|
||||
homepage = "https://github.com/alexcrichton/cc-rs"
|
||||
documentation = "https://docs.rs/cc"
|
||||
|
61
third_party/rust/cc/README.md
vendored
61
third_party/rust/cc/README.md
vendored
@ -8,9 +8,6 @@ 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. This crate calls out
|
||||
to the most relevant compiler for a platform, for example using `cl` on MSVC.
|
||||
|
||||
> **Note**: this crate was recently renamed from the `gcc` crate, so if you're
|
||||
> looking for the `gcc` crate you're in the right spot!
|
||||
|
||||
## Using cc-rs
|
||||
|
||||
First, you'll want to both add a build script for your crate (`build.rs`) and
|
||||
@ -36,19 +33,31 @@ fn main() {
|
||||
|
||||
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 a file
|
||||
named libfoo.a. You can call the functions in Rust by declaring functions in
|
||||
named `libfoo.a`. If the C files contain
|
||||
|
||||
```c
|
||||
void foo_function(void) { ... }
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```c
|
||||
int32_t bar_function(int32_t x) { ... }
|
||||
```
|
||||
|
||||
you can call them from Rust by declaring them in
|
||||
your Rust code like so:
|
||||
|
||||
```rust,no_run
|
||||
extern {
|
||||
fn foo_function();
|
||||
fn bar_function();
|
||||
fn bar_function(x: i32) -> i32;
|
||||
}
|
||||
|
||||
pub fn call() {
|
||||
unsafe {
|
||||
foo_function();
|
||||
bar_function();
|
||||
bar_function(42);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,6 +66,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
See [the Rustonomicon](https://doc.rust-lang.org/nomicon/ffi.html) for more details.
|
||||
|
||||
## External configuration via environment variables
|
||||
|
||||
To control the programs and flags used for building, the builder can set a
|
||||
@ -64,7 +75,7 @@ number of different environment variables.
|
||||
|
||||
* `CFLAGS` - a series of space separated flags passed to compilers. Note that
|
||||
individual flags cannot currently contain spaces, so doing
|
||||
something like: "-L=foo\ bar" is not possible.
|
||||
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
|
||||
@ -73,6 +84,7 @@ number of different environment variables.
|
||||
common is `-fPIC`).
|
||||
* `AR` - the `ar` (archiver) executable to use to build the static library.
|
||||
* `CRATE_CC_NO_DEFAULTS` - the default compiler flags may cause conflicts in some cross compiling scenarios. Setting this variable will disable the generation of default compiler flags.
|
||||
* `CXX...` - see [C++ Support](#c-support).
|
||||
|
||||
Each of these variables can also be supplied with certain prefixes and suffixes,
|
||||
in the following prioritized order:
|
||||
@ -89,7 +101,7 @@ 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
|
||||
[cargo]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#inputs-to-the-build-script
|
||||
|
||||
## Optional features
|
||||
|
||||
@ -116,7 +128,7 @@ 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 cc/clang on Linux distributions and Xcode on OSX, for example.
|
||||
installing cc/clang on Linux distributions and Xcode on macOS, 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
|
||||
@ -126,12 +138,12 @@ required varies per platform, but there are three broad categories:
|
||||
[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
|
||||
[MSYS2](https://www.msys2.org/), 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
|
||||
[msys2-help]: https://github.com/rust-lang/rust#building-on-windows
|
||||
|
||||
## C++ support
|
||||
|
||||
@ -147,10 +159,25 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
Remember that C++ does name mangling so `extern "C"` might be required to enable rust linker to find your functions.
|
||||
For C++ libraries, the `CXX` and `CXXFLAGS` environment variables are used instead of `CC` and `CFLAGS`.
|
||||
|
||||
The C++ standard library may be linked to the crate target. By default it's `libc++` for macOS, FreeBSD, and OpenBSD, `libc++_shared` for Android, nothing for MSVC, and `libstdc++` for anything else. It can be changed in one of two ways:
|
||||
|
||||
1. by using the `cpp_link_stdlib` method on `Build`:
|
||||
```rust,no-run
|
||||
fn main() {
|
||||
cc::Build::new()
|
||||
.cpp(true)
|
||||
.file("foo.cpp")
|
||||
.cpp_link_stdlib("stdc++") // use libstdc++
|
||||
.compile("libfoo.a");
|
||||
}
|
||||
```
|
||||
2. by setting the `CXXSTDLIB` environment variable.
|
||||
|
||||
In particular, for Android you may want to [use `c++_static` if you have at most one shared library](https://developer.android.com/ndk/guides/cpp-support).
|
||||
|
||||
Remember that C++ does name mangling so `extern "C"` might be required to enable Rust linker to find your functions.
|
||||
|
||||
## CUDA C++ support
|
||||
|
||||
@ -182,9 +209,9 @@ fn main() {
|
||||
This project is licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||
http://www.apache.org/licenses/LICENSE-2.0)
|
||||
https://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
||||
http://opensource.org/licenses/MIT)
|
||||
https://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
|
350
third_party/rust/cc/src/lib.rs
vendored
350
third_party/rust/cc/src/lib.rs
vendored
@ -78,10 +78,12 @@ mod winapi;
|
||||
mod com;
|
||||
#[cfg(windows)]
|
||||
mod setup_config;
|
||||
#[cfg(windows)]
|
||||
mod vs_instances;
|
||||
|
||||
pub mod windows_registry;
|
||||
|
||||
/// A builder for compilation of a native static library.
|
||||
/// A builder for compilation of a native library.
|
||||
///
|
||||
/// A `Build` is the main type of the `cc` crate and is used to control all the
|
||||
/// various configuration options and such of a compile. You'll find more
|
||||
@ -337,6 +339,35 @@ impl Build {
|
||||
self
|
||||
}
|
||||
|
||||
/// Add multiple directories to the `-I` include path.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use std::path::Path;
|
||||
/// # let condition = true;
|
||||
/// #
|
||||
/// let mut extra_dir = None;
|
||||
/// if condition {
|
||||
/// extra_dir = Some(Path::new("/path/to"));
|
||||
/// }
|
||||
///
|
||||
/// cc::Build::new()
|
||||
/// .file("src/foo.c")
|
||||
/// .includes(extra_dir)
|
||||
/// .compile("foo");
|
||||
/// ```
|
||||
pub fn includes<P>(&mut self, dirs: P) -> &mut Build
|
||||
where
|
||||
P: IntoIterator,
|
||||
P::Item: AsRef<Path>,
|
||||
{
|
||||
for dir in dirs {
|
||||
self.include(dir);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify a `-D` variable with an optional value.
|
||||
///
|
||||
/// # Example
|
||||
@ -655,11 +686,11 @@ impl Build {
|
||||
/// 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.
|
||||
/// See [`get_cpp_link_stdlib`](cc::Build::get_cpp_link_stdlib) documentation
|
||||
/// for the default value.
|
||||
/// If the `CXXSTDLIB` environment variable is set, its value will
|
||||
/// override the default value.
|
||||
/// override the default value, but not the value explicitly set by calling
|
||||
/// this function.
|
||||
///
|
||||
/// A value of `None` indicates that no automatic linking should happen,
|
||||
/// otherwise cargo will link against the specified library.
|
||||
@ -669,6 +700,7 @@ impl Build {
|
||||
/// Common values:
|
||||
/// - `stdc++` for GNU
|
||||
/// - `c++` for Clang
|
||||
/// - `c++_shared` or `c++_static` for Android
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -1384,7 +1416,7 @@ impl Build {
|
||||
cmd.push_opt_unless_duplicate("-DANDROID".into());
|
||||
}
|
||||
|
||||
if !target.contains("-ios") {
|
||||
if !target.contains("apple-ios") {
|
||||
cmd.push_cc_arg("-ffunction-sections".into());
|
||||
cmd.push_cc_arg("-fdata-sections".into());
|
||||
}
|
||||
@ -1423,7 +1455,38 @@ impl Build {
|
||||
if !(target.contains("android")
|
||||
&& android_clang_compiler_uses_target_arg_internally(&cmd.path))
|
||||
{
|
||||
cmd.args.push(format!("--target={}", target).into());
|
||||
if target.contains("darwin") {
|
||||
if let Some(arch) =
|
||||
map_darwin_target_from_rust_to_compiler_architecture(target)
|
||||
{
|
||||
cmd.args
|
||||
.push(format!("--target={}-apple-darwin", arch).into());
|
||||
}
|
||||
} else if target.contains("macabi") {
|
||||
if let Some(arch) =
|
||||
map_darwin_target_from_rust_to_compiler_architecture(target)
|
||||
{
|
||||
let ios = if arch == "arm64" { "ios" } else { "ios13.0" };
|
||||
cmd.args
|
||||
.push(format!("--target={}-apple-{}-macabi", arch, ios).into());
|
||||
}
|
||||
} else if target.contains("ios-sim") {
|
||||
if let Some(arch) =
|
||||
map_darwin_target_from_rust_to_compiler_architecture(target)
|
||||
{
|
||||
let deployment_target = env::var("IPHONEOS_DEPLOYMENT_TARGET")
|
||||
.unwrap_or_else(|_| "7.0".into());
|
||||
cmd.args.push(
|
||||
format!(
|
||||
"--target={}-apple-ios{}-simulator",
|
||||
arch, deployment_target
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
cmd.args.push(format!("--target={}", target).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
ToolFamily::Msvc { clang_cl } => {
|
||||
@ -1471,15 +1534,10 @@ impl Build {
|
||||
}
|
||||
|
||||
if target.contains("darwin") {
|
||||
if target.contains("x86_64") {
|
||||
if let Some(arch) = map_darwin_target_from_rust_to_compiler_architecture(target)
|
||||
{
|
||||
cmd.args.push("-arch".into());
|
||||
cmd.args.push("x86_64".into());
|
||||
} else if target.contains("arm64e") {
|
||||
cmd.args.push("-arch".into());
|
||||
cmd.args.push("arm64e".into());
|
||||
} else if target.contains("aarch64") {
|
||||
cmd.args.push("-arch".into());
|
||||
cmd.args.push("arm64".into());
|
||||
cmd.args.push(arch.into());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1558,7 +1616,7 @@ impl Build {
|
||||
cmd.args.push("-march=i686".into());
|
||||
}
|
||||
|
||||
// Looks like `musl-gcc` makes is hard for `-m32` to make its way
|
||||
// Looks like `musl-gcc` makes it hard for `-m32` to make its way
|
||||
// all the way to the linker, so we need to actually instruct the
|
||||
// linker that we're generating 32-bit executables as well. This'll
|
||||
// typically only be used for build scripts which transitively use
|
||||
@ -1635,14 +1693,17 @@ impl Build {
|
||||
let mut parts = target.split('-');
|
||||
if let Some(arch) = parts.next() {
|
||||
let arch = &arch[5..];
|
||||
cmd.args.push(("-march=rv".to_owned() + arch).into());
|
||||
if target.contains("linux") && arch.starts_with("64") {
|
||||
cmd.args.push(("-march=rv64gc").into());
|
||||
cmd.args.push("-mabi=lp64d".into());
|
||||
} else if target.contains("linux") && arch.starts_with("32") {
|
||||
cmd.args.push(("-march=rv32gc").into());
|
||||
cmd.args.push("-mabi=ilp32d".into());
|
||||
} else if arch.starts_with("64") {
|
||||
cmd.args.push(("-march=rv".to_owned() + arch).into());
|
||||
cmd.args.push("-mabi=lp64".into());
|
||||
} else {
|
||||
cmd.args.push(("-march=rv".to_owned() + arch).into());
|
||||
cmd.args.push("-mabi=ilp32".into());
|
||||
}
|
||||
cmd.args.push("-mcmodel=medany".into());
|
||||
@ -1651,9 +1712,7 @@ impl Build {
|
||||
}
|
||||
}
|
||||
|
||||
if target.contains("-ios") {
|
||||
// FIXME: potential bug. iOS is always compiled with Clang, but Gcc compiler may be
|
||||
// detected instead.
|
||||
if target.contains("apple-ios") {
|
||||
self.ios_flags(cmd)?;
|
||||
}
|
||||
|
||||
@ -1732,66 +1791,28 @@ impl Build {
|
||||
}
|
||||
|
||||
fn assemble(&self, lib_name: &str, dst: &Path, objs: &[Object]) -> Result<(), Error> {
|
||||
// Delete the destination if it exists as the `ar` tool at least on Unix
|
||||
// appends to it, which we don't want.
|
||||
// Delete the destination if it exists as we want to
|
||||
// create on the first iteration instead of appending.
|
||||
let _ = fs::remove_file(&dst);
|
||||
|
||||
let objects: Vec<_> = objs.iter().map(|obj| obj.dst.clone()).collect();
|
||||
// Add objects to the archive in limited-length batches. This helps keep
|
||||
// the length of the command line within a reasonable length to avoid
|
||||
// blowing system limits on limiting platforms like Windows.
|
||||
let objs: Vec<_> = objs
|
||||
.iter()
|
||||
.map(|o| o.dst.clone())
|
||||
.chain(self.objects.clone())
|
||||
.collect();
|
||||
for chunk in objs.chunks(100) {
|
||||
self.assemble_progressive(dst, chunk)?;
|
||||
}
|
||||
|
||||
let target = self.get_target()?;
|
||||
if target.contains("msvc") {
|
||||
let (mut cmd, program) = self.get_ar()?;
|
||||
let mut out = OsString::from("-out:");
|
||||
out.push(dst);
|
||||
cmd.arg(out).arg("-nologo");
|
||||
for flag in self.ar_flags.iter() {
|
||||
cmd.arg(flag);
|
||||
}
|
||||
|
||||
// Similar to https://github.com/rust-lang/rust/pull/47507
|
||||
// and https://github.com/rust-lang/rust/pull/48548
|
||||
let estimated_command_line_len = objects
|
||||
.iter()
|
||||
.chain(&self.objects)
|
||||
.map(|a| a.as_os_str().len())
|
||||
.sum::<usize>();
|
||||
if estimated_command_line_len > 1024 * 6 {
|
||||
let mut args = String::from("\u{FEFF}"); // BOM
|
||||
for arg in objects.iter().chain(&self.objects) {
|
||||
args.push('"');
|
||||
for c in arg.to_str().unwrap().chars() {
|
||||
if c == '"' {
|
||||
args.push('\\')
|
||||
}
|
||||
args.push(c)
|
||||
}
|
||||
args.push('"');
|
||||
args.push('\n');
|
||||
}
|
||||
|
||||
let mut utf16le = Vec::new();
|
||||
for code_unit in args.encode_utf16() {
|
||||
utf16le.push(code_unit as u8);
|
||||
utf16le.push((code_unit >> 8) as u8);
|
||||
}
|
||||
|
||||
let mut args_file = OsString::from(dst);
|
||||
args_file.push(".args");
|
||||
fs::File::create(&args_file)
|
||||
.unwrap()
|
||||
.write_all(&utf16le)
|
||||
.unwrap();
|
||||
|
||||
let mut args_file_arg = OsString::from("@");
|
||||
args_file_arg.push(args_file);
|
||||
cmd.arg(args_file_arg);
|
||||
} else {
|
||||
cmd.args(&objects).args(&self.objects);
|
||||
}
|
||||
run(&mut cmd, &program)?;
|
||||
|
||||
// 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);
|
||||
match fs::hard_link(&dst, &lib_dst).or_else(|_| {
|
||||
@ -1806,6 +1827,35 @@ impl Build {
|
||||
));
|
||||
}
|
||||
};
|
||||
} else {
|
||||
// Non-msvc targets (those using `ar`) need a separate step to add
|
||||
// the symbol table to archives since our construction command of
|
||||
// `cq` doesn't add it for us.
|
||||
let (mut ar, cmd) = self.get_ar()?;
|
||||
run(ar.arg("s").arg(dst), &cmd)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn assemble_progressive(&self, dst: &Path, objs: &[PathBuf]) -> Result<(), Error> {
|
||||
let target = self.get_target()?;
|
||||
|
||||
if target.contains("msvc") {
|
||||
let (mut cmd, program) = self.get_ar()?;
|
||||
let mut out = OsString::from("-out:");
|
||||
out.push(dst);
|
||||
cmd.arg(out).arg("-nologo");
|
||||
for flag in self.ar_flags.iter() {
|
||||
cmd.arg(flag);
|
||||
}
|
||||
// If the library file already exists, add the libary name
|
||||
// as an argument to let lib.exe know we are appending the objs.
|
||||
if dst.exists() {
|
||||
cmd.arg(dst);
|
||||
}
|
||||
cmd.args(objs);
|
||||
run(&mut cmd, &program)?;
|
||||
} else {
|
||||
let (mut ar, cmd) = self.get_ar()?;
|
||||
|
||||
@ -1835,10 +1885,7 @@ impl Build {
|
||||
for flag in self.ar_flags.iter() {
|
||||
ar.arg(flag);
|
||||
}
|
||||
run(
|
||||
ar.arg("crs").arg(dst).args(&objects).args(&self.objects),
|
||||
&cmd,
|
||||
)?;
|
||||
run(ar.arg("cq").arg(dst).args(objs), &cmd)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1848,6 +1895,7 @@ impl Build {
|
||||
enum ArchSpec {
|
||||
Device(&'static str),
|
||||
Simulator(&'static str),
|
||||
Catalyst(&'static str),
|
||||
}
|
||||
|
||||
let target = self.get_target()?;
|
||||
@ -1857,18 +1905,38 @@ impl Build {
|
||||
"Unknown architecture for iOS target.",
|
||||
)
|
||||
})?;
|
||||
let arch = match arch {
|
||||
"arm" | "armv7" | "thumbv7" => ArchSpec::Device("armv7"),
|
||||
"armv7s" | "thumbv7s" => ArchSpec::Device("armv7s"),
|
||||
"arm64e" => ArchSpec::Device("arm64e"),
|
||||
"arm64" | "aarch64" => ArchSpec::Device("arm64"),
|
||||
"i386" | "i686" => ArchSpec::Simulator("-m32"),
|
||||
"x86_64" => ArchSpec::Simulator("-m64"),
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
ErrorKind::ArchitectureInvalid,
|
||||
"Unknown architecture for iOS target.",
|
||||
));
|
||||
|
||||
let is_catalyst = match target.split('-').nth(3) {
|
||||
Some(v) => v == "macabi",
|
||||
None => false,
|
||||
};
|
||||
|
||||
let arch = if is_catalyst {
|
||||
match arch {
|
||||
"arm64e" => ArchSpec::Catalyst("arm64e"),
|
||||
"arm64" | "aarch64" => ArchSpec::Catalyst("arm64"),
|
||||
"x86_64" => ArchSpec::Catalyst("-m64"),
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
ErrorKind::ArchitectureInvalid,
|
||||
"Unknown architecture for iOS target.",
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match arch {
|
||||
"arm" | "armv7" | "thumbv7" => ArchSpec::Device("armv7"),
|
||||
"armv7s" | "thumbv7s" => ArchSpec::Device("armv7s"),
|
||||
"arm64e" => ArchSpec::Device("arm64e"),
|
||||
"arm64" | "aarch64" => ArchSpec::Device("arm64"),
|
||||
"i386" | "i686" => ArchSpec::Simulator("-m32"),
|
||||
"x86_64" => ArchSpec::Simulator("-m64"),
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
ErrorKind::ArchitectureInvalid,
|
||||
"Unknown architecture for iOS target.",
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1889,6 +1957,7 @@ impl Build {
|
||||
.push(format!("-mios-simulator-version-min={}", min_version).into());
|
||||
"iphonesimulator"
|
||||
}
|
||||
ArchSpec::Catalyst(_) => "macosx",
|
||||
};
|
||||
|
||||
self.print(&format!("Detecting iOS SDK path for {}", sdk));
|
||||
@ -1992,6 +2061,8 @@ impl Build {
|
||||
} else {
|
||||
format!("{}.exe", gnu)
|
||||
}
|
||||
} else if target.contains("apple-ios") {
|
||||
clang.to_string()
|
||||
} else if target.contains("android") {
|
||||
autodetect_android_compiler(&target, &host, gnu, clang)
|
||||
} else if target.contains("cloudabi") {
|
||||
@ -2002,7 +2073,11 @@ impl Build {
|
||||
{
|
||||
"clang".to_string()
|
||||
} else if target.contains("vxworks") {
|
||||
"wr-c++".to_string()
|
||||
if self.cpp {
|
||||
"wr-c++".to_string()
|
||||
} else {
|
||||
"wr-cc".to_string()
|
||||
}
|
||||
} else if self.get_host()? != target {
|
||||
let prefix = self.prefix_for_target(&target);
|
||||
match prefix {
|
||||
@ -2040,6 +2115,40 @@ impl Build {
|
||||
tool
|
||||
};
|
||||
|
||||
// New "standalone" C/C++ cross-compiler executables from recent Android NDK
|
||||
// are just shell scripts that call main clang binary (from Android NDK) with
|
||||
// proper `--target` argument.
|
||||
//
|
||||
// For example, armv7a-linux-androideabi16-clang passes
|
||||
// `--target=armv7a-linux-androideabi16` to clang.
|
||||
//
|
||||
// As the shell script calls the main clang binary, the command line limit length
|
||||
// on Windows is restricted to around 8k characters instead of around 32k characters.
|
||||
// To remove this limit, we call the main clang binary directly and contruct the
|
||||
// `--target=` ourselves.
|
||||
if host.contains("windows") && android_clang_compiler_uses_target_arg_internally(&tool.path)
|
||||
{
|
||||
if let Some(path) = tool.path.file_name() {
|
||||
let file_name = path.to_str().unwrap().to_owned();
|
||||
let (target, clang) = file_name.split_at(file_name.rfind("-").unwrap());
|
||||
|
||||
tool.path.set_file_name(clang.trim_start_matches("-"));
|
||||
tool.path.set_extension("exe");
|
||||
tool.args.push(format!("--target={}", target).into());
|
||||
|
||||
// Additionally, shell scripts for target i686-linux-android versions 16 to 24
|
||||
// pass the `mstackrealign` option so we do that here as well.
|
||||
if target.contains("i686-linux-android") {
|
||||
let (_, version) = target.split_at(target.rfind("d").unwrap() + 1);
|
||||
if let Ok(version) = version.parse::<u32>() {
|
||||
if version > 15 && version < 25 {
|
||||
tool.args.push("-mstackrealign".into());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// If we found `cl.exe` in our environment, the tool we're returning is
|
||||
// an MSVC-like tool, *and* no env vars were set then set env vars for
|
||||
// the tool that we're returning.
|
||||
@ -2087,9 +2196,8 @@ impl Build {
|
||||
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())
|
||||
.split_ascii_whitespace()
|
||||
.map(|slice| slice.to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -2175,8 +2283,11 @@ impl Build {
|
||||
))
|
||||
}
|
||||
|
||||
/// Returns the default C++ standard library for the current target: `libc++`
|
||||
/// for OS X and `libstdc++` for anything else.
|
||||
/// Returns the C++ standard library:
|
||||
/// 1. If [cpp_link_stdlib](cc::Build::cpp_link_stdlib) is set, uses its value.
|
||||
/// 2. Else if the `CXXSTDLIB` environment variable is set, uses its value.
|
||||
/// 3. Else the default is `libc++` for OS X and BSDs, `libc++_shared` for Android,
|
||||
/// `None` for MSVC and `libstdc++` for anything else.
|
||||
fn get_cpp_link_stdlib(&self) -> Result<Option<String>, Error> {
|
||||
match self.cpp_link_stdlib.clone() {
|
||||
Some(s) => Ok(s),
|
||||
@ -2197,6 +2308,8 @@ impl Build {
|
||||
Ok(Some("c++".to_string()))
|
||||
} else if target.contains("openbsd") {
|
||||
Ok(Some("c++".to_string()))
|
||||
} else if target.contains("android") {
|
||||
Ok(Some("c++_shared".to_string()))
|
||||
} else {
|
||||
Ok(Some("stdc++".to_string()))
|
||||
}
|
||||
@ -2231,6 +2344,12 @@ impl Build {
|
||||
Some(t) => return Ok((t, "lib.exe".to_string())),
|
||||
None => "lib.exe".to_string(),
|
||||
}
|
||||
} else if target.contains("illumos") {
|
||||
// The default 'ar' on illumos uses a non-standard flags,
|
||||
// but the OS comes bundled with a GNU-compatible variant.
|
||||
//
|
||||
// Use the GNU-variant to match other Unix systems.
|
||||
"gar".to_string()
|
||||
} else if self.get_host()? != target {
|
||||
match self.prefix_for_target(&target) {
|
||||
Some(p) => {
|
||||
@ -2286,7 +2405,9 @@ impl Build {
|
||||
"i686-unknown-linux-musl" => Some("musl"),
|
||||
"i686-unknown-netbsd" => Some("i486--netbsdelf"),
|
||||
"mips-unknown-linux-gnu" => Some("mips-linux-gnu"),
|
||||
"mips-unknown-linux-musl" => Some("mips-linux-musl"),
|
||||
"mipsel-unknown-linux-gnu" => Some("mipsel-linux-gnu"),
|
||||
"mipsel-unknown-linux-musl" => Some("mipsel-linux-musl"),
|
||||
"mips64-unknown-linux-gnuabi64" => Some("mips64-linux-gnuabi64"),
|
||||
"mips64el-unknown-linux-gnuabi64" => Some("mips64el-linux-gnuabi64"),
|
||||
"mipsisa32r6-unknown-linux-gnu" => Some("mipsisa32r6-linux-gnu"),
|
||||
@ -2324,6 +2445,9 @@ impl Build {
|
||||
"riscv-none-embed",
|
||||
]),
|
||||
"riscv64gc-unknown-linux-gnu" => Some("riscv64-linux-gnu"),
|
||||
"riscv32gc-unknown-linux-gnu" => Some("riscv32-linux-gnu"),
|
||||
"riscv64gc-unknown-linux-musl" => Some("riscv64-linux-musl"),
|
||||
"riscv32gc-unknown-linux-musl" => Some("riscv32-linux-musl"),
|
||||
"s390x-unknown-linux-gnu" => Some("s390x-linux-gnu"),
|
||||
"sparc-unknown-linux-gnu" => Some("sparc-linux-gnu"),
|
||||
"sparc64-unknown-linux-gnu" => Some("sparc64-linux-gnu"),
|
||||
@ -2489,14 +2613,13 @@ impl Build {
|
||||
return Ok(ret.clone());
|
||||
}
|
||||
|
||||
let sdk_path = self
|
||||
.cmd("xcrun")
|
||||
.arg("--show-sdk-path")
|
||||
.arg("--sdk")
|
||||
.arg(sdk)
|
||||
.stderr(Stdio::inherit())
|
||||
.output()?
|
||||
.stdout;
|
||||
let sdk_path = run_output(
|
||||
self.cmd("xcrun")
|
||||
.arg("--show-sdk-path")
|
||||
.arg("--sdk")
|
||||
.arg(sdk),
|
||||
"xcrun",
|
||||
)?;
|
||||
|
||||
let sdk_path = match String::from_utf8(sdk_path) {
|
||||
Ok(p) => p,
|
||||
@ -2548,11 +2671,7 @@ impl Tool {
|
||||
let family = if let Some(fname) = path.file_name().and_then(|p| p.to_str()) {
|
||||
if fname.contains("clang-cl") {
|
||||
ToolFamily::Msvc { clang_cl: true }
|
||||
} else if fname.contains("cl")
|
||||
&& !fname.contains("cloudabi")
|
||||
&& !fname.contains("uclibc")
|
||||
&& !fname.contains("clang")
|
||||
{
|
||||
} else if fname.ends_with("cl") || fname == "cl.exe" {
|
||||
ToolFamily::Msvc { clang_cl: false }
|
||||
} else if fname.contains("clang") {
|
||||
match clang_driver {
|
||||
@ -2842,7 +2961,7 @@ fn spawn(cmd: &mut Command, program: &str) -> Result<(Child, JoinHandle<()>), Er
|
||||
}
|
||||
|
||||
fn fail(s: &str) -> ! {
|
||||
let _ = writeln!(io::stderr(), "\n\nerror occurred: {}\n\n", s);
|
||||
eprintln!("\n\nerror occurred: {}\n\n", s);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
@ -2958,3 +3077,16 @@ fn autodetect_android_compiler(target: &str, host: &str, gnu: &str, clang: &str)
|
||||
clang_compiler
|
||||
}
|
||||
}
|
||||
|
||||
// Rust and clang/cc don't agree on how to name the target.
|
||||
fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<&'static str> {
|
||||
if target.contains("x86_64") {
|
||||
Some("x86_64")
|
||||
} else if target.contains("arm64e") {
|
||||
Some("arm64e")
|
||||
} else if target.contains("aarch64") {
|
||||
Some("arm64")
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
199
third_party/rust/cc/src/vs_instances.rs
vendored
Normal file
199
third_party/rust/cc/src/vs_instances.rs
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::io::BufRead;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::setup_config::{EnumSetupInstances, SetupInstance};
|
||||
|
||||
pub enum VsInstance {
|
||||
Com(SetupInstance),
|
||||
Vswhere(VswhereInstance),
|
||||
}
|
||||
|
||||
impl VsInstance {
|
||||
pub fn installation_name(&self) -> Option<Cow<str>> {
|
||||
match self {
|
||||
VsInstance::Com(s) => s
|
||||
.installation_name()
|
||||
.ok()
|
||||
.and_then(|s| s.into_string().ok())
|
||||
.map(Cow::from),
|
||||
VsInstance::Vswhere(v) => v.map.get("installationName").map(Cow::from),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn installation_path(&self) -> Option<PathBuf> {
|
||||
match self {
|
||||
VsInstance::Com(s) => s.installation_path().ok().map(PathBuf::from),
|
||||
VsInstance::Vswhere(v) => v.map.get("installationPath").map(PathBuf::from),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn installation_version(&self) -> Option<Cow<str>> {
|
||||
match self {
|
||||
VsInstance::Com(s) => s
|
||||
.installation_version()
|
||||
.ok()
|
||||
.and_then(|s| s.into_string().ok())
|
||||
.map(Cow::from),
|
||||
VsInstance::Vswhere(v) => v.map.get("installationVersion").map(Cow::from),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum VsInstances {
|
||||
ComBased(EnumSetupInstances),
|
||||
VswhereBased(VswhereInstance),
|
||||
}
|
||||
|
||||
impl IntoIterator for VsInstances {
|
||||
type Item = VsInstance;
|
||||
#[allow(bare_trait_objects)]
|
||||
type IntoIter = Box<Iterator<Item = Self::Item>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
match self {
|
||||
VsInstances::ComBased(e) => {
|
||||
Box::new(e.into_iter().filter_map(Result::ok).map(VsInstance::Com))
|
||||
}
|
||||
VsInstances::VswhereBased(v) => Box::new(std::iter::once(VsInstance::Vswhere(v))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VswhereInstance {
|
||||
map: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl TryFrom<&Vec<u8>> for VswhereInstance {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(output: &Vec<u8>) -> Result<Self, Self::Error> {
|
||||
let map: HashMap<_, _> = output
|
||||
.lines()
|
||||
.filter_map(Result::ok)
|
||||
.filter_map(|s| {
|
||||
let mut splitn = s.splitn(2, ": ");
|
||||
Some((splitn.next()?.to_owned(), splitn.next()?.to_owned()))
|
||||
})
|
||||
.collect();
|
||||
|
||||
if !map.contains_key("installationName")
|
||||
|| !map.contains_key("installationPath")
|
||||
|| !map.contains_key("installationVersion")
|
||||
{
|
||||
return Err("required properties not found");
|
||||
}
|
||||
|
||||
Ok(Self { map })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests_ {
|
||||
use std::borrow::Cow;
|
||||
use std::convert::TryFrom;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[test]
|
||||
fn it_parses_vswhere_output_correctly() {
|
||||
let output = br"instanceId: 58104422
|
||||
installDate: 21/02/2021 21:50:33
|
||||
installationName: VisualStudio/16.9.2+31112.23
|
||||
installationPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools
|
||||
installationVersion: 16.9.31112.23
|
||||
productId: Microsoft.VisualStudio.Product.BuildTools
|
||||
productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat
|
||||
state: 4294967295
|
||||
isComplete: 1
|
||||
isLaunchable: 1
|
||||
isPrerelease: 0
|
||||
isRebootRequired: 0
|
||||
displayName: Visual Studio Build Tools 2019
|
||||
description: The Visual Studio Build Tools allows you to build native and managed MSBuild-based applications without requiring the Visual Studio IDE. There are options to install the Visual C++ compilers and libraries, MFC, ATL, and C++/CLI support.
|
||||
channelId: VisualStudio.16.Release
|
||||
channelUri: https://aka.ms/vs/16/release/channel
|
||||
enginePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service
|
||||
releaseNotes: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-v16.9#16.9.2
|
||||
thirdPartyNotices: https://go.microsoft.com/fwlink/?LinkId=660909
|
||||
updateDate: 2021-03-17T21:16:46.5963702Z
|
||||
catalog_buildBranch: d16.9
|
||||
catalog_buildVersion: 16.9.31112.23
|
||||
catalog_id: VisualStudio/16.9.2+31112.23
|
||||
catalog_localBuild: build-lab
|
||||
catalog_manifestName: VisualStudio
|
||||
catalog_manifestType: installer
|
||||
catalog_productDisplayVersion: 16.9.2
|
||||
catalog_productLine: Dev16
|
||||
catalog_productLineVersion: 2019
|
||||
catalog_productMilestone: RTW
|
||||
catalog_productMilestoneIsPreRelease: False
|
||||
catalog_productName: Visual Studio
|
||||
catalog_productPatchVersion: 2
|
||||
catalog_productPreReleaseMilestoneSuffix: 1.0
|
||||
catalog_productSemanticVersion: 16.9.2+31112.23
|
||||
catalog_requiredEngineVersion: 2.9.3365.38425
|
||||
properties_campaignId: 156063665.1613940062
|
||||
properties_channelManifestId: VisualStudio.16.Release/16.9.2+31112.23
|
||||
properties_nickname:
|
||||
properties_setupEngineFilePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installershell.exe
|
||||
"
|
||||
.to_vec();
|
||||
|
||||
let vswhere_instance = super::VswhereInstance::try_from(&output);
|
||||
assert!(vswhere_instance.is_ok());
|
||||
|
||||
let vs_instance = super::VsInstance::Vswhere(vswhere_instance.unwrap());
|
||||
assert_eq!(
|
||||
vs_instance.installation_name(),
|
||||
Some(Cow::from("VisualStudio/16.9.2+31112.23"))
|
||||
);
|
||||
assert_eq!(
|
||||
vs_instance.installation_path(),
|
||||
Some(PathBuf::from(
|
||||
r"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools"
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
vs_instance.installation_version(),
|
||||
Some(Cow::from("16.9.31112.23"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_returns_an_error_for_empty_output() {
|
||||
let output = b"".to_vec();
|
||||
|
||||
let vswhere_instance = super::VswhereInstance::try_from(&output);
|
||||
|
||||
assert!(vswhere_instance.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_returns_an_error_for_output_consisting_of_empty_lines() {
|
||||
let output = br"
|
||||
|
||||
"
|
||||
.to_vec();
|
||||
|
||||
let vswhere_instance = super::VswhereInstance::try_from(&output);
|
||||
|
||||
assert!(vswhere_instance.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_returns_an_error_for_output_without_required_properties() {
|
||||
let output = br"instanceId: 58104422
|
||||
installDate: 21/02/2021 21:50:33
|
||||
productId: Microsoft.VisualStudio.Product.BuildTools
|
||||
productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat
|
||||
"
|
||||
.to_vec();
|
||||
|
||||
let vswhere_instance = super::VswhereInstance::try_from(&output);
|
||||
|
||||
assert!(vswhere_instance.is_err());
|
||||
}
|
||||
}
|
180
third_party/rust/cc/src/windows_registry.rs
vendored
180
third_party/rust/cc/src/windows_registry.rs
vendored
@ -47,8 +47,6 @@ pub fn find_tool(_target: &str, _tool: &str) -> Option<Tool> {
|
||||
/// Documented above.
|
||||
#[cfg(windows)]
|
||||
pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
|
||||
use std::env;
|
||||
|
||||
// This logic is all tailored for MSVC, if we're not that then bail out
|
||||
// early.
|
||||
if !target.contains("msvc") {
|
||||
@ -66,18 +64,6 @@ pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
|
||||
return impl_::find_devenv(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::with_family(path.into(), MSVC_FAMILY));
|
||||
}
|
||||
|
||||
// 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
|
||||
@ -85,7 +71,8 @@ pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
|
||||
// environment variables like `LIB`, `INCLUDE`, and `PATH` to ensure that
|
||||
// the tool is actually usable.
|
||||
|
||||
return impl_::find_msvc_15plus(tool, target)
|
||||
return impl_::find_msvc_environment(tool, target)
|
||||
.or_else(|| impl_::find_msvc_15plus(tool, target))
|
||||
.or_else(|| impl_::find_msvc_14(tool, target))
|
||||
.or_else(|| impl_::find_msvc_12(tool, target))
|
||||
.or_else(|| impl_::find_msvc_11(tool, target));
|
||||
@ -170,7 +157,9 @@ pub fn find_vs_version() -> Result<VsVers, String> {
|
||||
mod impl_ {
|
||||
use crate::com;
|
||||
use crate::registry::{RegistryKey, LOCAL_MACHINE};
|
||||
use crate::setup_config::{EnumSetupInstances, SetupConfiguration, SetupInstance};
|
||||
use crate::setup_config::SetupConfiguration;
|
||||
use crate::vs_instances::{VsInstances, VswhereInstance};
|
||||
use std::convert::TryFrom;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs::File;
|
||||
@ -178,6 +167,7 @@ mod impl_ {
|
||||
use std::iter;
|
||||
use std::mem;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::MSVC_FAMILY;
|
||||
@ -215,23 +205,61 @@ mod impl_ {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks to see if the `VSCMD_ARG_TGT_ARCH` environment variable matches the
|
||||
/// given target's arch. Returns `None` if the variable does not exist.
|
||||
#[cfg(windows)]
|
||||
fn is_vscmd_target(target: &str) -> Option<bool> {
|
||||
let vscmd_arch = env::var("VSCMD_ARG_TGT_ARCH").ok()?;
|
||||
// Convert the Rust target arch to its VS arch equivalent.
|
||||
let arch = match target.split("-").next() {
|
||||
Some("x86_64") => "x64",
|
||||
Some("aarch64") => "arm64",
|
||||
Some("i686") | Some("i586") => "x86",
|
||||
Some("thumbv7a") => "arm",
|
||||
// An unrecognized arch.
|
||||
_ => return Some(false),
|
||||
};
|
||||
Some(vscmd_arch == arch)
|
||||
}
|
||||
|
||||
/// Attempt to find the tool using environment variables set by vcvars.
|
||||
pub fn find_msvc_environment(target: &str, tool: &str) -> Option<Tool> {
|
||||
// Early return if the environment doesn't contain a VC install.
|
||||
if env::var_os("VCINSTALLDIR").is_none() {
|
||||
return None;
|
||||
}
|
||||
let vs_install_dir = env::var_os("VSINSTALLDIR")?.into();
|
||||
|
||||
// If the vscmd target differs from the requested target then
|
||||
// attempt to get the tool using the VS install directory.
|
||||
if is_vscmd_target(target) == Some(false) {
|
||||
// We will only get here with versions 15+.
|
||||
tool_from_vs15plus_instance(tool, target, &vs_install_dir)
|
||||
} else {
|
||||
// Fallback to simply using the current environment.
|
||||
env::var_os("PATH")
|
||||
.and_then(|path| {
|
||||
env::split_paths(&path)
|
||||
.map(|p| p.join(tool))
|
||||
.find(|p| p.exists())
|
||||
})
|
||||
.map(|path| Tool::with_family(path.into(), MSVC_FAMILY))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(bare_trait_objects)]
|
||||
fn vs16_instances() -> Box<Iterator<Item = PathBuf>> {
|
||||
let instances = if let Some(instances) = vs15plus_instances() {
|
||||
fn vs16_instances(target: &str) -> Box<Iterator<Item = PathBuf>> {
|
||||
let instances = if let Some(instances) = vs15plus_instances(target) {
|
||||
instances
|
||||
} else {
|
||||
return Box::new(iter::empty());
|
||||
};
|
||||
Box::new(instances.filter_map(|instance| {
|
||||
let instance = instance.ok()?;
|
||||
let installation_name = instance.installation_name().ok()?;
|
||||
if installation_name.to_str()?.starts_with("VisualStudio/16.") {
|
||||
Some(PathBuf::from(instance.installation_path().ok()?))
|
||||
} else if installation_name
|
||||
.to_str()?
|
||||
.starts_with("VisualStudioPreview/16.")
|
||||
{
|
||||
Some(PathBuf::from(instance.installation_path().ok()?))
|
||||
Box::new(instances.into_iter().filter_map(|instance| {
|
||||
let installation_name = instance.installation_name()?;
|
||||
if installation_name.starts_with("VisualStudio/16.") {
|
||||
Some(instance.installation_path()?)
|
||||
} else if installation_name.starts_with("VisualStudioPreview/16.") {
|
||||
Some(instance.installation_path()?)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -239,7 +267,7 @@ mod impl_ {
|
||||
}
|
||||
|
||||
fn find_tool_in_vs16_path(tool: &str, target: &str) -> Option<Tool> {
|
||||
vs16_instances()
|
||||
vs16_instances(target)
|
||||
.filter_map(|path| {
|
||||
let path = path.join(tool);
|
||||
if !path.is_file() {
|
||||
@ -267,11 +295,62 @@ mod impl_ {
|
||||
// [online]: https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/
|
||||
//
|
||||
// Returns MSVC 15+ instances (15, 16 right now), the order should be consider undefined.
|
||||
fn vs15plus_instances() -> Option<EnumSetupInstances> {
|
||||
//
|
||||
// However, on ARM64 this method doesn't work because VS Installer fails to register COM component on ARM64.
|
||||
// Hence, as the last resort we try to use vswhere.exe to list available instances.
|
||||
fn vs15plus_instances(target: &str) -> Option<VsInstances> {
|
||||
vs15plus_instances_using_com().or_else(|| vs15plus_instances_using_vswhere(target))
|
||||
}
|
||||
|
||||
fn vs15plus_instances_using_com() -> Option<VsInstances> {
|
||||
com::initialize().ok()?;
|
||||
|
||||
let config = SetupConfiguration::new().ok()?;
|
||||
config.enum_all_instances().ok()
|
||||
let enum_setup_instances = config.enum_all_instances().ok()?;
|
||||
|
||||
Some(VsInstances::ComBased(enum_setup_instances))
|
||||
}
|
||||
|
||||
fn vs15plus_instances_using_vswhere(target: &str) -> Option<VsInstances> {
|
||||
let program_files_path: PathBuf = env::var("ProgramFiles(x86)")
|
||||
.or_else(|_| env::var("ProgramFiles"))
|
||||
.ok()?
|
||||
.into();
|
||||
|
||||
let vswhere_path =
|
||||
program_files_path.join(r"Microsoft Visual Studio\Installer\vswhere.exe");
|
||||
|
||||
if !vswhere_path.exists() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let arch = target.split('-').next().unwrap();
|
||||
let tools_arch = match arch {
|
||||
"i586" | "i686" | "x86_64" => Some("x86.x64"),
|
||||
"arm" | "thumbv7a" => Some("ARM"),
|
||||
"aarch64" => Some("ARM64"),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let vswhere_output = Command::new(vswhere_path)
|
||||
.args(&[
|
||||
"-latest",
|
||||
"-products",
|
||||
"*",
|
||||
"-requires",
|
||||
&format!("Microsoft.VisualStudio.Component.VC.Tools.{}", tools_arch?),
|
||||
"-format",
|
||||
"text",
|
||||
"-nologo",
|
||||
])
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.output()
|
||||
.ok()?;
|
||||
|
||||
let vs_instances =
|
||||
VsInstances::VswhereBased(VswhereInstance::try_from(&vswhere_output.stdout).ok()?);
|
||||
|
||||
Some(vs_instances)
|
||||
}
|
||||
|
||||
// Inspired from official microsoft/vswhere ParseVersionString
|
||||
@ -284,15 +363,16 @@ mod impl_ {
|
||||
}
|
||||
|
||||
pub fn find_msvc_15plus(tool: &str, target: &str) -> Option<Tool> {
|
||||
let iter = vs15plus_instances()?;
|
||||
iter.filter_map(|instance| {
|
||||
let instance = instance.ok()?;
|
||||
let version = parse_version(instance.installation_version().ok()?.to_str()?)?;
|
||||
let tool = tool_from_vs15plus_instance(tool, target, &instance)?;
|
||||
Some((version, tool))
|
||||
})
|
||||
.max_by(|(a_version, _), (b_version, _)| a_version.cmp(b_version))
|
||||
.map(|(_version, tool)| tool)
|
||||
let iter = vs15plus_instances(target)?;
|
||||
iter.into_iter()
|
||||
.filter_map(|instance| {
|
||||
let version = parse_version(&instance.installation_version()?)?;
|
||||
let instance_path = instance.installation_path()?;
|
||||
let tool = tool_from_vs15plus_instance(tool, target, &instance_path)?;
|
||||
Some((version, tool))
|
||||
})
|
||||
.max_by(|(a_version, _), (b_version, _)| a_version.cmp(b_version))
|
||||
.map(|(_version, tool)| tool)
|
||||
}
|
||||
|
||||
// While the paths to Visual Studio 2017's devenv and MSBuild could
|
||||
@ -303,14 +383,11 @@ mod impl_ {
|
||||
//
|
||||
// [more reliable]: https://github.com/alexcrichton/cc-rs/pull/331
|
||||
fn find_tool_in_vs15_path(tool: &str, target: &str) -> Option<Tool> {
|
||||
let mut path = match vs15plus_instances() {
|
||||
let mut path = match vs15plus_instances(target) {
|
||||
Some(instances) => instances
|
||||
.filter_map(|instance| {
|
||||
instance
|
||||
.ok()
|
||||
.and_then(|instance| instance.installation_path().ok())
|
||||
})
|
||||
.map(|path| PathBuf::from(path).join(tool))
|
||||
.into_iter()
|
||||
.filter_map(|instance| instance.installation_path())
|
||||
.map(|path| path.join(tool))
|
||||
.find(|ref path| path.is_file()),
|
||||
None => None,
|
||||
};
|
||||
@ -337,10 +414,10 @@ mod impl_ {
|
||||
fn tool_from_vs15plus_instance(
|
||||
tool: &str,
|
||||
target: &str,
|
||||
instance: &SetupInstance,
|
||||
instance_path: &PathBuf,
|
||||
) -> Option<Tool> {
|
||||
let (bin_path, host_dylib_path, lib_path, include_path) =
|
||||
vs15plus_vc_paths(target, instance)?;
|
||||
vs15plus_vc_paths(target, instance_path)?;
|
||||
let tool_path = bin_path.join(tool);
|
||||
if !tool_path.exists() {
|
||||
return None;
|
||||
@ -364,9 +441,8 @@ mod impl_ {
|
||||
|
||||
fn vs15plus_vc_paths(
|
||||
target: &str,
|
||||
instance: &SetupInstance,
|
||||
instance_path: &PathBuf,
|
||||
) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf)> {
|
||||
let instance_path: PathBuf = instance.installation_path().ok()?.into();
|
||||
let version_path =
|
||||
instance_path.join(r"VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt");
|
||||
let mut version_file = File::open(version_path).ok()?;
|
||||
@ -403,7 +479,7 @@ mod impl_ {
|
||||
}
|
||||
|
||||
fn atl_paths(target: &str, path: &Path) -> Option<(PathBuf, PathBuf)> {
|
||||
let atl_path = path.join("atlfmc");
|
||||
let atl_path = path.join("atlmfc");
|
||||
let sub = lib_subdir(target)?;
|
||||
if atl_path.exists() {
|
||||
Some((atl_path.join("lib").join(sub), atl_path.join("include")))
|
||||
|
Loading…
Reference in New Issue
Block a user