Browse Source

Update to the 2018 edition

gh-actions
Alex Crichton 5 years ago
parent
commit
19feaba0eb
  1. 1
      Cargo.toml
  2. 6
      README.md
  3. 1
      cc-test/Cargo.toml
  4. 2
      cc-test/build.rs
  5. 2
      cc-test/tests/all.rs
  6. 14
      src/com.rs
  7. 2
      src/lib.rs
  8. 24
      src/setup_config.rs
  9. 110
      src/windows_registry.rs
  10. 5
      tests/cc_env.rs
  11. 5
      tests/cflags.rs
  12. 5
      tests/cxxflags.rs
  13. 5
      tests/test.rs

1
Cargo.toml

@ -15,6 +15,7 @@ keywords = ["build-dependencies"]
readme = "README.md" readme = "README.md"
categories = ["development-tools::build-utils"] categories = ["development-tools::build-utils"]
exclude = ["/.travis.yml", "/appveyor.yml"] exclude = ["/.travis.yml", "/appveyor.yml"]
edition = "2018"
[dependencies] [dependencies]
num_cpus = { version = "1.10", optional = true } num_cpus = { version = "1.10", optional = true }

6
README.md

@ -28,8 +28,6 @@ Next up, you'll want to write a build script like so:
```rust,no_run ```rust,no_run
// build.rs // build.rs
extern crate cc;
fn main() { fn main() {
cc::Build::new() cc::Build::new()
.file("foo.c") .file("foo.c")
@ -143,8 +141,6 @@ required varies per platform, but there are three broad categories:
`Build`: `Build`:
```rust,no_run ```rust,no_run
extern crate cc;
fn main() { fn main() {
cc::Build::new() cc::Build::new()
.cpp(true) // Switch to C++ library compilation. .cpp(true) // Switch to C++ library compilation.
@ -163,8 +159,6 @@ linked to the crate target.
on `Build` (currently for GNU/Clang toolchains only): on `Build` (currently for GNU/Clang toolchains only):
```rust,no_run ```rust,no_run
extern crate cc;
fn main() { fn main() {
cc::Build::new() cc::Build::new()
// Switch to CUDA C++ library compilation using NVCC. // Switch to CUDA C++ library compilation using NVCC.

1
cc-test/Cargo.toml

@ -2,6 +2,7 @@
name = "cc-test" name = "cc-test"
version = "0.1.0" version = "0.1.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"] authors = ["Alex Crichton <alex@alexcrichton.com>"]
edition = "2018"
[lib] [lib]
name = "cc_test" name = "cc_test"

2
cc-test/build.rs

@ -1,5 +1,3 @@
extern crate cc;
use std::env; use std::env;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;

2
cc-test/tests/all.rs

@ -1,5 +1,3 @@
extern crate cc_test;
use cc_test::*; use cc_test::*;
#[link(name = "OptLinkage", kind = "static")] #[link(name = "OptLinkage", kind = "static")]

14
src/com.rs

@ -13,13 +13,13 @@ use std::ops::Deref;
use std::os::windows::ffi::{OsStrExt, OsStringExt}; use std::os::windows::ffi::{OsStrExt, OsStringExt};
use std::ptr::null_mut; use std::ptr::null_mut;
use std::slice::from_raw_parts; use std::slice::from_raw_parts;
use winapi::CoInitializeEx; use crate::winapi::CoInitializeEx;
use winapi::IUnknown; use crate::winapi::IUnknown;
use winapi::Interface; use crate::winapi::Interface;
use winapi::BSTR; use crate::winapi::BSTR;
use winapi::COINIT_MULTITHREADED; use crate::winapi::COINIT_MULTITHREADED;
use winapi::{SysFreeString, SysStringLen}; use crate::winapi::{SysFreeString, SysStringLen};
use winapi::{HRESULT, S_FALSE, S_OK}; use crate::winapi::{HRESULT, S_FALSE, S_OK};
pub fn initialize() -> Result<(), HRESULT> { pub fn initialize() -> Result<(), HRESULT> {
let err = unsafe { CoInitializeEx(null_mut(), COINIT_MULTITHREADED) }; let err = unsafe { CoInitializeEx(null_mut(), COINIT_MULTITHREADED) };

2
src/lib.rs

@ -42,8 +42,6 @@
//! Use the `Build` struct to compile `src/foo.c`: //! Use the `Build` struct to compile `src/foo.c`:
//! //!
//! ```no_run //! ```no_run
//! extern crate cc;
//!
//! fn main() { //! fn main() {
//! cc::Build::new() //! cc::Build::new()
//! .file("src/foo.c") //! .file("src/foo.c")

24
src/setup_config.rs

@ -10,17 +10,17 @@
use std::ffi::OsString; use std::ffi::OsString;
use std::ptr::null_mut; use std::ptr::null_mut;
use winapi::Interface; use crate::winapi::Interface;
use winapi::BSTR; use crate::winapi::BSTR;
use winapi::LPCOLESTR; use crate::winapi::LPCOLESTR;
use winapi::LPSAFEARRAY; use crate::winapi::LPSAFEARRAY;
use winapi::S_FALSE; use crate::winapi::S_FALSE;
use winapi::{CoCreateInstance, CLSCTX_ALL}; use crate::winapi::{CoCreateInstance, CLSCTX_ALL};
use winapi::{IUnknown, IUnknownVtbl}; use crate::winapi::{IUnknown, IUnknownVtbl};
use winapi::{HRESULT, LCID, LPCWSTR, PULONGLONG}; use crate::winapi::{HRESULT, LCID, LPCWSTR, PULONGLONG};
use winapi::{LPFILETIME, ULONG}; use crate::winapi::{LPFILETIME, ULONG};
use com::{BStr, ComPtr}; use crate::com::{BStr, ComPtr};
// Bindings to the Setup.Configuration stuff // Bindings to the Setup.Configuration stuff
pub type InstanceState = u32; pub type InstanceState = u32;
@ -196,7 +196,7 @@ impl SetupConfiguration {
} }
pub fn enum_all_instances(&self) -> Result<EnumSetupInstances, i32> { pub fn enum_all_instances(&self) -> Result<EnumSetupInstances, i32> {
let mut obj = null_mut(); let mut obj = null_mut();
let this = try!(self.0.cast::<ISetupConfiguration2>()); let this = self.0.cast::<ISetupConfiguration2>()?;
let err = unsafe { this.EnumAllInstances(&mut obj) }; let err = unsafe { this.EnumAllInstances(&mut obj) };
if err < 0 { if err < 0 {
return Err(err); return Err(err);
@ -249,7 +249,7 @@ impl SetupInstance {
} }
pub fn product_path(&self) -> Result<OsString, i32> { pub fn product_path(&self) -> Result<OsString, i32> {
let mut s = null_mut(); let mut s = null_mut();
let this = try!(self.0.cast::<ISetupInstance2>()); let this = self.0.cast::<ISetupInstance2>()?;
let err = unsafe { this.GetProductPath(&mut s) }; let err = unsafe { this.GetProductPath(&mut s) };
let bstr = unsafe { BStr::from_raw(s) }; let bstr = unsafe { BStr::from_raw(s) };
if err < 0 { if err < 0 {

110
src/windows_registry.rs

@ -13,17 +13,7 @@
use std::process::Command; use std::process::Command;
use Tool; use crate::Tool;
#[cfg(windows)]
macro_rules! otry {
($expr:expr) => {
match $expr {
Some(val) => val,
None => return None,
}
};
}
/// Attempts to find a tool within an MSVC installation using the Windows /// Attempts to find a tool within an MSVC installation using the Windows
/// registry as a point to search from. /// registry as a point to search from.
@ -173,9 +163,9 @@ pub fn find_vs_version() -> Result<VsVers, String> {
#[cfg(windows)] #[cfg(windows)]
mod impl_ { mod impl_ {
use com; use crate::com;
use registry::{RegistryKey, LOCAL_MACHINE}; use crate::registry::{RegistryKey, LOCAL_MACHINE};
use setup_config::{EnumSetupInstances, SetupConfiguration, SetupInstance}; use crate::setup_config::{EnumSetupInstances, SetupConfiguration, SetupInstance};
use std::env; use std::env;
use std::ffi::OsString; use std::ffi::OsString;
use std::fs::File; use std::fs::File;
@ -184,7 +174,7 @@ mod impl_ {
use std::mem; use std::mem;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use Tool; use crate::Tool;
struct MsvcTool { struct MsvcTool {
tool: PathBuf, tool: PathBuf,
@ -226,10 +216,10 @@ mod impl_ {
return Box::new(iter::empty()); return Box::new(iter::empty());
}; };
Box::new(instances.filter_map(|instance| { Box::new(instances.filter_map(|instance| {
let instance = otry!(instance.ok()); let instance = instance.ok()?;
let installation_name = otry!(instance.installation_name().ok()); let installation_name = instance.installation_name().ok()?;
if otry!(installation_name.to_str()).starts_with("VisualStudio/16.") { if installation_name.to_str()?.starts_with("VisualStudio/16.") {
Some(PathBuf::from(otry!(instance.installation_path().ok()))) Some(PathBuf::from(instance.installation_path().ok()?))
} else { } else {
None None
} }
@ -264,16 +254,16 @@ mod impl_ {
// //
// [online]: https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/ // [online]: https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/
fn vs15_instances() -> Option<EnumSetupInstances> { fn vs15_instances() -> Option<EnumSetupInstances> {
otry!(com::initialize().ok()); com::initialize().ok()?;
let config = otry!(SetupConfiguration::new().ok()); let config = SetupConfiguration::new().ok()?;
config.enum_all_instances().ok() config.enum_all_instances().ok()
} }
pub fn find_msvc_15(tool: &str, target: &str) -> Option<Tool> { pub fn find_msvc_15(tool: &str, target: &str) -> Option<Tool> {
let iter = otry!(vs15_instances()); let iter = vs15_instances()?;
for instance in iter { for instance in iter {
let instance = otry!(instance.ok()); let instance = instance.ok()?;
let tool = tool_from_vs15_instance(tool, target, &instance); let tool = tool_from_vs15_instance(tool, target, &instance);
if tool.is_some() { if tool.is_some() {
return tool; return tool;
@ -324,7 +314,7 @@ mod impl_ {
fn tool_from_vs15_instance(tool: &str, target: &str, instance: &SetupInstance) -> Option<Tool> { fn tool_from_vs15_instance(tool: &str, target: &str, instance: &SetupInstance) -> Option<Tool> {
let (bin_path, host_dylib_path, lib_path, include_path) = let (bin_path, host_dylib_path, lib_path, include_path) =
otry!(vs15_vc_paths(target, instance)); vs15_vc_paths(target, instance)?;
let tool_path = bin_path.join(tool); let tool_path = bin_path.join(tool);
if !tool_path.exists() { if !tool_path.exists() {
return None; return None;
@ -340,7 +330,7 @@ mod impl_ {
tool.include.push(atl_include_path); tool.include.push(atl_include_path);
} }
otry!(add_sdks(&mut tool, target)); add_sdks(&mut tool, target)?;
Some(tool.into_tool()) Some(tool.into_tool())
} }
@ -349,19 +339,19 @@ mod impl_ {
target: &str, target: &str,
instance: &SetupInstance, instance: &SetupInstance,
) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf)> { ) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf)> {
let instance_path: PathBuf = otry!(instance.installation_path().ok()).into(); let instance_path: PathBuf = instance.installation_path().ok()?.into();
let version_path = let version_path =
instance_path.join(r"VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"); instance_path.join(r"VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt");
let mut version_file = otry!(File::open(version_path).ok()); let mut version_file = File::open(version_path).ok()?;
let mut version = String::new(); let mut version = String::new();
otry!(version_file.read_to_string(&mut version).ok()); version_file.read_to_string(&mut version).ok()?;
let version = version.trim(); let version = version.trim();
let host = match host_arch() { let host = match host_arch() {
X86 => "X86", X86 => "X86",
X86_64 => "X64", X86_64 => "X64",
_ => return None, _ => return None,
}; };
let target = otry!(lib_subdir(target)); let target = lib_subdir(target)?;
// The directory layout here is MSVC/bin/Host$host/$target/ // The directory layout here is MSVC/bin/Host$host/$target/
let path = instance_path.join(r"VC\Tools\MSVC").join(version); let path = instance_path.join(r"VC\Tools\MSVC").join(version);
// This is the path to the toolchain for a particular target, running // This is the path to the toolchain for a particular target, running
@ -384,7 +374,7 @@ mod impl_ {
fn atl_paths(target: &str, path: &Path) -> Option<(PathBuf, PathBuf)> { fn atl_paths(target: &str, path: &Path) -> Option<(PathBuf, PathBuf)> {
let atl_path = path.join("atlfmc"); let atl_path = path.join("atlfmc");
let sub = otry!(lib_subdir(target)); let sub = lib_subdir(target)?;
if atl_path.exists() { if atl_path.exists() {
Some((atl_path.join("lib").join(sub), atl_path.join("include"))) Some((atl_path.join("lib").join(sub), atl_path.join("include")))
} else { } else {
@ -395,15 +385,15 @@ mod impl_ {
// For MSVC 14 we need to find the Universal CRT as well as either // For MSVC 14 we need to find the Universal CRT as well as either
// the Windows 10 SDK or Windows 8.1 SDK. // the Windows 10 SDK or Windows 8.1 SDK.
pub fn find_msvc_14(tool: &str, target: &str) -> Option<Tool> { pub fn find_msvc_14(tool: &str, target: &str) -> Option<Tool> {
let vcdir = otry!(get_vc_dir("14.0")); let vcdir = get_vc_dir("14.0")?;
let mut tool = otry!(get_tool(tool, &vcdir, target)); let mut tool = get_tool(tool, &vcdir, target)?;
otry!(add_sdks(&mut tool, target)); add_sdks(&mut tool, target)?;
Some(tool.into_tool()) Some(tool.into_tool())
} }
fn add_sdks(tool: &mut MsvcTool, target: &str) -> Option<()> { fn add_sdks(tool: &mut MsvcTool, target: &str) -> Option<()> {
let sub = otry!(lib_subdir(target)); let sub = lib_subdir(target)?;
let (ucrt, ucrt_version) = otry!(get_ucrt_dir()); let (ucrt, ucrt_version) = get_ucrt_dir()?;
tool.path tool.path
.push(ucrt.join("bin").join(&ucrt_version).join(sub)); .push(ucrt.join("bin").join(&ucrt_version).join(sub));
@ -438,10 +428,10 @@ mod impl_ {
// For MSVC 12 we need to find the Windows 8.1 SDK. // For MSVC 12 we need to find the Windows 8.1 SDK.
pub fn find_msvc_12(tool: &str, target: &str) -> Option<Tool> { pub fn find_msvc_12(tool: &str, target: &str) -> Option<Tool> {
let vcdir = otry!(get_vc_dir("12.0")); let vcdir = get_vc_dir("12.0")?;
let mut tool = otry!(get_tool(tool, &vcdir, target)); let mut tool = get_tool(tool, &vcdir, target)?;
let sub = otry!(lib_subdir(target)); let sub = lib_subdir(target)?;
let sdk81 = otry!(get_sdk81_dir()); let sdk81 = get_sdk81_dir()?;
tool.path.push(sdk81.join("bin").join(sub)); tool.path.push(sdk81.join("bin").join(sub));
let sdk_lib = sdk81.join("lib").join("winv6.3"); let sdk_lib = sdk81.join("lib").join("winv6.3");
tool.libs.push(sdk_lib.join("um").join(sub)); tool.libs.push(sdk_lib.join("um").join(sub));
@ -454,10 +444,10 @@ mod impl_ {
// For MSVC 11 we need to find the Windows 8 SDK. // For MSVC 11 we need to find the Windows 8 SDK.
pub fn find_msvc_11(tool: &str, target: &str) -> Option<Tool> { pub fn find_msvc_11(tool: &str, target: &str) -> Option<Tool> {
let vcdir = otry!(get_vc_dir("11.0")); let vcdir = get_vc_dir("11.0")?;
let mut tool = otry!(get_tool(tool, &vcdir, target)); let mut tool = get_tool(tool, &vcdir, target)?;
let sub = otry!(lib_subdir(target)); let sub = lib_subdir(target)?;
let sdk8 = otry!(get_sdk8_dir()); let sdk8 = get_sdk8_dir()?;
tool.path.push(sdk8.join("bin").join(sub)); tool.path.push(sdk8.join("bin").join(sub));
let sdk_lib = sdk8.join("lib").join("win8"); let sdk_lib = sdk8.join("lib").join("win8");
tool.libs.push(sdk_lib.join("um").join(sub)); tool.libs.push(sdk_lib.join("um").join(sub));
@ -494,7 +484,7 @@ mod impl_ {
tool tool
}) })
.filter_map(|mut tool| { .filter_map(|mut tool| {
let sub = otry!(vc_lib_subdir(target)); let sub = vc_lib_subdir(target)?;
tool.libs.push(path.join("lib").join(sub)); tool.libs.push(path.join("lib").join(sub));
tool.include.push(path.join("include")); tool.include.push(path.join("include"));
let atlmfc_path = path.join("atlmfc"); let atlmfc_path = path.join("atlmfc");
@ -511,8 +501,8 @@ mod impl_ {
// trying to find. // trying to find.
fn get_vc_dir(ver: &str) -> Option<PathBuf> { fn get_vc_dir(ver: &str) -> Option<PathBuf> {
let key = r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7"; let key = r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); let key = LOCAL_MACHINE.open(key.as_ref()).ok()?;
let path = otry!(key.query_str(ver).ok()); let path = key.query_str(ver).ok()?;
Some(path.into()) Some(path.into())
} }
@ -524,10 +514,10 @@ mod impl_ {
// Returns a pair of (root, version) for the ucrt dir if found // Returns a pair of (root, version) for the ucrt dir if found
fn get_ucrt_dir() -> Option<(PathBuf, String)> { fn get_ucrt_dir() -> Option<(PathBuf, String)> {
let key = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots"; let key = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); let key = LOCAL_MACHINE.open(key.as_ref()).ok()?;
let root = otry!(key.query_str("KitsRoot10").ok()); let root = key.query_str("KitsRoot10").ok()?;
let readdir = otry!(Path::new(&root).join("lib").read_dir().ok()); let readdir = Path::new(&root).join("lib").read_dir().ok()?;
let max_libdir = otry!(readdir let max_libdir = readdir
.filter_map(|dir| dir.ok()) .filter_map(|dir| dir.ok())
.map(|dir| dir.path()) .map(|dir| dir.path())
.filter(|dir| dir .filter(|dir| dir
@ -536,7 +526,7 @@ mod impl_ {
.and_then(|c| c.as_os_str().to_str()) .and_then(|c| c.as_os_str().to_str())
.map(|c| c.starts_with("10.") && dir.join("ucrt").is_dir()) .map(|c| c.starts_with("10.") && dir.join("ucrt").is_dir())
.unwrap_or(false)) .unwrap_or(false))
.max()); .max()?;
let version = max_libdir.components().last().unwrap(); let version = max_libdir.components().last().unwrap();
let version = version.as_os_str().to_str().unwrap().to_string(); let version = version.as_os_str().to_str().unwrap().to_string();
Some((root.into(), version)) Some((root.into(), version))
@ -552,19 +542,19 @@ mod impl_ {
// asciibetically to find the newest one as that is what vcvars does. // asciibetically to find the newest one as that is what vcvars does.
fn get_sdk10_dir() -> Option<(PathBuf, String)> { fn get_sdk10_dir() -> Option<(PathBuf, String)> {
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0"; let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); let key = LOCAL_MACHINE.open(key.as_ref()).ok()?;
let root = otry!(key.query_str("InstallationFolder").ok()); let root = key.query_str("InstallationFolder").ok()?;
let readdir = otry!(Path::new(&root).join("lib").read_dir().ok()); let readdir = Path::new(&root).join("lib").read_dir().ok()?;
let mut dirs = readdir let mut dirs = readdir
.filter_map(|dir| dir.ok()) .filter_map(|dir| dir.ok())
.map(|dir| dir.path()) .map(|dir| dir.path())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
dirs.sort(); dirs.sort();
let dir = otry!(dirs let dir = dirs
.into_iter() .into_iter()
.rev() .rev()
.filter(|dir| dir.join("um").join("x64").join("kernel32.lib").is_file()) .filter(|dir| dir.join("um").join("x64").join("kernel32.lib").is_file())
.next()); .next()?;
let version = dir.components().last().unwrap(); let version = dir.components().last().unwrap();
let version = version.as_os_str().to_str().unwrap().to_string(); let version = version.as_os_str().to_str().unwrap().to_string();
Some((root.into(), version)) Some((root.into(), version))
@ -576,15 +566,15 @@ mod impl_ {
// instead of user mode applications, we would care. // instead of user mode applications, we would care.
fn get_sdk81_dir() -> Option<PathBuf> { fn get_sdk81_dir() -> Option<PathBuf> {
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1"; let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); let key = LOCAL_MACHINE.open(key.as_ref()).ok()?;
let root = otry!(key.query_str("InstallationFolder").ok()); let root = key.query_str("InstallationFolder").ok()?;
Some(root.into()) Some(root.into())
} }
fn get_sdk8_dir() -> Option<PathBuf> { fn get_sdk8_dir() -> Option<PathBuf> {
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0"; let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0";
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); let key = LOCAL_MACHINE.open(key.as_ref()).ok()?;
let root = otry!(key.query_str("InstallationFolder").ok()); let root = key.query_str("InstallationFolder").ok()?;
Some(root.into()) Some(root.into())
} }

5
tests/cc_env.rs

@ -1,12 +1,9 @@
extern crate cc;
extern crate tempdir;
use std::env; use std::env;
use std::ffi::OsString; use std::ffi::OsString;
use std::path::Path; use std::path::Path;
mod support; mod support;
use support::Test; use crate::support::Test;
#[test] #[test]
fn main() { fn main() {

5
tests/cflags.rs

@ -1,10 +1,7 @@
extern crate cc;
extern crate tempdir;
mod support; mod support;
use std::env; use std::env;
use support::Test; use crate::support::Test;
/// This test is in its own module because it modifies the environment and would affect other tests /// This test is in its own module because it modifies the environment and would affect other tests
/// when run in parallel with them. /// when run in parallel with them.

5
tests/cxxflags.rs

@ -1,10 +1,7 @@
extern crate cc;
extern crate tempdir;
mod support; mod support;
use std::env; use std::env;
use support::Test; use crate::support::Test;
/// This test is in its own module because it modifies the environment and would affect other tests /// This test is in its own module because it modifies the environment and would affect other tests
/// when run in parallel with them. /// when run in parallel with them.

5
tests/test.rs

@ -1,7 +1,4 @@
extern crate cc; use crate::support::Test;
extern crate tempdir;
use support::Test;
mod support; mod support;

Loading…
Cancel
Save