@@ -461,60 +461,22 @@ impl Config {
461
461
if !self . defined ( "CMAKE_TOOLCHAIN_FILE" ) {
462
462
if let Some ( s) = self . getenv_target_os ( "CMAKE_TOOLCHAIN_FILE" ) {
463
463
self . define ( "CMAKE_TOOLCHAIN_FILE" , s) ;
464
- } else if target. contains ( "redox" ) {
464
+ } else if target != host {
465
+ self . define ( "CMAKE_CROSSCOMPILING" , "True" ) ;
466
+
467
+ // Set `CMAKE_SYSTEM_NAME` and `CMAKE_SYSTEM_PROCESSOR` to
468
+ // allow cross-compiling to work.
469
+ //
470
+ // FIXME: Also set `CMAKE_SYSTEM_VERSION` somehow?
465
471
if !self . defined ( "CMAKE_SYSTEM_NAME" ) {
466
- self . define ( "CMAKE_SYSTEM_NAME" , "Generic" ) ;
472
+ let system_name = get_system_name ( & target) ;
473
+ self . define ( "CMAKE_SYSTEM_NAME" , system_name) ;
474
+ }
475
+
476
+ if !self . defined ( "CMAKE_SYSTEM_PROCESSOR" ) {
477
+ let system_processor = get_system_processor ( & target) ;
478
+ self . define ( "CMAKE_SYSTEM_PROCESSOR" , system_processor) ;
467
479
}
468
- } else if target != host && !self . defined ( "CMAKE_SYSTEM_NAME" ) {
469
- // Set CMAKE_SYSTEM_NAME and CMAKE_SYSTEM_PROCESSOR when cross compiling
470
- let os = getenv_unwrap ( "CARGO_CFG_TARGET_OS" ) ;
471
- let arch = getenv_unwrap ( "CARGO_CFG_TARGET_ARCH" ) ;
472
- // CMAKE_SYSTEM_NAME list
473
- // https://gitlab.kitware.com/cmake/cmake/-/issues/21489#note_1077167
474
- //
475
- // CMAKE_SYSTEM_PROCESSOR
476
- // some of the values come from https://en.wikipedia.org/wiki/Uname
477
- let ( system_name, system_processor) = match ( os. as_str ( ) , arch. as_str ( ) ) {
478
- ( "android" , "arm" ) => ( "Android" , "armv7-a" ) ,
479
- ( "android" , "x86" ) => ( "Android" , "i686" ) ,
480
- ( "android" , arch) => ( "Android" , arch) ,
481
- ( "dragonfly" , arch) => ( "DragonFly" , arch) ,
482
- ( "macos" , "aarch64" ) => ( "Darwin" , "arm64" ) ,
483
- ( "macos" , arch) => ( "Darwin" , arch) ,
484
- ( "freebsd" , "x86_64" ) => ( "FreeBSD" , "amd64" ) ,
485
- ( "freebsd" , arch) => ( "FreeBSD" , arch) ,
486
- ( "fuchsia" , arch) => ( "Fuchsia" , arch) ,
487
- ( "haiku" , arch) => ( "Haiku" , arch) ,
488
- ( "ios" , "aarch64" ) => ( "iOS" , "arm64" ) ,
489
- ( "ios" , arch) => ( "iOS" , arch) ,
490
- ( "linux" , arch) => {
491
- let name = "Linux" ;
492
- match arch {
493
- "powerpc" => ( name, "ppc" ) ,
494
- "powerpc64" => ( name, "ppc64" ) ,
495
- "powerpc64le" => ( name, "ppc64le" ) ,
496
- _ => ( name, arch) ,
497
- }
498
- }
499
- ( "netbsd" , arch) => ( "NetBSD" , arch) ,
500
- ( "openbsd" , "x86_64" ) => ( "OpenBSD" , "amd64" ) ,
501
- ( "openbsd" , arch) => ( "OpenBSD" , arch) ,
502
- ( "solaris" , arch) => ( "SunOS" , arch) ,
503
- ( "tvos" , "aarch64" ) => ( "tvOS" , "arm64" ) ,
504
- ( "tvos" , arch) => ( "tvOS" , arch) ,
505
- ( "visionos" , "aarch64" ) => ( "visionOS" , "arm64" ) ,
506
- ( "visionos" , arch) => ( "visionOS" , arch) ,
507
- ( "watchos" , "aarch64" ) => ( "watchOS" , "arm64" ) ,
508
- ( "watchos" , arch) => ( "watchOS" , arch) ,
509
- ( "windows" , "x86_64" ) => ( "Windows" , "AMD64" ) ,
510
- ( "windows" , "x86" ) => ( "Windows" , "X86" ) ,
511
- ( "windows" , "aarch64" ) => ( "Windows" , "ARM64" ) ,
512
- ( "none" , arch) => ( "Generic" , arch) ,
513
- // Others
514
- ( os, arch) => ( os, arch) ,
515
- } ;
516
- self . define ( "CMAKE_SYSTEM_NAME" , system_name) ;
517
- self . define ( "CMAKE_SYSTEM_PROCESSOR" , system_processor) ;
518
480
}
519
481
}
520
482
@@ -681,14 +643,12 @@ impl Config {
681
643
panic ! ( "unsupported msvc target: {}" , target) ;
682
644
}
683
645
}
684
- } else if target. contains ( "darwin" ) && !self . defined ( "CMAKE_OSX_ARCHITECTURES" ) {
685
- if target. contains ( "x86_64" ) {
686
- cmd. arg ( "-DCMAKE_OSX_ARCHITECTURES=x86_64" ) ;
687
- } else if target. contains ( "aarch64" ) {
688
- cmd. arg ( "-DCMAKE_OSX_ARCHITECTURES=arm64" ) ;
689
- } else {
690
- panic ! ( "unsupported darwin target: {}" , target) ;
691
- }
646
+ }
647
+ if target. contains ( "apple" ) && !self . defined ( "CMAKE_OSX_ARCHITECTURES" ) {
648
+ // Make sure that CMake does not build universal binaries on macOS.
649
+ // Explicitly specify the one single target architecture.
650
+ let arch = get_system_processor ( & target) ;
651
+ self . define ( "CMAKE_OSX_ARCHITECTURES" , arch) ;
692
652
}
693
653
if let Some ( ref generator) = generator {
694
654
cmd. arg ( "-G" ) . arg ( generator) ;
@@ -1142,6 +1102,128 @@ fn uses_named_pipe_jobserver(makeflags: &OsStr) -> bool {
1142
1102
. contains ( "--jobserver-auth=fifo:" )
1143
1103
}
1144
1104
1105
+ /// Find [`CMAKE_SYSTEM_NAME`] based on `$CARGO_CFG_TARGET_OS` if available,
1106
+ /// otherwise try to infer it from the given target.
1107
+ ///
1108
+ /// [`CMAKE_SYSTEM_NAME`]: https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_NAME.html
1109
+ fn get_system_name ( target : & str ) -> & ' static str {
1110
+ let mapping = [
1111
+ ( "aix" , "AIX" ) ,
1112
+ ( "android" , "Android" ) , // Matches "*-linux-android*".
1113
+ ( "cygwin" , "CYGWIN" ) ,
1114
+ ( "darwin" , "Darwin" ) , // Matches target triple "*-apple-darwin".
1115
+ ( "dragonfly" , "DragonFly" ) ,
1116
+ ( "emscripten" , "Emscripten" ) ,
1117
+ ( "freebsd" , "FreeBSD" ) ,
1118
+ ( "fuchsia" , "Fuchsia" ) ,
1119
+ ( "haiku" , "Haiku" ) ,
1120
+ ( "illumos" , "SunOS" ) ,
1121
+ ( "ios" , "iOS" ) ,
1122
+ ( "linux" , "Linux" ) , // Must be after "android".
1123
+ ( "macos" , "Darwin" ) , // Used when matching `CARGO_CFG_TARGET_OS`.
1124
+ ( "netbsd" , "NetBSD" ) ,
1125
+ ( "openbsd" , "OpenBSD" ) ,
1126
+ ( "redox" , "Generic" ) ,
1127
+ ( "solaris" , "SunOS" ) ,
1128
+ ( "tvos" , "tvOS" ) ,
1129
+ ( "visionos" , "visionOS" ) ,
1130
+ ( "wasi" , "WASI" ) ,
1131
+ ( "watchos" , "watchOS" ) ,
1132
+ ( "windows" , "Windows" ) ,
1133
+ ( "none" , "Generic" ) , // Must be last match to handle x86_64-unknown-linux-none.
1134
+ ] ;
1135
+
1136
+ // `CARGO_CFG_TARGET_OS` is available when in build.rs, and is usually
1137
+ // more correct than trying to extract the value from `TARGET`.
1138
+ if let Some ( os) = std:: env:: var_os ( "CARGO_CFG_TARGET_OS" ) {
1139
+ let os = os. to_str ( ) . expect ( "CARGO_CFG_TARGET_OS must be UTF-8" ) ;
1140
+ for ( known_os, system_name) in mapping {
1141
+ if os == known_os {
1142
+ return system_name;
1143
+ }
1144
+ }
1145
+ } else {
1146
+ for ( known_os, system_name) in mapping {
1147
+ // Fuzzy find based on `target`.
1148
+ // This is brittle, and should ideally be avoided.
1149
+ if target. contains ( known_os) {
1150
+ return system_name;
1151
+ }
1152
+ }
1153
+ }
1154
+
1155
+ warn ! ( "unknown OS for target {target:?}, falling back to Generic" ) ;
1156
+ "Generic"
1157
+ }
1158
+
1159
+ /// Find [`CMAKE_SYSTEM_PROCESSOR`] based on the given `arch` if available,
1160
+ /// otherwise try to infer it from the given target.
1161
+ ///
1162
+ /// [`CMAKE_SYSTEM_PROCESSOR`]: https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_PROCESSOR.html#system-names-known-to-cmake
1163
+ fn get_system_processor ( target : & str ) -> & str {
1164
+ let ( full_arch, _) = target
1165
+ . split_once ( "-" )
1166
+ . expect ( "rustc target must have at least two components" ) ;
1167
+
1168
+ // `CMAKE_SYSTEM_PROCESSOR` is based on `CMAKE_HOST_SYSTEM_PROCESSOR`,
1169
+ // which is set differently based on platform.
1170
+
1171
+ // Windows: Value of `$PROCESSOR_ARCHITECTURE` by default.
1172
+ if target. contains ( "windows" ) {
1173
+ return match full_arch {
1174
+ "i586" | "i686" => "X86" ,
1175
+ "x86_64" => "AMD64" ,
1176
+ "aarch64" => "ARM64" ,
1177
+ "arm64ec" => "AMD64" , // Unsure
1178
+ arch => {
1179
+ warn ! ( "unknown architecture {arch} in target {target:?}" ) ;
1180
+ arch
1181
+ }
1182
+ } ;
1183
+ }
1184
+
1185
+ // macOS/Apple: Same as the `-arch` value expected by the linker.
1186
+ if target. contains ( "apple" ) {
1187
+ return match full_arch {
1188
+ // Renamed
1189
+ "aarch64" => "arm64" ,
1190
+ "i686" => "i386" ,
1191
+ "powerpc" => "ppc" ,
1192
+ "powerpc64" => "ppc64" ,
1193
+ // Unchanged
1194
+ "arm64_32" => "arm64_32" ,
1195
+ "arm64e" => "arm64e" ,
1196
+ "armv7" => "armv7" ,
1197
+ "armv7k" => "armv7k" ,
1198
+ "armv7s" => "armv7s" ,
1199
+ "i386" => "i386" ,
1200
+ "x86_64" => "x86_64" ,
1201
+ "x86_64h" => "x86_64h" ,
1202
+ arch => {
1203
+ warn ! ( "unknown architecture {arch} in target {target:?}" ) ;
1204
+ arch
1205
+ }
1206
+ } ;
1207
+ }
1208
+
1209
+ // Unix, `uname -m` on most platforms by default.
1210
+ match full_arch {
1211
+ "arm" if target. contains ( "android" ) => "armv6-a" ,
1212
+ "armv7" if target. contains ( "android" ) => "armv7-a" ,
1213
+ "i686" if target. contains ( "android" ) => "i686" ,
1214
+ "i386" | "i486" | "i586" | "i686" | "i786" => "x86" ,
1215
+ "powerpc" => "ppc" ,
1216
+ "powerpc64" => "ppc64" ,
1217
+ "powerpc64le" => "ppc64le" ,
1218
+ "x86_64" if target. contains ( "openbsd" ) || target. contains ( "freebsd" ) => "amd64" ,
1219
+ "x86_64" => "x86_64" ,
1220
+ arch if arch. starts_with ( "arm" ) => "arm" ,
1221
+ arch if arch. starts_with ( "thumb" ) => "thumb" ,
1222
+ // TODO: Do we need to handle more here?
1223
+ arch => arch,
1224
+ }
1225
+ }
1226
+
1145
1227
#[ cfg( test) ]
1146
1228
mod tests {
1147
1229
use super :: uses_named_pipe_jobserver;
0 commit comments