AC_SUBST does not expand variable

2.4k views Asked by At

In an Autotools project I am trying to generate parts of my .conf file. The program needs to read from $(pkgdatadir), but I know that that variable is only set in Makefile.in, so I instead substituted datadir and PACKAGE.

configure.ac:

    AC_PREREQ([2.69])
    AC_INIT([foo], [1.0.0], [[email protected]])
    AC_CONFIG_SRCDIR([foo.c])
    AM_INIT_AUTOMAKE
    AC_CONFIG_HEADERS([config.h])
    AC_CONFIG_MACRO_DIRS([m4])

    AC_SUBST(datadir)
    AC_SUBST(PACKAGE)
    AC_CONFIG_FILES(foo.conf)

    AC_PROG_CC
    AC_PROG_INSTALL
    AC_PROG_MAKE_SET
    AC_PROG_MKDIR_P

    AC_CONFIG_FILES([Makefile])
    AC_OUTPUT

foo.conf.in:

    Dir = @datadir@/@PACKAGE@

The resulting foo.conf:

    Dir = ${prefix}/share/foo

I would like autoconf to evaluate the ${prefix} when substituting, and I don't know how to make that happen.

2

There are 2 answers

1
ptomato On BEST ANSWER

Unfortunately, you can't substitute Makefile variables like datadir at configure-time, since they aren't fully expanded. (See the documentation here.)

The unfortunate solution if you want to do both configure-time and build-time substitutions is to do a two-step substitution, from foo.conf.in.in to foo.conf.in at configure time, and foo.conf.in to foo.conf at build time:

in configure.ac:

AC_SUBST([PACKAGE])
AC_PROG_SED
AC_CONFIG_FILES([foo.conf.in])

in Makefile.am:

edit_script = $(SED) \
    -e 's,%datadir%,$(datadir),'g \
    -e ...other build-time substitutions you might want to do... \
    $(NULL)
foo.conf: foo.conf.in Makefile
    $(AM_V_GEN)rm -f $@ [email protected] && \
    $(edit_script) $< >[email protected] && \
    chmod a-w [email protected] && \
    mv [email protected] $@
CLEANFILES += foo.conf

in foo.conf.in.in:

 Dir = %datadir%/@PACKAGE@

I happen to use % signs for build-time substitutions so that I don't confuse them with configure-time substitutions marked by @. The makefile rule above also makes the generated foo.conf readonly so that you don't edit it by mistake and get your changes overwritten.

1
rocky On

A second parameter can be added to AC_CONFIG_FILES which is shell code to run in the context of the variables inside the configure script.

So you can add some sort of substitution there. For example change

AC_CONFIG_FILES(foo.conf)

to:

AC_CONFIG_FILES([foo.conf], [sed -i -e"s/\${prefix}/$prefix/" foo.conf])

What I do if this code gets long and unwieldy to put it all in a separate file and run that, or perhaps source it.

Disclaimer: When I tried to replicate your results, I was getting messages about --dataroot getting ignored and $prefix didn't appear in foo.conf 2nd disclaimer. I am not a fan of autoconf.