objc

objc runtime

This is a minimal Objective C runtime written in C, designed to be portable across different platforms, including ARM and x86 architectures, mostly targeting embedded systems. It uses the "gcc" ABI for the moment, as that is the most portable across different platforms.

Requirements

You will minimally need the following tools to build the runtime:

Building the libraries

Several static libraries are currently built:

A lot of this code is in development still. See the "examples" or documentation on what's been implemented so far.

Download the source code from GitHub:

git clone git@github.com:djthorpe/objc.git
cd objc

The TOOLCHAIN_PATH environment variable should point to the directory where the toolchain is installed. For Macintosh, you can use Homebrew to install the GCC toolchain, which is required for compiling the runtime on MacOS:

# Compile with GCC 15 for MacOS
brew install gcc@15
TOOLCHAIN_PATH=/opt/homebrew RELEASE=1 CC=gcc-15 make

Once you've made the libraries, use the make tests target to run the unit tests. There is information about test coverage in the tests directory.

Running Tests

On macOS, build and run all tests:

TOOLCHAIN_PATH=/opt/homebrew CC=gcc-15 RELEASE=1 make tests

Run an individual test target (replace <test_target> with e.g. fs_09):

cmake --build build --target <test_target>
ctest --output-on-failure --test-dir build --tests-regex <test_target>

See the tests README for a catalog of tests (fs_01..fs_09 and others) and details.

You can target different architectures by setting the TARGET environment variable. For a RP2040-based board, you can use the clang compiler with the ARM toolchain. The TARGET environment variable should be set to the target architecture, such as armv6m-none-eabi for the RP2040 Pico board:

# Compile for the RP2040 Pico board
CC=clang TARGET=armv6m-none-eabi TOOLCHAIN_PATH=/opt/LLVM-ET-Arm-19.1.5-Darwin-universal RELEASE=1 make

See the list of supported targets in the cmake directory. You can exclude the environment variable RELEASE=1 to build debugging versions of the libraries.

For Pico cross-compilation, after building, you can load a specific test onto a Pico W board (example for <test_target>):

cmake --build build --target <test_target> && picotool load -x build/src/tests/<test_target>/<test_target>.uf2

For Linux cross-compilation using Docker (Bookworm):

docker run --rm -i -v $(pwd):/root bookworm-builder bash -c "cd /root && make clean && CC=gcc make"
docker run --rm -i -v $(pwd):/root bookworm-builder bash -c "ctest --output-on-failure --test-dir build --tests-regex <test_target>"

Installing the libraries

The libraries should be installed under a prefix path:

PREFIX=/opt/picofuse make install

These can subsequently be used in projects to make executables for any combination of platform.

Documentation

To build the API documentation, you will need to have docker installed. The documentation is built using doxygen through docker so you don't need to have it installed directly.

make docs
open docs/index.html

The documentation is also published on the project documentation site.

Current status

References

Here are some references that may be useful for understanding the Objective C runtime and its implementation: