Skip to content

Commit 5dbf3e7

Browse files
committed
Work on ObjFW support in objc-sys
A lot of functionality is not yet available in ObjFW, this is now reflected in the API. Support for ObjFW is still not enabled, see #117 for that.
1 parent 56c6ca8 commit 5dbf3e7

File tree

14 files changed

+175
-54
lines changed

14 files changed

+175
-54
lines changed

objc-sys/build.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::env;
1+
use std::{env, path::Path};
22

33
/// TODO: Better validation of this
44
///
@@ -114,7 +114,9 @@ fn main() {
114114
}
115115
}
116116
(false, false, true) => {
117-
unimplemented!()
117+
// For now
118+
unimplemented!("ObjFW is not yet supported")
119+
// ObjFW(None)
118120
}
119121
(false, false, false) => {
120122
// Choose sensible defaults when generating docs
@@ -202,8 +204,8 @@ fn main() {
202204
WinObjC => "gnustep-1.8".into(),
203205
ObjFW(version) => {
204206
// Default in clang
205-
let _version = version.as_deref().unwrap_or("0.8");
206-
todo!()
207+
let version = version.as_deref().unwrap_or("0.8");
208+
format!("objfw-{}", version)
207209
}
208210
};
209211

@@ -221,12 +223,27 @@ fn main() {
221223
// - `-miphoneos-version-min={}`
222224
// - `-mmacosx-version-min={}`
223225
// - ...
224-
println!(
225-
"cargo:cc_args=-fobjc-arc -fobjc-arc-exceptions -fobjc-exceptions -fobjc-runtime={}",
226-
// TODO: -fobjc-weak ?
226+
//
227+
// TODO: -fobjc-weak ?
228+
let mut cc_args = format!(
229+
"-fobjc-arc -fobjc-arc-exceptions -fobjc-exceptions -fobjc-runtime={}",
227230
clang_runtime
228-
); // DEP_OBJC_[version]_CC_ARGS
231+
);
232+
233+
if let Runtime::ObjFW(_) = &runtime {
234+
// Add compability headers to make `#include <objc/objc.h>` work.
235+
let compat_headers = Path::new(env!("CARGO_MANIFEST_DIR")).join("compat-headers-objfw");
236+
cc_args.push_str(" -I");
237+
cc_args.push_str(compat_headers.to_str().unwrap());
238+
}
229239

230-
// Link to libobjc
231-
println!("cargo:rustc-link-lib=dylib=objc");
240+
println!("cargo:cc_args={}", cc_args); // DEP_OBJC_[version]_CC_ARGS
241+
242+
if let Runtime::ObjFW(_) = &runtime {
243+
// Link to libobjfw-rt
244+
println!("cargo:rustc-link-lib=dylib=objfw-rt");
245+
} else {
246+
// Link to libobjc
247+
println!("cargo:rustc-link-lib=dylib=objc");
248+
}
232249
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#import <ObjFW-RT/ObjFW-RT.h>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#import <ObjFW-RT/ObjFW-RT.h>

objc-sys/src/class.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use std::os::raw::{c_char, c_int, c_uint};
22

3-
use crate::{
4-
objc_ivar, objc_method, objc_object, objc_property, objc_property_attribute_t, objc_protocol,
5-
objc_selector, OpaqueData, BOOL, IMP,
6-
};
3+
#[cfg(not(objfw))]
4+
use crate::{objc_ivar, objc_method, objc_object, objc_property, objc_property_attribute_t};
5+
use crate::{objc_protocol, objc_selector, OpaqueData, BOOL, IMP};
76

87
/// An opaque type that represents an Objective-C class.
98
#[repr(C)]
@@ -14,6 +13,7 @@ pub struct objc_class {
1413
_p: OpaqueData,
1514
}
1615

16+
#[cfg(not(objfw))]
1717
/// This is `c_char` in GNUStep's libobjc2 and `uint8_t` in Apple's objc4.
1818
///
1919
/// The pointer represents opaque data, and is definitely not just an integer,
@@ -27,6 +27,7 @@ extern_c! {
2727
pub fn objc_getClass(name: *const c_char) -> *const objc_class;
2828
pub fn objc_getRequiredClass(name: *const c_char) -> *const objc_class;
2929
pub fn objc_lookUpClass(name: *const c_char) -> *const objc_class;
30+
#[cfg(not(objfw))]
3031
pub fn objc_getMetaClass(name: *const c_char) -> *const objc_class;
3132
pub fn objc_copyClassList(out_len: *mut c_uint) -> *mut *const objc_class;
3233
pub fn objc_getClassList(buffer: *mut *const objc_class, buffer_len: c_int) -> c_int;
@@ -42,9 +43,11 @@ extern_c! {
4243
name: *const c_char,
4344
extra_bytes: usize,
4445
) -> *mut objc_class;
46+
#[cfg(not(objfw))]
4547
pub fn objc_disposeClassPair(cls: *mut objc_class);
4648
pub fn objc_registerClassPair(cls: *mut objc_class);
4749

50+
#[cfg(not(objfw))]
4851
pub fn class_addIvar(
4952
cls: *mut objc_class,
5053
name: *const c_char,
@@ -58,53 +61,68 @@ extern_c! {
5861
imp: IMP,
5962
types: *const c_char,
6063
) -> BOOL;
64+
#[cfg(not(objfw))]
6165
pub fn class_addProperty(
6266
cls: *mut objc_class,
6367
name: *const c_char,
6468
attributes: *const objc_property_attribute_t,
6569
attributes_count: c_uint,
6670
) -> BOOL;
71+
#[cfg(not(objfw))]
6772
pub fn class_addProtocol(cls: *mut objc_class, protocol: *const objc_protocol) -> BOOL;
6873
pub fn class_conformsToProtocol(cls: *const objc_class, protocol: *const objc_protocol)
6974
-> BOOL;
75+
76+
#[cfg(not(objfw))] // Available in newer versions
7077
pub fn class_copyIvarList(
7178
cls: *const objc_class,
7279
out_len: *mut c_uint,
7380
) -> *mut *const objc_ivar;
81+
#[cfg(not(objfw))] // Available in newer versions
7482
pub fn class_copyMethodList(
7583
cls: *const objc_class,
7684
out_len: *mut c_uint,
7785
) -> *mut *const objc_method;
86+
#[cfg(not(objfw))] // Available in newer versions
7887
pub fn class_copyPropertyList(
7988
cls: *const objc_class,
8089
out_len: *mut c_uint,
8190
) -> *mut *const objc_property;
91+
#[cfg(not(objfw))]
8292
pub fn class_copyProtocolList(
8393
cls: *const objc_class,
8494
out_len: *mut c_uint,
8595
) -> *mut *const objc_protocol;
8696

97+
#[cfg(not(objfw))]
8798
pub fn class_createInstance(cls: *const objc_class, extra_bytes: usize) -> *mut objc_object;
99+
#[cfg(not(objfw))]
88100
pub fn class_getClassMethod(
89101
cls: *const objc_class,
90102
name: *const objc_selector,
91103
) -> *const objc_method;
104+
#[cfg(not(objfw))]
92105
pub fn class_getClassVariable(cls: *const objc_class, name: *const c_char) -> *const objc_ivar;
93106
#[cfg(apple)]
94107
pub fn class_getImageName(cls: *const objc_class) -> *const c_char;
108+
#[cfg(not(objfw))] // Available in newer versions
95109
pub fn class_getInstanceMethod(
96110
cls: *const objc_class,
97111
name: *const objc_selector,
98112
) -> *const objc_method;
99113
pub fn class_getInstanceSize(cls: *const objc_class) -> usize;
114+
#[cfg(not(objfw))]
100115
pub fn class_getInstanceVariable(
101116
cls: *const objc_class,
102117
name: *const c_char,
103118
) -> *const objc_ivar;
119+
#[cfg(not(objfw))]
104120
pub fn class_getIvarLayout(cls: *const objc_class) -> *const ivar_layout_type;
105121
pub fn class_getName(cls: *const objc_class) -> *const c_char;
122+
#[cfg(not(objfw))]
106123
pub fn class_getProperty(cls: *const objc_class, name: *const c_char) -> *const objc_property;
107124
pub fn class_getSuperclass(cls: *const objc_class) -> *const objc_class;
125+
#[cfg(not(objfw))]
108126
pub fn class_getVersion(cls: *const objc_class) -> c_int;
109127
#[cfg(apple)]
110128
pub fn class_getWeakIvarLayout(cls: *const objc_class) -> *const ivar_layout_type;
@@ -115,14 +133,17 @@ extern_c! {
115133
imp: IMP,
116134
types: *const c_char,
117135
) -> IMP;
136+
#[cfg(not(objfw))]
118137
pub fn class_replaceProperty(
119138
cls: *mut objc_class,
120139
name: *const c_char,
121140
attributes: *const objc_property_attribute_t,
122141
attributes_len: c_uint,
123142
);
124143
pub fn class_respondsToSelector(cls: *const objc_class, sel: *const objc_selector) -> BOOL;
144+
#[cfg(not(objfw))]
125145
pub fn class_setIvarLayout(cls: *mut objc_class, layout: *const ivar_layout_type);
146+
#[cfg(not(objfw))]
126147
pub fn class_setVersion(cls: *mut objc_class, version: c_int);
127148
#[cfg(apple)]
128149
pub fn class_setWeakIvarLayout(cls: *mut objc_class, layout: *const ivar_layout_type);

objc-sys/src/exception.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! Apple: `objc-exception.h`
33
//! GNUStep: `eh_personality.c`, which is a bit brittle to rely on, but I
44
//! think it's fine...
5+
#[cfg(not(objfw))]
56
use core::ffi::c_void;
67
#[cfg(apple)]
78
use std::os::raw::c_int;
@@ -24,6 +25,10 @@ pub type objc_exception_preprocessor =
2425
#[cfg(apple)]
2526
pub type objc_uncaught_exception_handler = unsafe extern "C" fn(exception: *mut objc_object);
2627

28+
#[cfg(objfw)]
29+
pub type objc_uncaught_exception_handler =
30+
Option<unsafe extern "C" fn(exception: *mut objc_object)>;
31+
2732
/// Only available on macOS.
2833
///
2934
/// Remember that this is non-null!
@@ -32,7 +37,9 @@ pub type objc_exception_handler =
3237
unsafe extern "C" fn(unused: *mut objc_object, context: *mut c_void);
3338

3439
extern_c! {
40+
#[cfg(not(objfw))]
3541
pub fn objc_begin_catch(exc_buf: *mut c_void) -> *mut objc_object;
42+
#[cfg(not(objfw))]
3643
pub fn objc_end_catch();
3744
/// See [`objc-exception.h`].
3845
///
@@ -49,7 +56,7 @@ extern_c! {
4956
pub fn objc_setExceptionPreprocessor(
5057
f: objc_exception_preprocessor,
5158
) -> objc_exception_preprocessor;
52-
#[cfg(apple)]
59+
#[cfg(any(apple, objfw))]
5360
pub fn objc_setUncaughtExceptionHandler(
5461
f: objc_uncaught_exception_handler,
5562
) -> objc_uncaught_exception_handler;

objc-sys/src/message.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//!
55
//! TODO: Some of these are only supported on _some_ GNUStep targets!
66
use crate::{objc_class, objc_object};
7-
#[cfg(gnustep)]
7+
#[cfg(any(gnustep, objfw))]
88
use crate::{objc_selector, IMP};
99

1010
/// Specifies data used when sending messages to superclasses.
@@ -21,16 +21,21 @@ pub struct objc_super {
2121
}
2222

2323
extern_c! {
24-
#[cfg(gnustep)]
24+
#[cfg(any(gnustep, objfw))]
2525
pub fn objc_msg_lookup(receiver: *mut objc_object, sel: *const objc_selector) -> IMP;
26-
#[cfg(gnustep)]
26+
#[cfg(objfw)]
27+
pub fn objc_msg_lookup_stret(receiver: *mut objc_object, sel: *const objc_selector) -> IMP;
28+
#[cfg(any(gnustep, objfw))]
2729
pub fn objc_msg_lookup_super(sup: *const objc_super, sel: *const objc_selector) -> IMP;
30+
#[cfg(objfw)]
31+
pub fn objc_msg_lookup_super_stret(sup: *const objc_super, sel: *const objc_selector) -> IMP;
2832
// #[cfg(gnustep)]
2933
// objc_msg_lookup_sender
3034
// objc_msgLookup family available in macOS >= 10.12
3135

3236
// objc_msgSend_noarg
3337

38+
#[cfg(not(objfw))]
3439
pub fn objc_msgSend();
3540
// objc_msgSend_debug
3641

@@ -48,7 +53,7 @@ extern_c! {
4853
// Struct return. Not available on __arm64__:
4954

5055
/// Not available on `target_arch = "aarch64"`
51-
#[cfg(not(target_arch = "aarch64"))]
56+
#[cfg(all(not(objfw), not(target_arch = "aarch64")))]
5257
pub fn objc_msgSend_stret();
5358
// objc_msgSend_stret_debug
5459

@@ -64,14 +69,14 @@ extern_c! {
6469
/// Not available on `target_arch = "aarch64"`
6570
#[cfg(all(apple, not(target_arch = "aarch64")))]
6671
pub fn _objc_msgForward_stret();
67-
/// Not available on `target_arch = "aarch64"`
68-
#[cfg(not(target_arch = "aarch64"))]
72+
/// Not available on `target_arch = "aarch64"`, always available on ObjFW
73+
#[cfg(any(objfw, not(target_arch = "aarch64")))]
6974
pub fn class_getMethodImplementation_stret();
7075

7176
// __x86_64__ and __i386__
7277

7378
/// Only available on `target_arch = "x86_64"` or `target_arch = "x86"`
74-
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
79+
#[cfg(all(not(objfw), any(target_arch = "x86_64", target_arch = "x86")))]
7580
pub fn objc_msgSend_fpret();
7681
// objc_msgSend_fpret_debug
7782

objc-sys/src/method.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
use std::os::raw::{c_char, c_uint};
1+
use std::os::raw::c_char;
2+
#[cfg(not(objfw))]
3+
use std::os::raw::c_uint;
24

3-
use crate::{objc_selector, OpaqueData, IMP};
5+
#[cfg(not(objfw))]
6+
use crate::IMP;
7+
use crate::{objc_selector, OpaqueData};
48

59
/// A type that represents a method in a class definition.
610
#[repr(C)]
@@ -20,6 +24,8 @@ pub struct objc_method_description {
2024
}
2125

2226
extern_c! {
27+
#![cfg(not(objfw))]
28+
2329
pub fn method_copyArgumentType(method: *const objc_method, index: c_uint) -> *mut c_char;
2430
pub fn method_copyReturnType(method: *const objc_method) -> *mut c_char;
2531
pub fn method_exchangeImplementations(method1: *mut objc_method, method2: *mut objc_method);

objc-sys/src/object.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
#[cfg(not(objfw))]
12
use core::ffi::c_void;
23
use std::os::raw::c_char;
34

4-
use crate::{objc_class, objc_ivar, OpaqueData};
5+
#[cfg(not(objfw))]
6+
use crate::objc_ivar;
7+
use crate::{objc_class, OpaqueData};
58

69
/// An opaque type that represents an object / an instance of a class.
710
#[repr(C)]
@@ -15,23 +18,31 @@ pub struct objc_object {
1518
extern_c! {
1619
pub fn object_getClass(obj: *const objc_object) -> *const objc_class;
1720
pub fn object_getClassName(obj: *const objc_object) -> *const c_char;
21+
pub fn object_setClass(obj: *mut objc_object, cls: *const objc_class) -> *const objc_class;
22+
23+
#[cfg(not(objfw))]
1824
pub fn object_getIndexedIvars(obj: *const objc_object) -> *const c_void;
25+
#[cfg(not(objfw))]
1926
pub fn object_getIvar(obj: *const objc_object, ivar: *const objc_ivar) -> *const objc_object;
20-
21-
pub fn object_setClass(obj: *mut objc_object, cls: *const objc_class) -> *const objc_class;
27+
#[cfg(not(objfw))]
2228
pub fn object_setIvar(obj: *mut objc_object, ivar: *const objc_ivar, value: *mut objc_object);
2329

2430
#[deprecated = "Not needed since ARC"]
2531
#[cfg(apple)]
2632
pub fn object_copy(obj: *const objc_object, size: usize) -> *mut objc_object;
33+
2734
#[deprecated = "Not needed since ARC"]
35+
#[cfg(not(objfw))]
2836
pub fn object_dispose(obj: *mut objc_object) -> *mut objc_object;
37+
2938
#[deprecated = "Not needed since ARC"]
39+
#[cfg(not(objfw))]
3040
pub fn object_setInstanceVariable(
3141
obj: *mut objc_object,
3242
name: *const c_char,
3343
value: *mut c_void,
3444
) -> *const objc_ivar;
45+
3546
// Available in macOS 10.12
3647
// #[deprecated = "Not needed since ARC"]
3748
// #[cfg(apple)]
@@ -40,12 +51,15 @@ extern_c! {
4051
// name: *const c_char,
4152
// value: *mut c_void,
4253
// ) -> *const objc_ivar;
54+
4355
#[deprecated = "Not needed since ARC"]
56+
#[cfg(not(objfw))]
4457
pub fn object_getInstanceVariable(
4558
obj: *const objc_object,
4659
name: *const c_char,
4760
out_value: *mut *const c_void,
4861
) -> *const objc_ivar;
62+
4963
#[deprecated = "Not needed since ARC"]
5064
#[cfg(apple)]
5165
pub fn objc_getFutureClass(name: *const c_char) -> *const objc_class;

objc-sys/src/property.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use std::os::raw::{c_char, c_uint};
1+
use std::os::raw::c_char;
2+
#[cfg(not(objfw))]
3+
use std::os::raw::c_uint;
24

35
use crate::OpaqueData;
46

@@ -22,6 +24,8 @@ pub struct objc_property_attribute_t {
2224
}
2325

2426
extern_c! {
27+
#![cfg(not(objfw))]
28+
2529
pub fn property_copyAttributeList(
2630
property: *const objc_property,
2731
out_len: *mut c_uint,

0 commit comments

Comments
 (0)