如何在config.ac中用bash变量递归替换路径



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

默认情况下,libdir设置为"${exec_prefix}/lib">exec_prefix设为'${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}"])

Makefile.am

bin_PROGRAMS = test
test_SOURCES = test.cpp

test.cpp

int main()
{}

中的path.conf

@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中使用的路径的扩展版本,以便自动工具使用该扩展路径生成path.conf


编辑:仅Bash解决方案

在@Aserre答案的帮助下,我挖掘了相关主题,并使用正则表达式完成了以下操作。

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

这意味着:当$libdir包含一个$时,用eval展开。

但在ac_OUTPUT 之前的config.ac脚本中不起作用

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

自动工具为安装目录变量的默认值提供特殊处理,以便用户能够在make install时间指定或覆盖安装前缀:

make install prefix=/my/special/prefix

你的建议会打破这种局面。如果用户在安装阶段指定的安装前缀与他们告诉configure的不同(或者默认情况下他们让configure选择),那么您最终将导致安装中断。

解决此类问题的最佳方法是在make install时在make的控制下构建配置文件,而不是在配置时进行。如果项目使用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本身的功能非常接近。

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

如果你100%确定${exec_prefix}变量的内容,你可以使用下面的行来实现你想要的:

libdir="$(eval echo ${exec_prefix})"

请注意,在许多情况下,不鼓励使用eval。这里,如果用户已经覆盖了变量exec_prefix的内容,例如使用exec_prefix='a; rm -rf /',则所有编写的代码都将被执行。

如果你完全可以控制你的环境(即,当你启动脚本时,你确定变量的值),应该没有问题,否则要警惕潜在的副作用

最新更新