diff options
Diffstat (limited to 'cc/src')
-rw-r--r-- | cc/src/lib.rs | 54 | ||||
-rw-r--r-- | cc/src/windows_registry.rs | 81 |
2 files changed, 102 insertions, 33 deletions
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> { |