Contents
Building Windows Binary On Linux (Cross compilation with MinGW)
Step by step compilation of GRASS and QGIS for Windows on Linux.
Building compiler and libraries
Warning: works only with GCC 3.x, problems were reported for GCC 4.x
Download scripts
Download and following scripts and put them in your PATH:
Warning: gcc must be configured with --enable-sjlj-exceptions
The scripts are slightly modified scripts from http://www.libsdl.org/extras/win32/cross/README.txt
Create directory
Create a new directory for example:
cd /home/user/ mkdir win
Set WIN
Set environment variable WIN to the directory created in previous step, for example:
export WIN=/home/user/win export TARGET=i586-mingw32msvc
I recommend to put this into your shell rc file (e.g. .bashrc)
Build Compiler
Run the script build-cross.sh, it should download and compile MinGW compiler, binutils and Win32 API.
XDR library
Download XDR library xdr-4.0-mingw2.tar.gz to $WIN/source and run
cd $WIN/source tar xfz xdr-4.0-mingw2.tar.gz cd xdr-4.0-mingw2 winconfigure --prefix=$WIN/i586-mingw32msvc winmake install
TODO: Use DLL. Currently if DLL is used db drivers do not work because of '\n' conversion (text mode expected). Find out how to force xdrlib to expect binary mode when compiled as DLL.
# $WIN/i586-mingw32msvc/bin/g++ --shared -o xdr.dll \
# -Wl,--out-implib=libxdr.dll.a \
# -Wl,--export-all-symbols \
# -Wl,--enable-auto-import \
# -Wl,--whole-archive libxdr.a \
# -Wl,--no-whole-archive -lwsock32 -liberty -lmingw32
# $WIN/i586-mingw32msvc/bin/strip xdr.dll
# cp xdr.dll $WIN/i586-mingw32msvc/bin/
# cp libxdr.dll.a $WIN/i586-mingw32msvc/lib
# rm -f $WIN/i586-mingw32msvc/lib/libxdr.a
Note: XDR is extracted from SunRPC 4.0 library and modified for compilation on MinGW
ZLIB
Download zlib http://www.zlib.net/zlib-1.2.3.tar.gz to $WIN/source and run
cd $WIN/source tar xfz zlib-1.2.3.tar.gz cd zlib-1.2.3
Note: zlib does not use autoconf, so it is impossible to run
- winconfigure (missing options), so you have to do
PREFIX=$WIN
TARGET=i586-mingw32msvc
export PATH="$PREFIX/bin:$PREFIX/$TARGET/bin:$PATH"
./configure --prefix=$WIN/$TARGET
make install
$WIN/i586-mingw32msvc/bin/g++ --shared -o z.dll \
-Wl,--out-implib=libz.dll.a \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive libz.a \
-Wl,--no-whole-archive
$WIN/i586-mingw32msvc/bin/strip z.dll
cp z.dll $WIN/i586-mingw32msvc/bin/
cp libz.dll.a $WIN/i586-mingw32msvc/lib
rm -f $WIN/i586-mingw32msvc/lib/libz.a
PROJ.4
Download proj.4 ftp://ftp.remotesensing.org/proj/proj-4.4.9.tar.gz to $WIN/source and run
cd $WIN/source tar xfz proj-4.4.9.tar.gz cd proj-4.4.9
- (Apply patch for Krovak?)
winconfigure --prefix=$WIN/i586-mingw32msvc
winmake install
$WIN/i586-mingw32msvc/bin/g++ --shared -o proj.dll \
-Wl,--out-implib=libproj.dll.a \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive src/.libs/libproj.a \
-Wl,--no-whole-archive -lmingw32
$WIN/i586-mingw32msvc/bin/strip proj.dll
cp proj.dll $WIN/i586-mingw32msvc/bin/
cp libproj.dll.a $WIN/i586-mingw32msvc/lib
rm -f $WIN/i586-mingw32msvc/lib/libproj.a
rm -f $WIN/i586-mingw32msvc/lib/libproj.la
GEOS
Download geos http://geos.refractions.net/geos-2.1.4.tar.bz2 to $WIN/source and run
cd $WIN/source
bunzip2 geos-2.1.4.tar.bz2
tar xf geos-2.1.4.tar
cd geos-2.1.4
winconfigure --prefix=$WIN/i586-mingw32msvc
winmake install
$WIN/i586-mingw32msvc/bin/g++ --shared -o geos.dll \
-Wl,--out-implib=libgeos.dll.a \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive ./source/geom/.libs/libgeos.a \
-Wl,--no-whole-archive -lmingw32
$WIN/i586-mingw32msvc/bin/strip geos.dll
cp geos.dll $WIN/i586-mingw32msvc/bin/
cp libgeos.dll.a $WIN/i586-mingw32msvc/lib
rm -f $WIN/i586-mingw32msvc/lib/libgeos.a
rm -f $WIN/i586-mingw32msvc/lib/libgeos.la
Create symbolic link:
cd $WIN/i586-mingw32msvc/bin/
ln -s i586-mingw32msvc-geos-config geos-config
GSL-library
Download the GSL-library into $WIN/source and extract it
cd $WIN/source
wget ftp://ftp.gnu.org/gnu/gsl/gsl-1.8.tar.gz
tar xvfz gsl-1.8.tar.gz
cd gsl-1.8
Configure GSL using winconfigure
winconfigure --prefix=$WIN/i586-mingw32msvc winmake winmake install
expat-library
Download the expat-library into $WIN/source and extract it
wget http://switch.dl.sourceforge.net/sourceforge/expat/expat-2.0.0.tar.gz
tar xvfz expat-2.0.0.tar.gz
cd expat-2.0.0
Configure and install expat
~/bin/winconfigure \ --prefix=$WIN/i586-mingw32msvc ~/bin/winmake ~/bin/winmake install
Postgres
Download postgresql-8.1.3-1-binaries-no-installer.zip (http://www.postgresql.org/ftp/binary/v8.1.3/win32/) to $WIN/source
cd $WIN/source
unzip postgresql-8.1.3-1-binaries-no-installer.zip
cd $WIN/source/pgsql
cp $WIN/source/pgsql/bin/*.dll $WIN/i586-mingw32msvc/bin
cp $WIN/source/pgsql/lib/libpq.a $WIN/i586-mingw32msvc/lib
cp $WIN/source/pgsql/include/libpq-fe.h $WIN/i586-mingw32msvc/include
cp $WIN/source/pgsql/include/postgres_ext.h $WIN/i586-mingw32msvc/include
GDAL
Download GDAL http://www.gdal.org/dl/gdal-1.3.2.tar.gz to $WIN/source
unpack GDAL:
cd $WIN/source
tar xfz gdal-1.3.2.tar.gz
cd gdal-1.3.2
Configure without almost everything, for me it worked with:
winconfigure \
--prefix=$WIN/i586-mingw32msvc \
--without-unix_stdio_64 \
--without-python \
--with-libtiff=internal \
--with-geotiff=internal \
--without-ogdi \
--without-xerces \
--without-hdf4 \
--without-grass \
--without-netcdf \
--without-jpeg \
--without-pg \
--without-libtool
winmake install
Create DLL and import library:
$WIN/i586-mingw32msvc/bin/g++ --shared -o gdal.dll \
-Wl,--out-implib=libgdal.dll.a \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive libgdal.a \
-Wl,--no-whole-archive -lgeos -lz -lmingw32
$WIN/i586-mingw32msvc/bin/strip gdal.dll
cp gdal.dll $WIN/i586-mingw32msvc/bin/
cp libgdal.dll.a $WIN/i586-mingw32msvc/lib
rm $WIN/i586-mingw32msvc/lib/libgdal.a
Modify CONFIG_LIBS in gdal-config:
cd $WIN/i586-mingw32msvc/bin/
mv gdal-config gdal-config.orig
cat gdal-config.orig \
| sed 's/CONFIG_LIBS=.*/CONFIG_LIBS="-lgdal -lgeos -lz"/' \
> gdal-config
chmod u+x gdal-config
After GRASS is built you will find further instructions on how to compile GRASS support into your GDAL.
SQLite
Download SQLite http://www.sqlite.org/sqlite-3.2.8.tar.gz to $WIN/source and run
cd $WIN/source
tar xfz sqlite-3.2.8.tar.gz
cd sqlite-3.2.8
Note: SQLite is using for example its own parser (lemon) which must be compiled first for Linux
modify Makefile.linux-gcc: TOP = ../sqlite-3.2.8
make -f Makefile.linux-gcc lemon keywordhash.h
cp Makefile.linux-gcc Makefile.mingw-gcc
modify Makefile.mingw-gcc (BCC,TCC,AR,RANLIB):
BCC = i586-mingw32msvc-gcc -g -O2
TCC = i586-mingw32msvc-gcc -O6
AR = i586-mingw32msvc-ar cr
RANLIB = i586-mingw32msvc-ranlib
delete tclsqlite.o from LIBOBJ in main.mk
winmake -f Makefile.mingw-gcc libsqlite3.a
$WIN/i586-mingw32msvc/bin/g++ --shared -o sqlite3.dll \
-Wl,--out-implib=libsqlite3.dll.a \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive libsqlite3.a \
-Wl,--no-whole-archive -lmingw32
$WIN/i586-mingw32msvc/bin/strip sqlite3.dll
cp sqlite3.dll $WIN/i586-mingw32msvc/bin/
cp libsqlite3.dll.a $WIN/i586-mingw32msvc/lib
cp sqlite3.h $WIN/i586-mingw32msvc/include
MSYS
MSYS is used as shell for GRASS.
Download MSYS-1.0*.exe (e.g. MSYS-1.0.11-2004.04.30-1.exe) and install it on Windows
wget http://switch.dl.sourceforge.net/sourceforge/mingw/MSYS-1.0.11-2004.04.30-1.exe
Warning: GRASS shell, msys.bat and rxvt.exe in path with spaces somehow cannot be started by QProcess. GRASS modules with space in path can be started without problem.
GRASS compilation
Download GRASS CVS HEAD to $WIN/source/grass6:
export CVSROOT=:pserver:grass-guest@intevation.de:/home/grass/grassrepository cvs login #password: "grass" (without quotes) cvs -z3 checkout grass6
cd $WIN/source/grass6
configure using winconfigure, for me it works with:
winconfigure \
--prefix=$WIN/i586-mingw32msvc \
--target=i586-mingw32msvc \
--without-jpeg \
--without-tiff \
--without-png \
--without-tcltk \
--without-postgres \
--without-mysql \
--without-sqlite \
--without-opengl \
--without-odbc \
--without-fftw \
--without-blas \
--without-lapack \
--without-motif \
--without-freetype \
--without-glw \
--without-nls \
--without-readline \
--without-opendwg \
--without-curses \
--without-x
winmake
winmake install
Copy grass6/dist.$ARCH/docs/html from Linux version to Windows version
Get somewhere (e.g. http://proj.maptools.org/) NAD27 grid shift files (conus,hawaii,ntv1_can.dat etc.) and copy them to grass/etc/nad
GDAL GRASS support
After compilation of GRASS return to the GDAL directory and compile in GRASS support:
cd $WIN/source/gdal-1.3.1 ~/bin/winconfigure \ --prefix=$WIN/i586-mingw32msvc \ --with-grass=$WIN/i586-mingw32msvc/grass-6.1.cvs \ --without-unix_stdio_64 \ --without-python \ --with-libtiff=internal \ --with-geotiff=internal \ --without-ogdi \ --without-xerces \ --without-hdf4 \ --without-netcdf \ --without-jpeg \ --without-pg \ --without-libtool
Remove '-lgrass_vask' from GDALmake.opt:
mv GDALmake.opt GDALmake.opt.orig cat GDALmake.opt.orig | sed 's/-lgrass_vask//' > GDALmake.opt
Compile and install. For dll linking add also grass libs, e.g.:
winmake install
$WIN/i586-mingw32msvc/bin/g++ --shared -o gdal.dll \
-Wl,--out-implib=libgdal.dll.a \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive libgdal.a \
-Wl,--no-whole-archive -lgeos -lz -lmingw32 \
-L $WIN/i586-mingw32msvc/grass-6.1.cvs/lib \
-lgrass_vect -lgrass_dig2 -lgrass_dgl -lgrass_rtree \
-lgrass_linkm -lgrass_dbmiclient -lgrass_dbmibase \
-lgrass_I -lgrass_gproj -lgrass_gmath -lgrass_gis \
-lgrass_datetime -lz
$WIN/i586-mingw32msvc/bin/strip gdal.dll
cp gdal.dll $WIN/i586-mingw32msvc/bin/
cp libgdal.dll.a $WIN/i586-mingw32msvc/lib
Go to apps/ and add to gdal_translate.cpp and gdalinfo.c :
#ifdef WIN32
#include <stdlib.h> /* _fmode */
#include <fcntl.h> /* _O_BINARY */
#undef _fmode
int _fmode = _O_BINARY;
#endif
and recompile the applications:
winmake clean; winmake
Modify again CONFIG_LIBS in gdal-config:
cd $WIN/i586-mingw32msvc/bin/
mv gdal-config gdal-config.orig
cat gdal-config.orig \
| sed 's/CONFIG_LIBS=.*/CONFIG_LIBS="-lgdal -lgeos -lz"/' \
> gdal-config
chmod u+x gdal-config
After that winconfigure in QGIS-dir works OK.
Running GRASS on Windows
Wine
It is possible to run GRASS for Windows on Linux using Wine http://www.winehq.com/ You have to add the path to your GRASS lib and bin directory into PATH variable defined in your .wine/system.reg
Windows
Start GRASS shell is not yet available. To start/run GRASS, so it is necessary to create GISRC file and set variables.
- create GISRC file, for example if you have GRASS mapset in
C:\gdata\spearfish\user1
- create a file C:\gdata\spearfish\user1\gisrc:
GISDBASE: C:\gdata\
LOCATION_NAME: spearfish
MAPSET: gisrc
- Create batch file to start GRASS in this mapset
- (if GRASS is installed in C:\grass) C:\gdata\spearfish\user1\grass.bat:
set PATH=C:\grass\bin;C:\grass\lib;%PATH%
set GISRC=C:\gdata\spearfish\user1\gisrc
set GISBASE=C:\grass
command.com
Now you can click on grass.bat and it opens shell where you can run GRASS commands. To enable command line history scrolling, run 'doskey' within the command.com terminal.
Quantum GIS compilation
Qt for Windows
Download qt-win-opensource-4.1.0-mingw.exe and run it on Windows or in Wine and extract Qt to $WIN/qt-4.1.0 (or move it there after extraction). In "MinGW Installation" tab leave the default option "Find MinGW" in "c:\MinGW". It will tell you that there is a problem with MinGW and if you want to continue, click on "Yes". The installer will extract Qt package.
Qt for Linux
Download qt-x11-opensource-src-4.1.0.tar.gz and compile it according to included instructions. You will need some Linux Qt binaries for cross-compilation (qmake, uic, moc, etc.).
Compilation of Quantum GIS
Download QGIS SVN HEAD source to $WIN/source/qgis_head
cd WIN/source/qgis_head export PREFIX=$WIN export TARGET=i586-mingw32msvc export PATH="$PREFIX/bin:$PREFIX/$TARGET/bin:$PATH"
Set PATH and LD_LIBRARY_PATH to qt4 binaries for Linux, e.g.:
export PATH=/home/usr1/qt-4.1.0/bin:$PATH
export LD_LIBRARY_PATH=/home/usr1/qt-4.1.0/lib:$LD_LIBRARY_PATH
./autogen.sh \
--prefix=$WIN/i586-mingw32msvc \
--target=$TARGET \
--host=$TARGET \
--build=i386-linux \
--with-qtdir=$WIN/qt-4.1.0 \
--with-projdir=$WIN/i586-mingw32msvc \
--with-gdal=$WIN/i586-mingw32msvc/bin/gdal-config \
--with-geos=$WIN/i586-mingw32msvc/bin/geos-config \
--with-sqlite3=$WIN/i586-mingw32msvc \
--with-grass=$WIN/i586-mingw32msvc/grass-6.1.cvs \
--without-postgresql
(Don't forget --without-postgresql, otherwise it will add Linux include paths!)
Note: I could build --with-postgresql and the correct libs were linked, when following the steps from Postgresql-Installation above. (SH)
winmake -f Makefile.win winmake -f Makefile.win install winmake -f Makefile.win cpgrass # Copy grass to qgis directory winmake -f Makefile.win cplibs # Copy DLL libs to qgis directory
Form the directory where MSYS was installed on Windows copy
m.ico msys.bat msys.ico bin/ etc/
to msys directory in the directory where qgis was installed ($prefix/msys) (MSYS is only necessary for GRASS Shell)
Strip and copy gdal_translate and gdalinfo to QGIS $prefix/qgis
Warning: Sometimes linking fails and runs OK if you run winmake second time?!
The resources/images etc. are installed to
$WIN/i586-mingw32msvc/share/qgis
and plugins/providers are installed to
$WIN/i586-mingw32msvc/lib/qgis
and qgis.exe is installed to
$WIN/i586-mingw32msvc/bin
When running, qgis.exe will look for the resources and plugins in
./share/qgis and ./lib/qgis
If you want to run qgis.exe from $WIN/i586-mingw32msvc/bin you have to make symbolic links
ln -s $WIN/i586-mingw32msvc/bin/share $WIN/i586-mingw32msvc/share/ ln -s $WIN/i586-mingw32msvc/bin/lib $WIN/i586-mingw32msvc/lib/
Note: Makefile.win runs strip on output executable because otherwise the otput files are very big (e.g. qgis.exe has 62M before strip and 5,6M striped)
Note: 'g++ -shared -o xxx.dll xxx.a' creates DLL but it seems to be 'empty' (does not work) => linking objects instead of archives
Note: Sometimes happens that for example src/plugins/grass/.libs/grassplugin.dll is almost empty, in that case delete the file and recompile.
Get somewhere (e.g. http://proj.maptools.org/) NAD27 grid shift files (conus,hawaii,ntv1_can.dat etc.) and copy them to qgis/share/proj
Building Plugins
In order to build all plugins for Windows, you need to make sure a Makefile.win is included in the src/plugins/<plugin-name>-folder.
The SPIT and Grid Maker standalone binaries do not build and are not included in the makefiles.
If the plugins build but are not recognized by QGIS, you can do the following from the src/plugins dir:
find ./ -name "*.dll"|xargs rm winmake -f Makefile.win install
For some reason the intial creation of the dll's seems to build incompatible binaries.
Making package
winmake -f Makefile.win pkg
Running Quantum GIS on Windows
To see the QGIS output printed to stdout/stderr on Windows I recommend to write a small batch file, for example qgis-run.bat:
c:\qgis\qgis.exe PAUSE
and run it instead of qgis.exe. It will open command.com and leave it open after qgis.exe exit.
Warning: In Wine, qgis.exe can freeze in qgisapp.cpp in QgsProviderRegistry::instance(plib) if there is no provider/plugin available in <prefix>/lib/qgis
Optional libraries for GRASS
Download PDCurses (substitutes ncurses) http://switch.dl.sourceforge.net/sourceforge/pdcurses/pdc27_ming_w32.zip
mkdir $WIN/binaries
- Copy pdc27_ming_w32.zip to $WIN/binaries
cd $WIN/binaries
mkdir pdcurses27
cd pdcurses27/
unzip ../pdc27_ming_w32.zip
cp -p *.h $WIN/i586-mingw32msvc/include/
cp -p *.a $WIN/i586-mingw32msvc/lib/
Note: For compilation of GRASS with curses edit in grass6/include/Make/Platform.make:
COMPATLIB = <full_path_to_i586-mingw32msvc/lib>/pdcurses.a
This needs to be fixed in configure.in of GRASS.