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