[GRASS-dev] lib/pngdriver Mingw compile error

Glynn Clements glynn at gclements.plus.com
Tue Oct 31 17:25:17 EST 2006

Paul Kelly wrote:

> Yep the first method worked, thanks. lib/display also had two similar 
> instances that needed changed. Patch included below but I haven't applied 
> it to CVS as I'm not clear on whether this is a wider problem that's better 
> worked around with a new library function or not. Also wondering if 
> there's complications committing to CVS from Windows when the files have 
> DOS line endings.

CVS assumes that files are text by default, and should convert line
endings automatically.

Binary files need to be marked as such using the -kb switch; ideally
using "cvs add -kb ..." when the file is first added, although you can
use "cvs admin -kb ..." to flag an existing file as binary.

[Files marked as binary will have -kb in the last field in the
CVS/Entries file; the gui/icons directory has this right, but almost
nothing else did. I've fixed a bunch of obvious cases (GIF/PNG

> Next problem is this one here:
> sh-2.04$ cd display/drivers/PNG
> sh-2.04$ make
> gcc -L/c/grass/grass6/dist.i686-pc-mingw32/lib -Wl,--export-dynamic  -L/c/grass/
> lib    -o /c/grass/grass6/dist.i686-pc-mingw32/driver/PNG  -L/c/grass/grass6/dis
> t.i686-pc-mingw32/lib OBJ.i686-pc-mingw32/main.o -lgrass_pngdriver -lgrass_drive
> r -lgrass_gis -lgrass_datetime -lxdr -liberty -lws2_32    -lz        -lgrass_gis
>   -lgrass_datetime -lxdr -liberty -lws2_32    -lz     -lpng  -lz    -lgrass_drive
> r -lgrass_gis -lgrass_datetime -lxdr -liberty -lws2_32    -lz        -lgrass_gis
>   -lgrass_datetime -lxdr -liberty -lws2_32    -lz       -lpng  -lz       -lxdr -l
> iberty -lws2_32    -lz
> OBJ.i686-pc-mingw32/main.o(.text+0x188): In function `main':
> c:/grass/grass6/display/drivers/PNG/main.c:43: undefined reference to `LIB_main'
> collect2: ld returned 1 exit status
> make: *** [/c/grass/grass6/dist.i686-pc-mingw32/driver/PNG] Error 1
> sh-2.04$
> LIB_main() should be defined in libgrass_driver, right?

Right; lib/driver/main.c.

> Bit lost on this 

Same here. As it's linking with -lgrass_driver, I have no idea why you
are getting that error. Can you use nm or dlltool to check that the
symbol is actually present in libgrass_driver.

> one. The only other modules with errors are:
> GRASS GIS compilation log
> -------------------------
> Started compilation: Tue Oct 31 09:43:40 WEST 2006
> --
> Errors in:
> /c/grass/grass6/lib/fonts/for_grass
> /c/grass/grass6/display/drivers/PNG
> /c/grass/grass6/imagery/i.class
> /c/grass/grass6/imagery/i.ortho.photo/photo.2image
> /c/grass/grass6/imagery/i.ortho.photo/photo.2target
> /c/grass/grass6/imagery/i.points
> /c/grass/grass6/imagery/i.vpoints
> /c/grass/grass6/raster/r.terraflow

No surprises there (apart from the PNG driver issue). The i.* stuff
tries to do various low-level stuff related to its terminal-oriented
interface, e.g. signal handling, timeouts etc.

I don't recall what the problem was with the fonts; something to do
with text/binary I/O, maybe?

> So looking fairly good. I was wondering to myself though, to get around 
> the need to use gis.m for monitor output in the native Windows version, 
> might it be a more worthwhile use of time to
> a) try and resurrect the libw11 native Windows monitor from GRASS 5, or

The main problem with monitors on Windows is the use of fork().

"d.mon start=..." runs mon.start using system(). mon.start starts the
driver using execl(), so the driver takes over the mon.start process. 
The driver initialises itself then goes into the background by
fork()ing and having the parent exit. At that point, the system() call
in d.mon returns, and d.mon then runs mon.select (unless you used the
-s switch).

This all works because the system("mon.select ...") doesn't return
until the driver has initialised itself and (the child version) is
listening on the socket.

On Windows, there are several problems with this:

1. Native Windows doesn't have fork() or execl().

2. Cygwin's versions didn't work correctly for this purpose on

3. Cygwin's versions won't work on any version of Windows for the
libW11 driver, as the child process doesn't inherit the various
Windows GUI objects created by the parent (cf X11, where the the only
system object is the connection to the X server).

4. Replacing the execl() with spawnl(_P_DETACH,...) and having the
driver run in the foreground eliminates the above issues, but the
result is that system("mon.start ...") returns before the driver has
initialised itself, so the subsequent mon.select fails.

To make the monitor startup work correctly on Windows, we either need
to add some kind of signalling mechanism, or add code to mon.start
which polls the driver until its ready to accept connections.

That still leaves one more problem:

5. Native windows doesn't support PF_LOCAL (Unix-domain) sockets.

> b) try and get some simple monitor view window working that reads the 
> output from the PNG driver

All of the above issues except #3 apply to all drivers, not just the X
driver (or W11 driver). Using direct rendering will suffice for simple
cases, but you can't combine multiple commands. Also, both the PNG
driver and direct rendering have the limiation that modules which use
the mouse won't work.

Glynn Clements <glynn at gclements.plus.com>

More information about the grass-dev mailing list