Size: 21732
Comment:
|
Size: 24789
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 7: | Line 7: |
Dependencies (version I have used successfully in parens): | = DEPENDENCIES |
Line 22: | Line 22: |
(verisons I have used in my own builds.) |
|
Line 24: | Line 26: |
= PREFACE |
|
Line 26: | Line 30: |
Line 31: | Line 34: |
Preparing to compile: I opted to place my build environment in a disk image to make it easier to move it from machine to machine. Use Disk Utility to create a sparse disk image with a max size of 50gb (it will shrink to the total size of the files contained.) |
= PREPARING BUILD ENVIRONMENT I opted to place my build environment in a disk image to make it easier to move it from machine to machine. I used Disk Utility to create a sparse disk image with a max size of 40gb (it will shrink to the total size of the files contained.) |
Line 49: | Line 52: |
I use these two variables in most of the scripts I provide. Set BROOT to the root of the build environment; in my case it was the disk image I made. We'll only be covering 10.5 in these instructions, but set MACOSX_DEPLOYMENT_TARGET as well. {{{ export BROOT=/Volumes/EMAN/ export MACOSX_DEPLOYMENT_TARGET=10.5 }}} |
|
Line 53: | Line 63: |
export BROOT=/Volumes/EMAN/ export CPUCOUNT=8 export ARCH=i386 |
|
Line 58: | Line 65: |
export EXECPREFIX=$PREFIX/$ARCH | |
Line 66: | Line 72: |
If you want to install all the dependencies in /usr/local, set PREFIX to accordingly. I chose to keep everything on the disk image I made, separated by deployment target. ------- = PATCHES REQUIRED |
|
Line 81: | Line 93: |
CMAKE | = BUILDING DEPENDENCIES -------- == CMAKE |
Line 91: | Line 107: |
PNG | == PNG |
Line 99: | Line 115: |
SZIP | == SZIP |
Line 107: | Line 123: |
GSL | == GSL |
Line 115: | Line 131: |
BOOST Patch to add fat binary support |
== BOOST Patch to add fat binary support: |
Line 122: | Line 138: |
Build bjam | Build bjam: |
Line 133: | Line 149: |
feature arch : native ppc i386 fat : composite propagated ; flags darwin.compile OPTIONS <arch>fat : -arch i386 -arch ppc -arch x86_64 -arch ppc64 ; flags darwin.link OPTIONS <arch>fat : -arch i386 -arch ppc -arch x86_64 -arch ppc64 ; }}} |
feature arch : native ppc i386 fat : composite propagated ; flags darwin.compile OPTIONS <arch>fat : -arch i386 -arch ppc -arch x86_64 -arch ppc64 ; flags darwin.link OPTIONS <arch>fat : -arch i386 -arch ppc -arch x86_64 -arch ppc64 ; }}} Configure, compile.. |
Line 144: | Line 162: |
JPEG | == JPEG |
Line 174: | Line 192: |
TIFF | == TIFF |
Line 191: | Line 209: |
HDF5 | == HDF5 |
Line 204: | Line 222: |
FFTW2 | == FFTW2 |
Line 215: | Line 233: |
EMAN expects srfftw.h, sfftw.h. This version doesn't seem to make the symlinks correctly. Fix these after install {{{ cd $BROOT/dep/$MACOSX_DEPLOYMENT_TARGET/include/ |
EMAN expects srfftw.h, sfftw.h. After install, go to the include directory (in my case $BROOT/dep/$MACOSX_DEPLOYMENT_TARGET/include) and make these links: {{{ |
Line 225: | Line 242: |
Qt3-Mac | == Qt3-Mac |
Line 260: | Line 277: |
Prepare libraries: | = PREPARE LIBRARIES Make copies of the dylibs. e.g.: |
Line 267: | Line 286: |
cp libboost_python-1_34_1.dylib libfftw.dylib libfftw3f.dylib libgsl.dylib libgslcblas.dylib libhdf5.dylib libjpeg.dylib libpng.dylib libpng12.dylib librfftw.dylib libsz.dylib libtiff.dylib qt3/libqt.dylib $BROOT/extlib/$MACOSX_DEPLOYMENT_TARGET | cp libboost_python-1_34_1.dylib libfftw.dylib libgsl.dylib libgslcblas.dylib libhdf5.dylib libjpeg.dylib libpng.dylib libpng12.dylib librfftw.dylib libsz.dylib libtiff.dylib qt3/libqt.dylib $BROOT/extlib/$MACOSX_DEPLOYMENT_TARGET |
Line 281: | Line 300: |
EMAN Do NOT load vars script. |
= BUILD EMAN Do not load vars script. |
Line 289: | Line 308: |
10.5 32 bits. Default options except those below. Replace any /Volumes/EMAN.. paths with the correct path to your build/install environment. |
qmake will fail without this: {{{ export DYLD_LIBRARY_PATH=$BROOT/dep/10.5/src/qt-mac-free-3.3.8/lib/ }}} == 10.5 32 bits Default options except those below. Replace any /Volumes/EMAN.. paths with the correct path to your build/install environment. Link against the libraries you created with the modified install_names. |
Line 338: | Line 364: |
10.5, 64 bits. Same as 10.5/32, but with changes: | == 10.5, 64 bits Same as 10.5/32, but with changes: |
Line 346: | Line 374: |
qmake will fail without this: {{{ export DYLD_LIBRARY_PATH=$BROOT/dep/10.5/src/qt-mac-free-3.3.8/lib/ }}} ------- EMAN Post-install |
------- = EMAN Post-install |
Line 358: | Line 380: |
Set EMAN dir icon using Finder... copy applet.icns and paste into folder icon in 'get info' | Set EMAN dir icon using Finder... copy appropriate .icns file and paste into folder icon in 'get info' |
Line 366: | Line 388: |
You can get all the files I will use on the downloads page. == Python dylib links |
|
Line 370: | Line 395: |
cd /Volumes/EMAN/stage/$MACOSX_DEPLOYMENT_TARGET/EMAN/EMAN/lib/; \ | cd $BROOT/stage/$MACOSX_DEPLOYMENT_TARGET/EMAN/EMAN/lib/; \ |
Line 377: | Line 402: |
== Creating App Bundles | |
Line 379: | Line 405: |
This is the basic structure of an app bundle: {{{ boxer.app/ /Contents /Info.plist # xml package definition /PkgInfo # identifies as application, framework, etc. /MacOS # bin directory /boxer # main executable /Resources # application resources dir /boxer.icns # app icon /icon-box.icns # file type icon }}} Our actual bundles will be slightly more complex and contain a few symlinks and wrappers to save on disk space and effort. === Info.plist files |
|
Line 436: | Line 480: |
CFBundleName is the localized display name for the application. If this is not set, it will be the name of the executable. Since we're using wrappers, we'll set this. | CFBundleName is the localized display name for the application. If this is not set, it will be the name of the executable. Since we'll be using wrappers, we'll set this, otherwise the program will come up as "boxer.wrapper" or similar. |
Line 461: | Line 505: |
I have made Info.plist files for all the gui programs: boxer, checkslice, ctfit, eman, helixboxer, QHelp, qindex, qplot, qsegment, triplot, v2, and v4. You can grab them on the downloads page. I also made icons for the programs and file types that you can use. {{{ emandir=/Volumes/EMAN/stage/$MACOSX_DEPLOYMENT_TARGET/EMAN/EMAN; skeldir=/Volumes/EMAN/Resources |
I have made Info.plist files for all the gui programs: boxer, checkslice, ctfit, eman, helixboxer, QHelp, qindex, qplot, qsegment, triplot, v2, and v4. I also made icons for the programs and file types that you can use. === Command-line wrapper To launch the GUI programs properly from the command line, you can either make your $PATH very complex, or just use a simple wrapper script. You'll use this as 'applaunch.sh' in the next few steps. {{{ #!/bin/bash basename=`basename $0` $EMANDIR/apps/$basename.app/Contents/MacOS/$basename $@ }}} === Finder wrapper On Linux and Windows, launching a program from Explorer/Konqueror/etc typically just adds any files to be opened as command line args. On Mac OS X, however, it's instead passed as an Objective-C object to the application. You can patch your ported program to support this, or you can use a wrapper script that emulates argv support. I chose to use PythonObjC because it is installed by default on OS X. I modified a script provided by Apple to function as the wrapper. You can download it from the resources page and use it as 'argvemulator.py' in the following steps. === Creating bundle structure and copying files into it I use the following script to automate the packaging. Be mindful of paths if you are using it with a different build/install environment directory structure. {{{ emandir=$BROOT/stage/$MACOSX_DEPLOYMENT_TARGET/EMAN/EMAN; skeldir=$BROOT/Resources |
Line 468: | Line 529: |
rm -rf apps mkdir apps |
}}} Clean out any existing app directory, and create a list of all binaries that link against Qt/Mac. {{{ rm -rf $emandir/apps mkdir $emandir/apps |
Line 472: | Line 537: |
cd bin | cd $emandir/bin |
Line 474: | Line 539: |
cd .. |
cd $emandir }}} Create the directory structure for the app bundle. Copy the PkgInfo file (they all use the same one.) Copy the icon file. Copy the correct plist file. Copy the argvemulator as a wrapper so it operates properly when launched from the Finder. Move the binary from the EMAN dir to a directory in the bundle. Link to another wrapper to make it launch properly (e.g. 'boxer') from the command line. Create symlinks 'lib' and 'extlib' so the dylibs can be found. {{{ |
Line 492: | Line 559: |
cd bin; \ | cd $emandir/bin; \ |
Line 502: | Line 569: |
Compiling for Mac OS X is generally the same as other platforms.
** NOTE ** ** I AM STILL WORKING ON THESE INSTRUCTIONS. **
= DEPENDENCIES
- boost (1_34_1)
- cmake (2.4.8)
- fftw (2.1.5)
- gsl (1.8)
- hdf5 (1.6.6)
- jpeg (v6b)
- png (1.2.23)
- numpy (1.0.4)
- Qt/Mac (3.3.8)
- szip (2.1)
- tiff (3.8.2)
- zlib (1.2.1)
(verisons I have used in my own builds.)
= PREFACE
You have two routes available. You can install the above dependencies using a package manager such as fink or macports. This is the easier and faster option, but has the downside of making it more difficult to distribute your built package or moving it to a different machine. If you choose this option, please skip to the end.
The other option is to build all dependencies manually from source. This is the method I chose for the self-contained EMAN package. However, some of the packages required either patches or some careful massaging to compile properly. It will require a bit more effort than using the package manager.
= PREPARING BUILD ENVIRONMENT
I opted to place my build environment in a disk image to make it easier to move it from machine to machine. I used Disk Utility to create a sparse disk image with a max size of 40gb (it will shrink to the total size of the files contained.)
I called the disk image "EMAN" and used the following directory structure for organization.
attachment:dirstructure.jpg
"build" is for EMAN build files. "dep" is the dependency tree root. "extlib" is for modified dependency libraries. "EMAN" is for the EMAN source itself. "Resources" are support files to be used in the creation of Mac OS X app bundles. "src" is for downloaded source tarballs and patches. "stage" is where the EMAN package will be prepared for distribution. "vars10.x.sh" is for environment variables specific to building for each Mac OS X version.
Because 10.4 and 10.5 use different versions of Python, I decided to build EMAN and dep libraries separately for each deployment target.
My build environment was 10.5 Leopard on Intel host using Xcode 3.0 for the 10.5 build. I have not personally built for 10.4 on a 10.4 host, but the instructions for 10.5 will probably work. Building for 10.4 target on a 10.5 host is possible and requires Xcode 2.5 to be installed in parallel to Xcode 3.0.
For simplicity's sake, I will only discuss building for 10.5 target on a 10.5 host in these instructions.
Mac OS X supports multiple architectures in a single "universal" or "fat" binary/library. This is achieved by passing -arch flags to gcc (this is a special Apple-gcc flag) which will take care of all the details. Alternatively you can compile for different architectures separately and merge them together afterwards. For 10.5 I built both 32 and 64 bit versions for both Intel and PowerPC (i386, x86_64, ppc, ppc64.) On 10.4 I built only 32 bit versions for Intel and PowerPC.
I use these two variables in most of the scripts I provide. Set BROOT to the root of the build environment; in my case it was the disk image I made. We'll only be covering 10.5 in these instructions, but set MACOSX_DEPLOYMENT_TARGET as well.
export BROOT=/Volumes/EMAN/ export MACOSX_DEPLOYMENT_TARGET=10.5
The following environment variables were sufficient to get clean universal builds of dependencies in most cases. I put these in vars10.5.sh for quick access:
#10.5 export MACOSX_DEPLOYMENT_TARGET=10.5 export PREFIX=$BROOT/dep/$MACOSX_DEPLOYMENT_TARGET export UARCH="-arch i386 -arch ppc -arch x86_64 -arch ppc64" export SROOT="-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" export LDF="-Wl,-headerpad_max_install_names" export CFLAGS="$SROOT $UARCH -O2 -g" export LDFLAGS="$UARCH $LDF" export PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin
If you want to install all the dependencies in /usr/local, set PREFIX to accordingly. I chose to keep everything on the disk image I made, separated by deployment target.
= PATCHES REQUIRED
Several dependencies required patches to compile properly. Most of them are taken from Fink/MacPorts, or other internet sources. I have them available for download (download page):
- boost.patch
- darwin.jam
- jpegpatch.zip
- libtool135update.zip
- qt3mac.patch.txt
- qt3mac.patch1.txt
- qt3mac.patch2.txt
I placed the patches in $BROOT/src/patches.
= BUILDING DEPENDENCIES
== CMAKE
./configure --prefix=$PREFIX --exec-prefix=$PREFIX/fat --disable-dependency-tracking --disable-static --enable-shared LDFLAGS="$LDFLAGS" CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" make make install
== PNG
./configure --prefix=$PREFIX --exec-prefix=$PREFIX/fat --disable-dependency-tracking --disable-static --enable-shared CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
== SZIP
./configure --prefix=$PREFIX --exec-prefix=$PREFIX/fat --disable-dependency-tracking --disable-static --enable-shared CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
== GSL
./configure --prefix=$PREFIX --exec-prefix=$PREFIX/fat --disable-dependency-tracking --disable-static --enable-shared CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
== BOOST
Patch to add fat binary support:
patch -p1 < $BROOT/src/patches/boost.patch
Build bjam:
./configure --with-toolset=darwin --with-libraries=python --prefix=$PREFIX --exec-prefix=$PREFIX/fat
In tools/build/v2/tools/darwin.jam:
- change sdkroot to use /Developer/SDKs/MacOSX10.5.sdk
- Add 64 bit (ppc64, x86_64) to fat arch
feature arch : native ppc i386 fat : composite propagated ; flags darwin.compile OPTIONS <arch>fat : -arch i386 -arch ppc -arch x86_64 -arch ppc64 ; flags darwin.link OPTIONS <arch>fat : -arch i386 -arch ppc -arch x86_64 -arch ppc64 ;
Configure, compile..
./tools/jam/src/bin.macosxx86/bjam -d+2 --user-config=user-config.jam --prefix=$PREFIX --libdir=$PREFIX/fat/lib/ --exec-prefix=$PREFIX/fat/bin/ --with-python sdkroot=$MACOSX_DEPLOYMENT_TARGET arch=fat install
== JPEG
Patches from http://www.kyngchaos.com/macosx/install/libjpeg or download page.
unzip $BROOT/src/patches/libtool135update.zip unzip $BROOT/src/patches/jpegpatch.zip cp /usr/share/libtool/config.* ./ patch makefile.cfg makefile.cfg.patch
./configure --prefix=$PREFIX --exec-prefix=$PREFIX/fat --disable-dependency-tracking --disable-static --enable-shared CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
In Makefile, change CC and move it below CFLAGS...
CC=gcc $(CFLAGS)
Patch archive_cmds in libtool: needs $CFLAGS
archive_cmds="\$nonopt \$(test .\$module = .yes && echo -bundle || echo -dynamiclib) $CFLAGS \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$linkopts -install_name \$rpath/\$soname \$verstring"
== TIFF
version-number needs to be changed to current_version in libtool
sed s/"version-number"/"current_version"/ Makefile.in > Makefile2.in sed s/"version-number"/"current_version"/ Makefile.am > Makefile2.am mv Makefile2.in Makefile.in mv Makefile2.am Makefile.am
./configure --prefix=$PREFIX --exec-prefix=$PREFIX/fat --disable-dependency-tracking --disable-static --enable-shared CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
== HDF5
./configure --prefix=$PREFIX --exec-prefix=$PREFIX/fat --disable-dependency-tracking --disable-static --enable-shared CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
Patch archive_cmds in libtool, needs $CFLAGS
archive_cmds="\$nonopt \$(test \\\"x\$module\\\" = xyes && echo -bundle || echo -dynamiclib) $CFLAGS \$allow_undefined_flag
== FFTW2
./configure --prefix=$PREFIX --exec-prefix=$PREFIX/fat --enable-float --disable-fortran --disable-dependency-tracking --disable-static --enable-shared CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
Patch archive_cmds to include $CFLAGS in libtool.. this one needs it twice.
archive_cmds="\$CC $CFLAGS -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs && \$CC \$(test .\$module = .yes && echo -bundle || echo -dynamiclib) $CFLAGS \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs\$linker_flags \$(test .\$module != .yes && echo -install_name \$rpath/\$soname \$verstring)"
EMAN expects srfftw.h, sfftw.h. After install, go to the include directory (in my case $BROOT/dep/$MACOSX_DEPLOYMENT_TARGET/include) and make these links:
ln -s fftw.h sfftw.h ln -s rfftw.h srfftw.h
== Qt3-Mac
Use patches from Fink, or download them from downloads page.
Carbon dependency makes it 32 bit only.
Apply patches
sed s/free-3.3.5/free-3.3.8/g $BROOT/src/patches/qt3mac.patch.txt > ./qt3mac.patch1.txt cmd="s|@PREFIX@|`pwd`|g" sed -e $cmd < ./qt3mac.patch1.txt | patch -p1 patch -p1 < $BROOT/src/patches/qt3mac.patch2.txt perl -pi.bak -e 's|cp \-P|cp \-Rp|' qmake/Makefile.unix
These must be in path for qmake to work correctly.
export DYLD_LIBRARY_PATH=`pwd`/lib export PATH=$PATH:`pwd`/bin
./configure -prefix $PREFIX/qt3 -bindir $PREFIX/fat/bin/qt3 -libdir $PREFIX/fat/lib/qt3 -plugindir $PREFIX/fat/plugins/qt3 -release -shared -qt-gif -system-zlib -qt-libjpeg -qt-libmng
In mkspecs/macx-g++/qmake.conf:
QMAKE_CFLAGS = -pipe -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk QMAKE_LFLAGS = -headerpad_max_install_names -arch ppc -arch i386 -Wl,-syslibroot,/Developer/SDKs/MacOSX10.5.sdk
= PREPARE LIBRARIES
Make copies of the dylibs. e.g.:
mkdir $BROOT/extlib/$MACOSX_DEPLOYMENT_TARGET cd $BROOT/dep/$MACOSX_DEPLOYMENT_TARGET/fat/lib cp libboost_python-1_34_1.dylib libfftw.dylib libgsl.dylib libgslcblas.dylib libhdf5.dylib libjpeg.dylib libpng.dylib libpng12.dylib librfftw.dylib libsz.dylib libtiff.dylib qt3/libqt.dylib $BROOT/extlib/$MACOSX_DEPLOYMENT_TARGET cd $BROOT/extlib/$MACOSX_DEPLOYMENT_TARGET mv libboost_python-1_34_1.dylib libboost_python.dylib
Set install_name. necessary for placing the app bundle wherever is convenient.
for i in *dylib;do install_name_tool -id @loader_path/../../extlib/$i $i;done
= BUILD EMAN
Do not load vars script.
$BROOT/dep/cmake/bin/ccmake -DCMAKE_INSTALL_NAME_DIR:STRING=@loader_path/../lib $BROOT/EMAN/
qmake will fail without this:
export DYLD_LIBRARY_PATH=$BROOT/dep/10.5/src/qt-mac-free-3.3.8/lib/
== 10.5 32 bits
Default options except those below. Replace any /Volumes/EMAN.. paths with the correct path to your build/install environment. Link against the libraries you created with the modified install_names.
BOOST_INCLUDE_PATH /Volumes/EMAN/dep/10.5/include/boost-1_34_1 BOOST_LIBRARY /Volumes/EMAN/extlib/10.5/libboost_python.dylib CMAKE_BACKWARDS_COMPATIBILITY 2.4 CMAKE_CXX_FLAGS -mmacosx-version-min=10.5 CMAKE_C_FLAGS -mmacosx-version-min=10.5 CMAKE_INSTALL_NAME_DIR @loader_path/../lib CMAKE_OSX_ARCHITECTURES i386;ppc CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk CMAKE_VERBOSE_MAKEFILE ON EMAN_INSTALL_PREFIX /Volumes/EMAN/stage/10.5/EMAN/EMAN EXECUTABLE_OUTPUT_PATH /Volumes/EMAN/build/10.5/32/EMAN/bin FFTW_INCLUDE_PATH /Volumes/EMAN/dep/10.5/include FFTW_LIBRARY /Volumes/EMAN/extlib/10.5/libfftw.dylib GSL_CBLAS_LIBRARY /Volumes/EMAN/extlib/10.5/libgslcblas.dylib GSL_INCLUDE_PATH /Volumes/EMAN/dep/10.5/include GSL_LIBRARY /Volumes/EMAN/extlib/10.5/libgsl.dylib HDF_INCLUDE_PATH /Volumes/EMAN/dep/10.5/include HDF_LIBRARY /Volumes/EMAN/extlib/10.5/libhdf5.dylib JPEG_LIBRARY /Volumes/EMAN/extlib/10.5/libjpeg.dylib LIBRARY_OUTPUT_PATH /Volumes/EMAN/build/10.5/32/EMAN/lib PNG_INCLUDE_PATH /Volumes/EMAN/dep/10.5/include PNG_LIBRARY /Volumes/EMAN/extlib/10.5/libpng.dylib PYTHON_INCLUDE_PATH /Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/Python.framework/Versions/2.5/Headers PYTHON_LIBRARY /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libpython.dylib QT_INCLUDE_DIR /Volumes/EMAN/dep/10.5/qt3/include QT_MOC_EXECUTABLE /Volumes/EMAN/dep/10.5/fat/bin/qt3/moc QT_QT_LIBRARY /Volumes/EMAN/extlib/10.5/libqt.dylib QT_UIC_EXECUTABLE /Volumes/EMAN/dep/10.5/fat/bin/qt3/uic RFFTW_LIBRARY /Volumes/EMAN/extlib/10.5/librfftw.dylib TIF_INCLUDE_PATH /Volumes/EMAN/dep/10.5/include TIF_LIBRARY /Volumes/EMAN/extlib/10.5/libtiff.dylib X11_X11_INCLUDE_PATH X11_X11_LIB X11_Xext_LIB X11_Xlib_INCLUDE_PATH X11_Xutil_INCLUDE_PATH Z_LIBRARY /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libz.dylib
== 10.5, 64 bits
Same as 10.5/32, but with changes:
EMAN_INSTALL_PREFIX /Volumes/EMAN/stage/10.5/EMAN/EMAN.64 CMAKE_OSX_ARCHITECTURES x86_64;ppc64 ENABLE_GUI OFF
= EMAN Post-install
Load environment vars to get $BROOT and $MACOSX_DEPLOYMENT_TARGET
Set EMAN dir icon using Finder... copy appropriate .icns file and paste into folder icon in 'get info'
This script does most of packaging work, but I'll step through it below.
$BROOT/Resources/scripts/makeapps.sh
You can get all the files I will use on the downloads page.
== Python dylib links
The python dylib loader seems to only look for .so files instead of .dylib files. This creates these links. If you built EMAN for 64 bits as well, repeat for that as well.
cd $BROOT/stage/$MACOSX_DEPLOYMENT_TARGET/EMAN/EMAN/lib/; \ for i in *.dylib; do \ test=`echo $i | sed s/dylib/so/`; \ ln -sv $i $test; \ done;
== Creating App Bundles
Qt/Mac GUI programs on Mac OS X will not connect properly to the window manager unless they have a .app bundle structure and correct Info.plist file. See the Apple Bundle documentation for more details.
This is the basic structure of an app bundle:
boxer.app/ /Contents /Info.plist # xml package definition /PkgInfo # identifies as application, framework, etc. /MacOS # bin directory /boxer # main executable /Resources # application resources dir /boxer.icns # app icon /icon-box.icns # file type icon
Our actual bundles will be slightly more complex and contain a few symlinks and wrappers to save on disk space and effort.
=== Info.plist files
First, we need to create Info.plist files for each EMAN GUI program. I'll use the boxer program as an example.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict>
This key tells the Finder which document types boxer can handle, as well as maps an icon to the file.
<key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeExtensions</key> <array> <string>box</string> </array> <key>CFBundleTypeIconFile</key> <string>icon-box.icns</string> <key>CFBundleTypeName</key> <string>Box database</string> <key>CFBundleTypeRole</key> <string>Editor</string> <key>LSIsAppleDefaultForType</key> <true/> </dict> <dict> <key>CFBundleTypeExtensions</key> <array> <string>mrc</string> </array> <key>CFBundleTypeRole</key> <string>Viewer</string> <key>LSIsAppleDefaultForType</key> <false/> </dict> <dict> <key>CFBundleTypeExtensions</key> <array> <string>dm3</string> </array> <key>CFBundleTypeRole</key> <string>Viewer</string> <key>LSIsAppleDefaultForType</key> <false/> </dict> </array>
CFBundleName is the localized display name for the application. If this is not set, it will be the name of the executable. Since we'll be using wrappers, we'll set this, otherwise the program will come up as "boxer.wrapper" or similar.
<key>CFBundleName</key> <string>Boxer</string>
The name of the executable that will run when opened via Finder
<key>CFBundleExecutable</key> <string>boxer.wrapper</string>
A few more keys that define the info string, the icon file to be used, etc.
<key>CFBundleGetInfoString</key> <string>EMAN</string> <key>CFBundleIconFile</key> <string>boxer</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleSignature</key> <string>????</string> </dict> </plist>
I have made Info.plist files for all the gui programs: boxer, checkslice, ctfit, eman, helixboxer, QHelp, qindex, qplot, qsegment, triplot, v2, and v4. I also made icons for the programs and file types that you can use.
=== Command-line wrapper
To launch the GUI programs properly from the command line, you can either make your $PATH very complex, or just use a simple wrapper script. You'll use this as 'applaunch.sh' in the next few steps.
basename=`basename $0` $EMANDIR/apps/$basename.app/Contents/MacOS/$basename $@
=== Finder wrapper
On Linux and Windows, launching a program from Explorer/Konqueror/etc typically just adds any files to be opened as command line args. On Mac OS X, however, it's instead passed as an Objective-C object to the application. You can patch your ported program to support this, or you can use a wrapper script that emulates argv support. I chose to use PythonObjC because it is installed by default on OS X. I modified a script provided by Apple to function as the wrapper. You can download it from the resources page and use it as 'argvemulator.py' in the following steps.
=== Creating bundle structure and copying files into it
I use the following script to automate the packaging. Be mindful of paths if you are using it with a different build/install environment directory structure.
emandir=$BROOT/stage/$MACOSX_DEPLOYMENT_TARGET/EMAN/EMAN; skeldir=$BROOT/Resources cd $emandir
Clean out any existing app directory, and create a list of all binaries that link against Qt/Mac.
rm -rf $emandir/apps mkdir $emandir/apps c="" cd $emandir/bin for i in *;do a=`otool -L $i | grep libqt`;if [ -n "$a" ];then c="$c $i";fi;done cd $emandir
Create the directory structure for the app bundle. Copy the PkgInfo file (they all use the same one.) Copy the icon file. Copy the correct plist file. Copy the argvemulator as a wrapper so it operates properly when launched from the Finder. Move the binary from the EMAN dir to a directory in the bundle. Link to another wrapper to make it launch properly (e.g. 'boxer') from the command line. Create symlinks 'lib' and 'extlib' so the dylibs can be found.
for i in $c;do \ cd $emandir; \ ad=$emandir/apps/$i.app; \ mkdir -v $ad; \ mkdir -v $ad/Contents; \ mkdir -v $ad/Contents/MacOS; \ mkdir -v $ad/Contents/Resources; \ mkdir -v $ad/Contents/Resources/EMAN; \ mkdir -v $ad/Contents/Resources/EMAN/bin; \ cp -v $skeldir/PkgInfo $ad/Contents/PkgInfo; \ cp -v $skeldir/icns/$i.icns $ad/Contents/Resources/$i.icns; \ cp -v $skeldir/plists/$i.plist $ad/Contents/Info.plist; \ cp -v $skeldir/scripts/argvemulator.py $ad/Contents/MacOS/$i.wrapper; \ mv -v $emandir/bin/$i $ad/Contents/Resources/EMAN/bin/$i; \ cd $emandir/bin; \ cp -v $skeldir/scripts/applaunch.sh ./$i; \ cd $ad/Contents/MacOS; \ ln -sv ../Resources/EMAN/bin/$i ./$i; \ cd $ad/Contents/Resources/EMAN; \ ln -sv ../../../../../lib ./lib; \ cd $ad/Contents/Resources; \ ln -sv ../../../../../extlib/ ./extlib; \ done