WEBlog -- Wouter's Eclectic Blog

Fri, 31 Oct 2008

Autotools and shell

Autotools can be nice, but they can be pretty ugly too, sometimes. Especially when you're trying to do something that the autotools weren't originally meant to do.

I was trying to generate scripts using autotools, in such a way that they'd be able to use variables that I've AC_SUBST'ed. At first, that did not seem possible, unless I wouldn't mind doing what autoconf.info suggests:

edit = sed \
	-e 's,@datadir\@,$(pkgdatadir),g' \
	-e 's,@prefix\@,$(prefix),g'

autoconf: Makefile $(srcdir)/autoconf.in
	rm -f autoconf autoconf.tmp
	$(edit) $(srcdir)/autoconf.in >autoconf.tmp
	chmod +x autoconf.tmp
	mv autoconf.tmp autoconf

autoheader: Makefile $(srcdir)/autoheader.in
	rm -f autoheader autoheader.tmp
	$(edit) $(srcdir)/autoconf.in >autoheader.tmp
	chmod +x autoheader.tmp
	mv autoheader.tmp autoheader

(sic, including the "autoconf.in" in the autoheader stub. Dunno whether that's a bug or whether autotools is really that ugly)

This would work, but it has one downside: it can replace instances of "@datadir@" with the likes of "${prefix}/lib/${PACKAGE}". Or, if the user is really sadistic, "${my_stupid_variable_specified_on_configure_command_line}/lib/${PACKAGE}". Personally, I do not like that approach.

So I had to find something else. With C programs, if you want to AC_SUBST something that could end up being something like the above, you'd just make sure you'd have something like -DFOO="@FOO@" in your AM_CFLAGS (or your program_CFLAGS); this would then evaluate your AC_SUBSTed variable, making it available (the proper way) to your C program. Occasionally, this is why it can sometimes be a good idea not to have a config.h...

Anyway, the solution to my little problem was to be found that way. First, I have a little sed program:

#!/bin/sh
sed -e '/@config_sh@/{
	rconfig.sh
	d
	}'

Or: 'replace all occurrences of @config_sh@ in the input with the contents of the file config.sh'. Simple. All we need now is to generate a config.sh file:

config.sh: Makefile
	env -i FOO=@FOO@ BAR=@BAR@ > config.sh
%: %.shin config.sh
	$(srcdir)/makesh < $< > $@

The first generates our config.sh file; the second uses the sed program above to turn any '.shin' file into a processed file. And now, my shell scripts only need to say '@config_sh@' somewhere appropriate to get access to all my AC_SUBSTed variables. Whee.

(Side note: I could probably run the sed inside the Makefile itself, but apparently my sed- and make-fu is not string enough -- whenever I try that, sed errors out one way or another. Oh well.)