diff options
-rw-r--r-- | cc/Cargo.toml | 2 | ||||
-rw-r--r-- | cc/azure-pipelines.yml | 4 | ||||
-rw-r--r-- | cc/ci/azure-install-rust.yml | 28 | ||||
-rw-r--r-- | cc/ci/azure-steps.yml | 11 | ||||
-rw-r--r-- | cc/src/bin/gcc-shim.rs | 39 | ||||
-rw-r--r-- | cc/src/lib.rs | 196 | ||||
-rw-r--r-- | cc/src/windows_registry.rs | 32 | ||||
-rw-r--r-- | cc/tests/cflags.rs | 18 | ||||
-rw-r--r-- | cc/tests/cxxflags.rs | 18 | ||||
-rw-r--r-- | cc/tests/support/mod.rs | 48 | ||||
-rw-r--r-- | cc/tests/test.rs | 41 | ||||
-rw-r--r-- | nitrocli/CHANGELOG.md | 1 | ||||
-rw-r--r-- | nitrocli/Cargo.lock | 4 |
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]] |