====== building OSX applications ====== Some handy commandlines for building and deploying applications and libraries on Mac/OSX Multiple architecture build flags for autoconf projects on OSX: PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH \ CFLAGS="-arch i386 -arch ppc -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" \ CXXFLAGS="-arch i386 -arch ppc -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" \ LDFLAGS="$CFLAGS" \ ./configure --disable-dependency-tracking //workaround// for some buggy configure/libtool scripts: PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH \ CFLAGS="-I/usr/local/include" CXXFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" \ CC="gcc -arch i386 -arch ppc -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" \ CXX="gcc -arch i386 -arch ppc -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" \ CPP='cpp' CXXCPP='cpp' LDFLAGS="$CFLAGS" \ ./configure --disable-dependency-tracking --enable-shared \\ for gtk+: set ''PKG_CONFIG_PATH'' ./configure --prefix /Users/rgareus/gtk/inst --libdir /Users/rgareus/gtk/inst/lib --disable-static --disable-dependency-tracking CFLAGS="-arch i386 -arch ppc -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 -I/Users/rgareus/gtk/inst/include/" CXXFLAGS="-arch i386 -arch ppc -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" LDFLAGS="-arch i386 -arch ppc -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 -L/Users/rgareus/gtk/inst/lib/" \\ find out compiler defines: eg ''%%__ppc%%'', ''%%__i386%%'', or ''%%__x86_64%%'': gcc -dM -E - < /dev/null \\ \\ ''strace'' on Mac is called ''dtruss'' :) \\ \\ update library paths: see also: http://doc.trolltech.com/qq/qq09-mac-deployment.html for file in $(ls *); do \ echo "$file --"; \ for dest in $(otool -L $file | grep local/| cut -f 1 -d ' '); do\ new=$(basename $dest); \ test "$file" = "$new" || echo "install_name_tool -change $dest $new $file";\ done ;\ done \\ Debugging/leak detection: * http://developer.apple.com/Mac/library/documentation/Performance/Conceptual/ManagingMemory/Articles/FindingLeaks.html * http://developer.apple.com/Mac/library/documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html#//apple_ref/doc/uid/20001884-CJBJFIDD export MallocStackLogging=1 export MallocCheckHeapStart=1000 export MallocCheckHeapEach=100 ./myapp leaks -nocontext `ps x | grep myapp | grep -v grep | awk '{print $1;}'` | less \\ auto-update lib-paths aka post-install script: export INSTALLED="" export LIBS_PATH="$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks" mkdir -p $LIBS_PATH export TARGET="$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME" follow_dependencies () { libname=$1 cd "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks" dependencies=`otool -arch all -L "$libname" | egrep '\/(opt|usr)\/local\/lib' | awk '{print $1}'` for l in $dependencies; do depname=`basename $l` deppath=`dirname $l` if [ ! -f "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/$depname" ]; then deploy_lib $depname "$deppath" fi done } update_links () { libname=$1 libpath=$2 for n in `ls $LIBS_PATH/*`; do install_name_tool \ -change "$libpath/$libname" \ @executable_path/../Frameworks/$libname \ "$n" done } deploy_lib () { libname=$1 libpath=$2 check=`echo $INSTALLED | grep $libname` if [ "X$check" = "X" ]; then if [ ! -f "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/$libname" ]; then cp -f "$libpath/$libname" "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/$libname" install_name_tool \ -id @executable_path/../Frameworks/$libname \ "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/$libname" follow_dependencies $libname fi export INSTALLED="$INSTALLED $libname" fi update_links $libname $libpath } update_executable() { LIBS=`otool -arch all -L "$TARGET" | egrep '\/(opt|usr)\/local\/lib' | awk '{print $1}'` for l in $LIBS; do libname=`basename $l` libpath=`dirname $l` deploy_lib $libname $libpath echo "install_name_tool -change $libpath/$libname @executable_path/../Frameworks/$libname \"$TARGET\"" install_name_tool \ -change $libpath/$libname \ @executable_path/../Frameworks/$libname \ "$TARGET" done } update_executable cd $LIBS_PATH && MORELIBS=`otool -arch all -L * | egrep '\/(opt|usr)\/local\/lib' | awk '{print $1}'` && cd - while [ "X$MORELIBS" != "X" ]; do for l in $MORELIBS; do libname=`basename $l` libpath=`dirname $l` deploy_lib "$libname" "$libpath" done cd $LIBS_PATH && MORELIBS=`otool -arch all -L * | egrep '\/(opt|usr)\/local\/lib' | awk '{print $1}'` && cd - done update_executable Roll a DMG: http://stackoverflow.com/questions/96882/how-do-i-create-a-nice-looking-dmg-for-mac-os-x-using-command-line-tools #!/bin/sh VERSION=2.0 DMGFILE=/tmp/oggzcap-$VERSION.dmg echo $DMGFILE BUILD=build/Release/OggZCap.app xcodebuild clean \ && xcodebuild \ ||exit #roll a DMG TMPFILE=/tmp/ogztmp.dmg MNTPATH=/tmp/mnt/ VOLNAME=OggZCap mkdir -p $MNTPATH if [ -e $TMPFILE -o -e $DMGFILE -o ! -d $MNTPATH ]; then echo "could not make DMG.." exit; fi hdiutil create -megabytes 100 $TMPFILE DiskDevice=$(hdid -nomount "${TMPFILE}" | grep Apple_HFS | cut -f 1 -d ' ') newfs_hfs -v "${VOLNAME}" "${DiskDevice}" mount -t hfs "${DiskDevice}" "${MNTPATH}" cp -r ${BUILD} ${MNTPATH}/ ln -s /Applications ${MNTPATH}/Applications # Umount the image umount "${DiskDevice}" hdiutil eject "${DiskDevice}" # Create a read-only version, use zlib compression hdiutil convert -format UDZO "${TMPFILE}" -o "${DMGFILE}" # Delete the temporary files rm $TMPFILE rmdir $MNTPATH {{tag>development}}