diff options
Diffstat (limited to 'cc')
| -rw-r--r-- | cc/.travis.yml | 1 | ||||
| -rw-r--r-- | cc/Cargo.toml | 3 | ||||
| -rw-r--r-- | cc/src/lib.rs | 54 | ||||
| -rw-r--r-- | cc/src/windows_registry.rs | 81 | ||||
| -rw-r--r-- | cc/tests/test.rs | 14 | 
5 files changed, 118 insertions, 35 deletions
| diff --git a/cc/.travis.yml b/cc/.travis.yml index 70349e6..47bbfd8 100644 --- a/cc/.travis.yml +++ b/cc/.travis.yml @@ -49,7 +49,6 @@ script:    - cargo test --manifest-path cc-test/Cargo.toml --target $TARGET --release $NO_RUN    - cargo doc    - cargo clean && cargo build -  - rustdoc --test README.md -L target/debug -L target/debug/deps  env:    global: diff --git a/cc/Cargo.toml b/cc/Cargo.toml index f5004be..3966026 100644 --- a/cc/Cargo.toml +++ b/cc/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "cc" -version = "1.0.25" +version = "1.0.28"  authors = ["Alex Crichton <alex@alexcrichton.com>"]  license = "MIT/Apache-2.0"  repository = "https://github.com/alexcrichton/cc-rs" @@ -14,6 +14,7 @@ code.  keywords = ["build-dependencies"]  readme = "README.md"  categories = ["development-tools"] +exclude = ["/.travis.yml", "/appveyor.yml"]  [badges]  travis-ci = { repository = "alexcrichton/cc-rs" } diff --git a/cc/src/lib.rs b/cc/src/lib.rs index 7672cf4..5eebd07 100644 --- a/cc/src/lib.rs +++ b/cc/src/lib.rs @@ -55,6 +55,7 @@  #![doc(html_root_url = "https://docs.rs/cc/1.0")]  #![cfg_attr(test, deny(warnings))] +#![allow(deprecated)]  #![deny(missing_docs)]  #[cfg(feature = "parallel")] @@ -112,6 +113,7 @@ pub struct Build {      archiver: Option<PathBuf>,      cargo_metadata: bool,      pic: Option<bool>, +    use_plt: Option<bool>,      static_crt: Option<bool>,      shared_flag: Option<bool>,      static_flag: Option<bool>, @@ -319,6 +321,7 @@ impl Build {              archiver: None,              cargo_metadata: true,              pic: None, +            use_plt: None,              static_crt: None,              warnings: None,              extra_warnings: None, @@ -822,6 +825,21 @@ impl Build {          self      } +    /// Configures whether the Procedure Linkage Table is used for indirect +    /// calls into shared libraries. +    /// +    /// The PLT is used to provide features like lazy binding, but introduces +    /// a small performance loss due to extra pointer indirection. Setting +    /// `use_plt` to `false` can provide a small performance increase. +    /// +    /// Note that skipping the PLT requires a recent version of GCC/Clang. +    /// +    /// This only applies to ELF targets. It has no effect on other platforms. +    pub fn use_plt(&mut self, use_plt: bool) -> &mut Build { +        self.use_plt = Some(use_plt); +        self +    } +      /// Configures whether the /MT flag or the /MD flag will be passed to msvc build tools.      ///      /// This option defaults to `false`, and affect only msvc targets. @@ -1123,6 +1141,11 @@ impl Build {                  }                  if self.pic.unwrap_or(!target.contains("windows-gnu")) {                      cmd.push_cc_arg("-fPIC".into()); +                    // PLT only applies if code is compiled with PIC support, +                    // and only for ELF targets. +                    if target.contains("linux") && !self.use_plt.unwrap_or(true) { +                        cmd.push_cc_arg("-fno-plt".into()); +                    }                  }              }          } @@ -1159,6 +1182,19 @@ impl Build {                          cmd.args.push("/ARCH:IA32".into());                      }                  } + +                // There is a check in corecrt.h that will generate a +                // compilation error if +                // _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE is +                // not defined to 1. The check was added in Windows +                // 8 days because only store apps were allowed on ARM. +                // This changed with the release of Windows 10 IoT Core. +                // The check will be going away in future versions of +                // the SDK, but for all released versions of the +                // Windows SDK it is required. +                if target.contains("arm") || target.contains("thumb") { +                    cmd.args.push("/D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1".into()); +                }              }              ToolFamily::Gnu => {                  if target.contains("i686") || target.contains("i586") { @@ -1214,6 +1250,11 @@ impl Build {                  if target.starts_with("arm-unknown-linux-") {                      cmd.args.push("-march=armv6".into());                      cmd.args.push("-marm".into()); +                    if target.ends_with("hf") { +                        cmd.args.push("-mfpu=vfp".into()); +                    } else { +                        cmd.args.push("-mfloat-abi=soft".into()); +                    }                  }                  // We can guarantee some settings for FRC @@ -1264,6 +1305,16 @@ impl Build {                  if target.starts_with("thumbv7m") {                      cmd.args.push("-march=armv7-m".into());                  } +                if target.starts_with("thumbv8m.base") { +                    cmd.args.push("-march=armv8-m.base".into()); +                } +                if target.starts_with("thumbv8m.main") { +                    cmd.args.push("-march=armv8-m.main".into()); + +                    if target.ends_with("eabihf") { +                        cmd.args.push("-mfpu=fpv5-sp-d16".into()) +                    } +                }                  if target.starts_with("armebv7r") | target.starts_with("armv7r") {                      if target.starts_with("armeb") {                          cmd.args.push("-mbig-endian".into()); @@ -1718,6 +1769,9 @@ impl Build {                          "thumbv7em-none-eabi" => Some("arm-none-eabi"),                          "thumbv7em-none-eabihf" => Some("arm-none-eabi"),                          "thumbv7m-none-eabi" => Some("arm-none-eabi"), +                        "thumbv8m.base-none-eabi" => Some("arm-none-eabi"), +                        "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-rumprun-netbsd" => Some("x86_64-rumprun-netbsd"),                          "x86_64-unknown-linux-musl" => Some("musl"), diff --git a/cc/src/windows_registry.rs b/cc/src/windows_registry.rs index bbcbb09..ca6b989 100644 --- a/cc/src/windows_registry.rs +++ b/cc/src/windows_registry.rs @@ -174,7 +174,7 @@ mod impl_ {      use std::io::Read;      use registry::{RegistryKey, LOCAL_MACHINE};      use com; -    use setup_config::{SetupConfiguration, SetupInstance}; +    use setup_config::{EnumSetupInstances, SetupConfiguration, SetupInstance};      use Tool; @@ -217,11 +217,15 @@ mod impl_ {      // Note that much of this logic can be found [online] wrt paths, COM, etc.      //      // [online]: https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/ -    pub fn find_msvc_15(tool: &str, target: &str) -> Option<Tool> { +    fn vs15_instances() -> Option<EnumSetupInstances> {          otry!(com::initialize().ok());          let config = otry!(SetupConfiguration::new().ok()); -        let iter = otry!(config.enum_all_instances().ok()); +        config.enum_all_instances().ok() +    } + +    pub fn find_msvc_15(tool: &str, target: &str) -> Option<Tool> { +        let iter = otry!(vs15_instances());          for instance in iter {              let instance = otry!(instance.ok());              let tool = tool_from_vs15_instance(tool, target, &instance); @@ -233,6 +237,44 @@ mod impl_ {          None      } +    // While the paths to Visual Studio 2017's devenv and MSBuild could +    // potentially be retrieved from the registry, finding them via +    // SetupConfiguration has shown to be [more reliable], and is preferred +    // according to Microsoft. To help head off potential regressions though, +    // we keep the registry method as a fallback option. +    // +    // [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 vs15_instances() { +            Some(instances) => instances +                .filter_map(|instance| { +                    instance +                        .ok() +                        .and_then(|instance| instance.installation_path().ok()) +                }).map(|path| PathBuf::from(path).join(tool)) +                .find(|ref path| path.is_file()), +            None => None, +        }; + +        if path.is_none() { +            let key = r"SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7"; +            path = LOCAL_MACHINE +                .open(key.as_ref()) +                .ok() +                .and_then(|key| key.query_str("15.0").ok()) +                .map(|path| PathBuf::from(path).join(tool)) +                .filter(|ref path| path.is_file()); +        } + +        path.map(|path| { +            let mut tool = Tool::new(path); +            if target.contains("x86_64") { +                tool.env.push(("Platform".into(), "X64".into())); +            } +            tool +        }) +    } +      fn tool_from_vs15_instance(tool: &str, target: &str, instance: &SetupInstance) -> Option<Tool> {          let (bin_path, host_dylib_path, lib_path, include_path) =              otry!(vs15_vc_paths(target, instance)); @@ -595,7 +637,7 @@ mod impl_ {          for subkey in key.iter().filter_map(|k| k.ok()) {              let val = subkey                  .to_str() -                .and_then(|s| s.trim_left_matches("v").replace(".", "").parse().ok()); +                .and_then(|s| s.trim_start_matches("v").replace(".", "").parse().ok());              let val = match val {                  Some(s) => s,                  None => continue, @@ -631,19 +673,7 @@ mod impl_ {      }      fn find_devenv_vs15(target: &str) -> Option<Tool> { -        let key = r"SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7"; -        LOCAL_MACHINE -            .open(key.as_ref()) -            .ok() -            .and_then(|key| key.query_str("15.0").ok()) -            .map(|path| { -                let path = PathBuf::from(path).join(r"Common7\IDE\devenv.exe"); -                let mut tool = Tool::new(path); -                if target.contains("x86_64") { -                    tool.env.push(("Platform".into(), "X64".into())); -                } -                tool -            }) +        find_tool_in_vs15_path(r"Common7\IDE\devenv.exe", target)      }      // see http://stackoverflow.com/questions/328017/path-to-msbuild @@ -657,22 +687,7 @@ mod impl_ {      }      fn find_msbuild_vs15(target: &str) -> Option<Tool> { -        // Seems like this could also go through SetupConfiguration, -        // or that find_msvc_15 could just use this registry key -        // instead of the COM interface. -        let key = r"SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7"; -        LOCAL_MACHINE -            .open(key.as_ref()) -            .ok() -            .and_then(|key| key.query_str("15.0").ok()) -            .map(|path| { -                let path = PathBuf::from(path).join(r"MSBuild\15.0\Bin\MSBuild.exe"); -                let mut tool = Tool::new(path); -                if target.contains("x86_64") { -                    tool.env.push(("Platform".into(), "X64".into())); -                } -                tool -            }) +        find_tool_in_vs15_path(r"MSBuild\15.0\Bin\MSBuild.exe", target)      }      fn find_old_msbuild(target: &str) -> Option<Tool> { diff --git a/cc/tests/test.rs b/cc/tests/test.rs index 820072f..573a99a 100644 --- a/cc/tests/test.rs +++ b/cc/tests/test.rs @@ -198,6 +198,20 @@ fn gnu_i686_pic() {  }  #[test] +fn gnu_x86_64_no_plt() { +    let target = "x86_64-unknown-linux-gnu"; +    let test = Test::gnu(); +    test.gcc() +        .pic(true) +        .use_plt(false) +        .target(&target) +        .host(&target) +        .file("foo.c") +        .compile("foo"); +    test.cmd(0).must_have("-fno-plt"); +} + +#[test]  fn gnu_set_stdlib() {      let test = Test::gnu();      test.gcc() | 
