{{{ #!forumlinks }}} = Porting Tribler to Mac OS/X = ''This page may be outdated. See [wiki:MacBuildFromScratch]'' This page contains the steps that were required to port Tribler to Mac OS/X. See also UniversalBinaryHowto for making an Universal Binary. See also VlcMacHowto for how to build VLC including Python bindings on Mac OS/X. == Prerequisites == To do this, you'll need: * SWIG (for instance, through Fink) * an SVN client that understands https. I'll assume its installed in /usr/local/bin. * Python 2.4 already installed. * wxPython >= 2.6 UNICODE for Python 2.4 already installed (http://www.wxpython.org/) * Maybe: Growl python bindings (see wiki:Growl). == Download some stuff == First, pull the Tribler source from SVN, and chdir to it: {{{ /usr/local/bin/svn co http://svn.tribler.org/abc/tags/tribler-3.3.6 tribler-3.3.6 cd tribler-3.3.6 }}} Tribler needs a modified M2Crypto library, which in turn requires OpenSSL. As the OpenSSL that ships with Mac OS/X is too old (0.9.7), we need to download a newer version at http://www.openssl.org/source/. Get at least version 0.9.8, and unpack it somewhere: {{{ wget http://www.openssl.org/source/openssl-0.9.8e.tar.gz tar xfz openssl-0.9.8e.tar.gz }}} Next, pull the modified M2Crypto source from SVN: {{{ /usr/local/bin/svn co http://svn.tribler.org/m2crypto/branches/main m2crypto }}} Alternatively, you can use the [http://wiki.osafoundation.org/Projects/MeTooCrypto official M2Crypto] release starting with 0.16. You'll need to edit {{{setup.py}}} such that it statically links OpenSSL's {{{libssl.a}}} and {{{libcrypto.a}}}. == Compile OpenSSL and M2Crypto == First, we compile OpenSSL: {{{ cd openssl ./config make cd .. }}} For Intel Mac, it seems that the "shared" flag is needed if config fails. Next, we compile M2Crypto: {{{ cd m2crypto python setup.py build cd .. }}} Newer versions of Python include bsddb. If not available, set it up: {{{ wget http://downloads.sleepycat.com/db-4.4.20.tar.gz tar xfz db-4.4.20.tar.gz mv db-4.4.20 db cd db/build_unix ../dist/configure make cd ../.. wget http://surfnet.dl.sourceforge.net/sourceforge/pybsddb/bsddb3-4.4.2.tar.gz tar xfz bsddb3-4.4.2.tar.gz mv bsddb3-4.4.2 bsddb3 cd bsddb3 python setup.py --berkeley-db-libdir=../db/build_unix/ --berkeley-db-incdir=../db/build_unix --berkeley-db=../db/build_unix/.libs/ build }}} == Run it == You can run Tribler by typing: {{{ LIBDIR=`ls m2crypto/build/ | grep "lib."` export PYTHONPATH=m2crypto/build/$LIBDIR/:bsddb3/build/$LIBDIR/ pythonw abc.py }}} (You should have only one lib directory in m2crypto/build/). == Create a setup script == To create an application bundle Tribler.app, I use the bundlebuilder extension to python. I prefer it over the more recent py2app as bundlebuilder allows me to ship libraries along *and* force them to be used before the ones installed on the user's system. Anyway, {{{setuptriblermac.py}}} contains the most recent setup script. Run the following command to build build/Tribler.app: {{{ python setuptriblermac.py build }}} If all goes well, a disk image is available as {{{Tribler.dmg}}}. You, however, may need to edit {{{setuptriblermac.py}}}, e.g. if you've installed a newer version of wxPython than 2.6. {{{ #!protected #:[[Include(wiki:ProtectedSectionMessage)]] Tribler developers can use {{{mac007.cs.vu.nl}}} to create the diskimage. Just {{{ ssh tribler@mac007.cs.vu.nl. cd build svn co https://svn.tribler.org/abc/tags/tribler-3.5.1 cd tribler-3.5.1 rm -rf `find . -name .svn` # otherwise Subversion data gets included in the release export PYTHONPATH=/Users/tribler/pkgs/m2crypto/lib/python2.4/site-packages vi setuptriblermac.py # Change 2.6-unicode to 2.8-unicode python2.4 setuptriblermac.py }}} The machine may not always be on. In that case, contact Arno. The machine is a G3@350 MHz, running MacOS 10.3.9. }}} = Required patches = Tribler needed patching on the following: * struct.pack/struct.unpack needed an explicit little-endian specifier. * mailto: urls should not encode the body= parameter. * files opened through the webbrowser should start with file://. * the 'About' action needed the specific id of wx.ID_ABOUT. == Issues == * FIXED: 'Open file' dialog boxes seem to fail. * FIXED: The 'invite friends' feature doesn't work well in combination with Thunderbird: the message contains %20's instead of spaces, etc. * FIXED: 'About box' in application menu does not work. * FIXED: Not encountering peers. * 'Seeding options' and 'Timeouts' in Preferences have too narrow dropdown selection boxes. = Tips and Tricks = == Linking with the right libs == When shipping an application on Mac OS/X, you must make sure you don't link to unshipped libraries which aren't part of a default Mac install. This can happen if you installed libraries system-wide, and subsequently link Tribler dynamically against those. Shipping the libraries doesn't help, since Mac OS/X (or gcc) includes absolute links to the installed libraries. There are two ways of detecting whether this is happening: 1. Once Tribler is running, check the output of {{{lsof | grep Tribler}}} to see if there are any system-wide libraries loaded which should have been shipped instead. 1. On a per library basis, lets take {{{__m2crypto.so}}} as an example, which is a custom library linked against libssl and libcrypto, of which a too low version ships with Mac OS/X. {{{otool -L __m2crypto.so}}} gives {{{ /usr/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8) /usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 71.1.4) }}} of which only {{{libSystem}}} is a default Mac lib. By the way, linking against the wrong Python is no problem since Python 2.4 is shipped with Tribler and by definition already loaded when any libraries are loaded by an {{{import}}} statement. So the following is correct as well: {{{ /Library/Frameworks/Python.framework/Versions/2.4/Python (compatibility version 2.4.0, current version 2.4.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.1.5) }}} There are also two ways of fixing this problem: 1. Link your custom library against static ({{{.a}}}) versions of the installed libs. 1. Ship the installed lib as well, and modify the reference in the custom library. The reference can be modified with {{{install_name_tool -change}}}. Be warned, the new reference cannot be longer than the old one.