1
votes

Is there a generic was to specify a rule for something that goes from something with an extension to something with no extension? (in this case, '.in' to '')?

I have a project that's using automake. I have some config file templates that need substitutions before installing them. For example, I have a 'foo.ini.in' file that I want to use to create 'foo.ini'. I have a few of these scattered throughout the codebase. However, for each one, I need to create a custom Makefile rule to make them work. Is there a better way? I currently do this in Makefile.am:

bazdir=$(libdir)/@PACKAGE_NAME@/baz

EXTRA_DIST = foo.ini.in bar.ini.in
CLEANFILES = foo.ini bar.ini

foo.ini: foo.ini.in
     sed -e 's|@LIBDIR@|$(bazdir)|g' $< > $@

bar.ini: bar.ini.in
     sed -e 's|@LIBDIR@|$(bazdir)|g' $< > $@

This works fine, but I need to duplicate the rule for every file. I'd like to write one rule that will do the substitution for any 'ini.in' files to 'ini' files. I've tried:

%.ini.in: %.ini
     sed ....

but autoconf complains that % pattern substitution is a non-portable gnumake-ism. It also doesn't like

.ini.in.ini: 
     sed .....

.. which I can't really blame it for not liking, because I can't even parse that.

Is there a way to do this?

NOTE: I can not use AC_CONFIG_FILES to do this substitution, because 'bazdir' is not fully expanded in that case.

1
Can you explain why bazdir cannot be fully expanded? Since $libdir and $PACKAGE_NAME variables can be set by the configure script? - Brett Hale

1 Answers

2
votes

Fortunately, there's a much better way: let the 'configured' files be generated from the templates using the configure script itself. As I mentioned in the comment, I don't see any reason to try to expand $bazdir in the Makefile.am itself. Maybe you can clear this up for me if there's some special reason for this.

In the configure.ac script, substitution variables are defined with the AC_SUBST macro. I'm guessing you want to replace LIBDIR with the value of $bazdir. Note that LIBDIR isn't a good choice of name, as libdir is already used in configure scripts; so let's use a variable name prepended with a project name: BAZ_LIBDIR

1/. set bazdir in the configure script: bazdir="${libdir}/${PACKAGE_NAME}/baz", and substitute with: AC_SUBST(BAZ_LIBDIR, $bazdir). Alternatively, just assign the value to BAZ_LIBDIR and use the single argument form of AC_SUBST. BAZ_LIBDIR is now ready for substitution...

2/. At the end of configure.ac, specify the files to be generated from their <file>.in templates, with AC_CONFIG_FILES. Typically this will list Makefile's, as well as data files, where the .in suffix is implicit.

Assuming a projectdir tree... could be any sort of tree layout of course:

BAZ_LIBDIR="${libdir}/${PACKAGE_NAME}/baz"
AC_SUBST(BAZ_LIBDIR)
...
AC_CONFIG_FILES([Makefile projectdir/Makefile])
AC_CONFIG_FILES([projectdir/foo.ini projectdir/bar.ini])
...
AC_OUTPUT

Instances of @BAZ_LIBDIR@ in the <file>.ini.in files will be replaced with the substitution value. No arcane sed invocations are required to generate <file>.ini files.

Another nice feature is that you needn't add foo.ini.in or bar.ini.in to the EXTRA_DIST variable in the Makefile.am - and make distclean will clean the bar.ini and foo.ini files.