This document describes how to build fldigi binaries for Windows systems (2000 or later). Fldigi developers prefer to use a toolchain that runs on Linux and compiles for Windows, and so this is the approach shown here.
For the sufficiently motivated and determined, it should be possible to build on Windows using the mingw and msys packages. An outline of steps needed to build on Windows can be found in an Icarus Project blog (note you will have to build a number of required packages for fldigi from source).
The cross-compiler used here is mingw-gcc and the build instructions have been tested with the version packaged (as mingw32) in recent releases of debian and Ubuntu. For openSUSE, the cross-compiler package is mingw32-cross-gcc-c++ in its most recent release.
The developers maintain their debian and Ubuntu win32 build tree as follows:
We assume that you will use the same or a similar arrangement. Define these variables or substitute their values whenever you encounter them in the build instructions:
AR=i586-mingw32msvc-ar CC=i586-mingw32msvc-gcc RANLIB=i586-mingw32msvc-ranlib SRC=/usr/local/src/win32 PREFIX=/usr/local/win32 CROSSCFG="--build=i686-pc-linux-gnu --host=i586-mingw32msvc" LINKCFG="--enable-static --disable-shared" PKGCFG="PKG_CONFIG=$PREFIX/bin/i586-mingw32msvc-pkg-config"
Once you have installed the cross-compiler, prepare the installation tree:
mkdir -p $PREFIX/bin $PREFIX/lib/pkgconfig
Place the following script in ''$PREFIX/bin/i586-mingw32msvc-pkg-config'' (the name is important) and give it execute permissions. Remember to set $PREFIX in the script code to the same value that you will use for everything else.
1 2 3 4 5 6 7 | #!/bin/sh PREFIX=/usr/local/win32 export PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig export PKG_CONFIG_PATH=$PKG_CONFIG_PATH_MINGW32MSVC exec pkg-config "$@" |
The developers maintain the openSUSE win32 build tree as follows:
mingw32-configure and mingw32-make are used each time configure or make are referenced in the build instructions
Packages are obtained from http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_<release_version>/</release_version>
Add this repository to the system configuration (see "zypper lr -d").
Source trees can be kept in separate directories under /usr/local/src/win32 (or in the build account's homedir)
The PKG_CONFIG argument /usr/bin/i686-w64-mingw32-pkg-config is passed to the configure scripts of libraries that require use of pkg-config
The supplied pre-built mingw32-foo and mingw32-foo-devel libraries are used (the openSUSE MinGW repository is missing only hamlib, xmlrpc-c and FLTK)
Developer-built mingw32 libraries are installed in the /usr/i686-w64-mingw32/sys-root/mingw directory tree
It is assumed you will use the same or a similar arrangement (such as when building with the win64 build tree). All of the environment variables and cross-compiler arguments described in the debian and Ubuntu section above are defined for you in openSUSE by the use of mingw32-configure and mingw32-make, with the exception of:
'' LINKCFG="--enable-static --disable-shared"''
You must supply LINKCFG when needed.
If you would like to examine the mingw32 variables and cross-compiler arguments for yourself, use:
$ rpm --eval "%_mingw32_configure" $ rpm --eval "%_mingw32_make"
Ensure the following list of pre-built packages are installed from the MinGW repository:
mingw32-zlib mingw32-zlib-devel mingw32-libpng mingw32-libpng-devel mingw32-libsndfile mingw32-libsndfile-devel mingw32-libsamplerate mingw32-libsamplerate-devel mingw32-pthreads mingw32-pthreads-devel mingw32-portaudio mingw32-portaudio-devel mingw32-libtool mingw32-libltdl mingw32-cross-nsis
Then skip ahead to building hamlib, xmlrpc-c and FLTK.
Obtain the latest release of zlib and extract it in $SRC. Build and install with:
''$ CC=$CC AR=$AR RANLIB=$RANLIB ./configure --prefix=$PREFIX/zlib --static''
''$ make && make install''
Create libz.a symlink:
''$ ln -s $PREFIX/zlib/lib/libz.a $PREFIX/lib/libz.a''
Create zlib-devel includes directory:
$ mkdir $PREFIX/zlib/include $ cp -p zconf.h $PREFIX/zlib/include $ cp -p zlib.h $PREFIX/zlib/include
Obtain the latest release of libpng and extract it in $SRC (You will need to have already built and installed zlib).
Build and install with:
$ ./configure --prefix=$PREFIX/png $CROSSCFG $LINKCFG \ CPPFLAGS=-I${PREFIX}/zlib/include LDFLAGS=-L${PREFIX}/zlib/lib $PKGCFG $ make && make install
Create pkg-config symlinks:
$ cd $PREFIX/lib/pkgconfig $ ln -s $PREFIX/png/lib/pkgconfig/libpng15.pc . $ ln -s ./libpng15.pc libpng.pc
Obtain the latest libsndfile release and extract it in $SRC. Build and install with:
$ ./configure --prefix=$PREFIX/sndfile $CROSSCFG $LINKCFG $PKGCFG $ make && rm -f tests/*dll $ make install
Create pkg-config symlinks:
''(cd $PREFIX/lib/pkgconfig; ln -s ../../sndfile/lib/pkgconfig/* .)''
Obtain the latest libsamplerate release and extract it in $SRC. Build and install with:
$ ./configure --prefix=$PREFIX/samplerate $CROSSCFG --disable-fftw --disable-sndfile $LINKCFG $ make && make install
Create pkg-config symlinks:
''(cd $PREFIX/lib/pkgconfig; ln -s ../../samplerate/lib/pkgconfig/* .)''
Download the latest release of pthreads-win32 and extract it in $SRC. Build and install it with:
$ make CROSS=i586-mingw32msvc- clean GC-inlined $ mkdir -p $PREFIX/ptw32/include $PREFIX/ptw32/lib $ cp pthread.h sched.h semaphore.h $PREFIX/ptw32/include $ cp libpthreadGC2.a pthreadGC2.dll $PREFIX/ptw32/lib
If building on debian 6.0.1 with MinGW 4.4.4, the cross-compiler seems to be missing pthread.h and the libpthread.a library, which will cause configure not to find pthreads for hamlib and fldigi itself. Build and install with:
$ make CROSS=i586-mingw32msvc- clean GC-inlined $ cp -p pthread.h sched.h semaphore.h $PREFIX/include $ cp -p libpthreadGC2.a pthreadGC2.dll $PREFIX/lib $ ln -s $PREFIX/lib/libpthreadGC2.a $PREFIX/lib/libpthread.a
Install the newly built pthreads library where the cross-compiler will find them:
$ sudo ln -s $PREFIX/include/pthread.h /usr/i586-mingw32msvc/include/pthread.h $ sudo ln -s $PREFIX/include/sched.h /usr/i586-mingw32msvc/include/sched.h $ sudo ln -s $PREFIX/include/semaphore.h /usr/i586-mingw32msvc/include/semaphore.h $ sudo ln -s $PREFIX/lib/libpthreadGC2.a /usr/i586-mingw32msvc/lib/libpthread.a $ sudo ln -s /usr/i586-mingw32msvc/lib/libpthread.a /usr/i586-mingw32msvc/lib/libpthreadGC2.a
and create the package configuration data for the pthreads library installed in $PREFIX:
$ cat << _EOF > $PREFIX/lib/pkgconfig/pthreadGC2.pc prefix=/usr/local/win32 exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: pthreadGC2 Description: Library to interface with win32 threads model Requires: Version: 2.8.0 Libs: -L${libdir} -lpthreadGC2 Cflags: -I${includedir} _EOF $ ln -s $PREFIX/lib/pkgconfig/pthreadGC2.pc $PREFIX/lib/pkgconfig/pthread.pc
Obtain the latest PortAudio "v19" trunk snapshot and extract it in $SRC.
If you wish to build PortAudio with support for multiple host APIs (WMME and DirectSound are recommended), you will need to apply mingw-portaudio.patch. This patch has been submitted upstream (2009-11-01) and may be included in the snapshot by the time you read this. For DirectSound support you will need to obtain the dsound.h header from the latest stable version of Wine and apply mingw-dsound.patch.
Create $PREFIX/directx/include and copy your patched dsound.h there.
Build and install with:
$ ./configure --prefix=$PREFIX/portaudio $CROSSCFG $LINKCFG --with-winapi=wmme,directx \ --with-dxdir=$PREFIX/directx $ make && make install
Omit the --with-winapi and --with-dxdir switches if you only want WMME, in which case you don't need dsound.h or the aforementioned patches.
Including the DirectSound switches does not work with debian 6.0.1, Wine + libwine-dev 1.0.1-3.1 and pa_snapshot from April 2011, so omit the winapi and dxdir switches until further notice.
Create pkg-config symlinks:
''(cd $PREFIX/lib/pkgconfig; ln -s ../../portaudio/lib/pkgconfig/* .)''
Obtain the latest release of libtool and extract it in $SRC.
If you care to build a library identical to the non-cross-compiler library, download both the orig.tar.gz and debian.tar.gz files from http://packages.debian.org/sid/libltdl-dev. Extract the orig.tar.gz file in $SRC then move into the $SRC/libtool-2.4 directory and issue:
$ tar xzvf libtool-2.4-2.debian.tar.gz $ for i in `ls debian/patches/*.patch`; do patch -p1 < $i done $ autoconf
Build and install with:
$ ./configure --prefix=$PREFIX/libtool $CROSSCFG $LINKCFG $ make && make install Create pkg-config and lib symlinks:
$ ln -s $PREFIX/libtool/include/ $PREFIX/include
$ ln -s $PREFIX/libtool/lib/ $PREFIX/lib
### hamlib Obtain the latest release of hamlib and extract it in $SRC. Build and install with:
$ ./configure --prefix=$PREFIX/hamlib $CROSSCFG $LINKCFG \
--without-rigmatrix --without-rpc-backends --without-winradio --without-gnuradio --without-usrp \
--without-cxx-binding --without-perl-binding --without-tcl-binding --without-python-binding
$ make && make install
**a. If building on debian 6.0.1 with MinGW 4.4.4.** You must build and install the libtool package (the cross-compiler seems to be missing libtool, which will cause configure to terminate). Prepare to build with:
$ sudo ln -s $PREFIX/libtool/include/ltdl.h /usr/i586-mingw32msvc/include/ltdl.h
$ sudo ln -s $PREFIX/libtool/include/libltdl /usr/i586-mingw32msvc/include/libltdl
$ sudo ln -s $PREFIX/libtool/lib/libltdl.a /usr/i586-mingw32msvc/lib/libltdl.a
Apply a one-line patch to lib/w32termios.h to prevent an incompatible redefinition of usleep():
*** lib/win32termios.h.orig 2011-03-12 09:57:08.000000000 -0500 --- lib/win32termios.h 2011-04-08 22:58:17.917938701 -0400 *************** *** 139,145 **** void termios_interrupt_event_loop( int , int ); void termios_setflags( int , int[] ); struct termios_list *find_port( int ); ! int usleep(unsigned int usec); int fcntl(int fd, int command, ...); const char *get_dos_port(const char *); void set_errno(int); --- 139,145 ---- void termios_interrupt_event_loop( int , int ); void termios_setflags( int , int[] ); struct termios_list *find_port( int ); ! //int usleep(unsigned int usec); int fcntl(int fd, int command, ...); const char *get_dos_port(const char *); void set_errno(int);
Apply a three-line patch to include/config.h.in to prevent a redefinition of sleep() (due to pthread.h itself including config.h):
*** include/config.h.in.orig 2011-04-08 22:54:32.634257118 -0400 --- include/config.h.in 2011-04-11 15:54:44.912874571 -0400 *************** *** 384,395 **** --- 384,398 ---- #if defined(HAVE_SSLEEP) && !defined(HAVE_SLEEP) #ifdef HAVE_WINBASE_H #include <windows.h> #include <winbase.h> #endif + #if !defined(DEFINED_SLEEP) /* TODO: what about SleepEx? */ static inline unsigned int sleep (unsigned int nb_sec) { Sleep(nb_sec*1000); return 0; } + #define DEFINED_SLEEP 1 + #endif #endif #ifndef HAVE_GETTIMEOFDAY #ifdef HAVE_SYS_TIME_H #include <sys/time.h>
And finally build and install with:
$ ./configure --prefix=$PREFIX/hamlib $CROSSCFG $LINKCFG \
--without-rigmatrix --without-rpc-backends --without-winradio --without-usrp \
--without-cxx-binding --without-perl-binding --without-python-binding
$ make && make install
$ make install-pkgconfigDATA
In the latest hamlib, there is no gnuradio and without-tcl-binding is the default. The build will terminate when it attempts to compile rigctrl.exe with shared libraries. This can be ignored since all of the libraries are complete at that point although the pkgconfig script hamlib.pc must be installed with a manually applied "make target". **b. If building on openSUSE:**
$ mingw32-configure --disable-shared --enable-static --without-rigmatrix \
--without-rpc-backends --without-winradio --without-usrp --without-cxx-binding \
--without-perl-binding --without-python-binding
Apply a one-line patch to include/config.h (getaddrinfo() exists in -lws2_32 and is defined in ws2tcpip.h):
*** include/config.h.orig 2011-04-26 20:41:49.000000000 -0400 --- include/config.h 2011-04-26 21:21:57.000000000 -0400 *************** *** 61,66 **** --- 61,67 ---- /* Define to 1 if you have the `getaddrinfo' function. */ /* #undef HAVE_GETADDRINFO */ + #define HAVE_GETADDRINFO 1 /* Define to 1 if you have the `getopt' function. */ #define HAVE_GETOPT 1
And finally build and install with:
$ mingw32-make && sudo mingw32-make install
$ sudo mingw32-make install-pkgconfigDATA
Then skip step 3. Create pkg-config symlinks: ''(cd $PREFIX/lib/pkgconfig; ln -s ../../hamlib/lib/pkgconfig/* .)'' ## xmlrpc-c ## Obtain the latest stable snapshot of xmlrpc-c and extract it in $SRC. Apply mingw-xmlrpc-c.patch and run autoconf. This is done by moving into the $SRC/xmlrpc-c-1.x.y directory and issuing:
$ patch -p1 < ../mingw-xmlrpc-c.patch
$ autoconf
Part of the patch may have already been incorporated into xmlrpc-c. Use the default "[n]" response to any query from patch.
Build and install with:
$ AR=$AR RANLIB=$RANLIB ./configure --prefix=$PREFIX/xmlrpc $CROSSCFG \ --disable-wininet-client --disable-curl-client --disable-libwww-client $ make BUILDTOOL_CC=gcc BUILDTOOL_CCLD=gcc CFLAGS_PERSONAL=-U_UNIX $ make install
If building on openSUSE:
$ mingw32-configure --disable-wininet-client --disable-curl-client \ --disable-libwww-client $ mingw32-make BUILDTOOL_CC=gcc BUILDTOOL_CCLD=gcc CFLAGS_PERSONAL=-U_UNIX $ sudo mingw32-make install
Then skip step 3.
Create xmlrpc-c-config symlink:
''$ ln -s ../xmlrpc/bin/xmlrpc-c-config $PREFIX/bin''
Obtain the latest release of FLTK 1.3.x (1.3.3 or later) and extract it in $SRC.
Apply mingw-fltk.patch to force MinGW compilation and avoid building the demos, and run autoconf.
This is done by moving into the $SRC/fltk-1.1.x directory and issuing
$ patch -p1 < ../mingw-fltk.patch $ autoconf
Build and install with:
$ ./configure --prefix=$PREFIX/fltk $CROSSCFG $LINKCFG --enable-threads $ make && make install
The latest MinGW uses gcc-4 which no longer supports -mno-cygwin.
The FLTK configure.in assumes both Cygwin and MinGW need -mno-cygwin. If FLTK is configured with enable-cygwin, the assumption is a native build environment instead. Since the latest mingw32-gcc is a full cross-compiler, the MinGW build environment is a native environment (in this case Windows instead of Cygwin).
The FLTK 1.3.x source includes a local copy of libpng 1.2.40 and is coded to use the libpng 1.2.x API. The latest MinGW provides libpng 1.5.2 whose API is incompatible with libpng 1.2.x. Until FLTK 1.1.x is updated to reflect the libpng 1.5.x API changes, use the older local copy of libpng.
If building on openSUSE:
$ mingw32-configure --disable-shared --enable-threads --enable-cygwin --enable-localpng
$ mingw32-make && sudo mingw32-make install
Then skip step 4.
Create the fltk-config symlink:
''$ ln -s ../fltk/bin/fltk-config $PREFIX/bin''
For the most recent debian (6.0.1 or later) and openSUSE, this package is included in mingw32. Skip building this library.
Download the latest release of the GNU binutils and extract it in $SRC. Change to the bfd subdirectory.
Build and install with:
$ ./configure --prefix=$PREFIX/bfd $CROSSCFG $LINKCFG --disable-nls $ make && make install
Get the fldigi source as described in the Debian build instructions.
Refer to the Debian build instructions for some general information about running configure. For MinGW you will need some additional flags:
Normal "release" binaries:
./configure $CROSSCFG --disable-nls --with-ptw32=$PREFIX/ptw32 $PKGCFG \ FLTK_CONFIG=$PREFIX/bin/fltk-config XMLRPC_C_CONFIG=$PREFIX/bin/xmlrpc-c-config
For Debug binaries:
./configure $CROSSCFG --disable-nls --enable-debug --with-ptw32=$PREFIX/ptw32 \ --with-bfd=$PREFIX/bfd $PKGCFG FLTK_CONFIG=$PREFIX/bin/fltk-config \ XMLRPC_C_CONFIG=$PREFIX/bin/xmlrpc-c-config
Prepare the MinGW libraries for static linking (as root):
$ cd /usr/i686-w64-mingw32/sys-root/mingw/lib
$ ln -s ./libjpeg.dll.a libjpeg.a
$ ln -s ./libportaudio.dll.a libportaudio.a
$ ln -s ./libpng15.dll.a libpng15.a
$ ln -s ./libsndfile.dll.a libsndfile.a
$ ln -s ./libsamplerate.dll.a libsamplerate.a
$ ln -s ./libz.dll.a libz.a
$ ln -s ./libltdl.dll.a libltdl.a
Normal binaries (there is currently an issue with xmlrpc-c, so disable it for now):
$ mingw32-configure --enable-static --disable-nls \ GNU1FLAGS="-Wl,-Bstatic" --without-xmlrpc
Debug binaries:
$ mingw32-configure --enable-static --enable-debug --disable-nls \ GNU1FLAGS="-Wl,-Bstatic" --without-xmlrpc
Instead of the traditional make install you will likely want to create an executable installer for the newly created binaries. The source tree contains a script that can do this. To use it you will need to install NSIS (packaged as nsis on Debian and Ubuntu) and run:
''$ make nsisinst''
There are no dll dependencies for fldigi.exe or any of the other flxxx applications. The executable is completely self contained.
Wiki: Compile Windows binary using Windows Subsystem for Linux (WSL)
Wiki: build_howto
Wiki: setupmxe_howto