Test your make-fu (update Makefile to maintain a version.h file)

Cristian Ionescu-Idbohrn cristian.ionescu-idbohrn at axis.com
Tue Feb 26 07:36:56 PST 2013

On Tue, 26 Feb 2013, Lubomir I. Ivanov wrote:
> well, i find no need to use an unix shell where it's not needed,

Not needed?  Do you mean you would like to rewrite the subsurface main
Makefile to avoid using a *nix shell and use only make buildins?

> but also GNU Make works without it and same goes for tools like
> grep. such software should not be bound to a shell.

Well, I happen to disagree.  Don't forget, the Makefile must also be
easily maintainable.

> the default Subsurface Makefile seems to depend on bash (or bash like
> shells),

Well, maybe the other way around. Bash is a posix-like shell, with
it's own extensions (so called bashisms).  From `man 1 bash':

	Bash is intended to be a conformant implementation of the Shell
	and Utilities portion of the IEEE POSIX specification (IEEE
	Standard 1003.1).  Bash can be configured to be POSIX-conformant
	by default.

> so the addition discussed in this thread would probably follow that
> as well.

Now I feel a bit lost again.  To be or not to be.  Shell fragments in
Makefiles or no shell fragments in Makefiles?

> my example (of make-fu written in 30minutes) is for something i will
> use for my own needs for the native Windows build, were bash is also
> available in fact. :-).

Great, so what's the point then?  Academic?

> now the question is, can someone write the same functionality for the
> default Makefile (which i don't use due to the oddities in my Windows
> and Linux setups) in a prettier way?
> i'm sure that answers most of the questions bellow with a few exceptions.

Whether this is pretty or not, I'll let others comment on, but I
believe it should be maintainable.  There are some sanity checks there
too.  Modified your example and got this (with marked the interesting
parts for subsurface Makefile):

 | # I'm assuming the $(VER_FILE) is generated, and .gitignore:d
*| VER_FILE = version.h
*| # There's only one line in $(VER_FILE); using the shell builtin `read'
*| OLD_VER = $(subst ",,$(shell read ignore ignore v <$(VER_FILE) && echo $$v))
 | #" workaround editor syntax highlighting quirk
*| ifeq ($(OLD_VER),)
*| $(warning $(VER_FILE) file not found, or empty version string)
*| endif
*| NEW_VER = $(shell git describe --tags --abbrev=7 2>&1)
*| ifeq ($(word 1,$(NEW_VER)),fatal:)
*| $(error "$(NEW_VER)")
*| endif
*| all: version test.o
*| version:
*| ifneq ($(OLD_VER),$(NEW_VER))
*| 	$(info updating $(VER_FILE) to $(NEW_VER))
*| 	@echo \#define VERSION \"$(NEW_VER)\" >$(VER_FILE)
*| endif
 | test.o: test.c $(VER_FILE)
 | 	gcc test.c -o test.o
*| clean:
*| 	rm -f $(VER_FILE) test.o

> well test.c is trivial:
> #include <stdio.h>
> #include "version.h"
> int main(void)
> {
> 	puts(VERSION);
> 	return 0;
> }

Sorry, not that `test', but the one shown by `man 1 test'.
But, never mind.



More information about the subsurface mailing list