====== 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}}