首页 > 解决方案 > 如何递归地用变量替换configure.ac中bash变量中的路径?

问题描述

我正在处理自动工具,情况如下:

默认情况下, libdir设置为'${exec_prefix}/lib'exec_prefix设置为'${prefix}'前缀设置为'/usr/local'

这里的关键递归和第一级libdir变量包含另一个变量以下路径。

那么如何将${libdir}转换为包含'/usr/local/lib'的变量?

信息:所有 3 个(libdir、exec_prefix、prefix)都可以根据配置进行更改。

考虑以下文件:

配置.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}"])

生成文件.am

bin_PROGRAMS = test
test_SOURCES = test.cpp

测试.cpp

int main()
{}

路径.conf.in

@libdir@

然后在调用之后:

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

配置日志显示:

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

并且生成的文件 path.conf 包含

${exec_prefix}/lib

目标是让一个变量包含要在path.conf.in中使用的路径的扩展版本,以便 autotools使用该扩展路径生成path.conf 。


编辑:仅 Bash 解决方案

挖掘相关主题并在@Aserre 回答的帮助下,我设法使用正则表达式执行以下操作。

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

这意味着:而$libdir包含一个$扩展与eval

但在 AC_OUTPUT 之前的 configure.ac 脚本中不起作用

标签: bashautotoolsautoconf

解决方案


目标是让一个变量包含要在path.conf.in中使用的路径的扩展版本,以便 autotools使用该扩展路径生成path.conf 。

Autotools 为安装目录变量的默认值提供特殊处理,以使用户能够指定或覆盖安装前缀make install

make install prefix=/my/special/prefix

你打算做的事情将打破这一点。如果用户在安装阶段指定了不同的安装前缀,而不是他们告诉的configure(或者他们configure默认选择),那么您最终将安装损坏。

解决此类问题的最佳方法是在make's 控制下构建配置文件make install,而不是在配置时进行。如果项目使用 Automake,那么这可能意味着这样的事情:

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

如果您愿意,您当然可以替换更多的输出变量。它非常接近configure它本身的功能。

当然,如果你这样做,那么你不必担心执行额外的扩展。


推荐阅读