Compiling GRASS GIS

From gvSIG CE Wiki

Jump to: navigation, search

Version used: GRASS 6.4.4

GRASS GIS 6.4tar (http://grass.osgeo.org) is a powerful collection of data processing modules that can be run seamlessly from within gvSIG CE/SEXTANTE to provide advanced geoprocessing capabilities.

The instructions on this page will show you how to compile a version of GRASS that does not include any GUI components and is suitable for use a geoprocessing backend from within gvSIG CE.

On the GRASS website (see above), you can find GRASS binaries for all supported OS and extensive instructions for how to compile GRASS GIS (see here). However, the aim of this page is to provide instructions for compiling a version of GRASS that has minimal dependencies (notably no dependencies on any GUI toolkits or proprietary 3rd party libraries), uses strictly GCC, and results in a highly portable set of binaries.

Contents

Prerequisites

We will use the source code of the latest stable version (http://grass.osgeo.org/grass64/source/grass-6.4.4.tar.gz).

Setting up the source code for correct compilation requires slightly different steps on each OS.

Linux

After compilation of each individual GRASS module, the Makefile will launch it in order to create a compact interface description that will be merged into the module's manual page. In order for this to work, the external libraries that GRASS depends on must be available in the dynamic linker's path:

 LD_LIBRARY_PATH_ORG=$LD_LIBRARY_PATH
 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$WORKSPACE/dist/lib

GRASS GIS requires the "curses" library for its interactive text interface (required for testing purposes only). All Linux systems should have a current version of "ncurses" in their official repositories. However, to make the binaries more portable, we will create our own library.

Get the source code here: http://ftp.gnu.org/pub/gnu/ncurses/ and configure, make and install:

 ./configure --prefix=$WORKSPACE/dist --with-shared=yes
 make
 make install

Unfortunately, the GRASS configure script will not detect the includes files for this library in the default location ("$WORKSPACE/dist/include/ncurses"). As a quick (and dirty) fix, we create some symlinks in "../include":

 ln -s $WORKSPACE/dist/include/ncurses/* $WORKSPACE/dist/include/

You are now ready to configure and compile the GRASS GIS source code on Linux.

Mac OS X

Download, compile and install "curses" exactly as described for Linux above.

Windows

Getting the GRASS GIS source code ready to build on Windows requires a little more work.

Download a minimal version of "libXDR" from http://download.osgeo.org/osgeo4w/x86_64/release/libxdr/libxdr-4.0-1-src.tar.bz2.

Unpack it, configure, compile and install:

 cd osgeo4w/xdr-4.0-mingw2
 ./configure --prefix=$WORKSPACE/dist --build=i686-w64-mingw32
 make
 make install

Next, we need PDCurses, a library for interactive text menu navigation. In this case, we simply take the binary builds available from http://download.osgeo.org/osgeo4w/x86_64/release/pdcurses/pdcurses-devel/pdcurses-devel-3.4-2.tar.bz2 (64 bit, static library and header files) and http://download.osgeo.org/osgeo4w/x86_64/release/pdcurses/pdcurses-3.4-2.tar.bz2 (DLL).

Simply unpack the two downloaded files into "$WORKSPACE/dist".

Then rename the static library:

 mv $WORKSPACE/dist/lib/pdcurses.a $WORKSPACE/dist/lib/libcurses.a

In addition, in order to be able to compile the projection support library, we have to define the function "_ftol", which MinGW does not provide as part of its runtime.

Open the file "lib/proj/ftol.c" and replace its contents with the following two function definitions:

 long _ftol(double fl)
 {
       return (long)fl;
 }
 
 long _ftol2(double x) { return _ftol(x); }

We also need to fix the static GDAL linking (more on this later) for "libGIS". Open the file "lib/gis/Makefile" and add " -Wl,--allow-multiple-definition" to the "EXTRA_LIBS". This will make sure that "libgdal.a" can be linked in statically, even though some of its symbols also appear in "libz.dll":

 EXTRA_LIBS = $(XDRLIB) $(SOCKLIB) $(DATETIMELIB) $(INTLLIB) $(MATHLIB) -Wl,--allow-multiple-definition

Finally, we need to amend the "configure" script slightly. The problem here is that GDAL/OGR is a C++ library (with a C API). When linking against this, the standard C++ runtime must also be linked in. However, for some reason this fails on MinGW64, so that we have to add "-lstdc++" manually.

Open the GRASS "configure" script with a text editor and find (ca. line 7900) the following block of code:

 GDAL=
 ac_save_libs="$LIBS"
 ac_save_cflags="$CFLAGS"
 LIBS="$LIBS $GDAL_LIBS"
 CFLAGS="$CFLAGS $GDAL_CFLAGS"
 cat > conftest.$ac_ext <<EOF

Change the "LIBS=" line to read:

 LIBS="$LIBS $GDAL_LIBS -lstdc++"

Next, find the following block of code:

 if { (eval echo configure:7920: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   GDAL_LIBS="$GDAL_LIBS $GDAL_DEP_LIBS"

Change the last line to read:

 GDAL_LIBS="$GDAL_LIBS $GDAL_DEP_LIBS -lstdc++"

Configuration

Now configure the sources.

Linux

 $ ./configure --prefix=$WORKSPACE/dist --with-includes=$WORKSPACE/dist/include/ --with-libs=$WORKSPACE/dist/lib/ --with-tiff=no --with-png=no --with-opengl=no --with-tcltk=no --with-fftw=no --with-sqlite=yes --with-postgres=yes --with-postgres-includes=$WORKSPACE/dist/include --with-postgres-libs=$WORKSPACE/dist/lib --enable-largefile --with-curses=yes --with-x=no --with-proj-libs=$WORKSPACE/dist/lib/ --with-proj-includes=$WORKSPACE/dist/include/ --with-proj-share=$WORKSPACE/dist/share/proj --with-regex=no --with-gdal=$WORKSPACE/dist/bin/gdal-config --with-cxx=no --enable-64bit=yes --enable-shared=yes --with-python=no --with-wxwidgets=no

Mac OS X

Same as on Linux

Windows

Add "--host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32" to the configuration:

 $ ./configure --prefix=$WORKSPACE/dist --with-includes=$WORKSPACE/dist/include/ --with-libs=$WORKSPACE/dist/lib/ --with-tiff=no --with-png=no --with-opengl=no --with-tcltk=no --with-fftw=no --with-sqlite=yes --with-postgres=yes --with-postgres-includes=$WORKSPACE/dist/include --with-postgres-libs=$WORKSPACE/dist/lib --enable-largefile --with-curses=yes --with-x=no --with-proj-libs=$WORKSPACE/dist/lib/ --with-proj-includes=$WORKSPACE/dist/include/ --with-proj-share=$WORKSPACE/dist/share/proj --with-regex=no --with-gdal=$WORKSPACE/dist/bin/gdal-config --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --with-cxx=no --enable-64bit=yes --enable-shared=yes --with-python=no --with-wxwidgets=no

Compilation

The above configuration should have set up a minimal version of GRASS GIS, with a result similar to this:

 GRASS is now configured for:  <architecture>
 
 Source directory:            /home/user/workspace_64/src/grass-6.4.4
 Build directory:             /home/user/workspace_64/src/grass-6.4.4
 Installation directory:      ${prefix}/grass-6.4.3
 Startup script in directory: ${exec_prefix}/bin
 C compiler:                  gcc -O0
 C++ compiler:
 Building shared libraries:   yes
 64bit support:               yes
 OpenGL platform:             none
 
 MacOSX application:         no
 MacOSX architectures:
 MacOSX SDK:
 
 Tcl/Tk NVIZ:                no
 
 BLAS support:               no
 C++ support:                no
 Cairo support:              no
 DWG support:                no
 FFMPEG support:             no
 FFTW support:               no
 FreeType support:           no
 GDAL support:               yes
 GEOS support:               no
 GLw support:                no
 LAPACK support:             no
 Large File support (LFS):   yes
 Motif support:              no
 MySQL support:              no
 NLS support:                no
 ODBC support:               no
 OGR support:                yes
 OpenGL support:             no
 PNG support:                no
 PostgreSQL support:         yes
 Python support:             no
 Readline support:           no
 SQLite support:             yes
 Tcl/Tk support:             no
 wxWidgets support:          no
 TIFF support:               no
 X11 support:                no

Before compiling the source, you can trim down the entries in the main "Makefile", in order to reduce the compilation to only those modules actually support by the SEXTANTE GRASS interface. Specifically, you can remove the following targets from the list of "SUBDIRS":

 display
 gui
 misc
 ps
 sites
 visualization

Then start the compilation like this:

 make GDAL_DYNAMIC=

Note the GDAL_DYNAMIC= (empty value) which serves to unset GDAL_DYNAMIC during compilation. This results in static linking of GRASS' GIS lib with GDAL. The reason for this is to avoid problems with a dynamically linked r.external (error message "Unable to load GDAL library"). The drawback with this is that (a) we need a static version of GDAL around, and (b) GDAL is C++ code and any constructors that are buggy will be called at library load time and may cause any sort of havoc (fingers crossed this won't happen). The situation is set to improve for GRASS 7. See Glynn Clements' comments here: [1].

After the compilation, there will be a summary of errors. Inspect it to check for any modules that did not compile. A completely compiled GRASS GIS should result in output similar to this:

 ----------------------------------------------------------------------
 Following modules are missing the 'description.html' file in src code:
 ----------------------------------------------------------------------
 GRASS GIS compilation log
 -------------------------
 Started compilation: Sun May  4 17:46:41 WEDT 2014
 --
 Errors in:
 /home/user/workspace_64/src/grass-6.4.3/lib/python
 --
 In case of errors please change into the directory with error and run 'make'.
 If you get multiple errors, you need to deal with them in the order they
 appear in the error log. If you get an error building a library, you will
 also get errors from anything which uses the library.
 --
 Finished compilation: Sun May  4 17:54:08 WEDT 2014
 Makefile:79: recipe for target `default' failed
 make: *** [default] Error 1

You can safely ignore the message about "Errors in lib/python", as well as the final exit status "Error 1".

Now install the binaries (remember "GDAL_DYNAMIC"!):

 make GDAL_DYNAMIC= install

3rd party modules

Compiling 3rd party modules is most easily done by leaving them in their external source code directories and then adjusting the variable "MODULE_TOPDIR", in each respective makefile, to point to the root of the GRASS source code tree.

E.g. with the setup described above, we can export an environment variable that will point to the current GRASS source tree (replace <grass-source-dir> with the actual folder name):

 export GRASS_SRC_DIR=$WORKSPACE/src/<grass64-source-dir>

We can then setup the Makefile of an individual module like this (example):

 MODULE_TOPDIR = $(GRASS_SRC_DIR)
 
 PGM = r.example
 
 LIBES = $(GISLIB)
 DEPENDENCIES = $(GISDEP)
 EXTRA_INC =
 EXTRA_CFLAGS = 
 
 include $(MODULE_TOPDIR)/include/Make/Module.make
 
 default: cmd

Running "make" from the source dir of "r.example" will then compile the source, while "make clean" and "make install" also work as expected. The latter will copy the compiled binary into the "bin" subfolder of your GRASS installation folder.

In the original GRASS source code tree, module are organized by class. E.g. all r.* modules reside in the "raster" subfolder. There is a higher level "Makefile" in the same folder that contains the names of all raster modules to compile. It is easy to mirror this mechanism for a tree of 3rd party modules in their respective subfolders (example):

 MODULE_TOPDIR = $(GRASS_SRC_DIR)
 
 SUBDIRS = \
 	r.example.1 \
 	r.example.2 \
 	r.example.3
 
 include $(MODULE_TOPDIR)/include/Make/Platform.make
 
 PGM = raster_ext
 
 include $(MODULE_TOPDIR)/include/Make/Dir.make
 
 default: htmldir
 
 htmldir: parsubdirs 
 
 clean: cleansubdirs

Running "make" on this Makefile with "r.example.n" in their respective subfolders will compile (clean, install) all modules listed under "SUBDIRS".

3rd party dependencies

Some 3rd party add-ons that are bundled by default with the gvSIG CE GRASS distribution may require additional external libraries. This section provides instructions for compiling them.

We compile dynamic versions of all required libraries, since we may wish to link them with other dynamic add-on libraries. This means that all generated library files (.so, .dll, .dylib) must also be copied into the destination folder for the binary distribution. The same is true for any add-ons that are themselves dynamic libraries.

GNU Scientific Library (GSL)

Needed for: Predictive modelling add-ons (r.dst.*).

The GSL provides a set of robust statistical function in C. It is light-weight and easy to compile.

 ./configure --enable-static=no --enable-shared=yes --prefix=$WORKSPACE/dist/
 make
 make install

Libxml2

Needed for: Predictive modelling add-ons (r.dst.*).

Libxml2 provides extensive XML reading/parsing/writing capabilities. It can be difficult to compile without errors in its current incarnation.

The following can be used to generate a minimal version of Libxml2:

 ./configure --enable-static=no --with-threads=no --with-legacy=no --with-ftp=no --with-html=no --with-c14n=no --with-zlib=no --with-python=no --prefix=$WORKSPACE/dist/
 make
 make install

Testing the GRASS GIS installation

NOTE: These instructions are still incomplete. There are still many problems with GRASS 6.4.x on Win7 64. For some reason, the "set_data.exe" keeps crashing (but clicking "Close" will start GRASS anyway, if the instructions below are followed). No proper fix/explanation for this seems to be available at this time (see http://osgeo-org.1560.x6.nabble.com/GRASS-GIS-1695-GRASSGIS-does-not-launch-td4994579.html). Note that none of this affects the performance of GRASS as a plug-in running under gvSIG CE/SEXANTE. But it does make testing GRASS separately under Windows difficult.

It may be a good idea to perform a quick test to make sure that GRASS works correctly.

Download GRASS testing database. This is basically an empty database with one location and one mapset that uses a projection-free, cartesian XY reference system.

Unpack the archive somewhere suitable. The following instructions assume that you have unpacked it to "$WORKSPACE/test".

Linux

 export LD_LIBRARY_PATH="$WORKSPACE/dist/lib/:$LD_LIBRARY_PATH"
 export PATH="$WORKSPACE/dist/bin:$PATH"

Launch GRASS with testing DB and the text interface like this:

 grass64 -text $WORKSPACE/test/grass_64_ce_test_2014_05_06/testloc/testms

Windows

When compiling and installing on MinGW using GCC and the GNU Makefiles, a GRASS start-up script is created that does not actually work on Windows. So some manual work is required.

First, we need a new GRASS settings file that contains the path to the directory where the testing location/mapset are stored (the "GISDBASE"), as well as the names of the location and mapset subfolders. The file must be called "grassrc6" and it must be placed in the "AppData\Roaming\GRASS6" folder of your Windows's user home folder (you might need to enable showing hidden folders in the Windows settings to be able to browse to the "AppData" folder):

 GISDBASE: C:\msys\home\user\workspace_64\test\grass_64_ce_test_2014_05_06
 LOCATION_NAME: testloc
 MAPSET: testms
 GRASS_GUI: text

Create a small batch script to set up and launch GRASS GIS (replace "C:\msys\home\user" with the path to your MSYS user directory)

 set PATH=C:\msys\home\user\workspace_64\dist\bin;%PATH%
 set GISBASE=C:\msys\home\user\workspace_64\dist\grass-6.4.4svn
 set GRASS_PAGER=more
 cd %GISBASE%\etc
 Init.bat -text

Now start a Window shell ("cmd.exe") and call the batch file created above.

Note: You will get an error message that "set_data.exe has stopped working". Ignore it.

All operating systems

You will see the "Welcome" screen. Press "RETURN", as advised.

Once logged into GRASS, execute the following commands:

 g.version
 g.parser
 
 r.in.gdal input=NAME.tif output=TESTRAST1 -o --o
 g.region rast=TESTRAST1
 r.info TESTRAST1
 r.shaded.relief map=test shadedmap=TESTRAST2 --o
 r.info TESTRAST2
 r.out.gdal input=TESTRAST2 output=TESTRAST2.tif createopt="TFW=YES,COMPRESS=DEFLATE"
 r.external input=NAME.tif output=TESTLINKEDRAST -o --o
 r.info TESTLINKEDRAST
 r.mapcalc result=TESTLINKEDRAST

All of these commands should complete without error messages. If you get "Unable to load GDAL library" at the "r.mapcalc" step, then something went wrong with the static linking of GDAL to GRASS' libGIS and you need to review the steps listed under "Compilation" above.

Next steps

If you also wish to build your own SAGA binaries, then continue with Compiling SAGA GIS.

Otherwise, go straight to Running gvSIG CE to learn where to place your binaries in the gvSIG CE program folder.

Previous steps

Go back to Compiling the C/C++ support libraries.