Skip to content

Commit 9f0769d

Browse files
committed
sys: Add README
1 parent e63fc13 commit 9f0769d

File tree

12 files changed

+156
-27
lines changed

12 files changed

+156
-27
lines changed

objc_sys/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ version = "0.0.0" # Remember to update html_root_url in lib.rs
44
authors = ["Mads Marquart <[email protected]>"]
55
edition = "2018"
66

7-
description = "Bindings to the Objective-C core runtime"
7+
description = "Raw bindings to Objective-C runtimes"
88
keywords = ["objective-c", "macos", "ios", "objc_msgSend", "sys"]
99
categories = [
1010
"external-ffi-bindings",
11+
# "no_std" # TODO
1112
"os::macos-apis",
1213
]
1314
repository = "https://github.com/madsmtm/objc"
@@ -20,6 +21,8 @@ exclude = [
2021
"helper-scripts/*",
2122
]
2223

24+
readme = "README.md"
25+
2326
# Downstream users can customize the linking to libobjc!
2427
# See https://doc.rust-lang.org/cargo/reference/build-scripts.html#overriding-build-scripts
2528
links = "objc"

objc_sys/README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# `objc_sys`
2+
3+
[![Latest version](https://badgen.net/crates/v/objc_sys)](https://crates.io/crates/objc_sys)
4+
[![License](https://badgen.net/badge/license/MIT/blue)](../LICENSE.txt)
5+
[![Documentation](https://docs.rs/objc_sys/badge.svg)](https://docs.rs/objc_sys/)
6+
[![CI Status](https://github.com/madsmtm/objc/workflows/CI/badge.svg)](https://github.com/madsmtm/objc/actions)
7+
8+
Raw Rust bindings to core Objective-C runtimes and ABIs.
9+
10+
## Runtime Support
11+
12+
`objc_sys` currently supports two runtimes (support for [`ObjFW`] may be
13+
added):
14+
- Apple's [`objc4`] on `cfg(target_vendor = "apple")` targets.
15+
- GNUStep's [`libobjc2`] on all other targets. See their [Objective-C Compiler
16+
and Runtime FAQ][gnustep-faq].
17+
18+
This library will probably only ever support ["Modern"][modern] Objective-C
19+
runtimes, since support for reference-counting primitives like `objc_retain`
20+
and `objc_autoreleasePoolPop` is a vital requirement for most applications.
21+
22+
Just so we're being clear, this rules out the GCC [`libobjc`][gcc-libobjc]
23+
runtime (see [this][gcc-objc-support]), and the [`mulle-objc`] runtime.
24+
25+
[`ObjFW`]: https://github.com/ObjFW/ObjFW
26+
[`objc4`]: https://opensource.apple.com/source/objc4/
27+
[`libobjc2`]: https://github.com/gnustep/libobjc2
28+
[gnustep-faq]: http://wiki.gnustep.org/index.php/Objective-C_Compiler_and_Runtime_FAQ
29+
[modern]: https://en.wikipedia.org/wiki/Objective-C#Modern_Objective-C
30+
[gcc-libobjc]: https://github.com/gcc-mirror/gcc/tree/master/libobjc
31+
[gcc-objc-support]: https://gcc.gnu.org/onlinedocs/gcc/Standards.html#Objective-C-and-Objective-C_002b_002b-Languages
32+
[`mulle-objc`]: https://github.com/mulle-objc/mulle-objc-runtime
33+
34+
35+
## Required Versions
36+
37+
At least `libobjc2` [version 1.7][libobjc2-1.7] or `objc4`
38+
[version 493.9][objc4-493.9] is required.
39+
40+
`objc4` version 493.9 is available with:
41+
- **macOS 10.7**
42+
- **iOS 5.0**
43+
- **tvOS 9.0**
44+
- **watchOS 1.0**
45+
- **bridgeOS 2.0**
46+
47+
So those are the **minimum supported Apple versions**. Functionality that was
48+
added after these versions are not (yet?) available in `objc_sys`.
49+
50+
[libobjc2-1.7]: https://github.com/gnustep/libobjc2/tree/1.7
51+
[objc4-493.9]: https://opensource.apple.com/source/objc4/
52+
53+
54+
## Configuring linking
55+
56+
This crate defines the `links` key in `Cargo.toml` so it's possible to
57+
change the linking to `libobjc`, see [the relevant cargo docs][overriding].
58+
59+
In the future, this crate may vendor the required source code to automatically
60+
build and link to the runtimes. Choosing static vs. dynamic linking here may
61+
also become an option.
62+
63+
[overriding]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#overriding-build-scripts
64+
65+
66+
## Objective-C compiler ABI configuration
67+
68+
Objective-C compilers like `clang` and `gcc` requires configuring the calling
69+
ABI to the runtime you're using:
70+
- `clang` uses the [`-fobjc-runtime`] flag, of which there are a few different
71+
[options][clang-objc-kinds].
72+
- `gcc` uses the [`-fgnu-runtime` or `-fnext-runtime`][gcc-flags] options.
73+
Note that Modern Objective-C features are ill supported.
74+
75+
This is relevant if you're building and linking to custom Objective-C sources
76+
in a build script. In the future, this crate may expose build script metadata
77+
to help with selecting these (and other required) flags.
78+
79+
[`-fobjc-runtime`]: https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fobjc-runtime
80+
[clang-objc-kinds]: https://clang.llvm.org/doxygen/classclang_1_1ObjCRuntime.html#af19fe070a7073df4ecc666b44137c4e5
81+
[gcc-flags]: https://gcc.gnu.org/onlinedocs/gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html
82+
83+
84+
## Design choices
85+
86+
It is recognized that the most primary consumer of this library will be macOS
87+
and secondly iOS applications. Therefore it was chosen not to use `bindgen` in
88+
our build script to not add compilation cost to those targets.<sup>1</sup>
89+
90+
Deprecated functions are also not included for future compability, since they
91+
could be removed in any macOS release, and then our code would break. If you
92+
have a need for these, please open an issue and we can discuss it!
93+
94+
Some items (in particular the `objc_msgSend_X` family) have `cfg`s that prevent
95+
their usage on different platforms; these are **semver-stable** in the sense
96+
that they will only get less restrictive, never more.
97+
98+
<sup>1</sup> That said, most of this is created with the help of `bindgen`'s
99+
commandline interface, so huge thanks to them!

objc_sys/helper-scripts/gen-git.fish

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Yup, this is terrible, but was a great help in creating the correct implementations
44

5-
# Source repo should be a path to https://github.com/madsmtm/objc4.git
5+
# Source repo should be a path to https://github.com/madsmtm/objc4-mirror.git
66
set source_repo $argv[1]
77
set to_repo $argv[2]
88

objc_sys/src/constants.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ use std::os::raw::c_int;
55

66
use crate::{id, Class, BOOL};
77

8-
/// The equivalent of true for Objective-C's [`BOOL`][`super::BOOL`] type.
98
#[cfg(not(target_arch = "aarch64"))]
9+
/// The equivalent of `true` for Objective-C's [`BOOL`][`super::BOOL`] type.
1010
pub const YES: BOOL = 1;
1111
#[cfg(target_arch = "aarch64")]
12+
/// The equivalent of `true` for Objective-C's [`BOOL`][`super::BOOL`] type.
1213
pub const YES: BOOL = true;
1314

14-
/// The equivalent of false for Objective-C's [`BOOL`][`super::BOOL`] type.
1515
#[cfg(not(target_arch = "aarch64"))]
16+
/// The equivalent of `false` for Objective-C's [`BOOL`][`super::BOOL`] type.
1617
pub const NO: BOOL = 0;
1718
#[cfg(target_arch = "aarch64")]
19+
/// The equivalent of `false` for Objective-C's [`BOOL`][`super::BOOL`] type.
1820
pub const NO: BOOL = false;
1921

2022
/// A quick alias for a [`null_mut`][`core::ptr::null_mut`] object / instance.

objc_sys/src/lib.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
1-
//! # Bindings to the objc_objective-C core runtime
1+
//! # Raw bindings to Objective-C runtimes
22
//!
3-
//! # Notable differences
3+
//! These bindings contain almost no documentation, so it is highly
4+
//! recommended to read the documentation of the original libraries:
5+
//! - Apple's [official documentation][apple].
6+
//! - Apple's `objc4` [source code][objc4] ([`git` mirror][objc4-mirror]), in
7+
//! particular `runtime.h`.
8+
//! - GNUStep's `libobjc2` [source code][libobjc2], in particular `runtime.h`.
49
//!
5-
//! Protocol / objc_protocol is no longer a type alias of objc_object, for
6-
//! better type safety. Their internal representation is the same, so the
7-
//! functionality is just a cast away.
8-
//!
9-
//! Deprecated functions are not included for future compability, since they
10-
//! could be removed at any macOS release, and then our code would break.
11-
12-
// TODO: Replace `extern "C"` with `extern "C-unwind"`.
10+
//! [apple]: https://developer.apple.com/documentation/objectivec/objective-c_runtime?language=objc
11+
//! [libobjc2]: https://github.com/gnustep/libobjc2/tree/v2.1/objc
12+
//! [objc4]: https://opensource.apple.com/source/objc4/objc4-818.2/runtime/
13+
//! [objc4-mirror]: https://github.com/madsmtm/objc4-mirror.git
1314
1415
#![no_std]
1516
#![allow(non_camel_case_types)]
1617
#![allow(non_upper_case_globals)]
1718
#![doc(html_root_url = "https://docs.rs/objc_sys/0.0.0")]
1819

20+
// TODO: Replace `extern "C"` with `extern "C-unwind"` where applicable.
21+
// See https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html.
22+
1923
// TODO: Remove this and add "no-std" category to Cargo.toml
24+
// Requires a better solution for C-types in `no_std` crates.
25+
// See https://github.com/japaric/cty/issues/14.
2026
extern crate std;
2127

2228
use core::cell::UnsafeCell;

objc_sys/src/message.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub struct objc_super {
1616
pub receiver: *mut objc_object,
1717
/// The particular superclass of the instance to message.
1818
///
19-
/// Named `class` in GNUStep and in older Objective-C versions.
19+
/// Named `class` in older Objective-C versions.
2020
pub super_class: *const objc_class,
2121
}
2222

objc_sys/src/method.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ pub struct objc_method {
99
_p: OpaqueData,
1010
}
1111

12+
/// Describes an Objective-C method.
1213
#[repr(C)]
1314
#[derive(Debug, Copy, Clone)]
1415
pub struct objc_method_description {
16+
/// The name of the method.
1517
pub name: *const objc_selector,
18+
/// The types of the method arguments.
1619
pub types: *const c_char,
1720
}
1821

objc_sys/src/object.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::os::raw::c_char;
33

44
use crate::{objc_class, objc_ivar, OpaqueData};
55

6-
/// An opaque type that represents an instance of a class.
6+
/// An opaque type that represents an object / an instance of a class.
77
#[repr(C)]
88
pub struct objc_object {
99
// `isa` field is deprecated, so we don't expose it here.

objc_sys/src/property.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@ use std::os::raw::{c_char, c_uint};
22

33
use crate::OpaqueData;
44

5+
/// An opaque type that describes a property in a class.
56
#[repr(C)]
67
pub struct objc_property {
78
_priv: [u8; 0],
89
_p: OpaqueData,
910
}
1011

12+
/// Describes an Objective-C property attribute.
1113
#[repr(C)]
1214
#[derive(Debug, Copy, Clone)]
1315
pub struct objc_property_attribute_t {
16+
/// The name of the attribute.
1417
pub name: *const c_char,
18+
/// The value of the attribute
19+
///
20+
/// Usually NULL.
1521
pub value: *const c_char,
1622
}
1723

objc_sys/src/selector.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ use std::os::raw::c_char;
22

33
use crate::{OpaqueData, BOOL};
44

5-
/// A type that represents a method selector.
5+
/// An opaque type that represents a method selector.
6+
///
7+
/// Selectors are immutable.
68
#[repr(C)]
79
pub struct objc_selector {
810
_priv: [u8; 0],

objc_sys/src/types.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,22 @@ use crate::{
44
objc_class, objc_ivar, objc_method, objc_object, objc_property, objc_protocol, objc_selector,
55
};
66

7-
/// The Objective-C `BOOL` type.
8-
///
9-
/// To convert an Objective-C `BOOL` into a Rust [`bool`], compare it with
10-
/// [`NO`][`super::NO`].
117
#[cfg(all(apple, not(target_arch = "aarch64")))]
12-
pub type BOOL = i8;
13-
/// TODO: Only if STRICT_APPLE_COMPATIBILITY is NOT defined.
14-
/// TODO: (__vxworks || _WIN32) becomes BOOL = c_int.
8+
type BOOL_INNER = i8;
9+
1510
#[cfg(all(gnustep, not(target_arch = "aarch64")))]
16-
pub type BOOL = u8;
11+
// TODO: Only if STRICT_APPLE_COMPATIBILITY is NOT defined.
12+
// TODO: (__vxworks || _WIN32) becomes BOOL = c_int.
13+
type BOOL_INNER = u8;
14+
1715
#[cfg(target_arch = "aarch64")]
18-
pub type BOOL = bool;
16+
type BOOL_INNER = bool;
17+
18+
/// The Objective-C `BOOL` type.
19+
///
20+
/// The type of this varies across platforms, so to convert an it into a Rust
21+
/// [`bool`], always compare it with [`YES`][`crate::YES`] or [`NO`][`crate::NO`].
22+
pub type BOOL = BOOL_INNER;
1923

2024
/// An immutable pointer to a selector.
2125
///
@@ -44,6 +48,10 @@ pub type Method = *mut objc_method;
4448

4549
/// An opaque type that represents a protocol.
4650
///
51+
/// This is not just a type alias of [`objc_object`], but of [`objc_protocol`]
52+
/// instead, for better type safety. Their internal representation is the same,
53+
/// so the functionality is just a cast away.
54+
///
4755
/// Type alias provided for convenience.
4856
pub type Protocol = objc_protocol;
4957

objc_sys/src/various.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::os::raw::{c_char, c_int};
77
use crate::objc_class;
88
use crate::{objc_AssociationPolicy, objc_object, OpaqueData, BOOL};
99

10-
/// A type that represents an instance variable.
10+
/// An opaque type that represents an instance variable.
1111
#[repr(C)]
1212
pub struct objc_ivar {
1313
_priv: [u8; 0],

0 commit comments

Comments
 (0)