Compiling FileZilla 3 under Windows

This documentation explains how to setup a build environment for FileZilla 3 and how to compile it under Windows using msys2. Msys2 is a cygwin environment. These instructions require you to run a 64bit Windows.
It will take some time to get everything working, but you will be able to use the build environment for other programs too.
For complete MSYS2 system and all needed decencies installed, you will need 7GiB free space on your disk.
Note to wiki contributors: Do not change version numbers on your own. The build process is somewhat fragile and does break if you change things

Installing the MSYS2 environment

Download the 64bit MSYS2 installer and install it in a convenient location: msys2-x86_64-20150512.exe
官方网站 http://msys2.github.io

Installing the compiler toolchain

FileZilla's shell extension needs to be build both for 32bit as well as 64bit, hence we're going to need compilers for both 32bit and 64bit.

Tools and compiler

修改源

mirrorlist.mingw32

##
## 32-bit Mingw-w64 repository mirrorlist
##

## Primary
## msys2.org
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686
Server = http://repo.msys2.org/mingw/i686
Server = http://downloads.sourceforge.net/project/msys2/REPOS/MINGW/i686
Server = http://www2.futureware.at/~nickoe/msys2-mirror/i686/

mirrorlist.mingw64

##
## 64-bit Mingw-w64 repository mirrorlist
##

## Primary
## msys2.org
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/x86_64
Server = http://repo.msys2.org/mingw/x86_64
Server = http://downloads.sourceforge.net/project/msys2/REPOS/MINGW/x86_64
Server = http://www2.futureware.at/~nickoe/msys2-mirror/x86_64/

mirrorlist.msys

##
## MSYS2 repository mirrorlist
##

## Primary
## msys2.org
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/msys/$arch
Server = http://repo.msys2.org/msys/$arch
Server = http://downloads.sourceforge.net/project/msys2/REPOS/MSYS2/$arch
Server = http://www2.futureware.at/~nickoe/msys2-mirror/msys/$arch/

First update

Start the MSYS2 shell

pacman -Syu

close MSYS2 shell.

Update the rest of the base packages with pacman -Su:

pacman -Su

Install tools and compiler toolchain

Start MSYS2 shell, execute the following command to install the necessary packages:

pacman -S base-devel msys2-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain 
pacman -S svn git curl wget
pacman -S ca-certificates

Execute the following to work around some most-annoying bugs in the toolchain

# Fix missing platform prefix for windres
[ -f /mingw64/bin/x86_64-w64-mingw32-windres.exe ] || ln -s /mingw64/bin/windres.exe /mingw64/bin/x86_64-w64-mingw32-windres.exe
[ -f /mingw32/bin/i686-w64-mingw32-windres.exe  ] || ln -s /mingw32/bin/windres.exe /mingw32/bin/i686-w64-mingw32-windres.exe
# Even when statically linking to libstdc++, it still tries to dynamically link to lib(win)pthread. On top of it, libtool is too
# stupid to recognize the semantics of -Wl,-Bstatic. This leaves one option: Removing the dynamic import libraries.
rm /mingw32/i686-w64-mingw32/lib/libpthread.dll.a
rm /mingw32/i686-w64-mingw32/lib/libwinpthread.dll.a
rm /mingw64/x86_64-w64-mingw32/lib/libpthread.dll.a
rm /mingw64/x86_64-w64-mingw32/lib/libwinpthread.dll.a

Setting up the environment

Execute the following commands:

mkdir ~/prefix
echo 'export PATH="$HOME/prefix/bin:/mingw64/bin:/mingw32/bin:$PATH"' >> ~/.profile
echo 'export PKG_CONFIG_PATH="$HOME/prefix/lib/pkgconfig"' >> ~/.profile
echo 'export PATH="$HOME/prefix/bin:/mingw64/bin:/mingw32/bin:$PATH"' >> ~/.bash_profile
echo 'export PKG_CONFIG_PATH="$HOME/prefix/lib/pkgconfig"' >> ~/.bash_profile

Restart the MSYS2 shell.

Building dependencies for 64bit

Building GMP

No dependence

cd ~
curl -O https://gmplib.org/download/gmp/gmp-6.1.2.tar.xz
tar xf gmp-6.1.2.tar.xz
cd gmp-6.1.2
./configure --build=x86_64-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --enable-fat
make && make install

Building Nettle

No dependence

cd ~
wget ftp://ftp.gnu.org/gnu/nettle/nettle-3.3.tar.gz
tar xf nettle-3.3.tar.gz
cd nettle-3.3
./configure --build=x86_64-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --enable-fat
make && make install

Building zlib

No dependence

cd ~
wget http://zlib.net/zlib-1.2.8.tar.gz
tar xf zlib-1.2.8.tar.gz
cd zlib-1.2.8
./configure --prefix="$HOME/prefix" --static
make && make install

Building libunistring

wget https://ftp.gnu.org/gnu/libunistring/libunistring-0.9.7.tar.xz
tar xf libunistring-0.9.7.tar.xz
cd libunistring-0.9.7
./configure --build=x86_64-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared
make && make install

Building GnuTLS

dependences: libunistring, zlib, Nettle , GMP

cd ~
wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.5/gnutls-3.5.8.tar.xz
tar xf gnutls-3.5.8.tar.xz
cd gnutls-3.5.8
./configure --prefix="$HOME/prefix" --enable-static --disable-shared --build=x86_64-w64-mingw32 --with-included-libtasn1 --disable-doc --disable-guile --without-p11-kit --enable-local-libopts --disable-nls
make && make install

# The __declspec(dllimport) is needed for DLLs, but we're linking statically. It thus results in undefined references. Remove it.
sed -i 's/__declspec(dllimport)//' "$HOME/prefix/include/gnutls/gnutls.h"

config后出现告警

configure: summary of build options:

  version:              3.5.8 shared 43:1:13
  Host/Target system:   i686-w64-mingw32
  Build system:         x86_64-pc-msys
  Install prefix:       /home/Neo/prefix
  Compiler:             i686-w64-mingw32-gcc
  Valgrind:             no
  CFlags:               -g -O2
  Library types:        Shared=no, Static=yes
  Local libopts:        yes
  Local libtasn1:       yes
  Local unistring:      no
  Use nettle-mini:      no
  Documentation:        no (manpages: no)

configure: External hardware support:

  /dev/crypto:          no
  Hardware accel:       x86
  Padlock accel:        yes
  Random gen. variant:  auto-detect
  PKCS#11 support:      no
  TPM support:          no

configure: Optional features:
(note that included applications might not compile properly
if features are disabled)

  SSL3.0 support:       yes
  SSL2.0 client hello:  yes
  DTLS-SRTP support:    yes
  ALPN support:         yes
  OCSP support:         yes
  Ses. ticket support:  yes
  OpenPGP support:      yes
  SRP support:          yes
  PSK support:          yes
  DHE support:          yes
  ECDHE support:        yes
  Anon auth support:    yes
  Heartbeat support:    yes
  IDNA support:         no
  Self checks:          no
  Non-SuiteB curves:    yes
  FIPS140 mode:         no

configure: Optional libraries:

  Guile wrappers:       no
  C++ library:          yes
  DANE library:         no
  OpenSSL compat:       no

configure: System files:

  Trust store pkcs11:
  Trust store dir:
  Trust store file:
  Blacklist file:
  CRL file:
  Priority file:        /etc/gnutls/default-priorities
  DNSSEC root key file: C:\Program Files\Unbound\root.key

configure: WARNING:
***
*** The DNSSEC root key file in C:\Program Files\Unbound\root.key was not found.
*** This file is needed for the verification of DNSSEC responses.
*** Use the command: unbound-anchor -a "C:\Program Files\Unbound\root.key"
*** to generate or update it.
***

安装unband

pacman -S mingw-w64-x86_64-unbound mingw-w64-i686-unbound

生成root.key (需要管理员权限)

unbound-anchor.exe -a "/c/Program Files/Unbound/root.key"

Building SQLite

cd ~
wget http://sqlite.org/2017/sqlite-autoconf-3180000.tar.gz
tar xf sqlite-autoconf-3180000.tar.gz
cd sqlite-autoconf-3180000
./configure --build=x86_64-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared
make && make install

Building wxWidgets

cd ~
svn co https://github.com/wxWidgets/wxWidgets/branches/WX_3_0_BRANCH wx3
cd wx3
./configure --prefix="$HOME/prefix" --enable-static --disable-shared --build=x86_64-w64-mingw32 --enable-unicode --without-libtiff --without-libjpeg --with-expat=builtin --with-libpng=builtin
make && make install

Building libfilezilla

cd ~
svn co https://svn.filezilla-project.org/svn/libfilezilla/trunk libfilezilla
cd libfilezilla
autoreconf -i 
./configure --build=x86_64-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared
make && make install

Building Filezilla

cd ~
svn co https://svn.filezilla-project.org/svn/FileZilla3/trunk filezilla

Building FileZilla

cd ~/filezilla
autoreconf -i
./configure --build=x86_64-w64-mingw32 --with-pugixml=builtin LDFLAGS="-static-libgcc -static-libstdc++"
make

Building dependencies for 32bit

Building GMP

./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --enable-fat
make && make install

Building Nettle

./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --enable-fat
make && make install

Building zlib

export CC=i686-w64-mingw32-gcc
./configure --prefix="$HOME/prefix" --static
make && make install

Building libunistring

./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared
make && make install

Building GnuTLS

./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --with-included-libtasn1 --disable-doc --disable-guile --without-p11-kit --enable-local-libopts --disable-nls
make && make install

# The __declspec(dllimport) is needed for DLLs, but we're linking statically. It thus results in undefined references. Remove it.
sed -i 's/__declspec(dllimport)//' "$HOME/prefix/include/gnutls/gnutls.h"

Building SQLite

./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared
make && make install

Building wxWidgets

./configure --prefix="$HOME/prefix" --enable-static --disable-shared --host=i686-w64-mingw32 --build=i686-w64-mingw32 --enable-unicode --without-libtiff --without-libjpeg --with-expat=builtin --with-libpng=builtin
make && make install

Building libfilezilla

autoreconf -i 
./configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared
make && make install

Building FileZilla

autoreconf -i
./configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --with-pugixml=builtin LDFLAGS="-static-libgcc -static-libstdc++"
make
strip src/interface/.libs/filezilla.exe
strip src/putty/.libs/fzsftp.exe
strip src/putty/.libs/fzputtygen.exe
strip src/fzshellext/64/.libs/libfzshellext-0.dll
strip src/fzshellext/32/.libs/libfzshellext-0.dll

进入data目录,使用NSIS编译 install.nsi

32bit build script

#! /bin/bash

tar xf gmp-6.1.2.tar.xz
cd ~/fsdeps/gmp-6.1.2/
./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --enable-fat
make && make install

tar xf nettle-3.3.tar.gz
cd ~/fsdeps/nettle-3.3/
./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --enable-fat
make && make install

tar xf zlib-1.2.11.tar.gz
cd ~/fsdeps/zlib-1.2.11/
export CC=i686-w64-mingw32-gcc
./configure --prefix="$HOME/prefix" --static
make && make install

tar xf libunistring-0.9.7.tar.xz
cd ~/fsdeps/libunistring-0.9.7/
./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared
make && make install

tar xf sqlite-autoconf-3180000.tar.gz
cd ~/fsdeps/sqlite-autoconf-3180000
./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared
make && make install

tar xf gnutls-3.5.9.tar.xz
cd ~/fsdeps/gnutls-3.5.9/
./configure --host=i686-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --with-included-libtasn1 --disable-doc --disable-guile --without-p11-kit --enable-local-libopts --disable-nls
make

# The __declspec(dllimport) is needed for DLLs, but we're linking statically. It thus results in undefined references. Remove it.
sed -i 's/__declspec(dllimport)//' "$HOME/prefix/include/gnutls/gnutls.h"

编译出错

D:\Program_Files\msys64\home\Neo\filezilla-3.25.1\src\engine/tlssocket_impl.cpp:1235: undefined reference to `_imp__gnutls_free'
D:\Program_Files\msys64\home\Neo\filezilla-3.25.1\src\engine/tlssocket_impl.cpp:1256: undefined reference to `_imp__gnutls_free'
../engine/libengine.a(libengine_a-tlssocket_impl.o): In function `~datum_holder':
D:\Program_Files\msys64\home\Neo\filezilla-3.25.1\src\engine/tlssocket_impl.cpp:105: undefined reference to `_imp__gnutls_free'
D:\Program_Files\msys64\home\Neo\filezilla-3.25.1\src\engine/tlssocket_impl.cpp:105: undefined reference to `_imp__gnutls_free'
D:\Program_Files\msys64\home\Neo\filezilla-3.25.1\src\engine/tlssocket_impl.cpp:105: undefined reference to `_imp__gnutls_free'
../engine/libengine.a(libengine_a-tlssocket_impl.o):D:\Program_Files\msys64\home\Neo\filezilla-3.25.1\src\engine/tlssocket_impl.cpp:105: more undefined references to `_imp__gnutls_free' follow
collect2.exe: error: ld returned 1 exit status
make[4]: *** [Makefile:922: filezilla.exe] Error 1
make[4]: Leaving directory '/home/Neo/filezilla-3.25.1/src/interface'
make[3]: *** [Makefile:2793: all-recursive] Error 1
make[3]: Leaving directory '/home/Neo/filezilla-3.25.1/src/interface'
make[2]: *** [Makefile:784: all] Error 2
make[2]: Leaving directory '/home/Neo/filezilla-3.25.1/src/interface'
make[1]: *** [Makefile:420: all-recursive] Error 1
make[1]: Leaving directory '/home/Neo/filezilla-3.25.1/src'
make: *** [Makefile:604: all-recursive] Error 1

解决方法
edit gnutls.h and remove the _SYM_EXPORT part from the gnutls_free declaration.
https://forum.filezilla-project.org/viewtopic.php?t=1227&start=180

// extern _SYM_EXPORT gnutls_free_function gnutls_free;
extern gnutls_free_function gnutls_free;

COM in plain C

https://www.codeproject.com/Articles/13601/COM-in-plain-C

阅读全文

A Brief Intro to Input Method Framework, Linux IME, and XIM

https://tedyin.com/posts/a-brief-intro-to-linux-input-method-framework/ There are chances one need an input method editor (IME). For CJK users, su...

阅读全文

使用Visual studio查看exe或DLL文件的依赖项

事先准备:只要 Visual Studio 任何版本即可。 点击开始 -> 程序 -> Visual Studio对应的版本,打开Visual Studio Tools -> 选择 命令提示 进入命...

阅读全文

3 条评论

欢迎留言