CompileMPlayerStatic
Version 6 (Adrian Stutz, 10/06/2008 08:07 pm)
| 1 | 1 | ||
|---|---|---|---|
| 2 | 6 | Adrian Stutz | h1. Compile MPlayer with static libraries |
| 3 | 6 | Adrian Stutz | |
| 4 | 6 | Adrian Stutz | |
| 5 | 4 | Adrian Stutz | [[PageOutline]] |
| 6 | 1 | ||
| 7 | 1 | If you want to compile MPlayer (the command-line player behind MPlayerOSX), there are two ways to go at it. MPlayer depends on various libraries and you can compile a version linked to the libraries installed on your system (shared) or put the libraries into one self-contained binary (static). |
|
| 8 | 1 | ||
| 9 | 6 | Adrian Stutz | Compiling MPlayer with statically linked libraries is a bit more tricky. On a regular Unix, you can use _--enable-static_ to create a build that links everything it uses statically. On OSX, this method will fail because Apple has deliberately broken static linking of its system libraries by excluding a static version of the "libc":http://en.wikipedia.org/wiki/Libc library that contains the most basic C functions. You could just download the source code of that library and build a static version yourself but that would be besides the point. Apple excluded it because it doesn't want its system libraries to be statically linked and therefore to be able to update them at a later time (which is not possible for statically linked libraries because they are built into the application binary). |
| 10 | 1 | ||
| 11 | 1 | So, instead of statically linking all libraries, you'd only want to statically link any non-system library. It's not needed to statically link the system libraries anyway. They are guaranteed to exist on all OSX installations and Apple takes care of making sure OSX is backwards-compatible if they change anything. |
|
| 12 | 1 | ||
| 13 | 1 | There are two possible ways to go about linking the extra libraries statically: |
|
| 14 | 6 | Adrian Stutz | * the install_name_tool way |
| 15 | 6 | Adrian Stutz | * the search_paths_first way |
| 16 | 1 | ||
| 17 | 1 | ||
| 18 | 6 | Adrian Stutz | h2. The install_name_tool Way |
| 19 | 1 | ||
| 20 | 2 | Adrian Stutz | |
| 21 | 6 | Adrian Stutz | OSX uses the "Mach-O":http://en.wikipedia.org/wiki/Mach-o binary structure that contains paths to all linked libraries. One way to statically link libraries is to first compile mplayer with shared libraries and then use "install_name_tool":http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/install_name_tool.1.html later to change the paths of the libraries to point to static ones. |
| 22 | 6 | Adrian Stutz | |
| 23 | 6 | Adrian Stutz | This way, the libraries and the application binary will be separate and the libraries have to be in a fixed relative location to the application binary. On OSX this is not so much of a concern since it's possible to bundle everything in an .app package. To the user the application binary and the libraries will appear as one single file. The most common way is to keep the libraries in a _Frameworks_ folder, so that the paths are changed to _../Frameworks/libexample.a_. |
| 24 | 6 | Adrian Stutz | |
| 25 | 2 | Adrian Stutz | I didn't use this method for the binaries included with MPlayerOSX Extended, mainly because the official version didn't use that way either. |
| 26 | 1 | ||
| 27 | 1 | If you'll need further instructions for this method, you'll find some with Google. Here's one: http://qin.laya.com/tech_coding_help/dylib_linking.html |
|
| 28 | 1 | ||
| 29 | 1 | ||
| 30 | 6 | Adrian Stutz | h2. The search_paths_first Way |
| 31 | 6 | Adrian Stutz | |
| 32 | 6 | Adrian Stutz | |
| 33 | 1 | With this method you link the libraries statically at compile time and they are included in the application binary. This creates only one single file, that will be rather large, since it includes all dependencies. But this way you will get an mplayer binary that can simply be copied anywhere and used without the GUI and the .app package. |
|
| 34 | 1 | ||
| 35 | 1 | But to get OSX to statically link the libraries is not very straight forward. OSX's compiler will search all paths and will link shared libraries preferentially, even if it found a static version in an earlier path. |
|
| 36 | 1 | To statically link libraries, |
|
| 37 | 6 | Adrian Stutz | * they cannot be in the same location as their shared counterparts |
| 38 | 6 | Adrian Stutz | * they have to be in an earlier path than their shared counterparts |
| 39 | 6 | Adrian Stutz | * the search_paths_first options has to be passed to the linker to make it stop searching when it found the static library |
| 40 | 1 | ||
| 41 | 6 | Adrian Stutz | You could use this method together with [[MacPorts]] by copying all static libraries into a separate directory structure and then specify this library path first. I chose to build everything by hand, mostly because I was curious and a little bit adventurous. |
| 42 | 2 | Adrian Stutz | |
| 43 | 2 | Adrian Stutz | |
| 44 | 6 | Adrian Stutz | h2. Building Preface |
| 45 | 6 | Adrian Stutz | |
| 46 | 6 | Adrian Stutz | |
| 47 | 1 | Another thing to keep in mind is OSX backward compatibility. If you just build away then the resulting binary will be only compatible with the OSX version you build it upon and may even run only on your system alone. What you need to do is to build it against the OSX SDK (installed with the developer tools) that only contains those parts that are guaranteed to exist on all installations and there are also SDKs to build for older OSX versions. |
|
| 48 | 1 | ||
| 49 | 2 | Adrian Stutz | To build against the OSX SDK, you have to set the correct CFLAGS and LDFLAGS: |
| 50 | 6 | Adrian Stutz | <pre> |
| 51 | 2 | Adrian Stutz | export MACOSX_DEPLOYMENT_TARGET=10.4 |
| 52 | 2 | Adrian Stutz | export CFLAGS="-mmacosx-version-min=10.4 -isystem /Developer/SDKs/MacOSX10.4u.sdk" |
| 53 | 1 | export LDFLAGS="-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk" |
|
| 54 | 1 | export CXXFLAGS="-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk" |
|
| 55 | 6 | Adrian Stutz | </pre> |
| 56 | 2 | Adrian Stutz | This defines 10.4 as the target and minimum OS for the build to run on. |
| 57 | 2 | Adrian Stutz | |
| 58 | 2 | Adrian Stutz | Then there are universal binaries. There are still many PPC macs around and so we need to compile for i386 and ppc. On some projects is possible to build an universal binary in one swoop but others need separate builds for both architectures. |
| 59 | 2 | Adrian Stutz | |
| 60 | 2 | Adrian Stutz | To try to directly build an universal binary, specify the arch options: |
| 61 | 6 | Adrian Stutz | <pre> |
| 62 | 2 | Adrian Stutz | export CFLAGS="$CFLAGS -arch i386 -arch ppc" |
| 63 | 2 | Adrian Stutz | export LDFLAGS="$LDFLAGS -arch i386 -arch ppc" |
| 64 | 2 | Adrian Stutz | export CXXFLAGS="$CXXFLAGS -arch i386 -arch ppc" |
| 65 | 6 | Adrian Stutz | </pre> |
| 66 | 6 | Adrian Stutz | It's also needed to set _--disable-dependency-tracking_ with the respective configure script, if the option is available. |
| 67 | 1 | ||
| 68 | 1 | And to cross compile for PPC (with altivec): |
|
| 69 | 6 | Adrian Stutz | <pre> |
| 70 | 1 | export CFLAGS="$CFLAGS -arch ppc -faltivec -mcpu=7450" |
|
| 71 | 1 | export LDFLAGS="$LDFLAGS -arch ppc" |
|
| 72 | 1 | export CXXFLAGS="$CXXFLAGS -arch ppc -faltivec -mcpu=7450" |
|
| 73 | 6 | Adrian Stutz | </pre> |
| 74 | 1 | ||
| 75 | 6 | Adrian Stutz | If all goes well, we'll end up with a universal binary. You can check this with the "lipo":http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/lipo.1.html tool: |
| 76 | 6 | Adrian Stutz | <pre> |
| 77 | 1 | Coil:mplayer adrian$ lipo -detailed_info mplayer |
|
| 78 | 1 | Fat header in: mplayer |
|
| 79 | 1 | fat_magic 0xcafebabe |
|
| 80 | 1 | nfat_arch 2 |
|
| 81 | 3 | Adrian Stutz | architecture i386 |
| 82 | 1 | cputype CPU_TYPE_I386 |
|
| 83 | 3 | Adrian Stutz | cpusubtype CPU_SUBTYPE_I386_ALL |
| 84 | 1 | offset 4096 |
|
| 85 | 3 | Adrian Stutz | size 11510420 |
| 86 | 3 | Adrian Stutz | align 2^12 (4096) |
| 87 | 1 | architecture ppc7400 |
|
| 88 | 1 | cputype CPU_TYPE_POWERPC |
|
| 89 | 3 | Adrian Stutz | cpusubtype CPU_SUBTYPE_POWERPC_7400 |
| 90 | 1 | offset 11517952 |
|
| 91 | 1 | size 10988308 |
|
| 92 | 1 | align 2^12 (4096) |
|
| 93 | 6 | Adrian Stutz | </pre> |
| 94 | 3 | Adrian Stutz | |
| 95 | 6 | Adrian Stutz | If it doesn't go well, the i386 and ppc builds have to be done separately, and then merged with _lipo_: |
| 96 | 6 | Adrian Stutz | <pre> |
| 97 | 1 | lipo -create libi386.a libppc.a -output libuniversal.a |
|
| 98 | 6 | Adrian Stutz | </pre> |
| 99 | 3 | Adrian Stutz | |
| 100 | 3 | Adrian Stutz | |
| 101 | 6 | Adrian Stutz | h2. Build Environment and Libraries |
| 102 | 6 | Adrian Stutz | |
| 103 | 6 | Adrian Stutz | |
| 104 | 1 | To build all the libraries, I created a separate root for the libraries to go into, downloaded the libraries one-by-one, compiled and finally installed them in the root. |
|
| 105 | 6 | Adrian Stutz | <pre> |
| 106 | 1 | mkdir ~/dev/mplayer |
|
| 107 | 1 | cd ~/dev/mplayer |
|
| 108 | 6 | Adrian Stutz | export MPPREFIX=@pwd@ |
| 109 | 6 | Adrian Stutz | </pre> |
| 110 | 1 | ||
| 111 | 6 | Adrian Stutz | But first, it's important to make sure that nothing interferes with the build process, especially [[MacPorts]]. For this we reset the PATH to the defaults and make sure that PKG_CONFIG_PATH is empty. |
| 112 | 6 | Adrian Stutz | <pre> |
| 113 | 3 | Adrian Stutz | export PATH="$MPPREFIX:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin" |
| 114 | 1 | export PKG_CONFIG_PATH="" |
|
| 115 | 6 | Adrian Stutz | </pre> |
| 116 | 1 | ||
| 117 | 3 | Adrian Stutz | The libraries that compile fine under OSX can then usually be compiled with: |
| 118 | 6 | Adrian Stutz | <pre> |
| 119 | 3 | Adrian Stutz | ./configure --disable-shared --disable-dependency-tracking --prefix=$MPPREFIX |
| 120 | 3 | Adrian Stutz | make |
| 121 | 3 | Adrian Stutz | make install |
| 122 | 6 | Adrian Stutz | </pre> |
| 123 | 3 | Adrian Stutz | |
| 124 | 6 | Adrian Stutz | Detailed information regarding compiling the different libraries can be found here: [[CompileMPlayerLibraries|Compile MPlayer Libraries]] |
| 125 | 5 | Adrian Stutz | |
| 126 | 3 | Adrian Stutz | |
| 127 | 6 | Adrian Stutz | h2. Build MPlayer |
| 128 | 6 | Adrian Stutz | |
| 129 | 6 | Adrian Stutz | |
| 130 | 3 | Adrian Stutz | MPlayer needs some more flags to be set to compile: |
| 131 | 6 | Adrian Stutz | <pre> |
| 132 | 3 | Adrian Stutz | export CFLAGS="-O4 -fomit-frame-pointer -pipe $CFLAGS" |
| 133 | 3 | Adrian Stutz | export CXXFLAGS="-O4 -fomit-frame-pointer -pipe $CXXFLAGS" |
| 134 | 6 | Adrian Stutz | </pre> |
| 135 | 3 | Adrian Stutz | |
| 136 | 3 | Adrian Stutz | And here's the configure I use: |
| 137 | 6 | Adrian Stutz | <pre> |
| 138 | 3 | Adrian Stutz | ./configure --extra-libs="-ldvdcss" --disable-x11 --disable-gl --disable-mencoder --disable-dvdread-internal --enable-apple-remote --prefix=$MPPREFIX |
| 139 | 6 | Adrian Stutz | </pre> |
| 140 | 3 | Adrian Stutz | |
| 141 | 3 | Adrian Stutz | Mostly I disable stuff that's not needed. X11 and GL video outputs, the whole mencoder, the internal dvdread because I have dvdread and dvdnav external and finally I enable the apple remote because it doesn't pick that up automatically (maybe because I don't have an IR reciever?). |
| 142 | 3 | Adrian Stutz | The --extra-libs tells the linker that it needs to include libdvdcss that is used by the external dvdread and doesn't get included automatically. |
| 143 | 3 | Adrian Stutz | |
| 144 | 3 | Adrian Stutz | To make the PPC build, these additional options are needed for the cross compile (with the right C/LDFLAGS): |
| 145 | 6 | Adrian Stutz | <pre> |
| 146 | 3 | Adrian Stutz | --enable-cross-compile --cc="cc -arch ppc" --host-cc="cc -arch i386" --target=ppc-darwin --disable-win32dll --enable-altivec |
| 147 | 6 | Adrian Stutz | </pre> |
| 148 | 3 | Adrian Stutz | |
| 149 | 3 | Adrian Stutz | |
| 150 | 6 | Adrian Stutz | h2. The _XOPEN_SOURCE issue |
| 151 | 6 | Adrian Stutz | |
| 152 | 6 | Adrian Stutz | |
| 153 | 3 | Adrian Stutz | This only affects compiling from OSX 10.5 against the 10.4 SDK. |
| 154 | 3 | Adrian Stutz | |
| 155 | 6 | Adrian Stutz | At some point you might run into compile errors about some standard functions not being found, that are appended by *$UNIX2003*. |
| 156 | 3 | Adrian Stutz | Those symbols were introduced with OSX 10.5's UNIX 2003 compliance. Apple kept the old functions for backwards compatibility and postfixed the new UNIX 2003 compatible functions with $UNIX2003. |
| 157 | 3 | Adrian Stutz | |
| 158 | 3 | Adrian Stutz | When compiling for 10.4 the old functions have obviously to be used. If you set the CFLAGS/LDFLAGS above, the compiler will do that automatically for you. |
| 159 | 3 | Adrian Stutz | |
| 160 | 6 | Adrian Stutz | Unless a source code file defines _XOPEN_SOURCE, _POSIX_C_SOURCE, _APPLE_C_SOURCE or !+LP64!+. Any of those flags make the headers use the postfixed symbols and when the linker then tries to link against those symbols in the 10.4 SDK, they obviously cannot be found. |
| 161 | 3 | Adrian Stutz | |
| 162 | 3 | Adrian Stutz | To work around this, all occurrences of those definitions have either to be removed or have to check for an OSX system like this: |
| 163 | 6 | Adrian Stutz | <pre> |
| 164 | 6 | Adrian Stutz | #if !defined(+APPLE+) |
| 165 | 1 | #define _XOPEN_SOURCE 600 |
|
| 166 | 1 | #endif |
|
| 167 | 6 | Adrian Stutz | </pre> |