#!/bin/bash # Compiling SWI-Prolog using MinGW # -------------------------------- # # This file provides an overview for building SWI-Prolog using MinGW, in # particular using the cross-compilers that are distributed with most # todays Linux distributions. This work is mostly done by Roberto # Bagnara (initial port of the Prolog kernel), Abramo Bagnara and Keri # Harris. # # The current releases are configured and build using CMake. As a # result, this README only applies for building the PREREQUISITES. See # CMAKE.md and/or scripts/make-distribution for configuring and building # SWI-Prolog. # # USE DOCKER INSTEAD # # These instructions are only required if you want to build in your # local (Linux) environment. We have created a Docker image for doing # the build which is a lot easier to manage. See: # # https://github.com/SWI-Prolog/docker-swipl-build-mingw.git # # USAGE # # You have been warned! Make sure to have a lot of time and coffee # before proceeding. # # The remainder of the file is an executable specification of the # installation process. The setup is designed to create ~/mingw32 and/or # ~/mingw64 for building and installing the prerequisites. We describe # the setup for Win64. Simply replace 64 with 32 to build for 32-bit # Windows. First, install the requires tools from the Linux packages: # # % sudo apt-get install wine wine-binfmt mingw-w64 # % sudo apt-get install cmake ninja-build nsis # # Next, create and prepare the prerequisite location (the script changes # your prompt to `W64` # # % cd ~ # % mkdir -p mingw64/src # % cd mingw64/src # % source `` to extract the archive. # # Once all is there, get the MinGW runtime libs in `bin`. The details # may depend on exact versions of MinGW, so please check. # # % mkdir -p ~/mingw64/bin # % cd ~/mingw64/bin # % cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll . # % cp /usr/lib/gcc/x86_64-w64-mingw32/9.2-win32/libgcc_s_seh-1.dll . # # Now, build the prerequisites: # # W64 build_prerequisites # # If this worked successfully, build SWI-Prolog. Below is the default # command, see CMAKE.md for various options: # # % cd /path/to/swipl-devel # % mkdir build.win64 # % cd build.win64 # % cmake -DCMAKE_BUILD_TYPE=Release \ # -DCMAKE_TOOLCHAIN_FILE=../cmake/cross/linux_win64.cmake \ # -DJAVA_COMPATIBILITY=ON \ # -G Ninja .. # % ninja # # If this succeeds you should be able to run `./src/swipl-win.exe` or # `./src/swipl.exe` # # To build an installer for installation on other systems, run # # % cpack # # # PREREQUISITES # # The open source libraries on which SWI-Prolog depends are downloaded # and built using the functions download_prerequisites() and # build_prerequisites(). In addition, the following need to be # installed: # # - The Oracle Java SDK for building JPL # - jdk--windows-i586.exe into # /C/Program Files (x86)/... (default on 64-bit Windows) # - jdk--windows-x64.exe into # /C/Program Files/... (default on 64-bit Windows) TARGETHOST="$1" MAKE="make -j 4" case "$TARGETHOST" in win64) BITS=64 ;; win32) BITS=32 ;; *) echo "Please run as . $BASH_SOURCE 'win32|win64'" return esac PS1=W$BITS' (\W\[\e[36m\]$(__git_ps1 "; %s")\[\e[0m\]) \!_> ' export BUILDARCH=$TARGETHOST # Versions of prerequisite packages. Used to download the right release # file. GMP_VERSION=6.1.2 PTHREADS_VERSION=2-9-1-release LIBDWARF_VERSION=20120410 SSL_VERSION=1.1.1d JPEG_VERSION=9b ZLIB_VERSION=1.2.12 ARCHIVE_VERSION=3.4.0 UUID_VERSION=1.6.2 BDB_VERSION=6.1.26 PCRE_VERSION=8.45 # TODO: update for PCRE2 FFI_VERSION=3.3 YAML_VERSION=0.2.2 PLDIR=pl-devel # installation prefix. This path should not have spaces in one of the # directory names. install="${install-$HOME/mingw$BITS}" src="$(pwd)" PATH=$install/swipl/bin:$PATH # Check whether we are cross-compiling or running under MSYS in Windows. # Note that the MSYS version has not yet been tested. case "$(uname)" in MINGW*) CROSSCOMPILING=no export PATH=$install/bin:$PATH DRIVEC="/C" MINGWGCC=gcc ;; *) export CROSSCOMPILING=yes export WINEDEBUG=-all DRIVEC="$HOME/.wine/drive_c" export WINEPATH="$(winepath -w $install/bin)" ;; esac if [ "$CROSSCOMPILING" = yes ]; then if [ -z "$CROSS" ]; then case $TARGETHOST in win64) CROSS=x86_64-w64-mingw32 ;; win32) if [ -r /usr/bin/i686-w64-mingw32-gcc ]; then CROSS=i686-w64-mingw32 else CROSS=i586-mingw32msvc fi ;; esac fi MINGWGCC=$CROSS-gcc export WINDRES=$CROSS-windres fi # See whether pthread is built-in if [ -r "$($MINGWGCC -print-file-name=libwinpthread-1.dll)" ]; then PTHREADS_VERSION= fi # Java configuration # Note that Win64 javac and javadoc crash under Wine (1.5.6). But, we # can use the native Linux versions if [ -z "$JAVAROOT" ]; then case $TARGETHOST in win64) JAVAROOT="$DRIVEC/Program Files/Java" if [ "$CROSSCOMPILING" = yes ]; then export JAVAC=javac export JAVADOC=javadoc fi ;; win32) JAVAROOT="$DRIVEC/Program Files (x86)/Java" ;; esac fi JAVAPREFIX="$(echo "$JAVAROOT"/jdk*)/bin" export JAVAPREFIX # Set some variables to find the Windows libraries and include files # export COFLAGS=-g export CIFLAGS="-I$install/include" export CPPFLAGS=-I$install/include export LDFLAGS="-L$install/lib" export PKGLDFLAGS=-I$install/lib ################################################################ # end of gathering info about the environment; the remainder are # functions that perform steps of the build process ################################################################ ################ # Handy for running autoconf from a directory config() { if [ -r ./configure ]; then ./configure --host=$CROSS --prefix=$install elif [ -r ../src/configure ]; then ./configure --host=$CROSS --prefix=$install fi } ################ # Create target directories make_mingw_dirs() { mkdir -p $install/include mkdir -p $install/lib mkdir -p $install/bin } ########################### # Download and install the GMP library. download_gmp() { GMP_FILE=gmp-$GMP_VERSION.tar.bz2 [ -f $GMP_FILE ] || \ wget ftp://ftp.gmplib.org/pub/gmp-$GMP_VERSION/$GMP_FILE tar jxf $GMP_FILE } build_gmp() { ( cd gmp-$GMP_VERSION ./configure --host=$CROSS --prefix=$install \ --enable-shared --disable-static make make install ) } ########################### # Download and install the Pthreads-win32 library. Only if PTHREADS_VERSION # is set. Else we assume a recent MinGW64, which ships with # libwinpthread download_pthread_win32() { if [ ! -z "$PTHREADS_VERSION" ]; then PTHREADS_FILE=pthreads-w32-$PTHREADS_VERSION.tar.gz cd $src [ -f $PTHREADS_FILE ] || \ wget ftp://sourceware.org/pub/pthreads-win32/$PTHREADS_FILE tar xzf $PTHREADS_FILE fi } build_pthread_win32() { if [ -d pthreads-w32-$PTHREADS_VERSION ]; then ( cd pthreads-w32-$PTHREADS_VERSION make -f GNUmakefile CROSS=$CROSS- \ LFLAGS="-lwsock32 -Wl,--out-implib=libpthreadGC2.dll.a" GC cp pthread.h semaphore.h sched.h $install/include/ cp pthreadGC2.dll $install/bin/ cp libpthreadGC2.dll.a $install/lib/ ) fi } ########################### # Download and install the DWARF debugging library. download_libdwarf() { LIBDWARF_FILE=libdwarf-$LIBDWARF_VERSION.tar.gz [ -f $LIBDWARF_FILE ] || \ wget http://www.prevanders.net/$LIBDWARF_FILE tar xzf $LIBDWARF_FILE } build_libdwarf() { ( cd dwarf-$LIBDWARF_VERSION/libdwarf ./configure --host=$CROSS --enable-shared sed -i -e "s|libdwarf.so|libdwarf.dll|" \ -e "s|\$(CFLAGS) -shared|\$(LDFLAGS) -shared|" \ -e "/_elf_/d" -e "/[ \t]pro_/d" -e "/dwarf_addr_finder/d" Makefile make PRELIBS="-Wl,--out-implib=libdwarf.dll.a" mkdir -p $install/bin cp libdwarf.dll $install/bin/ mkdir -p $install/lib cp libdwarf.a libdwarf.dll.a $install/lib/ mkdir -p $install/include cp dwarf.h libdwarf.h $install/include ) } ########################### # Download and install ssl download_ssl() { SSL_FILE=openssl-$SSL_VERSION.tar.gz [ -f $SSL_FILE ] || wget http://www.openssl.org/source/$SSL_FILE tar xzf $SSL_FILE } build_ssl() { ( cd openssl-$SSL_VERSION export CC=$MINGWGCC case $CROSS in i?86*) MINGW=mingw ;; x86_64*) MINGW=mingw64 ;; *) echo "SSL: Unknown CROSS: $CROSS" exit 1 ;; esac; ./Configure $MINGW --prefix=$install shared threads make depend make make install_sw ) } ########################### # Download and install BerkeleyDB # http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/overview/index.html download_libdb() { BDB_FILE=db-$BDB_VERSION.tar.gz [ -f $BDB_FILE ] || \ curl http://download.oracle.com/berkeley-db/$BDB_FILE > $BDB_FILE tar zxvf $BDB_FILE } build_libdb() { ( cd db-$BDB_VERSION/build_unix sed -i -e "s:WinIoCtl.h:winioctl.h:" ../src/dbinc/win_db.h ../dist/configure --enable-mingw --host=$CROSS --prefix=$install \ --enable-shared --disable-static make library_build make install_lib install_include ( cd $install/lib [ -f libdb.dll.a ] || ln -s libdb-*.dll.a libdb.dll.a [ -f libdb.la ] || ln -s libdb-*.la libdb.la ) ) } ########################### # Download and install jpeg download_jpeg() { JPEG_FILE=jpegsrc.v$JPEG_VERSION.tar.gz [ -f $JPEG_FILE ] || wget http://www.ijg.org/files/$JPEG_FILE tar xzf $JPEG_FILE } build_jpeg() { ( cd jpeg-$JPEG_VERSION ./configure --host=$CROSS --prefix=$install --enable-shared make make install ) } ########################### # Download and install libXpm download_libxpm() { if [ -d libXpm ]; then (cd libXpm && git pull) else git clone https://github.com/SWI-Prolog/libXpm.git fi } build_libxpm() { ( cd libXpm/lib autoconf ./configure --host=$CROSS --prefix=$install make -f Makefile.mingw make -f Makefile.mingw install ) } ########################### # Download and install zlib download_zlib() { ZLIB_FILE=zlib-$ZLIB_VERSION.tar.gz [ -f $ZLIB_FILE ] || wget http://zlib.net/$ZLIB_FILE tar xzf $ZLIB_FILE } build_zlib() { ( cd zlib-$ZLIB_VERSION make -f win32/Makefile.gcc PREFIX=$CROSS- BINARY_PATH=$install/bin INCLUDE_PATH=$install/include LIBRARY_PATH=$install/lib SHARED_MODE=1 IMPLIB=libz.dll.a install ) } ################################# # Download and install libarchive download_libarchive() { ARCHIVE_FILE=libarchive-$ARCHIVE_VERSION.tar.gz [ -f $ARCHIVE_FILE ] || \ wget http://www.libarchive.org/downloads/$ARCHIVE_FILE tar xzf $ARCHIVE_FILE } # lt_cv_deplibs_check_method=pass_all works around a bug in libtool # causing: "linker path does not have real file for library" error on MinGW # See http://lists.cairographics.org/archives/cairo/2009-July/017686.html build_libarchive() { ( cd libarchive-$ARCHIVE_VERSION export CFLAGS="-I$install/include" export LDFLAGS="-L$install/lib" export lt_cv_deplibs_check_method='pass_all' export ac_cv_func__localtime64_s='no' export ac_cv_func__ctime64_s='no' ./configure --host=$CROSS --prefix=$install --with-pic --with-zlib \ --without-iconv --without-openssl --without-nettle --without-xml2 \ --without-expat --without-libregex --without-bz2lib \ --without-lzmadec --without-lzma --without-lzo2 make make install ) } ################################# # Download and install libpcre # TODO: update for PCRE2 download_libpcre() { PCRE_FILE=pcre-$PCRE_VERSION.tar.gz [ -f $PCRE_FILE ] || \ wget https://ftp.pcre.org/pub/pcre/$PCRE_FILE tar xzf $PCRE_FILE } build_libpcre() { ( cd pcre-$PCRE_VERSION ./configure --host=$CROSS --prefix=$install \ --disable-static --disable-cpp --enable-utf8 --enable-unicode-properties make pcre.dll make install ) } ################################# # Download and install libuuid download_libuuid() { UUID_FILE=uuid-$UUID_VERSION.tar.gz [ -f $UUID_FILE ] || \ curl ftp://ftp.ossp.org/pkg/lib/uuid/$UUID_FILE > $UUID_FILE tar zxvf $UUID_FILE } build_libuuid() { ( cd uuid-$UUID_VERSION ./configure --host=$CROSS --prefix=$install make make install ) } ################################ # Download and install libffi download_libffi() { FFI_FILE=libffi-$FFI_VERSION.tar.gz [ -f $FFI_FILE ] || \ curl ftp://sourceware.org/pub/libffi/$FFI_FILE > $FFI_FILE tar zxvf $FFI_FILE } build_libffi() { ( cd libffi-$FFI_VERSION ./configure --host=$CROSS --prefix=$install make make install # Bit strange location for the headers cp $install/lib/libffi-$FFI_VERSION/include/*.h $install/include ) } ################################ # Download and install libyaml download_libyaml() { #tested 01f3a8786127748b5bbd4614880c4484570bbd44 git clone https://github.com/yaml/libyaml } build_libyaml() { ( cd libyaml ./bootstrap ./configure --host=$CROSS --prefix=$install make make install ) } ########################### # Do the whole lot for all prerequisites clean_prerequisites() { ( cd gmp-$GMP_VERSION && make distclean ) ( cd openssl-$SSL_VERSION && make distclean ) ( cd jpeg-$JPEG_VERSION && make distclean ) ( cd libXpm/lib && make distclean ) ( cd zlib-$ZLIB_VERSION && make distclean ) ( cd libarchive-$ARCHIVE_VERSION && make distclean ) ( cd uuid-$UUID_VERSION && make distclean ) ( cd ffi-$FFI_VERSION && make distclean ) if [ -d pthreads-w32-$PTHREADS_VERSION ]; then ( cd pthreads-w32-$PTHREADS_VERSION && make distclean ) fi } download_prerequisites() { download_gmp download_pthread_win32 download_libdwarf download_ssl download_jpeg download_libxpm download_zlib download_libarchive download_libuuid download_libdb download_libpcre download_libffi download_libyaml } build_prerequisites() { build_gmp build_pthread_win32 build_libdwarf build_ssl build_jpeg build_libxpm build_zlib build_libarchive build_libuuid build_libdb build_libpcre build_libffi build_libyaml }