[GRASS-dev] installed makefile cleanup

Glynn Clements glynn at gclements.plus.com
Tue Oct 2 17:52:18 EDT 2007


William Kyngesburye wrote:

> I sortof understand this.  Until you can work out the necessary  
> changes (if you decide to), how about some minimal changes to the the  
> extension compilation working?

Unfortunately, use of the "get it working for now" approach is
responsible for much of the current mess. I'd rather take the
opportunity to improve matters than to make them worse.

> Here are my revised changes to get it  
> working:
> 
> - platform.make.in:
> 
> RUN_GISBASE         = ${ARCH_DISTDIR}
> RUN_GISRC           = ${RUN_GISBASE}/demolocation/.grassrc${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}
> 
> this allows those to be overridden together in the make step, yet  
> still keeps the same configured default for a source build.

Seems okay.

Although, this should be moved into Grass.make.in, as there are no
substitutions. Platform.make.in should just be where configure dumps
its output.

On the same topic, the following substitutions in Grass.make.in should
really go into Platform.make.in:

	LIB_PREFIX=@GRASS_LIB_PREFIX@
	LIB_SUFFIX=@GRASS_LIB_SUFFIX@
	GRASS_LIBRARY_TYPE=@GRASS_LIBRARY_TYPE@

The ones related to the version can stay.

> - grass.make.in: add after "ifdef INST_NOW":
> 
> ifdef INST_XTN
> ARCH_INC = -I$(ARCH_DISTDIR)/include -I$(MODULE_TOPDIR)/include
> ARCH_LIBPATH = -L$(ARCH_LIBDIR) -L$(MODULE_TOPDIR)/lib
> endif
> 
> to look for includes and libs in both the module source/dist and the  
> installed GRASS

I would rather see additional variables, e.g.:

	ARCH_INC = -I$(ARCH_DISTDIR)/include -I$(GISBASE)/include
	ARCH_LIBPATH = -L$(ARCH_DISTDIR)/lib -L$(GISBASE)/lib

where $(ARCH_DISTDIR) is where new files are "staged" and $(GISBASE)
is where existing files are found. For normal compilation, the two
would be equal. When extending an existing installation, $(GISBASE)
would refer to the installation while $(ARCH_DISTDIR) refers to the
build location.

That would eliminate the need to conditionalise the settings.

There are quite a few Makefiles which currently use $(GISBASE) instead
of $(ARCH_DISTDIR), but that's relatively easy to fix.

> - grass.make.in: add at end:
> 
> ifdef INST_XTN
> include $(MODULE_TOPDIR)/include/Make/Install_xtn.make
> endif
> 
> and have a new Install_xtn.make fragment.  This is just a trimmed  
> version of the main makefile with just install targets and any  
> unnecessary bits removed.  It expects INST_DIR_XTN to be set in the  
> make command.

I'm not sure that this needs to be conditionalised. If there are parts
of the top-level Makefile which might be useful to extensions, they
should be moved into one of the *.make files (or a new file).

In general, the *.make files should define as much as possible
unconditionally, and leave it up to either individual Makefiles or the
user to decide what actually gets used.

> - module.make: for the bin/pgm and etc/pgm targets, conditionalize  
> the dependencies:
> 
> ifdef INST_XTN
> $(BIN)/$(PGM)$(EXE): $(ARCH_CMD_OBJS)
> else
> $(BIN)/$(PGM)$(EXE): $(ARCH_CMD_OBJS) $(DEPENDENCIES)
> endif
> 
> ...
> 
> ifdef INST_XTN
> $(ETC)/$(PGM)$(EXE): $(ARCH_CMD_OBJS)
> else
> $(ETC)/$(PGM)$(EXE): $(ARCH_CMD_OBJS) $(DEPENDENCIES)
> endif
> 
> since the dependencies are based off ARCH_LIBDIR, which will be in  
> the extension source dir, they won't be found.

Actually, extensions are the easy case. Dependencies which are part of
GRASS should use $(GISBASE), which would refer to the installed
version. Dependencies which are part of the extension would use
$(ARCH_DISTDIR).

The case of extending an existing installation is more tricky, as you
could have some of the dependencies in the installation and some in
the staging directory (this assumes that you want to be able to build
additional libraries, not just modules).

But it's not that tricky; we can omit the path from the dependency and
use the "vpath" directive, which allows multiple directories to be
used for locating dependencies. IOW, GISDEP etc would lose the
"$(ARCH_LIBDIR)/" prefix, and we would add e.g.:

	vpath %.$(LIB_SUFFIX) $(ARCH_LIBDIR):$(GISBASE)/lib

[Apparently, we need to use a semicolon on (native) Windows.]

In any case, the dependencies aren't critical. We don't actually build
the dependencies if they're missing. It just means that if e.g. libgis
failed to compile, we abandon trying to build modules straight away,
rather than compiling all of the object files then having the linking
stage fail.

> Then, to compile an extension, cd to its source and:
> 
> make INST_XTN=y GRASS_HOME=. MODULE_TOPDIR=/path/to/installed/grass  
> RUN_GISBASE=/path/to/installed/grass
> 
> Note: I still had problems with having an inst_xtn: target (similar  
> to the inst_now target) and putting INST_XTN=y before make.  No  
> infinite loop now, but after completing the compilation  
> (successfully) it exits with an error:

I wouldn't bother with that kind of hack for now. Work on separating
the variables so that it can handle mixing files from the installation
with those from the extension, and getting the extension to compile
into its staging directory.

> /Applications/GRASS-6.3.app/Contents/MacOS/tools/mkhtml.sh  
> v.strahler ; mkdir -p ./dist.i686-apple-darwin8.10.1/docs/html ; /usr/ 
> bin/install -c  -m 644 v.strahler.tmp.html ./dist.i686-apple- 
> darwin8.10.1/docs/html/v.strahler.html ; for file in  *.png *.jpg ;  
> do head -n 1 $file | grep '^#!' > /dev/null ; if [ $? -ne 0 ] ; then / 
> usr/bin/install -c  -m 644 $file ./dist.i686-apple-darwin8.10.1/docs/ 
> html ; fi done 2> /dev/null ; true
> INST_XTN= make
> make[2]: *** No rule to make target `dist.i686-apple-darwin8.10.1/lib/ 
> libgrass_display.dylib', needed by `dist.i686-apple-darwin8.10.1/bin/ 
> v.strahler'.  Stop.
> make[1]: *** [inst_xtn] Error 2
> make: *** [first] Error 2
> rm v.strahler.tmp.html
> 
> It looks like, when done, INST_XTN gets set to something other than  
> "Y" and it tries to do a normal compile (thus trying to compile  
> dependencies).
> 
> Is there a particular reason for doing it this way, instead of having  
> no extra make target and putting INST_XTN after make?

AFAICT, the INST_NOW mechanism is designed to first build everything
into the installation directory, then re-build (i.e. re-link) into the
staging directory (dist.<arch>).

Running:

	INST_NOW=y make

runs make with INST_NOW=y. The first target which is found is:

	# first found target
	first: pre default
		@if test -n "$(INST_NOW)" ; then \
			$(MAKE) inst_now ; \
		fi

This runs the pre and default targets (in parallel; "pre" should
probably come first). Then, it runs "$(MAKE) inst_now", which runs:

	inst_now:
		INST_NOW= $(MAKE)

IOW, the first pass has INST_NOW=y, while the second has INST_NOW
empty.

If you're using an identical mechanism with INST_XTN, the second pass
is going to fail.

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




More information about the grass-dev mailing list