[GRASS-dev] GRASS Make-system question

Hi,
i have a problem to set up a correct Makefile to compiling two
different modules using the same source file (main.c) but with
different EXTRA_CFLAGS. This is how far i got:

MODULE_TOPDIR = ../..

LIBES2 = $(RASTERLIB) $(GISLIB)
LIBES3 = $(G3DLIB) $(RASTERLIB) $(GISLIB)
DEPENDENCIES = $(G3DDEP) $(GISDEP) $(RASTERDEP)

PROGRAMS = r.colors.out r3.colors.out

r_colors_out_OBJS = main.o
r3_colors_out_OBJS = main.o

include $(MODULE_TOPDIR)/include/Make/Multi.make

default: multi

$(BIN)/r.colors.out$(EXE): LIBES = $(LIBES2)
$(BIN)/r3.colors.out$(EXE): LIBES = $(LIBES3)

I stuck trying to add a preprocess macro -DUSE_RASTER3D for r3.colors.out?

Can anybody give me a hint how to solve this. Where to put the
preprocess macro in the Makefile so is will be used exclusively by
r3.colors.out?

Thanks and best regards
Soeren

Soeren Gebbert wrote:

i have a problem to set up a correct Makefile to compiling two
different modules using the same source file (main.c)

It can't be done. A specific object file is built from a specific
source file using a specific command. That object file won't be
re-built if it already exists and is newer than the source file.

If you want to build multiple modules which share (some) code, and
don't want to go as far as making the common code into a library, the
parts which differ must be in separate object files and thus separate
source files. See e.g. raster/r.mapcalc/Makefile (which builds both
r.mapcalc and r3.mapcalc).

Can anybody give me a hint how to solve this.

Don't try to use quick hacks; do it properly. Either clone the file as
e.g. main3.c or make it support both 2d and 3d at run-time.

--
Glynn Clements <glynn@gclements.plus.com>

Hi Glynn,

Can anybody give me a hint how to solve this.

Don't try to use quick hacks; do it properly. Either clone the file as
e.g. main3.c or make it support both 2d and 3d at run-time.

Well, actually my intention was not a quick hack. I thought it would
be meaningful to use macros to reduce the appearance of cloned code
for easier code maintainability. I did not know that using macros to
decide at compile time the behavior of a program is a hack at all.

I changed the code of r/r3.color.out to meet your guideline.

I have to rethink the r/r3.colors approach to meet your guideline too,
but to also reducing cloned code. I am not a fan of cloned code and
modules with mixed behavior (raster and raster3d support) with the
need adding scripts to hide there complexity:

For example:
r.colors.fency does it all
-> script r.colors to offer only raster capabilities of r.colors.fancy
-> script r3.colors to offer only raster3d capabilities of r.colors.fancy

Best regards
Soeren

--
Glynn Clements <glynn@gclements.plus.com>

Soeren Gebbert wrote:

>> Can anybody give me a hint how to solve this.
>
> Don't try to use quick hacks; do it properly. Either clone the file as
> e.g. main3.c or make it support both 2d and 3d at run-time.

Well, actually my intention was not a quick hack. I thought it would
be meaningful to use macros to reduce the appearance of cloned code
for easier code maintainability. I did not know that using macros to
decide at compile time the behavior of a program is a hack at all.

It's not the use of macros that's a hack (there's plenty of code with
conditional sections), but building multiple, distinct object files
from the same source file.

With one exception[1], the GRASS 7.0 build system relies entirely upon
the '%.o: %.c' (etc) pattern rules in Compile.make. This ensures that
any changes to those rules affect everything; there's no need to hunt
down special cases which need to be changed separately (and, in
practice, are likely to be overlooked).

[1] macosx/app/Makefile has an explicit rule for "main.o: main.m".

I changed the code of r/r3.color.out to meet your guideline.

I have to rethink the r/r3.colors approach to meet your guideline too,
but to also reducing cloned code. I am not a fan of cloned code and
modules with mixed behavior (raster and raster3d support) with the
need adding scripts to hide there complexity:

If you want distinct modules, make each #ifdef'd chunk into a separate
function, then move those functions into separate source files, one
for 2d and one for 3d.

--
Glynn Clements <glynn@gclements.plus.com>

Hello Glynn,
i face some Make-system problems while implementing r3.colors on top
of r.colors. Because i have no clue how the make system actually works
i am lost. I have modified the r.colors Makefile to handle now
different main files to build two binaries:

{{{
MODULE_TOPDIR = ../..

LIBES = $(G3DLIB) $(RASTERLIB) $(GISLIB)
DEPENDENCIES = $(G3DDEP) $(GISDEP) $(RASTERDEP)

PROGRAMS = r.colors r3.colors

r_colors_OBJS = raster_main.o edit_colors.o rules.o stats.o
r3_colors_OBJS = raster3d_main.o edit_colors.o rules.o stats.o

include $(MODULE_TOPDIR)/include/Make/Multi.make

default: multi

# Insert thumbnail previews
r.colors.tmp.html: $(HTMLSRC) thumbnails.py
  $(call htmldesc,$<,$@)
  sed 's!^<DD><b>\([a-z0-9.]*\)</b>:!<DD><img width="80" height="12"
src="Colortable_\1.png"> <b>\1</b>:!' "$@" > "$@.tmp"
  mv -f "$@.tmp" "$@"
  $(MAKE) thumbnails

thumbnails: $(BIN)/r.mapcalc$(EXE)
  -$(call run_grass, ./thumbnails.py)

$(BIN)/r.mapcalc$(EXE):
  $(MAKE) -C ../r.mapcalc

.PHONY: thumbnails

.INTERMEDIATE: r.colors.tmp.html
}}}

The source code compile well, but i broke the thumbnail preview
creation. Here the compilation report and error:

{{{
Makefile:17: warning: overriding commands for target `r.colors.tmp.html'
../../include/Make/Multi.make:30: warning: ignoring old commands for
target `r.colors.tmp.html'
test -d OBJ.x86_64-unknown-linux-gnu || mkdir -p OBJ.x86_64-unknown-linux-gnu
gcc -ggdb -Wall -Werror-implicit-function-declaration -fno-common
-fopenmp -I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-D_FILE_OFFSET_BITS=64 -DPACKAGE=\""grassmods"\"
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-o OBJ.x86_64-unknown-linux-gnu/raster_main.o -c raster_main.c
gcc -ggdb -Wall -Werror-implicit-function-declaration -fno-common
-fopenmp -I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-D_FILE_OFFSET_BITS=64 -DPACKAGE=\""grassmods"\"
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-o OBJ.x86_64-unknown-linux-gnu/edit_colors.o -c edit_colors.c
gcc -ggdb -Wall -Werror-implicit-function-declaration -fno-common
-fopenmp -I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-D_FILE_OFFSET_BITS=64 -DPACKAGE=\""grassmods"\"
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-o OBJ.x86_64-unknown-linux-gnu/rules.o -c rules.c
gcc -ggdb -Wall -Werror-implicit-function-declaration -fno-common
-fopenmp -I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-D_FILE_OFFSET_BITS=64 -DPACKAGE=\""grassmods"\"
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-o OBJ.x86_64-unknown-linux-gnu/stats.o -c stats.c
: && gcc -L/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib
-L/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib
-lgomp -Wl,--export-dynamic
-Wl,-rpath-link,/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib
  -o /home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/bin/r.colors
OBJ.x86_64-unknown-linux-gnu/raster_main.o
OBJ.x86_64-unknown-linux-gnu/edit_colors.o
OBJ.x86_64-unknown-linux-gnu/rules.o
OBJ.x86_64-unknown-linux-gnu/stats.o -lgrass_g3d.7.0.svn
-lgrass_raster.7.0.svn -lgrass_gis.7.0.svn -lm
gcc -ggdb -Wall -Werror-implicit-function-declaration -fno-common
-fopenmp -I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-D_FILE_OFFSET_BITS=64 -DPACKAGE=\""grassmods"\"
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-I/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/include
-o OBJ.x86_64-unknown-linux-gnu/raster3d_main.o -c raster3d_main.c
: && gcc -L/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib
-L/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib
-lgomp -Wl,--export-dynamic
-Wl,-rpath-link,/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib
  -o /home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/bin/r3.colors
OBJ.x86_64-unknown-linux-gnu/raster3d_main.o
OBJ.x86_64-unknown-linux-gnu/edit_colors.o
OBJ.x86_64-unknown-linux-gnu/rules.o
OBJ.x86_64-unknown-linux-gnu/stats.o -lgrass_g3d.7.0.svn
-lgrass_raster.7.0.svn -lgrass_gis.7.0.svn -lm
GISRC=/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/demolocation/.grassrc70
GISBASE=/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu
PATH="/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/bin:$PATH"
PYTHONPATH="/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/etc/python:$PYTHONPATH"
LD_LIBRARY_PATH="/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/bin:/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib:/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib:/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib:/usr/local/lib/vtk-5.9:/usr/lib64/jvm/java-1.6.0-sun-1.6.0/jre/lib/amd64/xawt:/usr/local/lib:/home/soeren/src/grass7.0/grass_trunk/dist.x86_64-unknown-linux-gnu/lib:/usr/local/lib64/R/lib"
LC_ALL=C thumbnails.py --html-description < /dev/null | grep -v
'</body>\|</html>' > r.colors.tmp.html
/bin/sh: thumbnails.py: command not found
make: *** [r.colors.tmp.html] Error 1
}}}

Can you please give me a hint what i did wrong and how the Makefile
should look like?

Many thanks
Soeren

2011/6/23 Glynn Clements <glynn@gclements.plus.com>:

Soeren Gebbert wrote:

>> Can anybody give me a hint how to solve this.
>
> Don't try to use quick hacks; do it properly. Either clone the file as
> e.g. main3.c or make it support both 2d and 3d at run-time.

Well, actually my intention was not a quick hack. I thought it would
be meaningful to use macros to reduce the appearance of cloned code
for easier code maintainability. I did not know that using macros to
decide at compile time the behavior of a program is a hack at all.

It's not the use of macros that's a hack (there's plenty of code with
conditional sections), but building multiple, distinct object files
from the same source file.

With one exception[1], the GRASS 7.0 build system relies entirely upon
the '%.o: %.c' (etc) pattern rules in Compile.make. This ensures that
any changes to those rules affect everything; there's no need to hunt
down special cases which need to be changed separately (and, in
practice, are likely to be overlooked).

[1] macosx/app/Makefile has an explicit rule for "main.o: main.m".

I changed the code of r/r3.color.out to meet your guideline.

I have to rethink the r/r3.colors approach to meet your guideline too,
but to also reducing cloned code. I am not a fan of cloned code and
modules with mixed behavior (raster and raster3d support) with the
need adding scripts to hide there complexity:

If you want distinct modules, make each #ifdef'd chunk into a separate
function, then move those functions into separate source files, one
for 2d and one for 3d.

--
Glynn Clements <glynn@gclements.plus.com>

Soeren Gebbert wrote:

i face some Make-system problems while implementing r3.colors on top
of r.colors. Because i have no clue how the make system actually works
i am lost. I have modified the r.colors Makefile to handle now
different main files to build two binaries:

The source code compile well, but i broke the thumbnail preview
creation. Here the compilation report and error:

  ... LC_ALL=C thumbnails.py --html-description < /dev/null | grep -v

Why is it trying to generate a manual page for thumbnails.py?

Ah:
  r.colors.tmp.html: $(HTMLSRC) thumbnails.py
    $(call htmldesc,$<,$@)

This won't work with Multi.make, as HTMLSRC will be empty and so $<
will end up as "thumbnails.py". Instead, use:

  r.colors.tmp.html: $(BIN)/r.colors$(EXE) thumbnails.py
and:
  r3.colors.tmp.html: $(BIN)/r3.colors$(EXE) thumbnails.py

--
Glynn Clements <glynn@gclements.plus.com>

Hi Glynn,

This won't work with Multi.make, as HTMLSRC will be empty and so $<
will end up as "thumbnails.py". Instead, use:

   r\.colors\.tmp\.html: $\(BIN\)/r\.colors$\(EXE\) thumbnails\.py

and:
r3.colors.tmp.html: $(BIN)/r3.colors$(EXE) thumbnails.py

This works perfectly, thanks a lot!

The new r3.colors implementation is available in svn. Still missing is
the "-e" flag for r3.colors. I think i have to implement something
similar to the Cell_stats approach in the raster library based on
tiles in the g3d library.

Best regards
Soeren