[GRASS5] problem grass library gis.a

Hello grass developers,

I'm new to this grass-list, and am not sure if the basic questions below
should be asked in the devolpers list?
may the problems below has to do with deficiences in my programming skills.
I started to with shplib and ogr-libraries lately. I'm using grass for some
time and also plan to take advantage of the grass API /libraries to write
some geologic modelling tools (calculating strengths for european
lithosphere).
Some of the input data is already stored in both grass 2D raster format as
T(x,y,z) in a g3d format.

For this reason I would like to implement the functions:
G_open_cell_old (...)
G_get.......()
G3d_openCellOld (.....)
G3d_getDouble(G.....);
etc...
into my c++ routine.

I'm however confronted with several problems:
both gis.a as the g3d-library do offer problems. Concerning the g3d-lib I
can understand, since I had problems with the compilation of the g3d tool.
The comiplation (keep going) offered me the r3. ..... and g3. .....
grass-modules properly compiled (can be used) but possibly the g3d-library
not (see for compileOut.log at the end of this mail)

But the gis-library should work .. I guess
However when I compile my routine the following problem arises related to
the gis.a library:

nico@laptop:~/strength_map/strengthmap_prog/strengthmap_prog> make
g++ -o TEST main.o g2d.o yld.o /usr/local/grass5/lib/*.a
/usr/local/grass5/lib/libgis.a(flate.o)(.text+0x393): In function
`G_zlib_compress':
/home/nico/grass5.0.2/src/libes/gis/flate.c:353: undefined reference to
`deflateInit_'
/usr/local/grass5/lib/libgis.a(flate.o)(.text+0x3a8):/home/nico/grass5.0.2/s
rc/libes/gis/flate.c:363: undefined reference to `deflate'
/usr/local/grass5/lib/libgis.a(flate.o)(.text+0x3c8):/home/nico/grass5.0.2/s
rc/libes/gis/flate.c:370: undefined reference to `deflateEnd'
/usr/local/grass5/lib/libgis.a(flate.o)(.text+0x420):/home/nico/grass5.0.2/s
rc/libes/gis/flate.c:375: undefined reference to `deflateEnd'
etc...

GNU g++ compiler version: g++ (GCC) 3.3 20030226 (prerelease) (SuSE Linux).
makefile:
# EXTRA_CFLAGS = -I/home/nico/software/grass5.0.2/src/include
PGM=r.example
LIST = main.o
GISLIB = /usr/local/grass5/lib/*.a
LIBES = $(GISLIB)
DEPLIBS = $(DEPGISLIB)

OBJ = main.o g2d.o yld.o
CC = g++
EXE = TEST

main: $(OBJ)
  $(CC) -o $(EXE) $(OBJ) $(LIBES) $(MATHLIB) $(XDRLIB)

#$(BIN_CMD)/$(PGM): $(LIST) $(DEPLIBS)
# $(CC) $(LDFLAGS) -o $@ $(LIST) $(LIBES) $(MATHLIB) $(XDRLIB)

main.o : main.cpp
  $(CC) -c main.cpp

g2d.o : g2d.cpp
  $(CC) -c g2d.cpp

yld.o : yld.cpp
  $(CC) - yld.cpp

I've downloaded a template routine (r.example) to check if I've done
something wrong but same problem comes back.
Does anyone have a solution?

G3D - library. While gis.h and gis.a can be found in /usr/local/grass5/
include & lib, the g3d.h and g3d.a(?) are not.
I was confronted with some problems while compiling g3d (grass5.0.2) -
gmake5:
make[3]: Entering directory
`/home/nico/software/grass5.0.2/src.contrib/GMSL/g3d/src3d/raster/r3.showdsp
f.openGL'
gcc -I/home/nico/software/grass5.0.2/src/include -g -O2 -I/home/nico/softw
are/grass5.0.2/src/libes/dspf -I/home/nico/software/grass5.0.2/src/libes/ogs
f -I/usr/X11R6/include -c debugf.c -o OBJ.i686-pc-linux-gnu/debugf.o
debugf.c:44:20: macro "va_start" requires 2 arguments, but only 1 given
debugf.c: In function `debugf':
debugf.c:44: error: `va_start' undeclared (first use in this function)

the compiler already suggested to change the header of
GMSL/g3d/src3d/raster/r3.showdspf.openGL/debugf.c with #include <stdarg.h>
instead of #### (forgotten).

thanking in advance

Nico

N.J. Hardebol wrote:

But the gis-library should work .. I guess
However when I compile my routine the following problem arises related to
the gis.a library:

nico@laptop:~/strength_map/strengthmap_prog/strengthmap_prog> make
g++ -o TEST main.o g2d.o yld.o /usr/local/grass5/lib/*.a
/usr/local/grass5/lib/libgis.a(flate.o)(.text+0x393): In function
`G_zlib_compress':
/home/nico/grass5.0.2/src/libes/gis/flate.c:353: undefined reference to
`deflateInit_'
/usr/local/grass5/lib/libgis.a(flate.o)(.text+0x3a8):/home/nico/grass5.0.2/s
rc/libes/gis/flate.c:363: undefined reference to `deflate'
/usr/local/grass5/lib/libgis.a(flate.o)(.text+0x3c8):/home/nico/grass5.0.2/s
rc/libes/gis/flate.c:370: undefined reference to `deflateEnd'
/usr/local/grass5/lib/libgis.a(flate.o)(.text+0x420):/home/nico/grass5.0.2/s
rc/libes/gis/flate.c:375: undefined reference to `deflateEnd'
etc...

These are ZLIB functions (gzip compression). You need to add -lz to
the link command; this is normally done via $(XDRLIB). However, while
you are referencing that variable, you don't appear to be defining it
anywhere (the GRASS makefiles are dynamically generated by
concatenating several fragments, including src/CMD/head/head.<arch>
and the directory's Gmakefile).

I've downloaded a template routine (r.example) to check if I've done
something wrong but same problem comes back.
Does anyone have a solution?

Typically you would add your code to the GRASS source tree, along with
a Gmakefile; that way, all of the relevant make variables will be
defined. However, the GRASS build mechanism currently doesn't handle
C++ (at least, not in 5.0.2; the CVS HEAD version has some C++
support, but it isn't guaranteed; it probably won't work if your C++
compiler is significantly different to your C compiler, although
gcc/g++ will probably work).

G3D - library. While gis.h and gis.a can be found in /usr/local/grass5/
include & lib, the g3d.h and g3d.a(?) are not.

"make install" doesn't install the GRASS libraries or headers (except
for libgis and libdatetime), or any of the makefile fragments, so you
can't build "stand alone" GRASS modules (i.e. you can't build them
outside of the GRASS source tree).

I was confronted with some problems while compiling g3d (grass5.0.2) -
gmake5:
make[3]: Entering directory
`/home/nico/software/grass5.0.2/src.contrib/GMSL/g3d/src3d/raster/r3.showdsp
f.openGL'
gcc -I/home/nico/software/grass5.0.2/src/include -g -O2 -I/home/nico/softw
are/grass5.0.2/src/libes/dspf -I/home/nico/software/grass5.0.2/src/libes/ogs
f -I/usr/X11R6/include -c debugf.c -o OBJ.i686-pc-linux-gnu/debugf.o
debugf.c:44:20: macro "va_start" requires 2 arguments, but only 1 given
debugf.c: In function `debugf':
debugf.c:44: error: `va_start' undeclared (first use in this function)

I believe that has already been fixed in the CVS HEAD version (i.e.
the debug code has been removed). Either remove the references to
debugf.c and debugf.o from the Gmakefile, or remove the "#define DEBUG"
line from debugf.c.

--
Glynn Clements <glynn.clements@virgin.net>

many thanks,

the comments on linking the ZLib libraries did solve my problems to compile
my routine with some 2d raster functions, even outsite the grass source
three.

These are ZLIB functions (gzip compression). You need to add -lz to
the link command; this is normally done via $(XDRLIB). However, while
you are referencing that variable, you don't appear to be defining it
anywhere (the GRASS makefiles are dynamically generated by
concatenating several fragments, including src/CMD/head/head.<arch>
and the directory's Gmakefile).

However I become aware that I should invest more in experience on makefiles
and placing my code within the grass source tree especial for the g3d
functions this is a must - from what I understood ( since no libraries are
created in the usr/local/...)

typically you would add your code to the GRASS source tree, along with
a Gmakefile; that way, all of the relevant make variables will be
defined. However, the GRASS build mechanism currently doesn't handle
C++ (at least, not in 5.0.2; the CVS HEAD version has some C++
support, but it isn't guaranteed; it probably won't work if your C++
compiler is significantly different to your C compiler, although
gcc/g++ will probably work).

Combining c and c++ with g++ does work properly don't forget the extern "C"
(thank you Xueming WU) it was absent in one of my headers...

G3D - library. While gis.h and gis.a can be found in /usr/local/grass5/
include & lib, the g3d.h and g3d.a(?) are not.

Glynn Clements wrote:

"make install" doesn't install the GRASS libraries or headers (except
for libgis and libdatetime), or any of the makefile fragments, so you
can't build "stand alone" GRASS modules (i.e. you can't build them
outside of the GRASS source tree).

I will study this in more detail to solve my problems with g3d, does I have
to consider CVS and complex makefiles with calling other makefiles in the
grass source tree? - I'll study the programmanual grass50.
At this moment I'm working in Kdevelop as lazy programer without much
experience.. I think I can't handle it in Kdevlop anymore?

Nico Hardebol

Nico Hardebol wrote:

> "make install" doesn't install the GRASS libraries or headers (except
> for libgis and libdatetime), or any of the makefile fragments, so you
> can't build "stand alone" GRASS modules (i.e. you can't build them
> outside of the GRASS source tree).

I will study this in more detail to solve my problems with g3d, does I have
to consider CVS and complex makefiles with calling other makefiles in the
grass source tree? - I'll study the programmanual grass50.
At this moment I'm working in Kdevelop as lazy programer without much
experience.. I think I can't handle it in Kdevlop anymore?

It is possible to build "stand alone" GRASS modules (i.e. outside of
the GRASS source tree), but you have to have a "built" source tree
available (i.e. you have to have compiled GRASS and not have done
"make clean" since), and you have to set up your makefiles (or IDE
configuration) to point to the libraries and headers that are there,
and you have to know which compiler/linker switches to use.

But it's a lot easier to put your code into the GRASS source tree
along with a Gmakefile. That way, "gmake5" will create a makefile with
all of the correct settings.

The easiest way to get the Gmakefile correct is to copy one from
another module which uses the same libraries (i.e. if you are using
g3d, copy the Gmakefile from a module which uses g3d).

--
Glynn Clements <glynn.clements@virgin.net>

Hello,

In the mail of 4-7 Glynn Clements explained me that a Grass Module can be
most easily made by compiling it within the grass source tree. He also
mentioned that c++ source files possibly offer problems since the grass
build mechanism doe currently not handlee c++. Gcc/g++ will probably work
since no differnece in c & c++ compilers.
lynn Clements Wrote

typically you would add your code to the GRASS source tree, along with
a Gmakefile; that way, all of the relevant make variables will be
defined. However, the GRASS build mechanism currently doesn't handle
C++ (at least, not in 5.0.2; the CVS HEAD version has some C++
support, but it isn't guaranteed; it probably won't work if your C++
compiler is significantly different to your C compiler, although
gcc/g++ will probably work).

The easiest way to get the Gmakefile correct is to copy one from
another module which uses the same libraries (i.e. if you are using
g3d, copy the Gmakefile from a module which uses g3d).

I've done this with some good results, it relative easy to compile new
modules by simple modifactions of makefiles.

However at the moment I'm trying to compile a geophysical routine that uses
several g3d functions and some problems with compiling the c++ source within
the grass tree arises.
We have tried to setup a make-rule to compile cpp files within the grass
source tree.
I have found the rules to compile *.f and *.c files in the gmake.sh script
located in grass5.0.2/src/CMD/generic/

Obviously the section between lines 268-306 needs to be expanded with the
rule to compile a *.cpp file.
The rule is considered to be rougly the same as for *.c files, however with
additional flag "-XC++".

However we don't fully comprehend the lines 282-284 that uses the sed and
awk commands, which seem to filter out the *.f and *.c files based on their
suffix.

Could anybody please indicate how these lines have to be changed, so that
also object files can be build from *.cpp files.
Or has anybody modified the gmake5 gmake.sh rules to compile *.cpp source
code.

Best regards,

Nico

_______________________________________________
grass5 mailing list
grass5@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass5

N.J. Hardebol wrote:

However at the moment I'm trying to compile a geophysical routine that uses
several g3d functions and some problems with compiling the c++ source within
the grass tree arises.
We have tried to setup a make-rule to compile cpp files within the grass
source tree.
I have found the rules to compile *.f and *.c files in the gmake.sh script
located in grass5.0.2/src/CMD/generic/

Obviously the section between lines 268-306 needs to be expanded with the
rule to compile a *.cpp file.
The rule is considered to be rougly the same as for *.c files, however with
additional flag "-XC++".

You shouldn't need that flag; gcc can deduce the language from the
file's suffix, so simply giving the file a ".cc" suffix should cause
gcc to treat it as C++ source.

[Aside: gcc interprets any of the suffixes ".cc", ".cpp", ".cxx" or
".C" (upper-case "C") as signifying C++ code, but the (latest) GRASS
build system only understands ".cc".]

However we don't fully comprehend the lines 282-284 that uses the sed and
awk commands, which seem to filter out the *.f and *.c files based on their
suffix.

That code finds all of the ".o" files which are listed in the
Gmakefile, strips off the ".o" suffix and passes the results (i.e. the
base file names) to the while loop. The while loop then generates one
build rule for each file (i.e. .f -> .o, .cc -> .o or .c -> .o),
depending upon whether a .f or .cc file was found.

[Aside: if neither a .f or .cc file is found, a .c -> .o rule is
added. This handles the situation where the source file is actually a
.l (lex) or .y (yacc) file; in that case, a .c file won't exist when
gmake.sh is being used to generate the make.rules file, but it will be
generated subsequently.]

Could anybody please indicate how these lines have to be changed, so that
also object files can be build from *.cpp files.
Or has anybody modified the gmake5 gmake.sh rules to compile *.cpp source
code.

In the CVS HEAD version, that while loop looks like this:

    while read file
    do
  if test -f $file.f
  then
      echo '$(OBJARCH)/'${file}.o: ${file}.f
      echo ' $(FC) $(FFLAGS) -c' ${file}.f -o '$@'
  elif test -f $file.cc
  then
      echo '$(OBJARCH)/'${file}.o: ${file}.cc
      echo ' $(CXX) $(CXXFLAGS) -c' ${file}.cc -o '$@'
  else
      echo '$(OBJARCH)/'${file}.o: ${file}.c
      echo ' $(CC) $(CFLAGS) -c' ${file}.c -o '$@'
  fi
    done

The rest of gmake.sh is unchanged from 5.0.2.

However, the above references CXX and CXXFLAGS instead of CC and
CFLAGS. In order to work, this requires some changes which have been
made to other parts of the build system. For your purposes, it should
suffice to change CXX and CXXFLAGS to CC and CFLAGS respectively in
the above code, eliminating the need for the other changes.

This is part of the reason why C++ code only works with gcc. The
configure script currently performs all library and header tests using
the C compiler, resulting in a set of switches which are suitable for
the C compiler. To correctly support the use of a C++ compiler, it
should really re-do all of the tests with a C++ compiler; it may even
be necessary to provide a second set of configure switches which would
apply to C++ compilation.

Right now, we just take the switches which were chosen for C, use them
for C++, and hope that it works.

The other thing which needs to be borne in mind when using C++ is that
the GRASS header files aren't C++-aware, so you have to include them
from C++ like this:

  extern "C" {
  #include <gis.h>
  }

One other point: you can't use <imagery.h>, because that has:

  struct Cluster
  {
      ...
      int *class ; /* class of each point */

which is a syntax error in C++.

--
Glynn Clements <glynn.clements@virgin.net>