User Tools

Site Tools


howto:building_on_mingw_windows_target

Building on MinGW

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.

Build dependencies

debian and Ubuntu

The developers maintain their debian and Ubuntu win32 build tree as follows:

  Source trees are kept in separate directories under /usr/local/src/win32
  Binaries are installed in separate directories under /usr/local/win32
  Symbolic links are made in /usr/local/win32/bin and /usr/local/win32/lib/pkgconfig
  A PKG_CONFIG argument is passed to the configure scripts of libraries that require pkg-config 

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.

#!/bin/sh

PREFIX=/usr/local/win32
export PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH_MINGW32MSVC

exec pkg-config "$@"

openSUSE

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>/

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.

Libraries and Packages

zlib

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

libpng

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

sndfile

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/* .)

samplerate

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/* .)

pthreads-win32

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

PortAudio

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/* .)

libtool

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:
<code>
$ 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:
<code>
$ 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

FLTK

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

libbfd

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

Getting the source

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

openSUSE

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

Creating an installer

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.

howto/building_on_mingw_windows_target.txt · Last modified: 2017/10/11 10:35 by admin