Edit me

Modern Workflow

The modern workflow is static library based, which gives the following advantages over shared libraries:

  • static linking works on platforms that do not support dynamic libraries
  • static linking can be optimized to remove unused classes and categories
  • static linking produces executables that are easier to install and deploy

In contrast, the legacy workflow is shared library based.

The advantages of that approach are:

  • does not require mulle-sde for generating the link order
  • does not require cmake
  • fewer libraries to link

Technically you can also do legacy workflow with static libraries. But it can be a pain in the ass to link the multitude of static libraries in the correct order, with the correct linker flags in a cross-platform manner.

Legacy workflow

The legacy workflow installs the mulle-objc Foundation as a shared library. You use the custom compiler mulle-clang to compile Objective-C files. These are then liked with the Foundation shared library and some startup libraries.

You can use make or most IDEs with this setup.

Install a shared MulleFoundation library

Use mulle-sde to download all required components of the Foundation library and to build them. There will be an error, because it can not find an optional component MulleObjCDecimalFoundation. This is harmless.

You can change the install location with the --prefix option. Otherwise the usr directory of your home directory, will be the install destination.

mulle-sde install --standalone --prefix "${HOME}/usr" "https://github.com/MulleFoundation/Foundation/archive/latest.zip"

A shared (dynamic) libFoundation library and some other static libraries should be present in your ~/usr/lib folder now.

If you have the repositories already checked out, you can prefix the command with a search path, to avoid downloads e.g.

SRCROOT="/Volumes/Source/srcO" ; \
MULLE_FETCH_SEARCH_PATH="${SRCROOT}/MulleFoundation:\
${SRCROOT}/MulleWeb:\
${SRCROOT}/mulle-objc:\
${SRCROOT}/mulle-core:\
${SRCROOT}/mulle-concurrent:\
${SRCROOT}/mulle-c" mulle-sde install ...

Build and install Foundation-startup

The Foundation-startup must be built and installed separately.

mulle-sde install --only-project --prefix "${HOME}/usr" "https://github.com/MulleFoundation/Foundation-startup/archive/latest.zip"

This duplicates much of the work already done by the previous Foundation built, but this can not be avoided easily.

Usage

Write Hello World

Lets create the canonical hello world program:

cat <<EOF > hello-world.m
#import <Foundation/Foundation.h>

int   main( int argc, char *argv[])
{
   NSLog( @"Hello World");
   return( 0);
}
EOF

Build Hello World

Building is now platform specific (unless you use cmake). You must use mulle-clang to compile the source:

Linux:

mulle-clang hello-world.m \
            -o hello-world \
            -isystem "${HOME}/usr/include" \
            -L"${HOME}/usr/lib" \
            -Wl,-rpath -Wl,"${HOME}/usr/lib" \
            -lFoundation \
            -Wl,--whole-archive \
            -lFoundation-startup \
            -lmulle-atinit \
            -lmulle-atexit \
            -Wl,--no-whole-archive \
            -lpthread \
            -ldl \
            -lm

macOS:

On macOS we need to use Xcode platform headers and therefore need the SDK path, which can vary for each host. It is assumed you used the brew install method, otherwise you need to correct the -isystem, -L, -rpath values in the following commands:

XCODE_SDK_DIR="`xcrun --show-sdk-path`"
mulle-clang  hello-world.m \
            -o hello-world \\
            -isystem "/usr/local/include" \
            -isystem "${XCODE_SDK_DIR}/include" \
            -L"/usr/local/lib" \
            -Wl,-rpath -Wl,"/usr/local/lib" \
            -lFoundation \
            -Wl,-all_load \
            -lFoundation-startup \
            -lmulle_atinit \
            -lmulle_atexit
            -Wl,-noall_load

Run Hello World

And run your first mulle-objc executable.

./hello-world

Next

That is about the extent the legacy workflow is covered in this guide. You likely might want to read porting Xcode projects next.