如何用m4_foreach_w在configure中遍历动态构建的函数列表?
动态构建函数测试列表时m4_foreach_w未正确拆分列表
想要动态构建待测试的函数列表,之后针对列表中的每个函数调用对应宏。尝试使用m4_foreach_w处理空格分隔的列表,但工具并未拆分列表,导致整个列表被当作单个元素处理。
可复现示例(搭配空Makefile.in)
AC_INIT([faketest],[0.0],[],[],[]) AC_DEFUN([AC_CHECK_MY_FUNC], [ _ac_check_my_func_list="$1 $_ac_check_my_func_list" ac_cv_my_func_$1=yes ]) m4_define([MY_CHECK_FUNC_RES],[ m4_foreach_w([checkfunc], [$1], [ AC_MSG_CHECKING([for checkfunc]) AS_IF([test "x$ac_cv_my_func_checkfunc" = "xyes"], [ AC_MSG_RESULT(yes) AC_DEFINE(AS_TR_CPP(HAVE_MY_checkfunc), 1, [Define if your system has the checkfunc function]) ], [ AC_MSG_RESULT(no) ]) ]) ]) AC_CHECK_MY_FUNC([fake1], [#include <fake.h>], [if (fake1(x) == 0) return;]) AC_CHECK_MY_FUNC([fake2], [#include <fake.h>], [fake2("", "", 0);]) MY_CHECK_FUNC_RES([[$_ac_check_my_func_list]]) AC_CONFIG_FILES([ Makefile ]) AC_OUTPUT
预期输出
checking for fake2 ... no checking for fake1 ... no configure: creating ./config.status config.status: creating Makefile
实际输出
checking for fake2 fake1 ... no configure: creating ./config.status config.status: creating Makefile
补充:修改MY_CHECK_FUNC_RES调用的m4引号级别并未改变结果。
问题原因
m4_foreach_w是m4预处理阶段的工具,而_ac_check_my_func_list是shell变量,其值在configure脚本运行阶段才会展开。m4预处理时只能看到字面的$_ac_check_my_func_list,无法获取它的实际值,自然无法拆分列表。
解决方法
方法1:使用shell循环处理(推荐)
将MY_CHECK_FUNC_RES修改为生成shell循环代码,在configure运行时逐个处理列表元素:
m4_define([MY_CHECK_FUNC_RES],[ for checkfunc in $_ac_check_my_func_list; do AC_MSG_CHECKING([for $checkfunc]) AS_IF([test "x$ac_cv_my_func_$checkfunc" = "xyes"], [ AC_MSG_RESULT(yes) AC_DEFINE(AS_TR_CPP(HAVE_MY_$checkfunc), 1, [Define if your system has the $checkfunc function]) ], [ AC_MSG_RESULT(no) ]) done ])
调用时直接使用:
MY_CHECK_FUNC_RES
方法2:在m4阶段积累列表
改用m4宏来积累函数列表,让m4在预处理阶段就能获取完整列表:
AC_INIT([faketest],[0.0],[],[],[]) # 初始化m4列表宏 m4_define([_ac_check_my_func_list], []) AC_DEFUN([AC_CHECK_MY_FUNC], [ # 用m4宏积累逗号分隔的列表 m4_define([_ac_check_my_func_list], m4_defn([_ac_check_my_func_list])[$1,]) ac_cv_my_func_$1=yes ]) m4_define([MY_CHECK_FUNC_RES],[ # 使用m4_foreach处理逗号分隔的列表 m4_foreach([checkfunc], m4_defn([_ac_check_my_func_list]), [ AC_MSG_CHECKING([for checkfunc]) AS_IF([test "x$ac_cv_my_func_checkfunc" = "xyes"], [ AC_MSG_RESULT(yes) AC_DEFINE(AS_TR_CPP(HAVE_MY_checkfunc), 1, [Define if your system has the checkfunc function]) ], [ AC_MSG_RESULT(no) ]) ]) ]) AC_CHECK_MY_FUNC([fake1], [#include <fake.h>], [if (fake1(x) == 0) return;]) AC_CHECK_MY_FUNC([fake2], [#include <fake.h>], [fake2("", "", 0);]) MY_CHECK_FUNC_RES AC_CONFIG_FILES([ Makefile ]) AC_OUTPUT
两种方法都能实现逐个处理函数列表的需求,方法1更贴合shell脚本的运行逻辑,方法2则完全在m4预处理阶段完成列表构建。
内容的提问来源于stack exchange,提问作者Daria Phoebe Brashear
相关产品推荐
相关产品推荐

