@@ -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
}
@@ -480,6 +482,35 @@ impl Config {
480
482
if !self . defined ( "CMAKE_SYSTEM_NAME" ) {
481
483
cmd. arg ( "-DCMAKE_SYSTEM_NAME=SunOS" ) ;
482
484
}
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
+ }
483
514
}
484
515
if let Some ( ref generator) = self . generator {
485
516
cmd. arg ( "-G" ) . arg ( generator) ;
@@ -593,6 +624,11 @@ impl Config {
593
624
flagsflag. push ( " " ) ;
594
625
flagsflag. push ( arg) ;
595
626
}
627
+ if no_default_flags {
628
+ if target. is_ios_target ( ) {
629
+ flagsflag. push ( " -fPIC -fembed-bitcode" ) ;
630
+ }
631
+ }
596
632
cmd. arg ( flagsflag) ;
597
633
}
598
634
@@ -836,6 +872,135 @@ impl Config {
836
872
}
837
873
}
838
874
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
+
839
1004
fn run ( cmd : & mut Command , program : & str ) {
840
1005
println ! ( "running: {:?}" , cmd) ;
841
1006
let status = match cmd. status ( ) {
0 commit comments