8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
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.
13
14
14
15
#![ allow( clippy:: upper_case_acronyms) ]
15
16
16
17
use std:: process:: Command ;
17
18
18
19
use crate :: Tool ;
19
- #[ cfg( windows) ]
20
20
use crate :: ToolFamily ;
21
21
22
- #[ cfg( windows) ]
23
22
const MSVC_FAMILY : ToolFamily = ToolFamily :: Msvc { clang_cl : false } ;
24
23
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
+
25
39
/// Attempts to find a tool within an MSVC installation using the Windows
26
40
/// registry as a point to search from.
27
41
///
@@ -41,13 +55,6 @@ pub fn find(target: &str, tool: &str) -> Option<Command> {
41
55
/// Similar to the `find` function above, this function will attempt the same
42
56
/// operation (finding a MSVC tool in a local install) but instead returns a
43
57
/// `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) ]
51
58
pub fn find_tool ( target : & str , tool : & str ) -> Option < Tool > {
52
59
// This logic is all tailored for MSVC, if we're not that then bail out
53
60
// early.
@@ -56,15 +63,16 @@ pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
56
63
}
57
64
58
65
// Split the target to get the arch.
59
- let target = impl_ :: TargetArch ( target. split_once ( '-' ) ?. 0 ) ;
66
+ let target = TargetArch ( target. split_once ( '-' ) ?. 0 ) ;
60
67
61
68
// 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.
64
70
if tool. contains ( "msbuild" ) {
65
71
return impl_:: find_msbuild ( target) ;
66
72
}
67
73
74
+ // Looks like devenv isn't located in the same location as other tools like
75
+ // cl.exe and lib.exe.
68
76
if tool. contains ( "devenv" ) {
69
77
return impl_:: find_devenv ( target) ;
70
78
}
@@ -103,17 +111,8 @@ pub enum VsVers {
103
111
///
104
112
/// This is used by the cmake crate to figure out the correct
105
113
/// 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) ]
113
114
pub fn find_vs_version ( ) -> Result < VsVers , String > {
114
- use std:: env;
115
-
116
- match env:: var ( "VisualStudioVersion" ) {
115
+ match std:: env:: var ( "VisualStudioVersion" ) {
117
116
Ok ( version) => match & version[ ..] {
118
117
"17.0" => Ok ( VsVers :: Vs17 ) ,
119
118
"16.0" => Ok ( VsVers :: Vs16 ) ,
@@ -157,6 +156,7 @@ pub fn find_vs_version() -> Result<VsVers, String> {
157
156
}
158
157
}
159
158
159
+ /// Windows Implementation.
160
160
#[ cfg( windows) ]
161
161
mod impl_ {
162
162
use crate :: windows:: com;
@@ -180,24 +180,9 @@ mod impl_ {
180
180
use std:: sync:: atomic:: { AtomicBool , Ordering } ;
181
181
use std:: sync:: Once ;
182
182
183
- use super :: MSVC_FAMILY ;
183
+ use super :: { TargetArch , MSVC_FAMILY } ;
184
184
use crate :: Tool ;
185
185
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
-
201
186
struct MsvcTool {
202
187
tool : PathBuf ,
203
188
libs : Vec < PathBuf > ,
@@ -312,7 +297,7 @@ mod impl_ {
312
297
}
313
298
314
299
/// 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 > {
316
301
// Early return if the environment doesn't contain a VC install.
317
302
if env:: var_os ( "VCINSTALLDIR" ) . is_none ( ) {
318
303
return None ;
@@ -464,7 +449,7 @@ mod impl_ {
464
449
. collect ( )
465
450
}
466
451
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 > {
468
453
let iter = vs15plus_instances ( target) ?;
469
454
iter. into_iter ( )
470
455
. filter_map ( |instance| {
@@ -649,7 +634,7 @@ mod impl_ {
649
634
650
635
// For MSVC 14 we need to find the Universal CRT as well as either
651
636
// 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 > {
653
638
let vcdir = get_vc_dir ( "14.0" ) ?;
654
639
let mut tool = get_tool ( tool, & vcdir, target) ?;
655
640
add_sdks ( & mut tool, target) ?;
@@ -699,7 +684,7 @@ mod impl_ {
699
684
}
700
685
701
686
// 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 > {
703
688
let vcdir = get_vc_dir ( "12.0" ) ?;
704
689
let mut tool = get_tool ( tool, & vcdir, target) ?;
705
690
let sub = lib_subdir ( target) ?;
@@ -715,7 +700,7 @@ mod impl_ {
715
700
}
716
701
717
702
// 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 > {
719
704
let vcdir = get_vc_dir ( "11.0" ) ?;
720
705
let mut tool = get_tool ( tool, & vcdir, target) ?;
721
706
let sub = lib_subdir ( target) ?;
@@ -969,7 +954,7 @@ mod impl_ {
969
954
max_key
970
955
}
971
956
972
- pub fn has_msbuild_version ( version : & str ) -> bool {
957
+ pub ( super ) fn has_msbuild_version ( version : & str ) -> bool {
973
958
match version {
974
959
"17.0" => {
975
960
find_msbuild_vs17 ( TargetArch ( "x86_64" ) ) . is_some ( )
@@ -996,7 +981,7 @@ mod impl_ {
996
981
}
997
982
}
998
983
999
- pub fn find_devenv ( target : TargetArch < ' _ > ) -> Option < Tool > {
984
+ pub ( super ) fn find_devenv ( target : TargetArch < ' _ > ) -> Option < Tool > {
1000
985
find_devenv_vs15 ( target)
1001
986
}
1002
987
@@ -1005,7 +990,7 @@ mod impl_ {
1005
990
}
1006
991
1007
992
// 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 > {
1009
994
// VS 15 (2017) changed how to locate msbuild
1010
995
if let Some ( r) = find_msbuild_vs17 ( target) {
1011
996
Some ( r)
@@ -1041,3 +1026,75 @@ mod impl_ {
1041
1026
} )
1042
1027
}
1043
1028
}
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