Search code examples
bashautotoolsautoconf

How to recursively substitute variable for a path in bash variable in configure.ac?


I am dealing with autotools and here is the situation:

By default libdir is set to '${exec_prefix}/lib' with exec_prefix set to '${prefix}' and prefix set to '/usr/local'.

Key here recursion and at first level libdir variable contain another variable and a following path.

So how to convert ${libdir} into a variable containing '/usr/local/lib' ?

Info : all 3 (libdir, exec_prefix, prefix) can change according configuration.

Consider the following files:

configure.ac

AC_PREREQ([2.59])
AC_INIT([test], [0.0.0] )
AM_INIT_AUTOMAKE()
AC_CONFIG_SRCDIR([test.cpp])
AC_LANG([C++])
AC_PROG_CXXCPP
AC_PROG_CXX

AC_CONFIG_FILES([Makefile path.conf])

AC_MSG_NOTICE([">>> Before ac_output prefix=${prefix}"])
AC_OUTPUT
AC_MSG_NOTICE([">>> after ac_output prefix=${prefix}"])

Makefile.am

bin_PROGRAMS = test
test_SOURCES = test.cpp

test.cpp

int main()
{}

path.conf.in

@libdir@

Then after invoking :

aclocal && autoconf && automake -a --foreign && ./configure

configure log show:

configure: ">>> Before ac_output prefix=NONE"
...
...
...
configure: ">>> after ac_output prefix=/usr/local"

And generated file path.conf contains

${exec_prefix}/lib

The goal is to have a variable containing the expanded version of the path to be used in a path.conf.in so autotools generate path.conf with that expanded path.


Edit: Bash only solution

Digging related topics and helped by @Aserre answer, I manage to do the following with a regex.

while expr match "${libdir}" '^.*\$.*$' 1>/dev/null;
do
    echo ">${libdir}"
    libdir="$(eval echo ${libdir})"
done

Which means : While $libdir contain one $ expand with eval.

But does not work in configure.ac script before AC_OUTPUT


Solution

  • The goal is to have a variable containing the expanded version of the path to be used in a path.conf.in so autotools generate path.conf with that expanded path.

    The Autotools provide special handling for default values of the installation-directory variables, in order to enable the user to specify or override the installation prefix at make install time:

    make install prefix=/my/special/prefix
    

    What you propose to do will break that. If a user specifies a different installation prefix at the installation stage than they tell configure (or that they let configure choose by default) then you will end up with a broken installation.

    The best way to do address problems like this is to build the configuration file under make's control, at make install time, instead of doing it at configuration time. If the project uses Automake, then that might mean something like this:

    install-data-local:
        $(SED) -e 's,[@]libdir[@],$(libdir),' path.conf.in > $(sysconfdir)/path.conf
        chmod 0644 $(sysconfdir)/path.conf
        chown root:root $(sysconfdir)/path.conf
    
    uninstall-local:
        rm $(sysconfdir)/path.conf
    

    You can of course substitute more output variables than that if you like. It's pretty close to what configure does itself.

    And of course, if you do it this way then you do not need to worry about performing extra expansions.