# Common Pitfalls When Using MulleObjC-startup: Essential Guide for Developers

> Avoid missing universe registration crashes with MulleObjC-startup. Discover common pitfalls and essential linking steps for developers using this MulleObjC runtime bootstrap library.

- Repository: [mulle-objc/mulleobjc-startup](https://github.com/mulle-objc/mulleobjc-startup)
- Tags: best-practices
- Published: 2026-03-07

---

**MulleObjC-startup is a mandatory static library that provides the `__register_mulle_objc_universe` symbol required to bootstrap the MulleObjC runtime, and forgetting to link it or include its header is the most common cause of "universe registration missing" crashes.**

MulleObjC-startup serves as the bridge between your executable and the MulleObjC runtime. According to the mulle-objc/mulleobjc-startup repository, this lightweight library handles critical initialization through `mulle-atinit` and `mulle-atexit` dependencies. Understanding the common integration mistakes will save hours of debugging linker errors and runtime crashes.

## 1. Linking and Dependency Failures

### Forgetting to Link the Static Library

The most frequent pitfall occurs when developers add the package dependency but fail to link the actual library. The executable must contain the `__register_mulle_objc_universe` symbol defined in `src/MulleObjC-startup.m`. Without it, the MulleObjC runtime aborts during initialization.

Always explicitly link the target in your [`CMakeLists.txt`](https://github.com/mulle-objc/mulleobjc-startup/blob/main/CMakeLists.txt):

```cmake
target_link_libraries(${PROJECT_NAME} PUBLIC MulleObjC-startup)

```

For manual command-line builds, add the library to your linker flags:

```bash
clang main.o -lMulleObjC-startup -lMulleObjC -o myapp

```

### Missing Transitive Dependencies

MulleObjC-startup depends on **mulle-atinit** and **mulle-atexit** for proper constructor and destructor ordering. The library's [`CMakeLists.txt`](https://github.com/mulle-objc/mulleobjc-startup/blob/main/CMakeLists.txt) declares these as public dependencies, but overriding the linkage type to `PRIVATE` or manually excluding them causes crashes during static initialization or exit.

Verify your configuration retains public linkage so these helpers propagate automatically to your executable.

## 2. Header and Include Path Errors

### Omitting the Startup Header

Every source file that uses MulleObjC symbols must include the startup header first. Without `#import <MulleObjC-startup/MulleObjC-startup.h>`, the compiler may not establish the necessary runtime registration hooks, leading to silent failures or duplicate universe errors.

Place the import at the top of your main implementation file:

```objc
#import <MulleObjC-startup/MulleObjC-startup.h>  // Must precede other MulleObjC imports
#import <MulleObjC/MulleObjC.h>

```

### Incorrect Include Directory Configuration

When installing via `clib` or manual source inclusion, the headers reside outside standard system paths. Failing to add the correct `-I` or `-isystem` path results in "file not found" compilation errors.

If using CMake with `clib` sources, expose the directory explicitly:

```cmake
include_directories(BEFORE SYSTEM src/mulle-objc)

```

## 3. Build System Configuration Mistakes

### Skipping Mandatory Vibecoding Setup

The `mulle-sde` build system requires **vibecoding** to be active for automatic CMake generation and dependency resolution. As documented in [`AGENTS.md`](https://github.com/mulle-objc/mulleobjc-startup/blob/main/AGENTS.md), this is the mandatory first step for any project using MulleObjC-startup.

Execute the activation command once per session before adding dependencies:

```bash
mulle-sde vibecoding on

```

Neglecting this step causes stale build configurations and missing dependency trees.

### Wrong Project Dialect Settings

The repository expects a specific C dialect defined by the `PROJECT_DIALECT` environment variable. Compiling with incompatible flags generates ABI mismatches or subtle runtime errors.

Query the required dialect before building:

```bash
value="$(mulle-sde env get PROJECT_DIALECT)"
mulle-sde howto show --keyword styleguide --keyword "${value:-$(mulle-sde env get PROJECT_LANGUAGE)}"

```

## 4. Compatibility and Version Conflicts

### Mixing with Foundation-startup or Other Runtimes

Both **MulleObjC-startup** and **Foundation-startup** provide a `__register_mulle_objc_universe` symbol. Linking both libraries creates linker conflicts or causes the wrong universe configuration to initialize.

Link only one startup library. If your project requires Apple Foundation compatibility, use `Foundation-startup` exclusively and omit MulleObjC-startup.

### Version Mismatches and Stale Dependencies

The library defines `MULLE_OBJC__STARTUP_VERSION` (currently tracked in `src/MulleObjC-startup.m`). Using an outdated static library against a newer MulleObjC runtime causes binary incompatibility.

Regularly update the dependency using:

```bash
mulle-sde dependency update

```

Additionally, if you rename or move `src/MulleObjC-startup.m`, update the `VERSIONFILE` variable in [`.mulle/etc/project/version-info.sh`](https://github.com/mulle-objc/mulleobjc-startup/blob/main/.mulle/etc/project/version-info.sh) to prevent version detection failures.

## Practical Integration Examples

### Minimal Main File

```objc
/* main.m */
#import <MulleObjC-startup/MulleObjC-startup.h>
#import <MulleObjC/MulleObjC.h>

int main(int argc, const char * argv[])
{
    // Universe automatically registered by startup library
    NSLog(@"MulleObjC runtime active");
    return 0;
}

```

### Complete CMake Configuration

```cmake
cmake_minimum_required(VERSION 3.15)
project(MyApp LANGUAGES C)

# Add dependencies

find_package(MulleObjC-startup REQUIRED)
find_package(MulleObjC REQUIRED)

add_executable(${PROJECT_NAME} main.m)

# Critical: PUBLIC linkage ensures atinit/atexit propagate

target_link_libraries(${PROJECT_NAME}
    PUBLIC MulleObjC-startup
    PUBLIC MulleObjC
)

```

## Summary

- **Always link** `MulleObjC-startup` as a public dependency to ensure `mulle-atinit` and `mulle-atexit` propagate correctly.
- **Include the header** `<MulleObjC-startup/MulleObjC-startup.h>` in every file using MulleObjC symbols.
- **Enable vibecoding** via `mulle-sde vibecoding on` before running any build commands.
- **Avoid mixing** startup libraries; choose either MulleObjC-startup or Foundation-startup, never both.
- **Match versions** between the startup library and MulleObjC runtime to prevent ABI mismatches.
- **Set the correct include paths** when using `clib` or manual source inclusion to prevent header resolution failures.

## Frequently Asked Questions

### What happens if I forget to link MulleObjC-startup?

Your application will compile successfully but crash at runtime with a "universe registration missing" error. The MulleObjC runtime requires the `__register_mulle_objc_universe` symbol defined in `src/MulleObjC-startup.m` to initialize the object universe. Without this registration hook, the runtime cannot allocate classes or objects.

### Can I use MulleObjC-startup alongside Apple Foundation?

No. MulleObjC-startup conflicts with Foundation-startup because both define the same `__register_mulle_objc_universe` symbol. If you need Foundation compatibility, link only `Foundation-startup`, which provides its own universe registration compatible with the Apple runtime.

### Why does mulle-sde require "vibecoding" for this library?

Vibecoding activates the meta-build system that generates correct CMake files and resolves the transitive dependencies (`mulle-atinit`, `mulle-atexit`) automatically. Without it, `mulle-sde` cannot generate the proper `MulleObjC-startup-config.cmake` files needed for discovery, causing link errors even when the library is present in the file system.

### How do I verify the startup library version matches my runtime?

Check the `MULLE_OBJC__STARTUP_VERSION` definition in `src/MulleObjC-startup.m` and ensure it aligns with your MulleObjC runtime version. Run `mulle-sde dependency update` regularly to synchronize versions, and inspect [`.mulle/etc/project/version-info.sh`](https://github.com/mulle-objc/mulleobjc-startup/blob/main/.mulle/etc/project/version-info.sh) if you have modified the source tree structure.