automake
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: replacement of variable placeholders in files


From: Benoit SIGOURE
Subject: Re: replacement of variable placeholders in files
Date: Wed, 22 Aug 2007 13:41:46 +0200

On Aug 22, 2007, at 12:23 PM, Jason Curl wrote:

Dizzy wrote:
Hi

I have an input file named project.conf.in in which I have some variable placeholders of the form ${VARIABLE}. I am trying to use sed to replace them with some actual contents so I have added a make rule in Makefile.am such as:

project.conf:project.conf.in $(top_builddir)/config.status
$(SED) -e 'address@hidden/@'"${localstatedir}/@g" $ (top_srcdir)/conf/project.conf.in > $@

Instead of having the Makefile do this for you, why not during 'configure' time with the AC_CONFIG_FILES? And then define the variable substitutions as part of the configure script? Even define a macro if you want to logically separate everything.

e.g.

AC_CONFIG_FILES([project.conf
    Makefile
    subdir/Makefile])

That doesn't always work for several reasons. First off, people happen to this frequently to pass path information around. Paths are mostly always defined in term of $prefix (at least). At configure time, prefix is set to NONE so you can't do it here [1]. Moreover, several paths are defined in terms of others, eg:

bindir='${exec_prefix}/bin'
exec_prefix='${prefix}'
prefix='/usr/local'

So you end up doing several calls to `eval' to simulate the variable expansion performed by make. Needless to say this is fragile (but doable).

So Dizzy's idea wasn't bad, IMO it's the most reliable thing you can do: rely on make to expand the variables.

[1] AFAIR this is mostly historical because RMS initially wanted to make it possible to change the prefix at the last minute, e.g. by doing make install prefix=/some/path (which happens to be useful if you use stow)

Notice that I first have a string with single quotes so I tell bash to not deal with ${LOCALSTATEDIR} then I have a string with double quotes so bash can replace the ${localstatedir} variable contents and no space between which seems to work well if I run that command in shell.


Back to Dizzy's question:
I think the line should be:

$(SED) -e 's,$${LOCALSTATEDIR},${localstatedir},g' $(top_srcdir)/conf/ project.conf.in >$@

You don't need to worry about the double-quotes thing because it's not your shell that expands the value of ${localstatedir} but make. Actually you could write $(localstatedir) instead and it wouldn't change anything.

However I think that configure replaces the ${LOCALSTATEDIR} from the generated Makefile.in with "" (because there is no such variable so it puts an empty string) and ignores my single quotes.


This sounds unlikely, configure does not deal with unknown variables (moreover configure, well actually config.status, substitutes variables of the form @FOO@ and not ${FOO} and it ignores variables it doesn't know).

Actually what happens is that ${LOCALSTATEDIR} is recognized by make as a non-existant make variable and is (as such) expanded to an empty string. What you want to do is to escape this variable so that make ignores it (by using `$$' instead of a single `$').

Any idea how to implement such a make rule that should replace variable placeholders with contents of actual variables?

Thanks!

I hope this helps.

$ cat >configure.ac
AC_INIT([foo], [0.1])
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
$ cat >Makefile.am
foo: foo.in
^Ised -e 's,$${LOCALSTATEDIR},${localstatedir},g' $(top_srcdir)/ foo.in >$@
$ cat >foo.in
echo '${LOCALSTATEDIR}'
$ autoreconf -i
configure.ac:2: installing `./missing'
configure.ac:2: installing `./install-sh'
$ ./configure
checking for a BSD-compatible install... /opt/local/bin/ginstall -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /opt/local/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
configure: creating ./config.status
config.status: creating Makefile
$ make foo
sed -e 's,${LOCALSTATEDIR},/usr/local/var,g' ./foo.in >foo
$ sh foo
/usr/local/var

--
Benoit Sigoure aka Tsuna
EPITA Research and Development Laboratory


Attachment: PGP.sig
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]