@@ -20,12 +20,8 @@ fn alternative_locations_from_env<F>(var_os_func: F) -> Vec<PathBuf>
20
20
where
21
21
F : Fn ( & str ) -> Option < std:: ffi:: OsString > ,
22
22
{
23
- // FIXME: Define pairs of the environment variable name and the path suffix to apply, or
24
- // something, because right now this new function is totally wrong because it returns the
25
- // program files directory paths instead of the Git for Windows bin directory paths under them.
26
- //
27
- // But I am not really sure what this should do to handle the ProgramFiles environment variable
28
- // and figure out if it is 64-bit or 32-bit -- which we need in order to know whether to append
23
+ // I am not really sure what this should do to handle the ProgramFiles environment variable and
24
+ // figure out if it is 64-bit or 32-bit -- which we need in order to know whether to append
29
25
// `Git/mingw64/bin` or `Git/mingw32/bin`. We do need to look at the ProgramFiles environment
30
26
// variable in addition to the other two preferable architecture-specific ones (for which the
31
27
// mingw64 vs. mingw32 decision is easy), at least some of the time, for two reasons.
@@ -79,22 +75,50 @@ where
79
75
// using environment variables already, satisfies a weaker expectation that the environment
80
76
// value *or* actual value (obtainable via known folders or the registry), rather than some
81
77
// third value, is used. (4) is also a simple way to do the right thing on a 32-bit system.
82
- let suffix_x86 =
83
- let rules = [
84
78
85
- ] ;
79
+ // Should give a 64-bit program files path from a 32-bit or 64-bit process on a 64-bit system.
80
+ let varname_64bit = "ProgramW6432" ;
81
+
82
+ // Should give a 32-bit program files path from a 32-bit or 64-bit process on a 64-bit system.
83
+ // This variable is x86-specific, but neither Git nor Rust target 32-bit ARM on Windows.
84
+ let varname_x86 = "ProgramFiles(x86)" ;
85
+
86
+ // Should give a 32-bit program files path on a 32-bit system. We also need to check it on a
87
+ // 64-bit system. [FIXME: Somehow briefly explain why we still need to do that.]
88
+ let varname_current = "ProgramFiles" ;
89
+
90
+ // 64-bit relative bin dir. So far, this is always mingw64, not ucrt64, clang64, or clangarm64.
91
+ let suffix_64 = Path :: new ( "bin/mingw64" ) ;
86
92
87
- let names = [
88
- "ProgramW6432" , // 64-bit path from a 32-bit or 64-bit process on a 64-bit system.
89
- "ProgramFiles(x86)" , // 32-bit path from a 32-bit or 64-bit process on a 64-bit system.
90
- "ProgramFiles" , // 32-bit path on 32-bit system. Or if the parent cleared the others.
93
+ // 32-bit relative bin dir. This is always mingw32, not clang32.
94
+ let suffix_32 = Path :: new ( "bin/mingw32" ) ;
95
+
96
+ // Whichever of the 64-bit or 32-bit relative bin better matches this process's architecture.
97
+ // Unlike the system architecture, the process architecture is always known at compile time.
98
+ #[ cfg( target_pointer_width = "64" ) ]
99
+ let suffix_current = suffix_64;
100
+ #[ cfg( target_pointer_width = "32" ) ]
101
+ let suffix_current = suffix_32;
102
+
103
+ let rules = [
104
+ ( varname_64bit, suffix_64) ,
105
+ ( varname_x86, suffix_32) ,
106
+ ( varname_current, suffix_current) ,
91
107
] ;
92
108
93
109
let mut locations = vec ! [ ] ;
94
110
95
- for path in names. into_iter ( ) . filter_map ( var_os_func) . map ( PathBuf :: from) {
96
- if !locations. contains ( & path) {
97
- locations. push ( path) ;
111
+ for ( name, suffix) in rules {
112
+ if let Some ( value) = var_os_func ( name) {
113
+ let pf = Path :: new ( & value) ;
114
+ if pf. is_relative ( ) {
115
+ continue ;
116
+ } ;
117
+ let components = pf. iter ( ) . chain ( suffix. iter ( ) ) ;
118
+ let location = PathBuf :: from_iter ( components) ;
119
+ if !locations. contains ( & location) {
120
+ locations. push ( location) ;
121
+ }
98
122
}
99
123
}
100
124
0 commit comments