@@ -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 }
@@ -479,6 +481,32 @@ impl Config {
479481 if !self . defined ( "CMAKE_SYSTEM_NAME" ) {
480482 cmd. arg ( "-DCMAKE_SYSTEM_NAME=SunOS" ) ;
481483 }
484+ } else if target. is_apple_target ( ) {
485+ if !self . defined ( "CMAKE_OSX_ARCHITECTURES" ) {
486+ if let Some ( cmake_target_arch) = target. cmake_target_arch ( ) {
487+ cmd. arg ( format ! ( "-DCMAKE_OSX_ARCHITECTURES={}" , cmake_target_arch) ) ;
488+ }
489+ }
490+
491+ if !self . defined ( "CMAKE_OSX_SYSROOT" ) {
492+ if let Some ( sdk_name) = target. sdk_name ( ) {
493+ cmd. arg ( format ! ( "-DCMAKE_OSX_SYSROOT={}" , sdk_name) ) ;
494+ }
495+ }
496+
497+ if !self . defined ( "CMAKE_OSX_DEPLOYMENT_TARGET" ) {
498+ if let Some ( deployment_target) = target. deployment_target ( ) {
499+ cmd. arg ( format ! ( "-DCMAKE_OSX_DEPLOYMENT_TARGET={}" , deployment_target) ) ;
500+ }
501+ }
502+
503+ if target. is_cross_compiling ( ) {
504+ if !self . defined ( "CMAKE_SYSTEM_NAME" ) {
505+ if let Some ( cmake_system_name) = target. cmake_system_name ( ) {
506+ cmd. arg ( format ! ( "-DCMAKE_SYSTEM_NAME={}" , cmake_system_name) ) ;
507+ }
508+ }
509+ }
482510 }
483511 if let Some ( ref generator) = self . generator {
484512 cmd. arg ( "-G" ) . arg ( generator) ;
@@ -592,6 +620,11 @@ impl Config {
592620 flagsflag. push ( " " ) ;
593621 flagsflag. push ( arg) ;
594622 }
623+ if no_default_flags {
624+ if target. is_ios_target ( ) {
625+ flagsflag. push ( " -fPIC -fembed-bitcode" ) ;
626+ }
627+ }
595628 cmd. arg ( flagsflag) ;
596629 }
597630
@@ -835,6 +868,111 @@ impl Config {
835868 }
836869}
837870
871+ struct Target {
872+ rust_target : String ,
873+ rust_target_arch : String ,
874+ rust_target_vendor : String ,
875+ rust_target_platform : String ,
876+ }
877+
878+ impl Target {
879+ pub fn new ( target_triplet : & str ) -> Target {
880+ let parts: Vec < & str > = target_triplet. split ( '-' ) . collect ( ) ;
881+ if parts. len ( ) < 3 {
882+ fail ( & format ! ( "target triplet not in the form arch-vendor-platform: {}" , target_triplet) ) ;
883+ }
884+
885+ Target {
886+ rust_target : target_triplet. to_owned ( ) ,
887+ rust_target_arch : parts[ 0 ] . to_owned ( ) ,
888+ rust_target_vendor : parts[ 1 ] . to_owned ( ) ,
889+ rust_target_platform : parts[ 2 ] . to_owned ( ) ,
890+ }
891+ }
892+
893+ fn is_apple_target ( & self ) -> bool {
894+ self . is_ios_target ( ) || self . is_osx_target ( )
895+ }
896+
897+ fn is_ios_target ( & self ) -> bool {
898+ & self . rust_target_vendor == "apple" && & self . rust_target_platform == "ios"
899+ }
900+
901+ fn is_osx_target ( & self ) -> bool {
902+ & self . rust_target_vendor == "apple" && & self . rust_target_platform == "darwin"
903+ }
904+
905+ fn is_cross_compiling ( & self ) -> bool {
906+ self . is_ios_target ( )
907+ }
908+
909+ fn cmake_system_name ( & self ) -> Option < String > {
910+ if !self . is_cross_compiling ( ) {
911+ eprintln ! ( "Warning: cmake_system_name should only be used for cross-compiled targets. Target: {}" , self . rust_target) ;
912+ None
913+ } else if self . is_ios_target ( ) {
914+ Some ( "iOS" . to_owned ( ) )
915+ } else {
916+ eprintln ! ( "Warning: unknown system name for target: {}" , self . rust_target) ;
917+ None
918+ }
919+ }
920+
921+ fn cmake_target_arch ( & self ) -> Option < String > {
922+ if !self . is_apple_target ( ) {
923+ eprintln ! ( "Warning: sdk_name only supported for Apple targets. Target: {}" , self . rust_target) ;
924+ None
925+ } else {
926+ match self . rust_target_arch . as_str ( ) {
927+ "aarch64" => Some ( "arm64" . to_owned ( ) ) ,
928+ "armv7" => Some ( "armv7" . to_owned ( ) ) ,
929+ "armv7s" => Some ( "armv7s" . to_owned ( ) ) ,
930+ "i386" => Some ( "i386" . to_owned ( ) ) ,
931+ "x86_64" => Some ( "x86_64" . to_owned ( ) ) ,
932+ _ => {
933+ eprintln ! ( "Warning: unknown architecture for target: {}" , self . rust_target_arch) ;
934+ None
935+ }
936+ }
937+ }
938+ }
939+
940+ fn sdk_name ( & self ) -> Option < String > {
941+ if !self . is_apple_target ( ) {
942+ eprintln ! ( "Warning: sdk_name only supported for Apple targets. Target: {}" , self . rust_target) ;
943+ None
944+ } else if self . is_ios_target ( ) {
945+ match self . rust_target_arch . as_str ( ) {
946+ "aarch64" | "armv7" | "armv7s" => Some ( "iphoneos" . to_owned ( ) ) ,
947+ "i386" | "x86_64" => Some ( "iphonesimulator" . to_owned ( ) ) ,
948+ _ => {
949+ eprintln ! ( "Warning: unknown architecture for Apple target: {}" , self . rust_target_arch) ;
950+ None
951+ } ,
952+ }
953+ } else if self . is_osx_target ( ) {
954+ Some ( "macosx" . to_owned ( ) )
955+ } else {
956+ eprintln ! ( "Warning: unknown sdk name for target: {}" , self . rust_target) ;
957+ None
958+ }
959+ }
960+
961+ fn deployment_target ( & self ) -> Option < String > {
962+ if !self . is_apple_target ( ) {
963+ eprintln ! ( "Warning: deployment_target only supported for Apple targets. Target: {}" , self . rust_target) ;
964+ None
965+ } else if self . is_ios_target ( ) {
966+ Some ( std:: env:: var ( "IPHONEOS_DEPLOYMENT_TARGET" ) . unwrap_or_else ( |_| "7.0" . into ( ) ) )
967+ } else if self . is_osx_target ( ) {
968+ Some ( std:: env:: var ( "MACOSX_DEPLOYMENT_TARGET" ) . unwrap_or_else ( |_| "10.6" . into ( ) ) )
969+ } else {
970+ eprintln ! ( "Warning: unknown deployment target for target: {}" , self . rust_target) ;
971+ None
972+ }
973+ }
974+ }
975+
838976fn run ( cmd : & mut Command , program : & str ) {
839977 println ! ( "running: {:?}" , cmd) ;
840978 let status = match cmd. status ( ) {
0 commit comments