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.
14
+
15
+ #![ allow( clippy:: upper_case_acronyms) ]
13
16
14
17
#![ allow( clippy:: upper_case_acronyms) ]
15
18
16
19
use std:: process:: Command ;
17
20
18
21
use crate :: Tool ;
19
- #[ cfg( windows) ]
20
22
use crate :: ToolFamily ;
21
23
22
- #[ cfg( windows) ]
23
24
const MSVC_FAMILY : ToolFamily = ToolFamily :: Msvc { clang_cl : false } ;
24
25
25
- /// Attempts to find a tool within an MSVC installation using the Windows
26
- /// registry as a point to search from.
26
+ #[ derive( Copy , Clone ) ]
27
+ struct TargetArch < ' a > ( pub & ' a str ) ;
28
+
29
+ impl PartialEq < & str > for TargetArch < ' _ > {
30
+ fn eq ( & self , other : & & str ) -> bool {
31
+ self . 0 == * other
32
+ }
33
+ }
34
+
35
+ impl < ' a > From < TargetArch < ' a > > for & ' a str {
36
+ fn from ( target : TargetArch < ' a > ) -> Self {
37
+ target. 0
38
+ }
39
+ }
40
+
41
+ /// Attempts to find a tool within an MSVC installation:
42
+ /// 1. On Windows host, using the Windows registry as a point to search from;
43
+ /// 2. On non-Windows host, using related environment variables to search from.
44
+ ///
27
45
///
28
46
/// The `target` argument is the target that the tool should work for (e.g.
29
47
/// compile or link for) and the `tool` argument is the tool to find (e.g.
@@ -41,13 +59,6 @@ pub fn find(target: &str, tool: &str) -> Option<Command> {
41
59
/// Similar to the `find` function above, this function will attempt the same
42
60
/// operation (finding a MSVC tool in a local install) but instead returns a
43
61
/// `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
62
pub fn find_tool ( target : & str , tool : & str ) -> Option < Tool > {
52
63
// This logic is all tailored for MSVC, if we're not that then bail out
53
64
// early.
@@ -56,15 +67,16 @@ pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
56
67
}
57
68
58
69
// Split the target to get the arch.
59
- let target = impl_ :: TargetArch ( target. split_once ( '-' ) ?. 0 ) ;
70
+ let target = TargetArch ( target. split_once ( '-' ) ?. 0 ) ;
60
71
61
72
// 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.
73
+ // cl.exe and lib.exe.
64
74
if tool. contains ( "msbuild" ) {
65
75
return impl_:: find_msbuild ( target) ;
66
76
}
67
77
78
+ // Looks like devenv isn't located in the same location as other tools like
79
+ // cl.exe and lib.exe.
68
80
if tool. contains ( "devenv" ) {
69
81
return impl_:: find_devenv ( target) ;
70
82
}
@@ -103,17 +115,8 @@ pub enum VsVers {
103
115
///
104
116
/// This is used by the cmake crate to figure out the correct
105
117
/// 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
118
pub fn find_vs_version ( ) -> Result < VsVers , String > {
114
- use std:: env;
115
-
116
- match env:: var ( "VisualStudioVersion" ) {
119
+ match std:: env:: var ( "VisualStudioVersion" ) {
117
120
Ok ( version) => match & version[ ..] {
118
121
"17.0" => Ok ( VsVers :: Vs17 ) ,
119
122
"16.0" => Ok ( VsVers :: Vs16 ) ,
@@ -157,6 +160,7 @@ pub fn find_vs_version() -> Result<VsVers, String> {
157
160
}
158
161
}
159
162
163
+ /// Windows Implementation.
160
164
#[ cfg( windows) ]
161
165
mod impl_ {
162
166
use crate :: com;
@@ -174,24 +178,9 @@ mod impl_ {
174
178
use std:: process:: Command ;
175
179
use std:: str:: FromStr ;
176
180
177
- use super :: MSVC_FAMILY ;
181
+ use super :: { TargetArch , MSVC_FAMILY } ;
178
182
use crate :: Tool ;
179
183
180
- #[ derive( Copy , Clone ) ]
181
- pub struct TargetArch < ' a > ( pub & ' a str ) ;
182
-
183
- impl PartialEq < & str > for TargetArch < ' _ > {
184
- fn eq ( & self , other : & & str ) -> bool {
185
- self . 0 == * other
186
- }
187
- }
188
-
189
- impl < ' a > From < TargetArch < ' a > > for & ' a str {
190
- fn from ( target : TargetArch < ' a > ) -> Self {
191
- target. 0
192
- }
193
- }
194
-
195
184
struct MsvcTool {
196
185
tool : PathBuf ,
197
186
libs : Vec < PathBuf > ,
@@ -242,7 +231,7 @@ mod impl_ {
242
231
}
243
232
244
233
/// Attempt to find the tool using environment variables set by vcvars.
245
- pub fn find_msvc_environment ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
234
+ pub ( super ) fn find_msvc_environment ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
246
235
// Early return if the environment doesn't contain a VC install.
247
236
if env:: var_os ( "VCINSTALLDIR" ) . is_none ( ) {
248
237
return None ;
@@ -394,7 +383,7 @@ mod impl_ {
394
383
. collect ( )
395
384
}
396
385
397
- pub fn find_msvc_15plus ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
386
+ pub ( super ) fn find_msvc_15plus ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
398
387
let iter = vs15plus_instances ( target) ?;
399
388
iter. into_iter ( )
400
389
. filter_map ( |instance| {
@@ -565,7 +554,7 @@ mod impl_ {
565
554
566
555
// For MSVC 14 we need to find the Universal CRT as well as either
567
556
// the Windows 10 SDK or Windows 8.1 SDK.
568
- pub fn find_msvc_14 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
557
+ pub ( super ) fn find_msvc_14 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
569
558
let vcdir = get_vc_dir ( "14.0" ) ?;
570
559
let mut tool = get_tool ( tool, & vcdir, target) ?;
571
560
add_sdks ( & mut tool, target) ?;
@@ -615,7 +604,7 @@ mod impl_ {
615
604
}
616
605
617
606
// For MSVC 12 we need to find the Windows 8.1 SDK.
618
- pub fn find_msvc_12 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
607
+ pub ( super ) fn find_msvc_12 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
619
608
let vcdir = get_vc_dir ( "12.0" ) ?;
620
609
let mut tool = get_tool ( tool, & vcdir, target) ?;
621
610
let sub = lib_subdir ( target) ?;
@@ -631,7 +620,7 @@ mod impl_ {
631
620
}
632
621
633
622
// For MSVC 11 we need to find the Windows 8 SDK.
634
- pub fn find_msvc_11 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
623
+ pub ( super ) fn find_msvc_11 ( tool : & str , target : TargetArch < ' _ > ) -> Option < Tool > {
635
624
let vcdir = get_vc_dir ( "11.0" ) ?;
636
625
let mut tool = get_tool ( tool, & vcdir, target) ?;
637
626
let sub = lib_subdir ( target) ?;
@@ -885,7 +874,7 @@ mod impl_ {
885
874
max_key
886
875
}
887
876
888
- pub fn has_msbuild_version ( version : & str ) -> bool {
877
+ pub ( super ) fn has_msbuild_version ( version : & str ) -> bool {
889
878
match version {
890
879
"17.0" => {
891
880
find_msbuild_vs17 ( TargetArch ( "x86_64" ) ) . is_some ( )
@@ -912,16 +901,18 @@ mod impl_ {
912
901
}
913
902
}
914
903
915
- pub fn find_devenv ( target : TargetArch < ' _ > ) -> Option < Tool > {
904
+ // To find devenv we probe for it manually with dedicated registry keys.
905
+ pub ( super ) fn find_devenv ( target : TargetArch < ' _ > ) -> Option < Tool > {
916
906
find_devenv_vs15 ( target)
917
907
}
918
908
919
909
fn find_devenv_vs15 ( target : TargetArch < ' _ > ) -> Option < Tool > {
920
910
find_tool_in_vs15_path ( r"Common7\IDE\devenv.exe" , target)
921
911
}
922
912
913
+ // To find msbuild we probe for it manually with dedicated registry keys.
923
914
// see http://stackoverflow.com/questions/328017/path-to-msbuild
924
- pub fn find_msbuild ( target : TargetArch < ' _ > ) -> Option < Tool > {
915
+ pub ( super ) fn find_msbuild ( target : TargetArch < ' _ > ) -> Option < Tool > {
925
916
// VS 15 (2017) changed how to locate msbuild
926
917
if let Some ( r) = find_msbuild_vs17 ( target) {
927
918
Some ( r)
@@ -957,3 +948,73 @@ mod impl_ {
957
948
} )
958
949
}
959
950
}
951
+
952
+ /// Non-Windows Implementation.
953
+ #[ cfg( not( windows) ) ]
954
+ mod impl_ {
955
+ use std:: { env, ffi:: OsString } ;
956
+
957
+ use super :: { TargetArch , MSVC_FAMILY } ;
958
+ use crate :: Tool ;
959
+
960
+ /// Finding msbuild.exe tool under unix system is not currently supported.
961
+ /// Maybe can check it using an environment variable looks like `MSBUILD_BIN`.
962
+ pub ( super ) fn find_msbuild ( _target : TargetArch < ' _ > ) -> Option < Tool > {
963
+ None
964
+ }
965
+
966
+ // Finding devenv.exe tool under unix system is not currently supported.
967
+ // Maybe can check it using an environment variable looks like `DEVENV_BIN`.
968
+ pub ( super ) fn find_devenv ( _target : TargetArch < ' _ > ) -> Option < Tool > {
969
+ None
970
+ }
971
+
972
+ /// Attempt to find the tool using environment variables set by vcvars.
973
+ pub ( super ) fn find_msvc_environment ( tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
974
+ // Early return if the environment doesn't contain a VC install.
975
+ let _vc_install_dir = env:: var_os ( "VCINSTALLDIR" ) ?;
976
+ let _vs_install_dir = env:: var_os ( "VSINSTALLDIR" ) ?;
977
+
978
+ // Should we take the path of tool for the v[c|s] install dir?
979
+ // Both `VCINSTALLDIR` / `VSINSTALLDIR` are unused currently.
980
+
981
+ // Fallback to simply using the current environment.
982
+ env:: var_os ( "PATH" )
983
+ . and_then ( |path : OsString | {
984
+ env:: split_paths ( & path)
985
+ . map ( |p| p. join ( tool) )
986
+ . find ( |p| p. exists ( ) )
987
+ } )
988
+ . map ( |path| Tool :: with_family ( path. into ( ) , MSVC_FAMILY ) )
989
+ }
990
+
991
+ pub ( super ) fn find_msvc_15plus ( _tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
992
+ None
993
+ }
994
+
995
+ // For MSVC 14 we need to find the Universal CRT as well as either
996
+ // the Windows 10 SDK or Windows 8.1 SDK.
997
+ pub ( super ) fn find_msvc_14 ( _tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
998
+ None
999
+ }
1000
+
1001
+ // For MSVC 12 we need to find the Windows 8.1 SDK.
1002
+ pub ( super ) fn find_msvc_12 ( _tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
1003
+ None
1004
+ }
1005
+
1006
+ // For MSVC 11 we need to find the Windows 8 SDK.
1007
+ pub ( super ) fn find_msvc_11 ( _tool : & str , _target : TargetArch < ' _ > ) -> Option < Tool > {
1008
+ None
1009
+ }
1010
+
1011
+ pub ( super ) fn has_msbuild_version ( version : & str ) -> bool {
1012
+ match version {
1013
+ "17.0" => false ,
1014
+ "16.0" => false ,
1015
+ "15.0" => false ,
1016
+ "12.0" | "14.0" => false ,
1017
+ _ => false ,
1018
+ }
1019
+ }
1020
+ }
0 commit comments