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