aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cc/Cargo.toml2
-rw-r--r--cc/azure-pipelines.yml4
-rw-r--r--cc/ci/azure-install-rust.yml28
-rw-r--r--cc/ci/azure-steps.yml11
-rw-r--r--cc/src/bin/gcc-shim.rs39
-rw-r--r--cc/src/lib.rs196
-rw-r--r--cc/src/windows_registry.rs32
-rw-r--r--cc/tests/cflags.rs18
-rw-r--r--cc/tests/cxxflags.rs18
-rw-r--r--cc/tests/support/mod.rs48
-rw-r--r--cc/tests/test.rs41
-rw-r--r--nitrocli/CHANGELOG.md1
-rw-r--r--nitrocli/Cargo.lock4
13 files changed, 274 insertions, 168 deletions
diff --git a/cc/Cargo.toml b/cc/Cargo.toml
index 3a4c83b..52e18ce 100644
--- a/cc/Cargo.toml
+++ b/cc/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cc"
-version = "1.0.37"
+version = "1.0.40"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
license = "MIT/Apache-2.0"
repository = "https://github.com/alexcrichton/cc-rs"
diff --git a/cc/azure-pipelines.yml b/cc/azure-pipelines.yml
index e816196..e925da1 100644
--- a/cc/azure-pipelines.yml
+++ b/cc/azure-pipelines.yml
@@ -1,5 +1,9 @@
+# Note for forks: Azure Pipelines is triggered only by commits to the branches
+# matching the patterns below.
+# See https://docs.microsoft.com/en-us/azure/devops/pipelines/build/triggers
trigger:
- master
+ - ci-*
jobs:
- job: min_linux
diff --git a/cc/ci/azure-install-rust.yml b/cc/ci/azure-install-rust.yml
index 118d65e..9c1bae8 100644
--- a/cc/ci/azure-install-rust.yml
+++ b/cc/ci/azure-install-rust.yml
@@ -5,16 +5,30 @@ steps:
if [ "$toolchain" = "" ]; then
toolchain=stable
fi
- curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $toolchain
- echo "##vso[task.prependpath]$HOME/.cargo/bin"
+ if command -v rustup; then
+ rustup update $toolchain
+ rustup default $toolchain
+ else
+ curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $toolchain
+ echo "##vso[task.prependpath]$HOME/.cargo/bin"
+ fi
displayName: Install rust (unix)
condition: ne( variables['Agent.OS'], 'Windows_NT' )
- - script: |
- IF "%TOOLCHAIN%"=="" (SET TOOLCHAIN=stable-%TARGET%)
- curl -sSf -o rustup-init.exe https://win.rustup.rs
- rustup-init.exe -y --default-toolchain %TOOLCHAIN%
- echo ##vso[task.prependpath]%USERPROFILE%\.cargo\bin
+ - bash: |
+ set -e
+ toolchain=$TOOLCHAIN
+ if [ "$toolchain" = "" ]; then
+ toolchain=stable-$TARGET
+ fi
+ if command -v rustup; then
+ rustup update --no-self-update $toolchain
+ rustup default $toolchain
+ else
+ curl.exe -sSf -o rustup-init.exe https://win.rustup.rs
+ ./rustup-init.exe -y --default-toolchain $toolchain
+ echo "##vso[task.prependpath]$USERPROFILE/.cargo/bin"
+ fi
displayName: Install rust (windows)
condition: eq( variables['Agent.OS'], 'Windows_NT' )
diff --git a/cc/ci/azure-steps.yml b/cc/ci/azure-steps.yml
index c240ed0..bbf8ec6 100644
--- a/cc/ci/azure-steps.yml
+++ b/cc/ci/azure-steps.yml
@@ -3,15 +3,22 @@ steps:
- bash: rustup target add $TARGET
displayName: Install Rust target
+ # Remove the ubuntu-toolchain-r/test PPA, which is added by default. Some
+ # packages were removed, and this is causing the g++multilib install to fail.
+ # Similar issue: https://github.com/scikit-learn/scikit-learn/issues/13928
+ - bash: sudo add-apt-repository --remove ppa:ubuntu-toolchain-r/test
+ condition: eq( variables['Agent.OS'], 'Linux' )
+ displayName: Remove ppa:ubuntu-toolchain-r/test
+
- bash: sudo apt-get install g++-multilib
condition: eq( variables['Agent.OS'], 'Linux' )
displayName: Install g++-multilib
- script: cargo build
displayName: "Normal build"
- - bash: cargo test $NO_RUN -- --test-threads 1
+ - bash: cargo test $NO_RUN
displayName: "Crate tests"
- - bash: cargo test $NO_RUN --features parallel -- --test-threads 1
+ - bash: cargo test $NO_RUN --features parallel
displayName: "Crate tests (parallel)"
- bash: cargo test $NO_RUN --manifest-path cc-test/Cargo.toml --target $TARGET
displayName: "cc-test tests"
diff --git a/cc/src/bin/gcc-shim.rs b/cc/src/bin/gcc-shim.rs
index 7fd0ea8..1731df8 100644
--- a/cc/src/bin/gcc-shim.rs
+++ b/cc/src/bin/gcc-shim.rs
@@ -6,18 +6,43 @@ use std::io::prelude::*;
use std::path::PathBuf;
fn main() {
- let out_dir = PathBuf::from(env::var_os("GCCTEST_OUT_DIR").unwrap());
+ let mut args = env::args();
+ let program = args.next().expect("Unexpected empty args");
+
+ let out_dir = PathBuf::from(
+ env::var_os("GCCTEST_OUT_DIR").expect(&format!("{}: GCCTEST_OUT_DIR not found", program)),
+ );
+
+ // Find the first nonexistent candidate file to which the program's args can be written.
for i in 0.. {
- let candidate = out_dir.join(format!("out{}", i));
+ let candidate = &out_dir.join(format!("out{}", i));
+
+ // If the file exists, commands have already run. Try again.
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();
+ // Create a file and record the args passed to the command.
+ let mut f = File::create(candidate).expect(&format!(
+ "{}: can't create candidate: {}",
+ program,
+ candidate.to_string_lossy()
+ ));
+ for arg in args {
+ writeln!(f, "{}", arg).expect(&format!(
+ "{}: can't write to candidate: {}",
+ program,
+ candidate.to_string_lossy()
+ ));
+ }
break;
}
+
+ // Create a file used by some tests.
+ let path = &out_dir.join("libfoo.a");
+ File::create(path).expect(&format!(
+ "{}: can't create libfoo.a: {}",
+ program,
+ path.to_string_lossy()
+ ));
}
diff --git a/cc/src/lib.rs b/cc/src/lib.rs
index 9fef147..2d918b8 100644
--- a/cc/src/lib.rs
+++ b/cc/src/lib.rs
@@ -64,6 +64,7 @@ extern crate rayon;
use std::collections::HashMap;
use std::env;
use std::ffi::{OsStr, OsString};
+use std::fmt::{self, Display};
use std::fs;
use std::io::{self, BufRead, BufReader, Read, Write};
use std::path::{Path, PathBuf};
@@ -162,6 +163,12 @@ impl From<io::Error> for Error {
}
}
+impl Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:?}: {}", self.kind, self.message)
+ }
+}
+
/// 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
@@ -202,7 +209,7 @@ impl ToolFamily {
fn add_debug_flags(&self, cmd: &mut Tool) {
match *self {
ToolFamily::Msvc { .. } => {
- cmd.push_cc_arg("/Z7".into());
+ cmd.push_cc_arg("-Z7".into());
}
ToolFamily::Gnu | ToolFamily::Clang => {
cmd.push_cc_arg("-g".into());
@@ -211,26 +218,10 @@ impl ToolFamily {
}
}
- /// What the flag to include directories into header search path looks like
- fn include_flag(&self) -> &'static str {
- match *self {
- ToolFamily::Msvc { .. } => "/I",
- ToolFamily::Gnu | ToolFamily::Clang => "-I",
- }
- }
-
- /// What the flag to request macro-expanded source output looks like
- fn expand_flag(&self) -> &'static str {
- match *self {
- ToolFamily::Msvc { .. } => "/E",
- ToolFamily::Gnu | ToolFamily::Clang => "-E",
- }
- }
-
/// What the flags to enable all warnings
fn warnings_flags(&self) -> &'static str {
match *self {
- ToolFamily::Msvc { .. } => "/W4",
+ ToolFamily::Msvc { .. } => "-W4",
ToolFamily::Gnu | ToolFamily::Clang => "-Wall",
}
}
@@ -246,29 +237,11 @@ impl ToolFamily {
/// What the flag to turn warning into errors
fn warnings_to_errors_flag(&self) -> &'static str {
match *self {
- ToolFamily::Msvc { .. } => "/WX",
+ ToolFamily::Msvc { .. } => "-WX",
ToolFamily::Gnu | ToolFamily::Clang => "-Werror",
}
}
- /// NVCC-specific. Device code debug info flag. This is separate from the
- /// debug info flag passed to the C++ compiler.
- fn nvcc_debug_flag(&self) -> &'static str {
- match *self {
- ToolFamily::Msvc { .. } => unimplemented!(),
- ToolFamily::Gnu | ToolFamily::Clang => "-G",
- }
- }
-
- /// NVCC-specific. Redirect the following flag to the underlying C++
- /// compiler.
- fn nvcc_redirect_flag(&self) -> &'static str {
- match *self {
- ToolFamily::Msvc { .. } => unimplemented!(),
- ToolFamily::Gnu | ToolFamily::Clang => "-Xcompiler",
- }
- }
-
fn verbose_stderr(&self) -> bool {
*self == ToolFamily::Clang
}
@@ -447,12 +420,19 @@ impl Build {
let mut cmd = compiler.to_command();
let is_arm = target.contains("aarch64") || target.contains("arm");
- command_add_output_file(&mut cmd, &obj, target.contains("msvc"), false, is_arm);
+ command_add_output_file(
+ &mut cmd,
+ &obj,
+ self.cuda,
+ target.contains("msvc"),
+ false,
+ is_arm,
+ );
// We need to explicitly tell msvc not to link and create an exe
// in the root directory of the crate
- if target.contains("msvc") {
- cmd.arg("/c");
+ if target.contains("msvc") && !self.cuda {
+ cmd.arg("-c");
}
cmd.arg(&src);
@@ -493,7 +473,6 @@ impl Build {
/// .shared_flag(true)
/// .compile("libfoo.so");
/// ```
-
pub fn shared_flag(&mut self, shared_flag: bool) -> &mut Build {
self.shared_flag = Some(shared_flag);
self
@@ -588,7 +567,7 @@ impl Build {
/// Set warnings flags.
///
/// Adds some flags:
- /// - "/Wall" for MSVC.
+ /// - "-Wall" for MSVC.
/// - "-Wall", "-Wextra" for GNU and Clang.
///
/// Enabled by default.
@@ -764,9 +743,8 @@ impl Build {
/// 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.
+ /// This option is automatically scraped from the `DEBUG` environment
+ /// variable by build scripts, so it's not required to call this function.
pub fn debug(&mut self, debug: bool) -> &mut Build {
self.debug = Some(debug);
self
@@ -818,7 +796,7 @@ impl Build {
/// Configures whether the compiler will emit position independent code.
///
- /// This option defaults to `false` for `windows-gnu` targets and
+ /// This option defaults to `false` for `windows-gnu` and `riscv` targets and
/// to `true` for all other targets.
pub fn pic(&mut self, pic: bool) -> &mut Build {
self.pic = Some(pic);
@@ -1002,10 +980,10 @@ impl Build {
)
};
let is_arm = target.contains("aarch64") || target.contains("arm");
- command_add_output_file(&mut cmd, &obj.dst, msvc, is_asm, is_arm);
+ command_add_output_file(&mut cmd, &obj.dst, self.cuda, msvc, is_asm, is_arm);
// armasm and armasm64 don't requrie -c option
if !msvc || !is_asm || !is_arm {
- cmd.arg(if msvc { "/c" } else { "-c" });
+ cmd.arg("-c");
}
cmd.arg(&obj.src);
@@ -1020,7 +998,7 @@ impl Build {
for &(ref a, ref b) in self.env.iter() {
cmd.env(a, b);
}
- cmd.arg(compiler.family.expand_flag());
+ cmd.arg("-E");
assert!(
self.files.len() <= 1,
@@ -1110,7 +1088,7 @@ impl Build {
}
for directory in self.include_directories.iter() {
- cmd.args.push(cmd.family.include_flag().into());
+ cmd.args.push("-I".into());
cmd.args.push(directory.into());
}
@@ -1147,15 +1125,10 @@ impl Build {
}
for &(ref key, ref value) in self.definitions.iter() {
- let lead = if let ToolFamily::Msvc { .. } = cmd.family {
- "/"
- } else {
- "-"
- };
if let Some(ref value) = *value {
- cmd.args.push(format!("{}D{}={}", lead, key, value).into());
+ cmd.args.push(format!("-D{}={}", key, value).into());
} else {
- cmd.args.push(format!("{}D{}", lead, key).into());
+ cmd.args.push(format!("-D{}", key).into());
}
}
@@ -1177,32 +1150,29 @@ impl Build {
// If the flag is not conditioned on target variable, it belongs here :)
match cmd.family {
ToolFamily::Msvc { .. } => {
- assert!(!self.cuda,
- "CUDA C++ compilation not supported for MSVC, yet... but you are welcome to implement it :)");
-
- cmd.args.push("/nologo".into());
+ cmd.push_cc_arg("-nologo".into());
let crt_flag = match self.static_crt {
- Some(true) => "/MT",
- Some(false) => "/MD",
+ Some(true) => "-MT",
+ Some(false) => "-MD",
None => {
let features = self
.getenv("CARGO_CFG_TARGET_FEATURE")
.unwrap_or(String::new());
if features.contains("crt-static") {
- "/MT"
+ "-MT"
} else {
- "/MD"
+ "-MD"
}
}
};
- cmd.args.push(crt_flag.into());
+ cmd.push_cc_arg(crt_flag.into());
match &opt_level[..] {
// Msvc uses /O1 to enable all optimizations that minimize code size.
- "z" | "s" | "1" => cmd.push_opt_unless_duplicate("/O1".into()),
+ "z" | "s" | "1" => cmd.push_opt_unless_duplicate("-O1".into()),
// -O3 is a valid value for gcc and clang compilers, but not msvc. Cap to /O2.
- "2" | "3" => cmd.push_opt_unless_duplicate("/O2".into()),
+ "2" | "3" => cmd.push_opt_unless_duplicate("-O2".into()),
_ => {}
}
}
@@ -1219,7 +1189,11 @@ impl Build {
cmd.push_cc_arg("-ffunction-sections".into());
cmd.push_cc_arg("-fdata-sections".into());
}
- if self.pic.unwrap_or(!target.contains("windows-gnu")) {
+ // Disable generation of PIC on RISC-V for now: rust-lld doesn't support this yet
+ if self
+ .pic
+ .unwrap_or(!target.contains("windows-gnu") && !target.contains("riscv"))
+ {
cmd.push_cc_arg("-fPIC".into());
// PLT only applies if code is compiled with PIC support,
// and only for ELF targets.
@@ -1232,8 +1206,8 @@ impl Build {
if self.get_debug() {
if self.cuda {
- let nvcc_debug_flag = cmd.family.nvcc_debug_flag().into();
- cmd.args.push(nvcc_debug_flag);
+ // NVCC debug flag
+ cmd.args.push("-G".into());
}
let family = cmd.family;
family.add_debug_flags(cmd);
@@ -1250,13 +1224,13 @@ impl Build {
cmd.args.push("-m64".into());
} else if target.contains("86") {
cmd.args.push("-m32".into());
- cmd.args.push("/arch:IA32".into());
+ cmd.push_cc_arg("-arch:IA32".into());
} else {
- cmd.args.push(format!("--target={}", target).into());
+ cmd.push_cc_arg(format!("--target={}", target).into());
}
} else {
if target.contains("i586") {
- cmd.args.push("/ARCH:IA32".into());
+ cmd.push_cc_arg("-arch:IA32".into());
}
}
@@ -1271,7 +1245,7 @@ impl Build {
// Windows SDK it is required.
if target.contains("arm") || target.contains("thumb") {
cmd.args
- .push("/D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1".into());
+ .push("-D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1".into());
}
}
ToolFamily::Gnu => {
@@ -1422,6 +1396,21 @@ impl Build {
cmd.args.push("-mfloat-abi=soft".into());
}
}
+ if target.starts_with("riscv32") || target.starts_with("riscv64") {
+ // get the 32i/32imac/32imc/64gc/64imac/... part
+ let mut parts = target.split('-');
+ if let Some(arch) = parts.next() {
+ let arch = &arch[5..];
+ cmd.args.push(("-march=rv".to_owned() + arch).into());
+ // ABI is always soft-float right now, update this when this is no longer the
+ // case:
+ if arch.starts_with("64") {
+ cmd.args.push("-mabi=lp64".into());
+ } else {
+ cmd.args.push("-mabi=ilp32".into());
+ }
+ }
+ }
}
}
@@ -1480,18 +1469,18 @@ impl Build {
};
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);
+ 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));
+ cmd.arg(&format!("-D{}={}", key, value));
} else {
- cmd.arg(&format!("/D{}", key));
+ cmd.arg(&format!("-D{}", key));
}
}
if target.contains("i686") || target.contains("i586") {
- cmd.arg("/safeseh");
+ cmd.arg("-safeseh");
}
for flag in self.flags.iter() {
cmd.arg(flag);
@@ -1509,9 +1498,9 @@ impl Build {
let target = self.get_target()?;
if target.contains("msvc") {
let (mut cmd, program) = self.get_ar()?;
- let mut out = OsString::from("/OUT:");
+ let mut out = OsString::from("-out:");
out.push(dst);
- cmd.arg(out).arg("/nologo");
+ cmd.arg(out).arg("-nologo");
// Similar to https://github.com/rust-lang/rust/pull/47507
// and https://github.com/rust-lang/rust/pull/48548
@@ -1610,16 +1599,21 @@ impl Build {
}
};
+ let min_version =
+ std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into());
+
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());
+ cmd.args
+ .push(format!("-miphoneos-version-min={}", min_version).into());
"iphoneos"
}
ArchSpec::Simulator(arch) => {
cmd.args.push(arch.into());
- cmd.args.push("-mios-simulator-version-min=7.0".into());
+ cmd.args
+ .push(format!("-mios-simulator-version-min={}", min_version).into());
"iphonesimulator"
}
};
@@ -1751,10 +1745,13 @@ impl Build {
}
} else if target.contains("cloudabi") {
format!("{}-{}", target, traditional)
- } else if target == "wasm32-wasi" ||
- target == "wasm32-unknown-wasi" ||
- target == "wasm32-unknown-unknown" {
+ } else if target == "wasm32-wasi"
+ || target == "wasm32-unknown-wasi"
+ || target == "wasm32-unknown-unknown"
+ {
"clang".to_string()
+ } else if target.contains("vxworks") {
+ "wr-c++".to_string()
} else if self.get_host()? != target {
// CROSS_COMPILE is of the form: "arm-linux-gnueabi-"
let cc_env = self.getenv("CROSS_COMPILE");
@@ -1783,6 +1780,7 @@ impl Build {
"armv7-unknown-netbsd-eabihf" => Some("armv7--netbsdelf-eabihf"),
"i586-unknown-linux-musl" => Some("musl"),
"i686-pc-windows-gnu" => Some("i686-w64-mingw32"),
+ "i686-uwp-windows-gnu" => Some("i686-w64-mingw32"),
"i686-unknown-linux-musl" => Some("musl"),
"i686-unknown-netbsd" => Some("i486--netbsdelf"),
"mips-unknown-linux-gnu" => Some("mips-linux-gnu"),
@@ -1800,6 +1798,11 @@ impl Build {
"powerpc-unknown-netbsd" => Some("powerpc--netbsd"),
"powerpc64-unknown-linux-gnu" => Some("powerpc-linux-gnu"),
"powerpc64le-unknown-linux-gnu" => Some("powerpc64le-linux-gnu"),
+ "riscv32i-unknown-none-elf" => Some("riscv32-unknown-elf"),
+ "riscv32imac-unknown-none-elf" => Some("riscv32-unknown-elf"),
+ "riscv32imc-unknown-none-elf" => Some("riscv32-unknown-elf"),
+ "riscv64gc-unknown-none-elf" => Some("riscv64-unknown-elf"),
+ "riscv64imac-unknown-none-elf" => Some("riscv64-unknown-elf"),
"s390x-unknown-linux-gnu" => Some("s390x-linux-gnu"),
"sparc-unknown-linux-gnu" => Some("sparc-linux-gnu"),
"sparc64-unknown-linux-gnu" => Some("sparc64-linux-gnu"),
@@ -1817,6 +1820,7 @@ impl Build {
"thumbv8m.main-none-eabi" => Some("arm-none-eabi"),
"thumbv8m.main-none-eabihf" => Some("arm-none-eabi"),
"x86_64-pc-windows-gnu" => Some("x86_64-w64-mingw32"),
+ "x86_64-uwp-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"),
@@ -1846,6 +1850,7 @@ impl Build {
nvcc_tool
.args
.push(format!("-ccbin={}", tool.path.display()).into());
+ nvcc_tool.family = tool.family;
nvcc_tool
} else {
tool
@@ -2151,7 +2156,7 @@ impl Tool {
/// with a "-Xcompiler" flag to get passed to the underlying C++ compiler.
fn push_cc_arg(&mut self, flag: OsString) {
if self.cuda {
- self.args.push(self.family.nvcc_redirect_flag().into());
+ self.args.push("-Xcompiler".into());
}
self.args.push(flag);
}
@@ -2407,13 +2412,16 @@ fn fail(s: &str) -> ! {
std::process::exit(1);
}
-fn command_add_output_file(cmd: &mut Command, dst: &Path, msvc: bool, is_asm: bool, is_arm: bool) {
- if msvc && is_asm && is_arm {
- cmd.arg("-o").arg(&dst);
- } else if msvc && is_asm {
- cmd.arg("/Fo").arg(dst);
- } else if msvc {
- let mut s = OsString::from("/Fo");
+fn command_add_output_file(
+ cmd: &mut Command,
+ dst: &Path,
+ cuda: bool,
+ msvc: bool,
+ is_asm: bool,
+ is_arm: bool,
+) {
+ if msvc && !cuda && !(is_asm && is_arm) {
+ let mut s = OsString::from("-Fo");
s.push(&dst);
cmd.arg(s);
} else {
diff --git a/cc/src/windows_registry.rs b/cc/src/windows_registry.rs
index af812a7..ee39339 100644
--- a/cc/src/windows_registry.rs
+++ b/cc/src/windows_registry.rs
@@ -180,8 +180,8 @@ mod impl_ {
use std::ffi::OsString;
use std::fs::File;
use std::io::Read;
- use std::mem;
use std::iter;
+ use std::mem;
use std::path::{Path, PathBuf};
use Tool;
@@ -218,7 +218,7 @@ mod impl_ {
}
}
- fn vs16_instances() -> Box<Iterator<Item=PathBuf>> {
+ fn vs16_instances() -> Box<Iterator<Item = PathBuf>> {
let instances = if let Some(instances) = vs15_instances() {
instances
} else {
@@ -236,17 +236,19 @@ mod impl_ {
}
fn find_tool_in_vs16_path(tool: &str, target: &str) -> Option<Tool> {
- vs16_instances().filter_map(|path| {
- let path = path.join(tool);
- if !path.is_file() {
- return None;
- }
- let mut tool = Tool::new(path);
- if target.contains("x86_64") {
- tool.env.push(("Platform".into(), "X64".into()));
- }
- Some(tool)
- }).next()
+ vs16_instances()
+ .filter_map(|path| {
+ let path = path.join(tool);
+ if !path.is_file() {
+ return None;
+ }
+ let mut tool = Tool::new(path);
+ if target.contains("x86_64") {
+ tool.env.push(("Platform".into(), "X64".into()));
+ }
+ Some(tool)
+ })
+ .next()
}
fn find_msbuild_vs16(target: &str) -> Option<Tool> {
@@ -727,7 +729,9 @@ mod impl_ {
// see http://stackoverflow.com/questions/328017/path-to-msbuild
pub fn find_msbuild(target: &str) -> Option<Tool> {
// VS 15 (2017) changed how to locate msbuild
- if let Some(r) = find_msbuild_vs15(target) {
+ if let Some(r) = find_msbuild_vs16(target) {
+ return Some(r);
+ } else if let Some(r) = find_msbuild_vs15(target) {
return Some(r);
} else {
find_old_msbuild(target)
diff --git a/cc/tests/cflags.rs b/cc/tests/cflags.rs
new file mode 100644
index 0000000..df6b0a7
--- /dev/null
+++ b/cc/tests/cflags.rs
@@ -0,0 +1,18 @@
+extern crate cc;
+extern crate tempdir;
+
+mod support;
+
+use std::env;
+use support::Test;
+
+/// This test is in its own module because it modifies the environment and would affect other tests
+/// when run in parallel with them.
+#[test]
+fn gnu_no_warnings_if_cflags() {
+ env::set_var("CFLAGS", "-arbitrary");
+ let test = Test::gnu();
+ test.gcc().file("foo.c").compile("foo");
+
+ test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra");
+}
diff --git a/cc/tests/cxxflags.rs b/cc/tests/cxxflags.rs
new file mode 100644
index 0000000..26426af
--- /dev/null
+++ b/cc/tests/cxxflags.rs
@@ -0,0 +1,18 @@
+extern crate cc;
+extern crate tempdir;
+
+mod support;
+
+use std::env;
+use support::Test;
+
+/// This test is in its own module because it modifies the environment and would affect other tests
+/// when run in parallel with them.
+#[test]
+fn gnu_no_warnings_if_cxxflags() {
+ env::set_var("CXXFLAGS", "-arbitrary");
+ let test = Test::gnu();
+ test.gcc().file("foo.cpp").cpp(true).compile("foo");
+
+ test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra");
+}
diff --git a/cc/tests/support/mod.rs b/cc/tests/support/mod.rs
index 72ca3fa..7d74719 100644
--- a/cc/tests/support/mod.rs
+++ b/cc/tests/support/mod.rs
@@ -1,10 +1,11 @@
#![allow(dead_code)]
use std::env;
-use std::ffi::OsStr;
+use std::ffi::{OsStr, OsString};
use std::fs::{self, File};
+use std::io;
use std::io::prelude::*;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
use cc;
use tempdir::TempDir;
@@ -26,9 +27,10 @@ impl Test {
if gcc.ends_with("deps") {
gcc.pop();
}
+ let td = TempDir::new_in(&gcc, "gcc-test").unwrap();
gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX));
Test {
- td: TempDir::new("gcc-test").unwrap(),
+ td: td,
gcc: gcc,
msvc: false,
}
@@ -48,17 +50,18 @@ impl Test {
}
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();
+ link_or_copy(
+ &self.gcc,
+ self.td
+ .path()
+ .join(&format!("{}{}", name, env::consts::EXE_SUFFIX)),
+ )
+ .unwrap();
self
}
pub fn gcc(&self) -> cc::Build {
let mut cfg = cc::Build::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 {
@@ -70,7 +73,7 @@ impl Test {
.opt_level(2)
.debug(false)
.out_dir(self.td.path())
- .__set_env("PATH", env::join_paths(path).unwrap())
+ .__set_env("PATH", self.path())
.__set_env("GCCTEST_OUT_DIR", self.td.path());
if self.msvc {
cfg.compiler(self.td.path().join("cl"));
@@ -79,6 +82,12 @@ impl Test {
cfg
}
+ fn path(&self) -> OsString {
+ let mut path = env::split_paths(&env::var_os("PATH").unwrap()).collect::<Vec<_>>();
+ path.insert(0, self.td.path().to_owned());
+ env::join_paths(path).unwrap()
+ }
+
pub fn cmd(&self, i: u32) -> Execution {
let mut s = String::new();
File::open(self.td.path().join(format!("out{}", i)))
@@ -131,3 +140,22 @@ impl Execution {
self
}
}
+
+/// Hard link an executable or copy it if that fails.
+///
+/// We first try to hard link an executable to save space. If that fails (as on Windows with
+/// different mount points, issue #60), we copy.
+#[cfg(not(target_os = "macos"))]
+fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
+ let from = from.as_ref();
+ let to = to.as_ref();
+ fs::hard_link(from, to).or_else(|_| fs::copy(from, to).map(|_| ()))
+}
+
+/// Copy an executable.
+///
+/// On macOS, hard linking the executable leads to strange failures (issue #419), so we just copy.
+#[cfg(target_os = "macos")]
+fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
+ fs::copy(from, to).map(|_| ())
+}
diff --git a/cc/tests/test.rs b/cc/tests/test.rs
index 5147b77..74eca1e 100644
--- a/cc/tests/test.rs
+++ b/cc/tests/test.rs
@@ -1,7 +1,6 @@
extern crate cc;
extern crate tempdir;
-use std::env;
use support::Test;
mod support;
@@ -112,26 +111,6 @@ fn gnu_warnings_overridable() {
}
#[test]
-fn gnu_no_warnings_if_cflags() {
- env::set_var("CFLAGS", "-Wflag-does-not-exist");
- let test = Test::gnu();
- test.gcc().file("foo.c").compile("foo");
-
- test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra");
- env::set_var("CFLAGS", "");
-}
-
-#[test]
-fn gnu_no_warnings_if_cxxflags() {
- env::set_var("CXXFLAGS", "-Wflag-does-not-exist");
- let test = Test::gnu();
- test.gcc().file("foo.c").compile("foo");
-
- test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra");
- env::set_var("CXXFLAGS", "");
-}
-
-#[test]
fn gnu_x86_64() {
for vendor in &["unknown-linux-gnu", "apple-darwin"] {
let target = format!("x86_64-{}", vendor);
@@ -311,11 +290,11 @@ fn msvc_smoke() {
test.gcc().file("foo.c").compile("foo");
test.cmd(0)
- .must_have("/O2")
+ .must_have("-O2")
.must_have("foo.c")
- .must_not_have("/Z7")
- .must_have("/c")
- .must_have("/MD");
+ .must_not_have("-Z7")
+ .must_have("-c")
+ .must_have("-MD");
test.cmd(1).must_have(test.td.path().join("foo.o"));
}
@@ -324,14 +303,14 @@ fn msvc_opt_level_0() {
let test = Test::msvc();
test.gcc().opt_level(0).file("foo.c").compile("foo");
- test.cmd(0).must_not_have("/O2");
+ test.cmd(0).must_not_have("-O2");
}
#[test]
fn msvc_debug() {
let test = Test::msvc();
test.gcc().debug(true).file("foo.c").compile("foo");
- test.cmd(0).must_have("/Z7");
+ test.cmd(0).must_have("-Z7");
}
#[test]
@@ -339,7 +318,7 @@ fn msvc_include() {
let test = Test::msvc();
test.gcc().include("foo/bar").file("foo.c").compile("foo");
- test.cmd(0).must_have("/I").must_have("foo/bar");
+ test.cmd(0).must_have("-I").must_have("foo/bar");
}
#[test]
@@ -351,7 +330,7 @@ fn msvc_define() {
.file("foo.c")
.compile("foo");
- test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR");
+ test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
}
#[test]
@@ -359,7 +338,7 @@ fn msvc_static_crt() {
let test = Test::msvc();
test.gcc().static_crt(true).file("foo.c").compile("foo");
- test.cmd(0).must_have("/MT");
+ test.cmd(0).must_have("-MT");
}
#[test]
@@ -367,5 +346,5 @@ fn msvc_no_static_crt() {
let test = Test::msvc();
test.gcc().static_crt(false).file("foo.c").compile("foo");
- test.cmd(0).must_have("/MD");
+ test.cmd(0).must_have("-MD");
}
diff --git a/nitrocli/CHANGELOG.md b/nitrocli/CHANGELOG.md
index d99ff9e..d74f7b8 100644
--- a/nitrocli/CHANGELOG.md
+++ b/nitrocli/CHANGELOG.md
@@ -8,6 +8,7 @@ Unreleased
- Moved its output into `status` command
- Removed previously deprecated `--ascii` option from `otp set` command
- Bumped `libc` dependency to `0.2.62`
+- Bumped `cc` dependency to `1.0.40`
0.2.4
diff --git a/nitrocli/Cargo.lock b/nitrocli/Cargo.lock
index 42fb47b..3b6b852 100644
--- a/nitrocli/Cargo.lock
+++ b/nitrocli/Cargo.lock
@@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
-version = "1.0.37"
+version = "1.0.40"
[[package]]
name = "cfg-if"
@@ -96,7 +96,7 @@ dependencies = [
name = "nitrokey-sys"
version = "3.4.3"
dependencies = [
- "cc 1.0.37",
+ "cc 1.0.40",
]
[[package]]