@@ -115,6 +115,40 @@ pub fn find_target(build: &Build, target: TargetSelection) {
115
115
}
116
116
117
117
let compiler = cfg. get_compiler ( ) ;
118
+
119
+ // When the cc crate cannot find the appropriate C compiler for the requested target, rather
120
+ // than erroring out it returns the default C compiler. In most cases, this is wrong.
121
+ //
122
+ // For example, let's say that you're cross-compiling for aarch64-unknown-none from an x86_64
123
+ // host, and that target is not recognized by the cc crate. In that case, the detected cc will
124
+ // be an x86_64 compiler, even though we're compiling for aarch64-unknown-none. If a crate then
125
+ // compiles some C code in its build script, the resulting rlib will have mixed AArch64 and
126
+ // x86_64 objects in it, and the linker will show rather unhelpful messages.
127
+ //
128
+ // To avoid the confusing error messages, we detect whether the configuration is likely broken,
129
+ // and if so we replace the detected C compiler with a stub binary that prints a useful error
130
+ // message, telling the user to manually configure their C compiler.
131
+ //
132
+ // We use a custom binary rather than erroring out directly here because some build steps might
133
+ // not need a C compiler at all, and it would be annoying to prevent the build in those cases.
134
+ let default_cc = new_cc_build ( build, build. build ) . get_compiler ( ) ;
135
+ if target != build. build && !compiler. is_like_clang ( ) && compiler. path ( ) == default_cc. path ( ) {
136
+ let mut broken_cc = new_cc_build ( build, target) ;
137
+ broken_cc. compiler (
138
+ std:: env:: current_exe ( )
139
+ . expect ( "failed to retrieve path to the bootstrap executable" )
140
+ . parent ( )
141
+ . unwrap ( )
142
+ . join ( format ! ( "broken-cc{}" , std:: env:: consts:: EXE_SUFFIX ) ) ,
143
+ ) ;
144
+ broken_cc. flag ( & format ! ( "--broken-cc-target={target}" ) ) ;
145
+ broken_cc. flag ( & format ! ( "--broken-cc-detected={}" , default_cc. path( ) . display( ) ) ) ;
146
+
147
+ build. cc . borrow_mut ( ) . insert ( target, broken_cc. get_compiler ( ) ) ;
148
+ build. cxx . borrow_mut ( ) . insert ( target, broken_cc. get_compiler ( ) ) ;
149
+ return ;
150
+ }
151
+
118
152
let ar = if let ar @ Some ( ..) = config. and_then ( |c| c. ar . clone ( ) ) {
119
153
ar
120
154
} else {
0 commit comments