@@ -318,14 +318,16 @@ impl Config {
318318 let host = self . host . clone ( ) . unwrap_or_else ( || getenv_unwrap ( "HOST" ) ) ;
319319 let msvc = target_triplet. contains ( "msvc" ) ;
320320 let ndk = self . uses_android_ndk ( ) ;
321+ let target = Target :: new ( & target_triplet) ;
322+ let no_default_flags = ndk || target. is_ios_target ( ) ;
321323 let mut c_cfg = cc:: Build :: new ( ) ;
322324 c_cfg
323325 . cargo_metadata ( false )
324326 . opt_level ( 0 )
325327 . debug ( false )
326328 . warnings ( false )
327329 . host ( & host)
328- . no_default_flags ( ndk ) ;
330+ . no_default_flags ( no_default_flags ) ;
329331 if !ndk {
330332 c_cfg. target ( & target_triplet) ;
331333 }
@@ -337,7 +339,7 @@ impl Config {
337339 . debug ( false )
338340 . warnings ( false )
339341 . host ( & host)
340- . no_default_flags ( ndk ) ;
342+ . no_default_flags ( no_default_flags ) ;
341343 if !ndk {
342344 cxx_cfg. target ( & target_triplet) ;
343345 }
@@ -480,6 +482,35 @@ impl Config {
480482 if !self . defined ( "CMAKE_SYSTEM_NAME" ) {
481483 cmd. arg ( "-DCMAKE_SYSTEM_NAME=SunOS" ) ;
482484 }
485+ } else if target. is_apple_target ( ) {
486+ if !self . defined ( "CMAKE_OSX_ARCHITECTURES" ) {
487+ if let Some ( cmake_target_arch) = target. cmake_target_arch ( ) {
488+ cmd. arg ( format ! ( "-DCMAKE_OSX_ARCHITECTURES={}" , cmake_target_arch) ) ;
489+ }
490+ }
491+
492+ if !self . defined ( "CMAKE_OSX_SYSROOT" ) {
493+ if let Some ( sdk_name) = target. sdk_name ( ) {
494+ cmd. arg ( format ! ( "-DCMAKE_OSX_SYSROOT={}" , sdk_name) ) ;
495+ }
496+ }
497+
498+ if !self . defined ( "CMAKE_OSX_DEPLOYMENT_TARGET" ) {
499+ if let Some ( deployment_target) = target. deployment_target ( ) {
500+ cmd. arg ( format ! (
501+ "-DCMAKE_OSX_DEPLOYMENT_TARGET={}" ,
502+ deployment_target
503+ ) ) ;
504+ }
505+ }
506+
507+ if target. is_cross_compiling ( ) {
508+ if !self . defined ( "CMAKE_SYSTEM_NAME" ) {
509+ if let Some ( cmake_system_name) = target. cmake_system_name ( ) {
510+ cmd. arg ( format ! ( "-DCMAKE_SYSTEM_NAME={}" , cmake_system_name) ) ;
511+ }
512+ }
513+ }
483514 }
484515 if let Some ( ref generator) = self . generator {
485516 cmd. arg ( "-G" ) . arg ( generator) ;
@@ -593,6 +624,11 @@ impl Config {
593624 flagsflag. push ( " " ) ;
594625 flagsflag. push ( arg) ;
595626 }
627+ if no_default_flags {
628+ if target. is_ios_target ( ) {
629+ flagsflag. push ( " -fPIC -fembed-bitcode" ) ;
630+ }
631+ }
596632 cmd. arg ( flagsflag) ;
597633 }
598634
@@ -836,6 +872,135 @@ impl Config {
836872 }
837873}
838874
875+ struct Target {
876+ rust_target : String ,
877+ rust_target_arch : String ,
878+ rust_target_vendor : String ,
879+ rust_target_platform : String ,
880+ }
881+
882+ impl Target {
883+ pub fn new ( target_triplet : & str ) -> Target {
884+ let parts: Vec < & str > = target_triplet. split ( '-' ) . collect ( ) ;
885+ if parts. len ( ) < 3 {
886+ fail ( & format ! (
887+ "target triplet not in the form arch-vendor-platform: {}" ,
888+ target_triplet
889+ ) ) ;
890+ }
891+
892+ Target {
893+ rust_target : target_triplet. to_owned ( ) ,
894+ rust_target_arch : parts[ 0 ] . to_owned ( ) ,
895+ rust_target_vendor : parts[ 1 ] . to_owned ( ) ,
896+ rust_target_platform : parts[ 2 ] . to_owned ( ) ,
897+ }
898+ }
899+
900+ fn is_apple_target ( & self ) -> bool {
901+ self . is_ios_target ( ) || self . is_osx_target ( )
902+ }
903+
904+ fn is_ios_target ( & self ) -> bool {
905+ & self . rust_target_vendor == "apple" && & self . rust_target_platform == "ios"
906+ }
907+
908+ fn is_osx_target ( & self ) -> bool {
909+ & self . rust_target_vendor == "apple" && & self . rust_target_platform == "darwin"
910+ }
911+
912+ fn is_cross_compiling ( & self ) -> bool {
913+ self . is_ios_target ( )
914+ }
915+
916+ fn cmake_system_name ( & self ) -> Option < String > {
917+ if !self . is_cross_compiling ( ) {
918+ eprintln ! ( "Warning: cmake_system_name should only be used for cross-compiled targets. Target: {}" , self . rust_target) ;
919+ None
920+ } else if self . is_ios_target ( ) {
921+ Some ( "iOS" . to_owned ( ) )
922+ } else {
923+ eprintln ! (
924+ "Warning: unknown system name for target: {}" ,
925+ self . rust_target
926+ ) ;
927+ None
928+ }
929+ }
930+
931+ fn cmake_target_arch ( & self ) -> Option < String > {
932+ if !self . is_apple_target ( ) {
933+ eprintln ! (
934+ "Warning: sdk_name only supported for Apple targets. Target: {}" ,
935+ self . rust_target
936+ ) ;
937+ None
938+ } else {
939+ match self . rust_target_arch . as_str ( ) {
940+ "aarch64" => Some ( "arm64" . to_owned ( ) ) ,
941+ "armv7" => Some ( "armv7" . to_owned ( ) ) ,
942+ "armv7s" => Some ( "armv7s" . to_owned ( ) ) ,
943+ "i386" => Some ( "i386" . to_owned ( ) ) ,
944+ "x86_64" => Some ( "x86_64" . to_owned ( ) ) ,
945+ _ => {
946+ eprintln ! (
947+ "Warning: unknown architecture for target: {}" ,
948+ self . rust_target_arch
949+ ) ;
950+ None
951+ }
952+ }
953+ }
954+ }
955+
956+ fn sdk_name ( & self ) -> Option < String > {
957+ if !self . is_apple_target ( ) {
958+ eprintln ! (
959+ "Warning: sdk_name only supported for Apple targets. Target: {}" ,
960+ self . rust_target
961+ ) ;
962+ None
963+ } else if self . is_ios_target ( ) {
964+ match self . rust_target_arch . as_str ( ) {
965+ "aarch64" | "armv7" | "armv7s" => Some ( "iphoneos" . to_owned ( ) ) ,
966+ "i386" | "x86_64" => Some ( "iphonesimulator" . to_owned ( ) ) ,
967+ _ => {
968+ eprintln ! (
969+ "Warning: unknown architecture for Apple target: {}" ,
970+ self . rust_target_arch
971+ ) ;
972+ None
973+ }
974+ }
975+ } else if self . is_osx_target ( ) {
976+ Some ( "macosx" . to_owned ( ) )
977+ } else {
978+ eprintln ! ( "Warning: unknown sdk name for target: {}" , self . rust_target) ;
979+ None
980+ }
981+ }
982+
983+ fn deployment_target ( & self ) -> Option < String > {
984+ if !self . is_apple_target ( ) {
985+ eprintln ! (
986+ "Warning: deployment_target only supported for Apple targets. Target: {}" ,
987+ self . rust_target
988+ ) ;
989+ None
990+ } else if self . is_ios_target ( ) {
991+ Some ( std:: env:: var ( "IPHONEOS_DEPLOYMENT_TARGET" ) . unwrap_or_else ( |_| "7.0" . into ( ) ) )
992+ } else if self . is_osx_target ( ) {
993+ Some ( std:: env:: var ( "MACOSX_DEPLOYMENT_TARGET" ) . unwrap_or_else ( |_| "10.6" . into ( ) ) )
994+ } else {
995+ eprintln ! (
996+ "Warning: unknown deployment target for target: {}" ,
997+ self . rust_target
998+ ) ;
999+ None
1000+ }
1001+ }
1002+ }
1003+
8391004fn run ( cmd : & mut Command , program : & str ) {
8401005 println ! ( "running: {:?}" , cmd) ;
8411006 let status = match cmd. status ( ) {
0 commit comments