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#![ allow( clippy:: upper_case_acronyms) ]
1516
1617use std:: process:: Command ;
1718
1819use crate :: Tool ;
19- #[ cfg( windows) ]
2020use crate :: ToolFamily ;
2121
22- #[ cfg( windows) ]
2322const MSVC_FAMILY : ToolFamily = ToolFamily :: Msvc { clang_cl : false } ;
2423
24+ #[ derive( Copy , Clone ) ]
25+ struct TargetArch < ' a > ( pub & ' a str ) ;
26+
27+ impl PartialEq < & str > for TargetArch < ' _ > {
28+ fn eq ( & self , other : & & str ) -> bool {
29+ self . 0 == * other
30+ }
31+ }
32+
33+ impl < ' a > From < TargetArch < ' a > > for & ' a str {
34+ fn from ( target : TargetArch < ' a > ) -> Self {
35+ target. 0
36+ }
37+ }
38+
2539/// Attempts to find a tool within an MSVC installation using the Windows
2640/// registry as a point to search from.
2741///
@@ -41,13 +55,6 @@ pub fn find(target: &str, tool: &str) -> Option<Command> {
4155/// Similar to the `find` function above, this function will attempt the same
4256/// operation (finding a MSVC tool in a local install) but instead returns a
4357/// `Tool` which may be introspected.
44- #[ cfg( not( windows) ) ]
45- pub fn find_tool ( _target : & str , _tool : & str ) -> Option < Tool > {
46- None
47- }
48-
49- /// Documented above.
50- #[ cfg( windows) ]
5158pub fn find_tool ( target : & str , tool : & str ) -> Option < Tool > {
5259 // This logic is all tailored for MSVC, if we're not that then bail out
5360 // early.
@@ -56,15 +63,16 @@ pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
5663 }
5764
5865 // Split the target to get the arch.
59- let target = impl_ :: TargetArch ( target. split_once ( '-' ) ?. 0 ) ;
66+ let target = TargetArch ( target. split_once ( '-' ) ?. 0 ) ;
6067
6168 // Looks like msbuild isn't located in the same location as other tools like
62- // cl.exe and lib.exe. To handle this we probe for it manually with
63- // dedicated registry keys.
69+ // cl.exe and lib.exe.
6470 if tool. contains ( "msbuild" ) {
6571 return impl_:: find_msbuild ( target) ;
6672 }
6773
74+ // Looks like devenv isn't located in the same location as other tools like
75+ // cl.exe and lib.exe.
6876 if tool. contains ( "devenv" ) {
6977 return impl_:: find_devenv ( target) ;
7078 }
@@ -103,17 +111,8 @@ pub enum VsVers {
103111///
104112/// This is used by the cmake crate to figure out the correct
105113/// generator.
106- #[ cfg( not( windows) ) ]
107- pub fn find_vs_version ( ) -> Result < VsVers , String > {
108- Err ( "not windows" . to_string ( ) )
109- }
110-
111- /// Documented above
112- #[ cfg( windows) ]
113114pub fn find_vs_version ( ) -> Result < VsVers , String > {
114- use std:: env;
115-
116- match env:: var ( "VisualStudioVersion" ) {
115+ match std:: env:: var ( "VisualStudioVersion" ) {
117116 Ok ( version) => match & version[ ..] {
118117 "17.0" => Ok ( VsVers :: Vs17 ) ,
119118 "16.0" => Ok ( VsVers :: Vs16 ) ,
@@ -157,6 +156,7 @@ pub fn find_vs_version() -> Result<VsVers, String> {
157156 }
158157}
159158
159+ /// Windows Implementation.
160160#[ cfg( windows) ]
161161mod impl_ {
162162 use crate :: windows:: com;
@@ -180,24 +180,9 @@ mod impl_ {
180180 use std:: sync:: atomic:: { AtomicBool , Ordering } ;
181181 use std:: sync:: Once ;
182182
183- use super :: MSVC_FAMILY ;
183+ use super :: { TargetArch , MSVC_FAMILY } ;
184184 use crate :: Tool ;
185185
186- #[ derive( Copy , Clone ) ]
187- pub struct TargetArch < ' a > ( pub & ' a str ) ;
188-
189- impl PartialEq < & str > for TargetArch < ' _ > {
190- fn eq ( & self , other : & & str ) -> bool {
191- self . 0 == * other
192- }
193- }
194-
195- impl < ' a > From < TargetArch < ' a > > for & ' a str {
196- fn from ( target : TargetArch < ' a > ) -> Self {
197- target. 0
198- }
199- }
200-
201186 struct MsvcTool {
202187 tool : PathBuf ,
203188 libs : Vec < PathBuf > ,
@@ -312,7 +297,7 @@ mod impl_ {
312297 }
313298
314299 /// Attempt to find the tool using environment variables set by vcvars.
315- pub fn find_msvc_environment ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
300+ pub ( super ) fn find_msvc_environment ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
316301 // Early return if the environment doesn't contain a VC install.
317302 if env:: var_os ( "VCINSTALLDIR" ) . is_none ( ) {
318303 return None ;
@@ -464,7 +449,7 @@ mod impl_ {
464449 . collect ( )
465450 }
466451
467- pub fn find_msvc_15plus ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
452+ pub ( super ) fn find_msvc_15plus ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
468453 let iter = vs15plus_instances ( target) ?;
469454 iter. into_iter ( )
470455 . filter_map ( |instance| {
@@ -649,7 +634,7 @@ mod impl_ {
649634
650635 // For MSVC 14 we need to find the Universal CRT as well as either
651636 // the Windows 10 SDK or Windows 8.1 SDK.
652- pub fn find_msvc_14 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
637+ pub ( super ) fn find_msvc_14 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
653638 let vcdir = get_vc_dir ( "14.0" ) ?;
654639 let mut tool = get_tool ( tool, & vcdir, target) ?;
655640 add_sdks ( & mut tool, target) ?;
@@ -699,7 +684,7 @@ mod impl_ {
699684 }
700685
701686 // For MSVC 12 we need to find the Windows 8.1 SDK.
702- pub fn find_msvc_12 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
687+ pub ( super ) fn find_msvc_12 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
703688 let vcdir = get_vc_dir ( "12.0" ) ?;
704689 let mut tool = get_tool ( tool, & vcdir, target) ?;
705690 let sub = lib_subdir ( target) ?;
@@ -715,7 +700,7 @@ mod impl_ {
715700 }
716701
717702 // For MSVC 11 we need to find the Windows 8 SDK.
718- pub fn find_msvc_11 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
703+ pub ( super ) fn find_msvc_11 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
719704 let vcdir = get_vc_dir ( "11.0" ) ?;
720705 let mut tool = get_tool ( tool, & vcdir, target) ?;
721706 let sub = lib_subdir ( target) ?;
@@ -969,7 +954,7 @@ mod impl_ {
969954 max_key
970955 }
971956
972- pub fn has_msbuild_version ( version : & str ) -> bool {
957+ pub ( super ) fn has_msbuild_version ( version : & str ) -> bool {
973958 match version {
974959 "17.0" => {
975960 find_msbuild_vs17 ( TargetArch ( "x86_64" ) ) . is_some ( )
@@ -996,7 +981,7 @@ mod impl_ {
996981 }
997982 }
998983
999- pub fn find_devenv ( target : TargetArch < ' _ > ) -> Option < Tool > {
984+ pub ( super ) fn find_devenv ( target : TargetArch < ' _ > ) -> Option < Tool > {
1000985 find_devenv_vs15 ( target)
1001986 }
1002987
@@ -1005,7 +990,7 @@ mod impl_ {
1005990 }
1006991
1007992 // see http://stackoverflow.com/questions/328017/path-to-msbuild
1008- pub fn find_msbuild ( target : TargetArch < ' _ > ) -> Option < Tool > {
993+ pub ( super ) fn find_msbuild ( target : TargetArch < ' _ > ) -> Option < Tool > {
1009994 // VS 15 (2017) changed how to locate msbuild
1010995 if let Some ( r) = find_msbuild_vs17 ( target) {
1011996 Some ( r)
@@ -1041,3 +1026,75 @@ mod impl_ {
10411026 } )
10421027 }
10431028}
1029+
1030+ /// Non-Windows Implementation.
1031+ #[ cfg( not( windows) ) ]
1032+ mod impl_ {
1033+ use std:: { env, ffi:: OsString } ;
1034+
1035+ use super :: { TargetArch , MSVC_FAMILY } ;
1036+ use crate :: Tool ;
1037+
1038+ /// Finding msbuild.exe tool under unix system is not currently supported.
1039+ /// Maybe can check it using an environment variable looks like `MSBUILD_BIN`.
1040+ pub ( super ) fn find_msbuild ( _target : TargetArch < ' _ > ) -> Option < Tool > {
1041+ None
1042+ }
1043+
1044+ // Finding devenv.exe tool under unix system is not currently supported.
1045+ // Maybe can check it using an environment variable looks like `DEVENV_BIN`.
1046+ pub ( super ) fn find_devenv ( _target : TargetArch < ' _ > ) -> Option < Tool > {
1047+ None
1048+ }
1049+
1050+ /// Attempt to find the tool using environment variables set by vcvars.
1051+ pub ( super ) fn find_msvc_environment ( tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
1052+ // Early return if the environment doesn't contain a VC install.
1053+ let vc_install_dir = env:: var_os ( "VCINSTALLDIR" ) ?;
1054+ let vs_install_dir = env:: var_os ( "VSINSTALLDIR" ) ?;
1055+
1056+ let get_tool = |install_dir : OsString | {
1057+ env:: split_paths ( & install_dir)
1058+ . map ( |p| p. join ( tool) )
1059+ . find ( |p| p. exists ( ) )
1060+ . map ( |path| Tool :: with_family ( path. into ( ) , MSVC_FAMILY ) )
1061+ } ;
1062+
1063+ // Take the path of tool for the vc install directory.
1064+ get_tool ( vc_install_dir)
1065+ // Take the path of tool for the vs install directory.
1066+ . or_else ( || get_tool ( vs_install_dir) )
1067+ // Take the path of tool for the current path environment.
1068+ . or_else ( || env:: var_os ( "PATH" ) . and_then ( |path| get_tool ( path) ) )
1069+ }
1070+
1071+ pub ( super ) fn find_msvc_15plus ( _tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
1072+ None
1073+ }
1074+
1075+ // For MSVC 14 we need to find the Universal CRT as well as either
1076+ // the Windows 10 SDK or Windows 8.1 SDK.
1077+ pub ( super ) fn find_msvc_14 ( _tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
1078+ None
1079+ }
1080+
1081+ // For MSVC 12 we need to find the Windows 8.1 SDK.
1082+ pub ( super ) fn find_msvc_12 ( _tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
1083+ None
1084+ }
1085+
1086+ // For MSVC 11 we need to find the Windows 8 SDK.
1087+ pub ( super ) fn find_msvc_11 ( _tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
1088+ None
1089+ }
1090+
1091+ pub ( super ) fn has_msbuild_version ( version : & str ) -> bool {
1092+ match version {
1093+ "17.0" => false ,
1094+ "16.0" => false ,
1095+ "15.0" => false ,
1096+ "12.0" | "14.0" => false ,
1097+ _ => false ,
1098+ }
1099+ }
1100+ }
0 commit comments