1
1
use std:: { env, path:: Path } ;
2
2
3
- /// TODO: Better validation of this
4
- ///
5
- /// The version is used for providing different behaviour when:
6
- /// - CGException.cpp getObjCPersonality (GNUStep >= 1.7)
7
- /// - Clang.cpp Clang::AddObjCRuntimeArgs (GNUStep >= 2.0)
8
- /// - isLegacyDispatchDefaultForArch (macOS < 10.6, GNUStep < 1.6)
9
- /// - hasNativeARC (macOS < 10.7, iOS < 5)
10
- /// - shouldUseARCFunctionsForRetainRelease (macOS < 10.10, iOS < 8)
11
- /// - shouldUseRuntimeFunctionsForAlloc (macOS < 10.10, iOS < 8)
12
- /// - shouldUseRuntimeFunctionForCombinedAllocInit (macOS >= 10.14.4, iOS >= 12.2, watchOS >= 5.2)
13
- /// - hasOptimizedSetter (macOS >= 10.8, iOS >= 6, GNUStep >= 1.7)
14
- /// - hasSubscripting (macOS < 10.11, iOS < 9)
15
- /// - hasTerminate (macOS < 10.8, iOS < 5)
16
- /// - hasARCUnsafeClaimAutoreleasedReturnValue (macOS >= 10.11, iOS >= 9, watchOS >= 2)
17
- /// - hasEmptyCollections (macOS >= 10.11, iOS >= 9, watchOS >= 2)
18
- /// - ... (incomplete)
19
- ///
20
- /// `macosx-fragile` and `gcc` was not considered in this analysis, made on
21
- /// clang version 13's source code:
22
- /// https://github.com/llvm/llvm-project/blob/llvmorg-13.0.0/clang/include/clang/Basic/ObjCRuntime.h
23
- ///
24
- /// In short, it's not ultra important, but enables some optimizations if this
25
- /// is specified.
26
- type Version = String ;
27
-
28
- // For clang "-fobjc-runtime" support
29
- #[ allow( clippy:: upper_case_acronyms) ]
30
- enum AppleRuntime {
31
- MacOS ( Version ) ,
32
- IOS ( Version ) ,
33
- TvOS ( Version ) ,
34
- WatchOS ( Version ) ,
35
- Unknown ,
36
- // BridgeOS,
37
- }
38
- use AppleRuntime :: * ;
39
-
3
+ /// The selected runtime (and runtime version).
40
4
enum Runtime {
41
- Apple ( AppleRuntime ) ,
5
+ Apple ,
42
6
GNUStep ( u8 , u8 ) ,
43
7
WinObjC ,
44
8
#[ allow( dead_code) ]
45
9
ObjFW ( Option < String > ) ,
46
10
}
47
- use Runtime :: * ;
48
-
49
- fn get_env ( env : & str ) -> Option < String > {
50
- println ! ( "cargo:rerun-if-env-changed={env}" ) ;
51
- match env:: var ( env) {
52
- Ok ( var) => Some ( var) ,
53
- Err ( env:: VarError :: NotPresent ) => None ,
54
- Err ( env:: VarError :: NotUnicode ( var) ) => panic ! ( "Invalid unicode for {env}: {var:?}" ) ,
55
- }
56
- }
57
11
58
12
fn main ( ) {
59
13
// The script doesn't depend on our code
@@ -102,39 +56,28 @@ fn main() {
102
56
103
57
let runtime = match ( apple, gnustep, objfw) {
104
58
// Same logic as in https://github.com/rust-lang/rust/blob/1.63.0/compiler/rustc_target/src/spec/apple_base.rs
105
- ( true , false , false ) => Apple ( match & * target_os {
106
- "macos" if target_arch == "aarch64" => {
107
- MacOS ( get_env ( "MACOSX_DEPLOYMENT_TARGET" ) . unwrap_or_else ( || "11.0" . into ( ) ) )
108
- }
109
- "macos" => MacOS ( get_env ( "MACOSX_DEPLOYMENT_TARGET" ) . unwrap_or_else ( || "10.7" . into ( ) ) ) ,
110
- "ios" => IOS ( get_env ( "IPHONEOS_DEPLOYMENT_TARGET" ) . unwrap_or_else ( || "7.0" . into ( ) ) ) ,
111
- "tvos" => TvOS ( get_env ( "TVOS_DEPLOYMENT_TARGET" ) . unwrap_or_else ( || "7.0" . into ( ) ) ) ,
112
- "watchos" => {
113
- WatchOS ( get_env ( "WATCHOS_DEPLOYMENT_TARGET" ) . unwrap_or_else ( || "5.0" . into ( ) ) )
114
- }
115
- _ => Unknown ,
116
- } ) ,
59
+ ( true , false , false ) => Runtime :: Apple ,
117
60
( false , true , false ) => {
118
61
// Choose defaults when generating docs
119
62
if cfg ! ( feature = "unstable-docsrs" ) {
120
63
if "windows" == target_os {
121
- WinObjC
64
+ Runtime :: WinObjC
122
65
} else {
123
- GNUStep ( 1 , 7 )
66
+ Runtime :: GNUStep ( 1 , 7 )
124
67
}
125
68
} else if env:: var_os ( "CARGO_FEATURE_UNSTABLE_WINOBJC" ) . is_some ( ) {
126
- WinObjC
69
+ Runtime :: WinObjC
127
70
} else if env:: var_os ( "CARGO_FEATURE_GNUSTEP_2_1" ) . is_some ( ) {
128
- GNUStep ( 2 , 1 )
71
+ Runtime :: GNUStep ( 2 , 1 )
129
72
} else if env:: var_os ( "CARGO_FEATURE_GNUSTEP_2_0" ) . is_some ( ) {
130
- GNUStep ( 2 , 0 )
73
+ Runtime :: GNUStep ( 2 , 0 )
131
74
} else if env:: var_os ( "CARGO_FEATURE_GNUSTEP_1_9" ) . is_some ( ) {
132
- GNUStep ( 1 , 9 )
75
+ Runtime :: GNUStep ( 1 , 9 )
133
76
} else if env:: var_os ( "CARGO_FEATURE_GNUSTEP_1_8" ) . is_some ( ) {
134
- GNUStep ( 1 , 8 )
77
+ Runtime :: GNUStep ( 1 , 8 )
135
78
} else {
136
79
// CARGO_FEATURE_GNUSTEP_1_7
137
- GNUStep ( 1 , 7 )
80
+ Runtime :: GNUStep ( 1 , 7 )
138
81
}
139
82
}
140
83
( false , false , true ) => {
@@ -148,50 +91,37 @@ fn main() {
148
91
149
92
// Add `#[cfg(RUNTIME)]` directive
150
93
let runtime_cfg = match runtime {
151
- Apple ( _ ) => "apple" ,
94
+ Runtime :: Apple => "apple" ,
152
95
// WinObjC can be treated like GNUStep 1.8
153
- GNUStep ( _, _) | WinObjC => "gnustep" ,
154
- ObjFW ( _) => "objfw" ,
96
+ Runtime :: GNUStep ( _, _) | Runtime :: WinObjC => "gnustep" ,
97
+ Runtime :: ObjFW ( _) => "objfw" ,
155
98
} ;
156
99
println ! ( "cargo:rustc-cfg={runtime_cfg}" ) ;
157
100
158
- if let Apple ( runtime ) = & runtime {
101
+ if let Runtime :: Apple = & runtime {
159
102
// A few things are defined differently depending on the __OBJC2__
160
103
// variable, which is set for all platforms except 32-bit macOS.
161
- if let ( MacOS ( _ ) , "x86" ) = ( runtime , & * target_arch) {
104
+ if target_os == "macos" && target_arch == "x86" {
162
105
println ! ( "cargo:rustc-cfg=apple_old" ) ;
163
106
} else {
164
107
println ! ( "cargo:rustc-cfg=apple_new" ) ;
165
108
}
166
109
}
167
110
168
- let clang_runtime = match & runtime {
169
- Apple ( runtime) => {
170
- match ( runtime, & * target_arch) {
171
- // The fragile runtime is expected on i686-apple-darwin, see:
172
- // https://github.com/llvm/llvm-project/blob/release/13.x/clang/lib/Driver/ToolChains/Darwin.h#L228-L231
173
- // https://github.com/llvm/llvm-project/blob/release/13.x/clang/lib/Driver/ToolChains/Clang.cpp#L3639-L3640
174
- // https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtVersionsPlatforms.html
175
- ( MacOS ( version) , "x86" ) => format ! ( "macosx-fragile-{version}" ) ,
176
- ( MacOS ( version) , _) => format ! ( "macosx-{version}" ) ,
177
- ( IOS ( version) , _) => format ! ( "ios-{version}" ) ,
178
- ( WatchOS ( version) , _) => format ! ( "watchos-{version}" ) ,
179
- // tvOS doesn't have its own -fobjc-runtime string
180
- ( TvOS ( version) , _) => format ! ( "ios-{version}" ) ,
181
- // Choose a sensible default for other platforms that
182
- // specified `apple`; this is likely not going to work anyhow
183
- ( Unknown , _) => "macosx" . into ( ) ,
184
- }
185
- }
111
+ let clang_objc_runtime = match & runtime {
112
+ // Default to `clang`'s own heuristics.
113
+ //
114
+ // Note that the `cc` crate forwards the correct deployment target to clang as well.
115
+ Runtime :: Apple => "" . into ( ) ,
186
116
// Default in clang is 1.6
187
117
// GNUStep's own default is 1.8
188
- GNUStep ( major, minor) => format ! ( "gnustep-{major}.{minor}" ) ,
118
+ Runtime :: GNUStep ( major, minor) => format ! ( " -fobjc-runtime= gnustep-{major}.{minor}" ) ,
189
119
// WinObjC's libobjc2 is a fork of gnustep's from version 1.8
190
- WinObjC => "gnustep-1.8" . into ( ) ,
191
- ObjFW ( version) => {
120
+ Runtime :: WinObjC => " -fobjc-runtime= gnustep-1.8" . into ( ) ,
121
+ Runtime :: ObjFW ( version) => {
192
122
// Default in clang
193
123
let version = version. as_deref ( ) . unwrap_or ( "0.8" ) ;
194
- format ! ( "objfw-{version}" )
124
+ format ! ( " -fobjc-runtime= objfw-{version}" )
195
125
}
196
126
} ;
197
127
@@ -204,14 +134,8 @@ fn main() {
204
134
// Assume the compiler is clang; if it isn't, this is probably going to
205
135
// fail anyways, since we're using newer runtimes than GCC supports.
206
136
//
207
- // TODO: Should add we these, or is it someone else's responsibility?
208
- // - `-mios-simulator-version-min={}`
209
- // - `-miphoneos-version-min={}`
210
- // - `-mmacosx-version-min={}`
211
- // - ...
212
- //
213
137
// TODO: -fobjc-weak ?
214
- let mut cc_args = format ! ( "-fobjc-exceptions -fobjc-runtime={clang_runtime }" ) ;
138
+ let mut cc_args = format ! ( "-fobjc-exceptions{clang_objc_runtime }" ) ;
215
139
216
140
if let Runtime :: ObjFW ( _) = & runtime {
217
141
// Add compability headers to make `#include <objc/objc.h>` work.
0 commit comments