aboutsummaryrefslogtreecommitdiff
path: root/cc/src
diff options
context:
space:
mode:
Diffstat (limited to 'cc/src')
-rw-r--r--cc/src/lib.rs54
-rw-r--r--cc/src/windows_registry.rs81
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> {