How to Integrate MulleObjC-startup into Your Project Using mulle-sde

To integrate MulleObjC-startup using mulle-sde, initialize your project with mulle-sde init, add the library with mulle-sde add github:mulle-objc/MulleObjC-startup, and build with mulle-sde run to automatically link the startup routines and runtime dependencies.

The mulle-objc/mulleobjc-startup repository provides the essential __register_mulle_objc_universe symbol and runtime initialization helpers required for any MulleObjC application. When you integrate MulleObjC-startup into your project using mulle-sde, the tool automatically resolves transitive dependencies like MulleObjC and mulle-core, then configures CMake to link the static library correctly.

Initializing Your mulle-sde Project

Before adding the startup library, you need a working mulle-sde project structure. The tool generates the necessary CMake scaffolding and dependency management files.

Creating a New Executable Project

Run the initialization command with the appropriate craft (template) for Objective-C development:

mulle-sde init -d my-project -m mulle-objc/objc-developer executable
cd my-project
mulle-sde vibecoding on          # optional: enables colourful output

This creates the my-project directory with a CMakeLists.txt pre-configured for MulleObjC development and a mulle-sde environment ready to manage dependencies.

Configuring an Existing Project

If you have an existing CMake project, ensure your CMakeLists.txt includes the mulle-sde integration lines. The tool looks for these markers to inject dependency configurations automatically when you add libraries.

Adding MulleObjC-startup to Your Dependencies

The core integration step uses the mulle-sde add command to fetch and register the startup library.

Execute the following from your project root:

mulle-sde add github:mulle-objc/MulleObjC-startup

This single command performs three critical operations:

  1. Clones the repository into your project's stash directory (.mulle/var/${MULLE_HOST}/stash), fetching the source code including src/MulleObjC-startup.m.
  2. Registers the dependency graph, parsing the library's requirements and automatically pulling in mulle-atinit, mulle-atexit, and the core MulleObjC runtime.
  3. Updates CMakeLists.txt, injecting the necessary target_link_libraries entries to link the static MulleObjC-startup library and its transitive dependencies.

The src/MulleObjC-startup.m file contains the implementation of __register_mulle_objc_universe, the entry point that initializes the Objective-C universe before your main function executes.

Including Headers and Writing Startup Code

Once the dependency is added, you can reference the startup header in your source files to ensure proper initialization sequencing.

Add the import statement to your main source file:

#import <MulleObjC-startup/MulleObjC-startup.h>

This header exposes the __register_mulle_objc_universe declaration and any auxiliary macros required for runtime initialization. You typically do not need to call this function manually—the startup library uses constructor attributes (via mulle-atinit) to execute it automatically before main.

Complete Example

Here is a minimal executable that uses the startup library to initialize the MulleObjC runtime:

/* main.m – minimal executable using MulleObjC-startup */
#import <MulleObjC-startup/MulleObjC-startup.h>
#import <MulleObjC/MulleObjC.h>

int main(void)
{
    // The universe is already registered by the startup library.
    // You can now create and use Objective‑C objects.
    MulleObjCClass *cls = mulle_objc_class_lookup( "NSObject" );
    id obj = mulle_objc_object_new( cls );
    
    // Use your object...
    
    mulle_objc_object_release( obj );
    return 0;
}

Building and Running Your Application

With the dependency integrated and source files written, use mulle-sde to build and execute.

Run the build command from your project root:

mulle-sde run

This command invokes CMake, which links the static MulleObjC-startup library together with the MulleObjC runtime and the mulle-atinit/mulle-atexit helpers. The resulting binary automatically calls the startup routine defined in src/MulleObjC-startup.m before entering your main function, ensuring the Objective-C universe is fully initialized.

Summary

  • Use mulle-sde add github:mulle-objc/MulleObjC-startup to automatically fetch the library and resolve transitive dependencies like mulle-atinit and mulle-atexit.
  • The startup library provides __register_mulle_objc_universe in src/MulleObjC-startup.m, which initializes the Objective-C runtime before main executes.
  • Include <MulleObjC-startup/MulleObjC-startup.h> in your source files to ensure proper initialization sequencing.
  • Build with mulle-sde run to link the static library and execute your binary with the runtime fully configured.

Frequently Asked Questions

What does MulleObjC-startup actually do?

MulleObjC-startup provides the __register_mulle_objc_universe symbol that initializes the Objective-C runtime universe before your main function executes. According to the mulle-objc/mulleobjc-startup source code, the implementation in src/MulleObjC-startup.m uses constructor attributes via mulle-atinit to ensure automatic registration, eliminating the need for manual runtime setup in your application code.

Can I use MulleObjC-startup without mulle-sde?

While technically possible, manual integration is strongly discouraged because MulleObjC-startup depends on complex transitive dependencies including mulle-atinit, mulle-atexit, and the core MulleObjC runtime. The mulle-sde tool automatically resolves these dependencies, configures CMake with correct linking order, and manages the stash directory structure. Manual configuration would require replicating this dependency resolution and build system integration by hand.

Where is the startup routine defined in the source code?

The startup routine is defined in src/MulleObjC-startup.m within the mulle-objc/mulleobjc-startup repository. This file implements the __register_mulle_objc_universe function, which serves as the entry point for runtime initialization. The function is marked with constructor attributes that ensure execution during program startup, before control reaches the main function of your executable.

How do I verify that the universe registration succeeded?

You can verify successful registration by checking the return value of runtime functions in your main function after including <MulleObjC-startup/MulleObjC-startup.h>. If the universe failed to register, calls like mulle_objc_class_lookup would return NULL or cause runtime errors. Successful execution of mulle-sde run without linker errors regarding missing __register_mulle_objc_universe symbols also confirms correct integration, as the build system would fail to link if the startup library were missing.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →