Bundling OSX app without GLUT and without Fmodex [nasty!]

Ok, this is really really horrible, but it’ll make your app a lot lighter.
Tested in OF0.9.3

These instructions come in two parts, you must modify your OF install, and every project. If you forget to tweak a project both libs will be included, but not linked (you can delete them from the app bundle manually).

The weak is done in a way so that your xcode files will still work on an unmodified OF install.

So, here it goes:

Remove the setting FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../libs/glut/lib/osx\"" (you can find it through xcode cmd+shift+f search)

Then, in CoreOF.xcconfig, redefine LIB_FMODEX and remove glut from OF_CORE_FRAMEWORKS:

// disable fmodex!
LIB_FMODEX = -Wl,-U,_FMOD_System_Close
REMOVED_DEPS = yes

OF_CORE_FRAMEWORKS = -framework Accelerate -framework AGL -framework AppKit -framework ApplicationServices -framework AudioToolbox -framework AVFoundation -framework Cocoa -framework CoreAudio -framework CoreFoundation -framework CoreMedia -framework CoreServices -framework CoreVideo -framework IOKit -framework OpenGL -framework QuartzCore -framework QuickTime -framework QTKit //-framework GLUT

Now go into the project config, build phases, run scripts, and wrap the glut and fmodex entries in an if:

if [ REMOVED_DEPS -ne "yes"]
then
    # Copy libfmod and change install directory for fmod to run
    rsync -aved ../../../libs/fmodex/lib/osx/libfmodex.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/";
    install_name_tool -change @executable_path/libfmodex.dylib @executable_path/../Frameworks/libfmodex.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME";
    # Copy GLUT framework (must remove for AppStore submissions)
    rsync -aved ../../../libs/glut/lib/osx/GLUT.framework "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/"
fi
3 Likes

Why does glut need to be removed for appstore submissions? I was relying on it due to a bug in glfw.

google is your friend :slight_smile:

“The application bundle may not contain tools or frameworks provided by Apple, or using bundle identifiers in the ‘com.apple’ namespace. Invalid bundle: [AppName.app/Content/Frameworks/GLUT.framework], with bundle identifier ‘com.apple.glut’.”

p.s. i myself am not submitting to the appstore. i just want the binaries to be as light as possible.

revisiting this a few years later i realize no modification to OFCore is needed, it can all be done in the project config.

so, new instructions:

  1. grab OF_CORE_LIBS from CoreOf.xcconfig, paste it into Project.xcconfig and get rid of everything you don’t like. You can even add “-Wl,-s” to the end of OF_CORE_LIBS to strip unused symbols (be careful, this also strips debug symbols!)
REMOVED_DEPS = yes
LIB_FMODEX = -Wl,-U,_FMOD_System_Close
LIB_CAIRO1 = ""
LIB_CAIRO2 = ""
LIB_CAIRO3 = ""

OF_CORE_LIBS = $(LIB_TESS) $(LIB_GLEW) $(LIB_CAIRO1) $(LIB_CAIRO2) $(LIB_CAIRO3) $(LIB_FMODEX) $(LIB_RTAUDIO) $(LIB_GLFW) $(LIB_FREEIMAGE) $(LIB_FREETYPE) $(LIB_BOOST_FS) $(LIB_BOOST_SYSTEM) $(LIB_CURL) $(LIB_URIPARSER) $(LIB_PUGIXML)
  1. Modify the “run script task” to get rid of dependencies (ie don’t copy fmod)

if [ REMOVED_DEPS -ne “yes”]
then
rsync -aved “$OF_PATH/libs/fmodex/lib/osx/libfmodex.dylib” “$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/”;
install_name_tool -change @executable_path/libfmodex.dylib @executable_path/…/Frameworks/libfmodex.dylib “$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME”;
fi

for me this changes the binary size by around 25%.

before: 13.8mb (4.8mb compressed)
after: 9.1mb (3.2mb compressed)

1 Like

Beautiful thanks for sharing. I myself was experiment with similar ideas.
Nice idea of overwriting things per project in Project.xcconfig
one suggestion is do that as a include, like app.xcconfig, so your changes will survive projectGenerator changes.

One idea for XCode project settings:
if we use a variable in Project.xcconfig, lets say

OF_USE_LIB_FMOD = YES

and inside .sh

if [ "$OF_USE_LIB_FMOD" == "YES" ] ; then
echo "\033[32;1;4mUsing libfmod\033[0m"
rsync -aved "$OF_PATH/libs/fmod/lib/osx/libfmod.dylib" "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/";
else
echo "\033[31;1;4mNot using libfmod\033[0m"
fi

this way we could remove per project only editing Project.xcconfig.

1 Like

i think something along the lines of disabling certain large parts would be neat (e.g i often don’t use freetype, and sometimes not even freeimage) but… i think most people don’t care about a few megabytes plus/minus. also i realized suggesting “-Wl,-s” is a bad idea as general setting, because it strips debug symbols making debugging impossible.

Yes, I think the same.
In a fork I use to test some different stuff I even separated everything in different xcconfig files to be included (or not) separately

1 Like