Build a cross compiler from linux to windows (mingw)

It is not too difficult to find mingw cross compiler to produce windows binaries from linux, except that it does not include the fortran part (g77, or gfortran for 4.*). Here is a relatively simple script which can build gcc, g77 (and other compilers as well, I guess: the difficult part is to build the bootstrap gcc + system headers/libs; once you get this right, all the other parts are much easier).

The script has the following characteristics:

  1. It needs the tarballs in the archives directory
  2. It will build everything in the build directory
  3. It will install everything in the install directory
  4. By default, the above directories are created in the directory of the script
  5. It does not build gcc in the sources, but in separate build directories, which is the advised way to do it

It is not too difficult to do it by hand once you know exactly what to do. The basic scheme is the following:

  1. Build the binutils with target mingw32 and install it in $PREFIX (e.g. –prefix=$PREFIX –target=mingw32).
  2. Add $PREFIX in your path.
  3. Copy the include path content of both w32api and mingw32-runtime in $PREFIX/mingw32/include
  4. Create an empty build directory for the bootstrap gcc, and inside it, build a minimal gcc (e.g. –enable-languages=c) with the same options than binutils for target and prefix.
  5. The tricky part: once the bootstrapped gcc is built, go back into w32api directory, and configure it with *host* as mingw32 and prefix as $PREFIX/mingw32: configure –prefix=$PREFIX/mingw32 –host=mingw32. Build and install it
  6. In the parent directory of w32api build directory, make a soft link from the w32api build directory and w32api (e.g. ln -s w32api-3.11 w32api). I think that this is a bug, but wo doing this, mingw32 won’t pick up the w32api headers (it does not look in $PREFIX/target/include).
  7. Make sure that the extracted archive of mingw runtime is in the parent directory of w32api
  8. configure, build and install mingw runtime the exact same way as w32api (same host, same prefix)
  9. now, you can build the final gcc, g77, etc… by just using –target=mingw32.

I managed to build both gcc 3.* and 4.* series for C and fortran using the sources provided on mingw website. I have not extensively tested the built compilers, but I managed to compile non trivial programs with both g77 and gfortran (blas, lapack). The only thing not working properly is dlltool, to produce the .lib from the dll: using the import library with visual studio will crash, but this does not seem to work with mingw32 on windows either (e.g. this is a bug in mingw).

    Advertisements

    5 thoughts on “Build a cross compiler from linux to windows (mingw)

    1. Can you please post the script that I have to use to build gfortran cross-compiler to compile fortran sources for windows using linux?

      • Since then, I converted the bash script to a make file, for better portability. See here: http://github.com/cournape/cross-mingw-w64/tree/master

        Makefile.w64 builds a cross toolchain, and Makefile.w64.native a native toolchain. It expects the sources to be in $CWD/archives directory, build everything in a build directory $CWD/build, and install things in $CWD/install. It has been used successfully on both linux and mac os x.

    2. I’ve download all the latest archives and I’ve simply modified the makefile.mingw32 script to bind the new version of the various libraries.
      make -f makefile.mingw32 shows me this error.
      Do you have any idea?
      Thank you!

      (cd /var/tmp/mingw32/build/mingwrt-3.15.2-mingw32 && make -j2)
      make[1]: Entering directory `/var/tmp/mingw32/build/mingwrt-3.15.2-mingw32′
      gcc -c -D__CRTDLL__ -U__MSVCRT__ -g -O2 -I/var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/include -I/var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/../include -nostdinc -iwithprefixbefore include -I /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/../w32api/include /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/crt1.c -o crt1.o
      gcc -c -D__CRTDLL__ -U__MSVCRT__ -g -O2 -I/var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/include -I/var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/../include -nostdinc -iwithprefixbefore include -I /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/../w32api/include /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/dllcrt1.c -o dllcrt1.o
      /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/dllcrt1.c:15:21: error: windows.h: Nessun file o directory
      /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/dllcrt1.c:37: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘WINAPI’
      /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/dllcrt1.c:41: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘WINAPI’
      make[1]: *** [dllcrt1.o] Error 1
      make[1]: *** Waiting for unfinished jobs….
      /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/crt1.c:21:21: error: windows.h: Nessun file o directory
      /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/crt1.c:102: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘long’
      /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/crt1.c: In function ‘__mingw_CRTStartup’:
      /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/crt1.c:195: error: ‘_gnu_exception_handler’ undeclared (first use in this function)
      /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/crt1.c:195: error: (Each undeclared identifier is reported only once
      /var/tmp/mingw32/archives/mingwrt-3.15.2-mingw32/crt1.c:195: error: for each function it appears in.)
      make[1]: *** [crt1.o] Error 1
      make[1]: Leaving directory `/var/tmp/mingw32/build/mingwrt-3.15.2-mingw32′
      make: *** [/var/tmp/mingw32/build/mingwrt-3.15.2-mingw32/build.done] Error 2

    3. hi

      my team are currently working on cross compilation to create an executable program of minisip from linux to windows using i586-mingw32msvc-gcc,what the problem here is that the created .exe is not working with wine. here is the sample script that we using to build the .exe

      #! /usr/bin/env bash
      #
      #This scripts is a modified version of the buildall.script.
      #Thi script compiles and install all the minisip libraries and GTK GUI
      # for a win32 system.
      #Modify the parameters (basically the prefix_*) to adapt to your cross-compile environment.
      #It is not really good if you are developing or debugging, as everytime you run the script it
      # recompiles ALL the source code.
      #This options are added for the w32 compilation … modify if needed, specially the cross-compile folder
      #This is the CROSS_COMPILE_FOLDER
      prefix_cross=”/usr/local/cross”
      prefix_cross_include=”$prefix_cross/include”
      prefix_cross_lib=”$prefix_cross/lib”
      host_type_name=”i586-mingw32msvc”
      host_option=”–host=$host_type_name”
      build_option=”–build=i686-pc-linux-gnu”
      strip_bin=”i586-mingw32msvc-strip”
      #strip_generated_files=”yes”
      # Simple script to build minisip.
      #
      # This script needs to be executed at the root of the repository trunk. It
      # will build minisip and with all the associated libraries. The build will be
      # done “in place”, that is, no files will be installed on your system.
      #
      # Instructions:
      # Use buildall.sh script the first time you get the sources of minisip. It will
      # create all files needed and compile all the sources.
      # Then, if you modify a file in the sources and do not want to recompile all
      # MiniSIP again, use the “buildonly.sh” script
      # Note that you con modify the configuration of minisip by editing the
      # configure_params variable in this script. Some useful options are commented
      # out by default, but feel free to use them.
      SUBDIRS=”${SUBDIRS} libmutil”
      SUBDIRS=”${SUBDIRS} libmnetutil”
      SUBDIRS=”${SUBDIRS} libmcrypto”
      SUBDIRS=”${SUBDIRS} libmikey”
      SUBDIRS=”${SUBDIRS} libmstun”
      SUBDIRS=”${SUBDIRS} libmsip”
      SUBDIRS=”${SUBDIRS} libzrtpcpp”
      SUBDIRS=”${SUBDIRS} libminisip”
      SUBDIRS=”${SUBDIRS} minisip”
      #If you are debugging, you probably want to build with “g++ -g”, to build
      #with all debug symbols, useful for coredumps with gdb.
      #Comment this line if you don’t want to build with debug code
      compiler_debug=”-ggdb”
      #Also useful, you may want to call make with some options … supply them
      #here.
      #For example, -k forces make to keep compiling even there are errors in the
      # sources. I like this one.
      make_options=”-k”
      #Possible configure commands are shown in: ./configure –help
      # check each folder for more details.
      #This are common params, usable in all folders
      base_configure_params=””
      base_configure_params=”$base_configure_params –enable-debug”
      base_configure_params=”$base_configure_params –disable-static”
      #base_configure_params=”$base_configure_params –disable-shared”
      #set special options for libmutil
      libmutil_configure_params=””
      libmutil_configure_params=”$libmutil_configure_params –enable-memdebug”
      #set special options for libminisip
      # do a ./configure –help to see ALL available options … here
      # show just a sample
      libminisip_configure_params=””
      libminisip_configure_params=”$libminisip_configure_params –enable-dsound”
      libminisip_configure_params=”$libminisip_configure_params –disable-alsa”
      libminisip_configure_params=”$libminisip_configure_params –disable-gconf”
      #–enable-autocall enables automatic calling for debug purposes (default disabled)
      #–enable-ipaq enables various fixes for the iPAQ (default disabled)
      #–enable-ipsec-enable enables ipsec features (default disabled)
      #–enable-aec enables push-2-talk features (default enabled)
      #–enable-video enables video features (default disabled)
      #–enable-buzzer enables IPAQ buzzer (default disabled)
      #–enable-dsound enables DirectSound sound support (default disabled)
      #–enable-portaudio enable PortAudio V19 support (default auto).
      #–enable-gconf enables support for GConf (default enabled).
      #–enable-sdl enables SDL video output if the required library is found
      #–enable-video enables video features (default disabled)
      #set special options for minisip
      # do a ./configure –help to see ALL available options … here
      # show just a sample
      minisip_configure_params=””
      minisip_configure_params=”$minisip_configure_params –enable-gtk”
      minisip_configure_params=”$minisip_configure_params –disable-shared”
      #minisip_configure_params=”$minisip_configure_params –enable-textui”
      #Here you could have per gui-specific parameters …
      for subdir in ${SUBDIRS}
      do
      echo “+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++”
      echo “Building ${subdir} … ”
      echo “+++++++++++++++++++++++++++++++++++++”
      cd ${subdir}
      ./bootstrap
      configure_params=”$base_configure_params”
      if [ ${subdir} = “libmutil” ]; then
      LOC_MUTIL_LIBS=-L$PWD/.libs
      #${subdir}.$LIBS_EXTENSION
      LOC_MUTIL_CFLAGS=-I$PWD/include
      echo libmutil can use special params
      configure_params=”$configure_params $libmutil_configure_params”
      MUTIL_LIBS=”$LOC_MUTIL_LIBS -lmutil” \
      MUTIL_CFLAGS=$LOC_MUTIL_CFLAGS \
      CPPFLAGS=”-I$prefix_cross_include ” \
      CXXFLAGS=”-Wall $compiler_debug” \
      LDFLAGS=”-L$prefix_cross_lib” \
      ./configure $host_option $build_option prefix=$prefix_cross $configure_params
      fi
      if [ ${subdir} = “libmnetutil” ]; then
      LOC_MNETUTIL_LIBS=-L$PWD/.libs
      LOC_MNETUTIL_CFLAGS=-I$PWD/include
      MUTIL_LIBS=”$LOC_MUTIL_LIBS -lmutil” \
      MUTIL_CFLAGS=$LOC_MUTIL_CFLAGS \
      CPPFLAGS=”-I$prefix_cross_include ” \
      CXXFLAGS=”-Wall $compiler_debug” \
      LDFLAGS=”-L$prefix_cross_lib” \
      ./configure $host_option $build_option prefix=$prefix_cross $configure_params
      fi
      if [ ${subdir} = “libmcrypto” ]; then
      LOC_MCRYPTO_LIBS=-L$PWD/.libs
      LOC_MCRYPTO_CFLAGS=-I$PWD/include
      MUTIL_LIBS=”$LOC_MUTIL_LIBS -lmutil” \
      MUTIL_CFLAGS=$LOC_MUTIL_CFLAGS \
      CPPFLAGS=”-I$prefix_cross_include ” \
      CXXFLAGS=”-Wall $compiler_debug” \
      LDFLAGS=”-L$prefix_cross_lib” \
      ./configure $host_option $build_option prefix=$prefix_cross $configure_params
      fi
      if [ ${subdir} = “libmikey” ]; then
      LOC_MIKEY_LIBS=-L$PWD/.libs
      LOC_MIKEY_CFLAGS=-I$PWD/include
      MUTIL_LIBS=”$LOC_MUTIL_LIBS -lmutil” \
      MUTIL_CFLAGS=$LOC_MUTIL_CFLAGS \
      MNETUTIL_LIBS=”$LOC_MNETUTIL_LIBS -lmnetutil” \
      MNETUTIL_CFLAGS=$LOC_MNETUTIL_CFLAGS \
      CPPFLAGS=”-I$prefix_cross_include ” \
      CXXFLAGS=”-Wall $compiler_debug” \
      LDFLAGS=”-L$prefix_cross_lib” \
      ./configure $host_option $build_option prefix=$prefix_cross $configure_params
      fi
      if [ ${subdir} = “libmstun” ]; then
      LOC_MSTUN_LIBS=-L$PWD/.libs
      LOC_MSTUN_CFLAGS=-I$PWD/include
      MUTIL_LIBS=”$LOC_MUTIL_LIBS -lmutil” \
      MUTIL_CFLAGS=$LOC_MUTIL_CFLAGS \
      MNETUTIL_LIBS=”$LOC_MNETUTIL_LIBS -lmnetutil” \
      MNETUTIL_CFLAGS=$LOC_MNETUTIL_CFLAGS \
      CPPFLAGS=”-I$prefix_cross_include ” \
      CXXFLAGS=”-Wall $compiler_debug” \
      LDFLAGS=”-L$prefix_cross_lib” \
      ./configure $host_option $build_option prefix=$prefix_cross $configure_params
      fi
      if [ ${subdir} = “libmsip” ]; then
      LOC_MSIP_LIBS=-L$PWD/.libs
      LOC_MSIP_CFLAGS=-I$PWD/include
      MUTIL_LIBS=”$LOC_MUTIL_LIBS -lmutil” \
      MUTIL_CFLAGS=$LOC_MUTIL_CFLAGS \
      MNETUTIL_LIBS=”$LOC_MNETUTIL_LIBS -lmnetutil” \
      MNETUTIL_CFLAGS=$LOC_MNETUTIL_CFLAGS \
      CPPFLAGS=”-I$prefix_cross_include ” \
      CXXFLAGS=”-Wall $compiler_debug” \
      LDFLAGS=”-L$prefix_cross_lib” \
      ./configure $host_option $build_option prefix=$prefix_cross $configure_params
      fi
      if [ ${subdir} = “libzrtpcpp” ]; then
      LOC_ZRTPCPP_LIBS=-L$PWD/.libs
      LOC_ZRTPCPP_CFLAGS=-I$PWD/include
      MUTIL_LIBS=”$LOC_MUTIL_LIBS -lmutil” \
      MUTIL_CFLAGS=$LOC_MUTIL_CFLAGS \
      MNETUTIL_LIBS=”$LOC_MNETUTIL_LIBS -lmnetutil” \
      MNETUTIL_CFLAGS=$LOC_MNETUTIL_CFLAGS \
      CPPFLAGS=”-I$prefix_cross_include ” \
      CXXFLAGS=”-Wall $compiler_debug” \
      LDFLAGS=”-L$prefix_cross_lib” \
      ./configure $host_option $build_option prefix=$prefix_cross $configure_params
      fi
      if [ ${subdir} = “libminisip” ] ; then
      LOC_LIBMINISIP_LIBS=-L$PWD/.libs
      LOC_LIBMINISIP_CFLAGS=-I$PWD/include
      configure_params_libminisip=”$configure_params $libminisip_configure_params”
      echo libminisip can also have special config params
      configure_params=”$configure_params $minisip_configure_params”
      MUTIL_LIBS=”$LOC_MUTIL_LIBS -lmutil” \
      MUTIL_CFLAGS=$LOC_MUTIL_CFLAGS \
      MNETUTIL_LIBS=”$LOC_MNETUTIL_LIBS -lmnetutil” \
      MNETUTIL_CFLAGS=$LOC_MNETUTIL_CFLAGS \
      MIKEY_LIBS=”$LOC_MIKEY_LIBS -lmikey” \
      MIKEY_CFLAGS=$LOC_MIKEY_CFLAGS \
      MSIP_LIBS=”$LOC_MSIP_LIBS -lmsip” \
      MSIP_CFLAGS=$LOC_MSIP_CFLAGS \
      CPPFLAGS=”-I$prefix_cross_include ” \
      CXXFLAGS=”-Wall $compiler_debug” \
      LDFLAGS=”-L$prefix_cross_lib” \
      ./configure $host_option $build_option prefix=$prefix_cross $configure_params_libminisip
      fi
      if [ ${subdir} = “minisip” ]; then
      echo minisip can also have special config params
      configure_params_minisip=”$configure_params $minisip_configure_params”
      MUTIL_LIBS=”$LOC_MUTIL_LIBS -lmutil” \
      MUTIL_CFLAGS=$LOC_MUTIL_CFLAGS \
      MNETUTIL_LIBS=”$LOC_MNETUTIL_LIBS -lmnetutil” \
      MNETUTIL_CFLAGS=$LOC_MNETUTIL_CFLAGS \
      MIKEY_LIBS=”$LOC_MIKEY_LIBS -lmikey” \
      MIKEY_CFLAGS=$LOC_MIKEY_CFLAGS \
      MSIP_LIBS=”$LOC_MSIP_LIBS -lmsip” \
      MSIP_CFLAGS=$LOC_MSIP_CFLAGS \
      LIBMINISIP_LIBS=”$LOC_LIBMINISIP_LIBS -lminisip” \
      LIBMINISIP_CFLAGS=$LOC_LIBMINISIP_CFLAGS \
      CPPFLAGS=”-I$prefix_cross_include ” \
      CXXFLAGS=”-Wall $compiler_debug” \
      LDFLAGS=”-L$prefix_cross_lib” \
      ./configure $host_option $build_option prefix=$prefix_cross $configure_params_minisip
      fi
      echo “==========================================================”
      echo “configure_params (${subdir})= $configure_params”
      echo “==========================================================”
      make clean
      make
      make install
      export PKG_CONFIG_PATH=$prefix_cross/lib/pkgconfig/
      echo $prefix_cross/share/aclocal >> /usr/share/aclocal/dirlist
      echo $prefix_cross/share/aclocal >> /usr/local/share/aclocal/dirlist
      cd ..
      done
      mkdir -p compiled_files
      mkdir -p compiled_files/bin
      mkdir -p compiled_files/lib
      mkdir -p compiled_files/share
      mkdir -p compiled_files/share/minisip
      mkdir -p compiled_files/lib/libminisip
      mkdir -p compiled_files/lib/libminisip/plugins
      tmp_lib=”libmutil”
      cp -f $tmp_lib/.libs/$tmp_lib-0.dll compiled_files/bin
      tmp_lib=”libmnetutil”
      cp -f $tmp_lib/.libs/$tmp_lib-0.dll compiled_files/bin
      tmp_lib=”libmcrypto”
      cp -f $tmp_lib/.libs/$tmp_lib-0.dll compiled_files/bin
      tmp_lib=”libmikey”
      cp -f $tmp_lib/.libs/$tmp_lib-0.dll compiled_files/bin
      tmp_lib=”libzrtpcpp”
      cp -f $tmp_lib/.libs/$tmp_lib-0.dll compiled_files/bin
      tmp_lib=”libmsip”
      cp -f $tmp_lib/.libs/$tmp_lib-0.dll compiled_files/bin
      tmp_lib=”libmstun”
      cp -f $tmp_lib/.libs/$tmp_lib-0.dll compiled_files/bin
      tmp_lib=”libminisip”
      cp -f $tmp_lib/.libs/$tmp_lib-0.dll compiled_files/bin
      cp -f $tmp_lib/.libs/mdsound.dll compiled_files/lib/libminisip/plugins
      cp -f $tmp_lib/.libs/mdsound.la compiled_files/lib/libminisip/plugins
      cp -f minisip/minisip/gui/gtkgui/minisip_gtkgui.exe compiled_files/bin
      cp -f $prefix_cross/lib/libcrypto.dll compiled_files/bin/libeay32.dll
      cp -f $prefix_cross/lib/libssl.dll compiled_files/bin/ssleay32.dll
      cp -f $prefix_cross/share/minisip/* compiled_files/share/minisip
      find minisip/ -name minisip_gtkgui.exe -size +200k -exec cp -f {} compilied_files/ \;
      echo 3
      #find minisip/ -name minisip_textui.exe -size +200k -exec cp -f {} compilied_files/ \;
      $strip_bin -R compiled_files/*

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s