I want to provide some updated (slightly modified) directions on how I compile FileZilla binaries for Tiger. Everytime a new version comes out I reference the wiki and it's not quite what I'm doing.
See the
Compiling_FileZilla_3_under_Mac_OS_X page on the wiki if you need help finding any of these packages. Xcode is a prerequisite.
We'll start with wxWidgets 2.8.10. In Firefox, files end up in ~/Downloads by default, which is what I will assume here.
Code: Select all
cd /tmp
tar xzf ~/Downloads/wxMac-2.8.10.tar.gz
mkdir build-wx
cd build-wx
../wxMac-2.8.10/configure --disable-compat26 --enable-unicode --enable-universal_binary --prefix $HOME/filezilla/wxMac-2.8.10 && nice make && make install
cd ~/filezilla
ln -s wxMac-2.8.10 wxMac
You will need to edit the file ~/filezilla/wxMac-2.8.10/bin/wx-config. Remove "-arch ppc" and "-arch i386" from the file. These are both on the same line and only in the file once.
Next build GNU gettext 0.17.
Code: Select all
cd /tmp
tar xzf ~/Downloads/gettext-0.17.tar.gz
cd gettext-0.17
./configure --prefix $HOME/filezilla/gettext-0.17 && nice make && make install
cd ~/filezilla
ln -s gettext-0.17 gettext
Then pkg-config 0.23.
Code: Select all
cd /tmp
tar xzf ~/Downloads/pkg-config-0.23.tar.gz
cd pkg-config-0.23
./configure --prefix $HOME/filezilla/pkg-config-0.23 && nice make && make install
cd ~/filezilla
ln -s pkg-config-0.23 pkg-config
Now you will need to create some environment files. I build FileZilla for Tiger machines on PowerPC and Intel processors. I have created a set of files which tell the build tools about the kind of binary I need.
I put all these files in the ~/filezilla/env directory. These directions assume you will do the same. The first file is for building Tiger binaries on Leopard (10.6) or later systems. If you use this, you can build Tiger binaries on Leopard (or later) systems. Otherwise, when you build on Leopard or later, the binaries will not run on Tiger. Keep in mind certain features have been disabled to be compatible with Tiger (e.g. power management).
Here is the ~/filezilla/env/tiger environment file.
Code: Select all
SDK="/Developer/SDKs/MacOSX10.4u.sdk"
ARCH="-isysroot ${SDK}"
export MACOSX_DEPLOYMENT_TARGET="10.4"
export CFLAGS="${CFLAGS} ${ARCH} -O2"
export CXXFLAGS="${CFLAGS}"
export LDFLAGS="${LDFLAGS} ${ARCH} -Wl,-syslibroot,${SDK}"
This next one is for building universal binaries, i.e. binaries that will run on both PowerPC and Intel processors. It's called ~/filezilla/env/universal.
Code: Select all
ARCH="-arch ppc -arch i386"
export CFLAGS="${CFLAGS} ${ARCH} -O2"
export CXXFLAGS="${CFLAGS}"
export LDFLAGS="${LDFLAGS} ${ARCH}"
This next file is called ~/filezilla/env/fzlibs.
Code: Select all
. ~/filezilla/env/tiger
. ~/filezilla/env/universal
The final file is specific build instructions for FileZilla itself. It's called ~/filezilla/env/filezilla.
Code: Select all
. ~/filezilla/env/fzlibs
export PATH=~/filezilla/pkg-config/bin:~/filezilla/gettext/bin:~/filezilla/wxMac/bin:$PATH
export PKG_CONFIG_PATH=$HOME/filezilla/gnutls/lib/pkgconfig:$PKG_CONFIG_PATH
export CPPFLAGS="${CPPFLAGS} -I$HOME/filezilla/libidn/include"
export LDFLAGS="${LDFLAGS} -L$HOME/filezilla/libidn/lib"
Now that we have our environment files, we can proceed with the build. We'll start with building libidn 1.18.
Code: Select all
cd /tmp
tar xzf ~/Downloads/libidn-1.18.tar.gz
cd libidn-1.18
source ~/filezilla/env/fzlibs
./configure --prefix $HOME/filezilla/libidn-1.18 --disable-dependency-tracking && nice make && make install
cd ~/filezilla
ln -s libidn-1.18 libidn
Next we build libgpg-error 1.7.
Code: Select all
cd /tmp
tar xjf ~/Downloads/libgpg-error-1.7.tar.bz2
cd libgpg-error-1.7
source ~/filezilla/env/fzlibs
./configure --prefix $HOME/filezilla/libgpg-error-1.7 --disable-dependency-tracking && nice make && make install
cd ~/filezilla
ln -s libgpg-error-1.7 libgpg-error
Now we can build libgcrypt 1.4.5.
Code: Select all
cd /tmp
tar xjf ~/Downloads/libgcrypt-1.4.5.tar.bz2
cd libgcrypt-1.4.5
source ~/filezilla/env/fzlibs
./configure --with-gpg-error-prefix=$HOME/filezilla/libgpg-error --prefix $HOME/filezilla/libgcrypt-1.4.5 --disable-dependency-tracking --disable-asm && nice make && make install
cd ~/filezilla
ln -s libgcrypt-1.4.5 libgcrypt
The final library necessary is gnutls 2.8.5.
Code: Select all
cd /tmp
tar xjf ~/Downloads/gnutls-2.8.5.tar.bz2
cd gnutls-2.8.5
source ~/filezilla/env/fzlibs
./configure --prefix $HOME/filezilla/gnutls-2.8.5 --with-libgcrypt-prefix=$HOME/filezilla/libgcrypt --disable-dependency-tracking && nice make && make install
cd ~/filezilla
ln -s gnutls-2.8.5 gnutls
Lastly, we can actually build FileZilla 3.3.2 itself.
Code: Select all
cd /tmp
tar xjf ~/Downloads/FileZilla_3.3.2_src.tar.bz2
cd filezilla-3.3.2
source ~/filezilla/env/filezilla
./configure --disable-dependency-tracking && nice make
rm -rf FileZilla.app
nice make
cd FileZilla.app/Contents/MacOS/
strip filezilla fzputtygen fzsftp
cd ../../..
mv FileZilla.app ~/Desktop
I always run into an error after the first make. Something about the build order is not right and it can't find some of the translation files. I'm not sure why this is, but removing the FileZilla.app directory and rerunning make generates the translation files and completes the build.
Because I build binaries for distribution, I need to edit the dynamic libraries to make their path relative to the filezilla binary. Otherwise, this copy of FileZilla will only run on this machine. I have created a script to help me with this. Either this process is terrible, or I'm really missing something about Mac dylibs. If someone knows an easier way of doing this, I'd love to learn about it. For now, I'll make use of my script.
It's called ~/filezilla/bin/mac-dylib-tool.pl.
Code: Select all
#! /usr/bin/perl
sub syntax {
print "syntax: max-dylib-tool.pl command pattern file\n";
print " command = [ dylib | exe ]\n";
print " pattern = regular expression pattern\n";
print " file = file to alter (dylib or exe)\n";
}
sub fix_dylib_path {
$PREFIX = $_[0];
$FILE = $_[1];
@OUTPUT = `otool -L ${FILE}`;
while (<@OUTPUT>) {
if ($_ =~ m/^($PREFIX)\/(.*)(\.dylib)$/) {
$LIB = $2 . $3;
$CMD = "install_name_tool -change ${1}/${LIB} \@executable_path/../Frameworks/${LIB} ${FILE}";
`${CMD}`;
}
}
}
sub fix_dylib_id {
$PREFIX = $_[0];
$DYLIB = $_[1];
$CMD = "install_name_tool -id \@executable_path/../Frameworks/${DYLIB} ${DYLIB}";
`${CMD}`;
fix_dylib_path($PREFIX, $DYLIB);
}
if ($#ARGV != 2) {
syntax();
die;
}
if ($ARGV[0] eq "dylib") {
fix_dylib_id($ARGV[1], $ARGV[2]);
} elsif ($ARGV[0] eq "exe") {
fix_dylib_path($ARGV[1], $ARGV[2]);
} else {
syntax();
}
First we will make a copy of all the dylibs we need for FileZilla. The build process won't work with our modified dylibs, so we don't want to change the originals.
Code: Select all
cd ~/filezilla
mkdir Frameworks
cd Frameworks
cp ../wxMac/lib/libwx_base_carbonu-2.8.0.dylib .
cp ../wxMac/lib/libwx_base_carbonu_net-2.8.0.dylib .
cp ../wxMac/lib/libwx_base_carbonu_xml-2.8.0.dylib .
cp ../wxMac/lib/libwx_macu_adv-2.8.0.dylib .
cp ../wxMac/lib/libwx_macu_aui-2.8.0.dylib .
cp ../wxMac/lib/libwx_macu_core-2.8.0.dylib .
cp ../wxMac/lib/libwx_macu_html-2.8.0.dylib .
cp ../wxMac/lib/libwx_macu_xrc-2.8.0.dylib .
cp ../libidn/lib/libidn.11.dylib .
cp ../libgpg-error/lib/libgpg-error.0.dylib .
cp ../libgcrypt/lib/libgcrypt.11.dylib .
cp ../gnutls/lib/libgnutls.26.dylib .
Now we can use the script to modify each dynamic library.
Code: Select all
cd ~/filezilla/Frameworks
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libwx_base_carbonu-2.8.0.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libwx_base_carbonu_net-2.8.0.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libwx_base_carbonu_xml-2.8.0.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libwx_macu_adv-2.8.0.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libwx_macu_aui-2.8.0.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libwx_macu_core-2.8.0.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libwx_macu_html-2.8.0.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libwx_macu_xrc-2.8.0.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libidn.11.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libgpg-error.0.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libgcrypt.11.dylib
perl ~/filezilla/bin/mac-dylib-tool.pl dylib $HOME/filezilla/[A-Za-z0-9\-.]+/lib libgnutls.26.dylib
Finally, we fix the filezilla executable itself and copy our modified dylibs.
Code: Select all
cd ~/Desktop/FileZilla.app/Contents/MacOS
perl ~/filezilla/bin/mac-dylib-tool.pl exe $HOME/filezilla/[A-Za-z0-9\-.]+/lib filezilla
cd ..
cp -r ~/filezilla/Frameworks .
And with that, we now have a distributable FileZilla binary that
should work on any Mac with Tiger or later.
A few notes about abstracting this process a little. I don't know anyone other than me who actually needs all this. This is mainly for my reference and for whoever may find it interesting. Here are a few things you may want to edit to suit your needs.
If you have a multi-core processor, you will be able to speed up compilation time by telling make to run in parallel. To do this, change all the "nice make" lines to "nice make -j2". That's for a dual-core processor. Tri-cores would be -j3, Quad-cores would be -j4, etc. I have a quad-core and -j4 really speeds up compile times for FileZilla.
If you don't need to compile for Tiger from Leopard or later (i.e. either you're compiling on Tiger, or you don't need binaries that will run on Tiger), then you can omit all the tiger environment file references. Remove the ". ~/filezilla/env/tiger" line from fzlibs and don't bother creating the tiger file at all.
If you don't need a universal binary, then you can speed up compile times and reduce size by compiling solely for your architecture. To do this, all you really need to do is remove all references to the universal environment file. A few other minor things you can do to be more efficient include removing "--disable-dependency-tracking" from the configure lines. This is only needed for universal builds. Also on libgcrypt, I had to use "--disable-asm" so it would build for both architectures. You can remove that line if only compiling for your native system.
If you don't need Tiger binaries
and you don't need a universal build, you can leave out all references to the fzlibs environment file. Just remove the line from the filezilla environment file. Then you can leave out all the "source ~/filezilla/env/fzlibs" lines. Remember you still (and always) need the final "source ~/filezilla/env/filezilla" line when compiling FileZilla itself.
If you aren't going to distribute your binary (i.e. it only needs to work on the machine you compiled it on), you can leave out all the mac-dylib-tool stuff and coping dylibs to the ~/filezilla/Frameworks directory. This is only needed if you are going to give your binary to others.
Static libraries would be easier, but then gnutls has to be handled special. They don't seem interested in fixing their static build process (which I cannot get to work in a universal build without special handling). Linking statically will also reduce size because you can compress the filezilla library more. UPX on Mac hasn't worked reliably for me, so I've stopped using it. Stripping dylibs seem to break things also, so I don't do that either.
I think I've rambled on long enough now. Thanks to everyone who has helped with this. FileZilla is the best -- thanks especially and explicitly to botg!