Skip to content

Commit c34105e

Browse files
author
cavivie
committed
Support finding windows tools on non-Windows host
1 parent 2d6a3b2 commit c34105e

File tree

2 files changed

+78
-20
lines changed

2 files changed

+78
-20
lines changed

src/lib.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ mod vs_instances;
8787
#[cfg(windows)]
8888
mod windows_sys;
8989

90-
pub mod windows_registry;
90+
pub mod windows_helper;
9191

9292
/// A builder for compilation of a native library.
9393
///
@@ -2187,7 +2187,7 @@ impl Build {
21872187
} else {
21882188
"ml.exe"
21892189
};
2190-
let mut cmd = windows_registry::find(&target, tool).unwrap_or_else(|| self.cmd(tool));
2190+
let mut cmd = windows_helper::find(&target, tool).unwrap_or_else(|| self.cmd(tool));
21912191
cmd.arg("-nologo"); // undocumented, yet working with armasm[64]
21922192
for directory in self.include_directories.iter() {
21932193
cmd.arg("-I").arg(&**directory);
@@ -2540,7 +2540,7 @@ impl Build {
25402540
traditional
25412541
};
25422542

2543-
let cl_exe = windows_registry::find_tool(&target, "cl.exe");
2543+
let cl_exe = windows_helper::find_tool(&target, "cl.exe");
25442544

25452545
let tool_opt: Option<Tool> = self
25462546
.env_tool(env)
@@ -3008,7 +3008,7 @@ impl Build {
30083008

30093009
if lib.is_empty() {
30103010
name = String::from("lib.exe");
3011-
match windows_registry::find(&target, "lib.exe") {
3011+
match windows_helper::find(&target, "lib.exe") {
30123012
Some(t) => t,
30133013
None => self.cmd("lib.exe"),
30143014
}
@@ -3543,7 +3543,6 @@ impl Tool {
35433543
Self::with_features(path, clang_driver, false)
35443544
}
35453545

3546-
#[cfg(windows)]
35473546
/// Explicitly set the `ToolFamily`, skipping name-based detection.
35483547
fn with_family(path: PathBuf, family: ToolFamily) -> Self {
35493548
Self {

src/windows_registry.rs renamed to src/windows_helper.rs

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! A helper module to probe the Windows Registry when looking for
12-
//! windows-specific tools.
11+
//! A helper module to looking for windows-specific tools:
12+
//! 1. On Windows host, probe the Windows Registry if needed;
13+
//! 2. On non-Windows host, check specified environment variables.
1314
1415
use std::process::Command;
1516

1617
use crate::Tool;
17-
#[cfg(windows)]
1818
use crate::ToolFamily;
1919

20-
#[cfg(windows)]
2120
const MSVC_FAMILY: ToolFamily = ToolFamily::Msvc { clang_cl: false };
2221

23-
/// Attempts to find a tool within an MSVC installation using the Windows
24-
/// registry as a point to search from.
22+
/// Attempts to find a tool within an MSVC installation:
23+
/// 1. On Windows host, using the Windows registry as a point to search from;
24+
/// 2. On non-Windows host, using related environment variables to search from.
25+
///
2526
///
2627
/// The `target` argument is the target that the tool should work for (e.g.
2728
/// compile or link for) and the `tool` argument is the tool to find (e.g.
@@ -39,13 +40,6 @@ pub fn find(target: &str, tool: &str) -> Option<Command> {
3940
/// Similar to the `find` function above, this function will attempt the same
4041
/// operation (finding a MSVC tool in a local install) but instead returns a
4142
/// `Tool` which may be introspected.
42-
#[cfg(not(windows))]
43-
pub fn find_tool(_target: &str, _tool: &str) -> Option<Tool> {
44-
None
45-
}
46-
47-
/// Documented above.
48-
#[cfg(windows)]
4943
pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
5044
// This logic is all tailored for MSVC, if we're not that then bail out
5145
// early.
@@ -54,12 +48,13 @@ pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
5448
}
5549

5650
// Looks like msbuild isn't located in the same location as other tools like
57-
// cl.exe and lib.exe. To handle this we probe for it manually with
58-
// dedicated registry keys.
51+
// cl.exe and lib.exe.
5952
if tool.contains("msbuild") {
6053
return impl_::find_msbuild(target);
6154
}
6255

56+
// Looks like devenv isn't located in the same location as other tools like
57+
// cl.exe and lib.exe.
6358
if tool.contains("devenv") {
6459
return impl_::find_devenv(target);
6560
}
@@ -152,6 +147,7 @@ pub fn find_vs_version() -> Result<VsVers, String> {
152147
}
153148
}
154149

150+
/// Windows Implementation.
155151
#[cfg(windows)]
156152
mod impl_ {
157153
use crate::com;
@@ -882,6 +878,7 @@ mod impl_ {
882878
}
883879
}
884880

881+
// To find devenv we probe for it manually with dedicated registry keys.
885882
pub fn find_devenv(target: &str) -> Option<Tool> {
886883
find_devenv_vs15(&target)
887884
}
@@ -890,6 +887,7 @@ mod impl_ {
890887
find_tool_in_vs15_path(r"Common7\IDE\devenv.exe", target)
891888
}
892889

890+
// To find msbuild we probe for it manually with dedicated registry keys.
893891
// see http://stackoverflow.com/questions/328017/path-to-msbuild
894892
pub fn find_msbuild(target: &str) -> Option<Tool> {
895893
// VS 15 (2017) changed how to locate msbuild
@@ -927,3 +925,64 @@ mod impl_ {
927925
})
928926
}
929927
}
928+
929+
/// Non-Windows Implementation.
930+
#[cfg(not(windows))]
931+
mod impl_ {
932+
use std::{env, ffi::OsString};
933+
934+
use super::MSVC_FAMILY;
935+
use crate::Tool;
936+
937+
/// Finding msbuild.exe tool under unix system is not currently supported.
938+
/// Maybe can check it using an environment variable looks like `MSBUILD_BIN`.
939+
pub fn find_msbuild(_target: &str) -> Option<Tool> {
940+
None
941+
}
942+
943+
// Finding devenv.exe tool under unix system is not currently supported.
944+
// Maybe can check it using an environment variable looks like `DEVENV_BIN`.
945+
pub fn find_devenv(_target: &str) -> Option<Tool> {
946+
None
947+
}
948+
949+
/// Attempt to find the tool using environment variables set by vcvars.
950+
pub fn find_msvc_environment(tool: &str, _target: &str) -> Option<Tool> {
951+
// Early return if the environment doesn't contain a VC install.
952+
let _vc_install_dir = env::var_os("VCINSTALLDIR")?;
953+
let vs_install_dir = env::var_os("VSINSTALLDIR")?;
954+
955+
let search = |path: OsString| {
956+
env::split_paths(&path)
957+
.map(|p| p.join(tool))
958+
.find(|p| p.exists())
959+
};
960+
961+
search(vs_install_dir)
962+
.or_else(|| {
963+
// Fallback to simply using the current environment.
964+
env::var_os("PATH").and_then(search)
965+
})
966+
.map(|path| Tool::with_family(path.into(), MSVC_FAMILY))
967+
}
968+
969+
pub fn find_msvc_15plus(_tool: &str, _target: &str) -> Option<Tool> {
970+
None
971+
}
972+
973+
// For MSVC 14 we need to find the Universal CRT as well as either
974+
// the Windows 10 SDK or Windows 8.1 SDK.
975+
pub fn find_msvc_14(_tool: &str, _target: &str) -> Option<Tool> {
976+
None
977+
}
978+
979+
// For MSVC 12 we need to find the Windows 8.1 SDK.
980+
pub fn find_msvc_12(_tool: &str, _target: &str) -> Option<Tool> {
981+
None
982+
}
983+
984+
// For MSVC 11 we need to find the Windows 8 SDK.
985+
pub fn find_msvc_11(_tool: &str, _target: &str) -> Option<Tool> {
986+
None
987+
}
988+
}

0 commit comments

Comments
 (0)