Skip to content

Commit 1ded654

Browse files
committed
Make objc2_exception work on GNUStep & WinObjc
1 parent a497298 commit 1ded654

File tree

7 files changed

+48
-35
lines changed

7 files changed

+48
-35
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ env:
1010
RUST_BACKTRACE: 1
1111
# Faster compilation and error on warnings
1212
RUSTFLAGS: "-C debuginfo=0 -D warnings"
13+
CC: clang
14+
CXX: clang++
1315

1416
jobs:
1517
fmt:
@@ -84,8 +86,6 @@ jobs:
8486
tar -xzf v1.9.tar.gz
8587
mkdir libobjc2-1.9/build
8688
cd libobjc2-1.9/build
87-
export CC="clang"
88-
export CXX="clang++"
8989
cmake ../
9090
sudo make install
9191
@@ -122,7 +122,15 @@ jobs:
122122
with:
123123
command: test
124124
# Temporary fix
125-
args: --verbose --no-fail-fast --no-default-features --package objc2_sys --package objc2 --package objc2_encode --package objc2_foundation
125+
args: --verbose --no-fail-fast --no-default-features --package objc2_sys --package objc2 --package objc2_encode --package objc2_exception --package objc2_foundation
126+
127+
- name: Test GNUStep with features
128+
if: contains(matrix.platform.os, 'ubuntu')
129+
uses: actions-rs/cargo@v1
130+
with:
131+
command: test
132+
# Temporary fix
133+
args: --verbose --no-fail-fast --no-default-features --features exception,verify_message --package objc2_sys --package objc2 --package objc2_encode --package objc2_exception --package objc2_foundation
126134

127135
- name: Test
128136
if: ${{ !contains(matrix.platform.os, 'ubuntu') }}

objc2_exception/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ keywords = ["objective-c", "macos", "ios", "try", "catch"]
99
categories = [
1010
"api-bindings",
1111
"development-tools::ffi",
12-
"no-std",
12+
# "no-std", # TODO
1313
"os::macos-apis",
1414
]
1515
readme = "README.md"
@@ -19,5 +19,8 @@ license = "MIT"
1919

2020
build = "build.rs"
2121

22+
[dependencies]
23+
objc2_sys = { path = "../objc2_sys" }
24+
2225
[build-dependencies]
2326
cc = "1"

objc2_exception/build.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1+
use std::env;
2+
13
fn main() {
2-
cc::Build::new()
3-
.file("extern/exception.m")
4-
.flag("-fobjc-exceptions")
5-
.compile("librustobjcexception.a");
4+
println!("cargo:rerun-if-changed=extern/exception.m");
5+
6+
let mut builder = cc::Build::new();
7+
builder.file("extern/exception.m");
8+
9+
// Assume the C compiler is clang; if it isn't, this is probably going to
10+
// fail anyways.
11+
for flag in env::var("DEP_OBJC_CLANG_ARGS").unwrap().split(' ') {
12+
builder.flag(flag);
13+
}
14+
15+
builder.compile("librust_objc_try_catch_exception.a");
616
}

objc2_exception/extern/exception.m

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
/// This is always available when building Objective-C.
1+
// Don't include any headers, cross compilation is difficult to set up
2+
// properly in such situations.
3+
4+
/// We're linking to `libobjc` so this should be available.
25
///
36
/// See <https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-runtime-objc-retain>.
47
id objc_retain(id value);
58

69
// We return `unsigned char`, since it is guaranteed to be an `u8` on all platforms
7-
unsigned char RustObjCExceptionTryCatch(void (*f)(void *), void *context, id *error) {
10+
unsigned char rust_objc_try_catch_exception(void (*f)(void *), void *context, id *error) {
811
@try {
912
f(context);
1013
if (error) {

objc2_exception/src/lib.rs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,13 @@ use core::ffi::c_void;
2222
use core::mem;
2323
use core::ptr;
2424

25-
#[link(name = "objc", kind = "dylib")]
26-
// TODO: "C-unwind"
27-
extern "C" {
28-
/// See [`objc-exception.h`][objc-exception].
29-
///
30-
/// [objc-exception]: https://opensource.apple.com/source/objc4/objc4-818.2/runtime/objc-exception.h.auto.html
31-
// Header marks this with _Nonnull, but LLVM output shows otherwise
32-
fn objc_exception_throw(exception: *mut c_void) -> !;
33-
// fn objc_exception_rethrow();
34-
}
25+
use objc2_sys::{objc_exception_throw, objc_object};
3526

3627
extern "C" {
37-
fn RustObjCExceptionTryCatch(
28+
fn rust_objc_try_catch_exception(
3829
f: extern "C" fn(*mut c_void),
3930
context: *mut c_void,
40-
error: *mut *mut c_void,
31+
error: *mut *mut objc_object,
4132
) -> u8; // std::os::raw::c_uchar
4233
}
4334

@@ -47,13 +38,7 @@ extern "C" {
4738
/// stabilized.
4839
///
4940
/// [rfc-1861]: https://rust-lang.github.io/rfcs/1861-extern-types.html
50-
#[repr(C)]
51-
pub struct Exception {
52-
/// See the [Nomicon] for details on representing opaque structs.
53-
///
54-
/// [Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
55-
_priv: [u8; 0],
56-
}
41+
pub type Exception = objc_object;
5742

5843
/// Throws an Objective-C exception.
5944
///
@@ -70,7 +55,7 @@ pub struct Exception {
7055
/// [RFC-2945]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html
7156
#[inline]
7257
pub unsafe fn throw(exception: *mut Exception) -> ! {
73-
objc_exception_throw(exception as *mut _)
58+
objc_exception_throw(exception)
7459
}
7560

7661
unsafe fn try_no_ret<F: FnOnce()>(closure: F) -> Result<(), *mut Exception> {
@@ -87,12 +72,12 @@ unsafe fn try_no_ret<F: FnOnce()>(closure: F) -> Result<(), *mut Exception> {
8772
let context = &mut closure as *mut _ as *mut c_void;
8873

8974
let mut exception = ptr::null_mut();
90-
let success = RustObjCExceptionTryCatch(f, context, &mut exception);
75+
let success = rust_objc_try_catch_exception(f, context, &mut exception);
9176

9277
if success == 0 {
9378
Ok(())
9479
} else {
95-
Err(exception as *mut _)
80+
Err(exception)
9681
}
9782
}
9883

objc2_sys/build.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,10 @@ fn main() {
160160

161161
// Add clang arguments
162162
println!(
163-
"cargo:clang_args=-fobjc-arc -fobjc-arc-exceptions -fobjc-exceptions -fobjc-weak -fobjc-runtime={}",
164-
// -fobjc-arc implies -fobjc-link-runtime, so people actually don't
165-
// even need to specify `-lobjc` (though they probably still should).
163+
"cargo:clang_args=-fobjc-link-runtime -fobjc-arc -fobjc-arc-exceptions -fobjc-exceptions -fobjc-runtime={}",
164+
// `-fobjc-link-runtime` -> people don't need to specify `-lobjc`.
165+
166+
// -fobjc-weak ?
166167
clang_runtime
167168
); // DEP_OBJC_CLANG_ARGS
168169

objc2_sys/src/exception.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ pub type objc_exception_handler =
3434
extern "C" {
3535
pub fn objc_begin_catch(exc_buf: *mut c_void) -> *mut objc_object;
3636
pub fn objc_end_catch();
37+
/// See [`objc-exception.h`][objc-exception].
38+
///
39+
/// [objc-exception]: https://opensource.apple.com/source/objc4/objc4-818.2/runtime/objc-exception.h.auto.html
3740
pub fn objc_exception_throw(exception: *mut objc_object) -> !;
3841
#[cfg(apple)]
3942
pub fn objc_exception_rethrow() -> !;

0 commit comments

Comments
 (0)