@@ -318,14 +318,16 @@ impl Config {
318
318
let host = self . host . clone ( ) . unwrap_or_else ( || getenv_unwrap ( "HOST" ) ) ;
319
319
let msvc = target_triplet. contains ( "msvc" ) ;
320
320
let ndk = self . uses_android_ndk ( ) ;
321
+ let target = Target :: new ( & target_triplet) ;
322
+ let no_default_flags = ndk || target. is_ios_target ( ) ;
321
323
let mut c_cfg = cc:: Build :: new ( ) ;
322
324
c_cfg
323
325
. cargo_metadata ( false )
324
326
. opt_level ( 0 )
325
327
. debug ( false )
326
328
. warnings ( false )
327
329
. host ( & host)
328
- . no_default_flags ( ndk ) ;
330
+ . no_default_flags ( no_default_flags ) ;
329
331
if !ndk {
330
332
c_cfg. target ( & target_triplet) ;
331
333
}
@@ -337,7 +339,7 @@ impl Config {
337
339
. debug ( false )
338
340
. warnings ( false )
339
341
. host ( & host)
340
- . no_default_flags ( ndk ) ;
342
+ . no_default_flags ( no_default_flags ) ;
341
343
if !ndk {
342
344
cxx_cfg. target ( & target_triplet) ;
343
345
}
@@ -479,6 +481,32 @@ impl Config {
479
481
if !self . defined ( "CMAKE_SYSTEM_NAME" ) {
480
482
cmd. arg ( "-DCMAKE_SYSTEM_NAME=SunOS" ) ;
481
483
}
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
+ }
482
510
}
483
511
if let Some ( ref generator) = self . generator {
484
512
cmd. arg ( "-G" ) . arg ( generator) ;
@@ -592,6 +620,11 @@ impl Config {
592
620
flagsflag. push ( " " ) ;
593
621
flagsflag. push ( arg) ;
594
622
}
623
+ if no_default_flags {
624
+ if target. is_ios_target ( ) {
625
+ flagsflag. push ( " -fPIC -fembed-bitcode" ) ;
626
+ }
627
+ }
595
628
cmd. arg ( flagsflag) ;
596
629
}
597
630
@@ -835,6 +868,111 @@ impl Config {
835
868
}
836
869
}
837
870
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
+
838
976
fn run ( cmd : & mut Command , program : & str ) {
839
977
println ! ( "running: {:?}" , cmd) ;
840
978
let status = match cmd. status ( ) {
0 commit comments