Currently, if a command registered with AC_CONFIG_COMMANDS_PRE itself calls AC_CONFIG_COMMANDS_PRE, such commands will never be executed. This occurs because each invocation of AC_CONFIG_COMMANDS_PRE appends the argument to one big macro (AC_OUTPUT_COMMANDS_PRE) which is then expanded once near the end of the configure output. To solve this, we can keep track of the command registrations that occur during expansion of AC_OUTPUT_COMMANDS_PRE, then after the original registrations have been handled, output *those* commands, and so on until there are no more commands. This is similar to how atexit works in the C library (although atexit uses a last-in first-out ordering, whereas this implementation is first-in first-out). * lib/m4sugar/m4sugar.m4 (m4_output_rec): New macro to help perform this command expansion loop. * lib/autoconf/status.m4 (AC_OUTPUT): Use m4_output_rec to expand AC_OUTPUT_COMMANDS_PRE and AC_OUTPUT_COMMANDS_POST * tests/base.at (AC_CONFIG_COMMANDS_PRE/POST: nested invocation): New test. --- lib/autoconf/status.m4 | 4 ++-- lib/m4sugar/m4sugar.m4 | 21 +++++++++++++++++++++ tests/base.at | 21 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4 index d125843..9b6e13c 100644 --- a/lib/autoconf/status.m4 +++ b/lib/autoconf/status.m4 @@ -1268,7 +1268,7 @@ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' m4_ifdef([_AC_SEEN_CONFIG(HEADERS)], [DEFS=-DHAVE_CONFIG_H], [AC_OUTPUT_MAKE_DEFS()]) dnl Commands to run before creating config.status. -AC_OUTPUT_COMMANDS_PRE()dnl +m4_output_rec([AC_OUTPUT_COMMANDS_PRE])dnl : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -1281,7 +1281,7 @@ test $ac_write_fail = 0 || AC_MSG_ERROR([write failure creating $CONFIG_STATUS]) dnl Commands to run after config.status was created -AC_OUTPUT_COMMANDS_POST()dnl +m4_output_rec([AC_OUTPUT_COMMANDS_POST])dnl # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4 index b732abc..f2e04c3 100644 --- a/lib/m4sugar/m4sugar.m4 +++ b/lib/m4sugar/m4sugar.m4 @@ -1305,6 +1305,27 @@ m4_define([_m4_map_args_w], [m4_substr([$1], [$2], m4_eval(m4_len([$1]) - [$2] - [$3]))]) +# _m4_output_rec(MACRO) +# --------------------- +# Internal recursive part of m4_output_rec. This clobbers the definition of +# MACRO so it should not be called directly. +m4_define([_m4_output_rec], [m4_ifnblank(m4_defn([$1]), +[m4_define([$1], [m4_define([$1])]m4_defn([$1]))dnl +m4_indir([$1])dnl +_m4_output_rec([$1])])]) + + +# m4_output_rec(MACRO) +# -------------------- +# Until the definition of MACRO is empty, repeatedly expand MACRO in a +# context where it has been redefined to the empty string. The original +# definition of MACRO is restored after all expansion is complete. +m4_define([m4_output_rec], +[m4_pushdef([$1], m4_defn([$1]))dnl +_m4_output_rec([$1])dnl +m4_popdef([$1])]) + + # m4_stack_foreach(MACRO, FUNC) # m4_stack_foreach_lifo(MACRO, FUNC) # ---------------------------------- diff --git a/tests/base.at b/tests/base.at index 87a0417..35bfd48 100644 --- a/tests/base.at +++ b/tests/base.at @@ -767,3 +767,24 @@ FOO ]]) AT_CLEANUP + + +# -------------------------------------- # +# Nested AC_CONFIG_COMMANDS_{PRE,POST}. # +# -------------------------------------- # + +AT_SETUP([AC_CONFIG_COMMANDS_PRE/POST: nested invocation]) +AT_KEYWORDS([AC@&t@_CONFIG_COMMANDS_PRE AC@&t@_CONFIG_COMMANDS_POST +AC@&t@_OUTPUT m4@&t@_output_rec]) + +AT_DATA([configure.ac], +[[AC_INIT([test], [1]) +AC_CONFIG_COMMANDS_PRE([AC_CONFIG_COMMANDS_PRE([m4_define([okpre])])]) +AC_CONFIG_COMMANDS_POST([AC_CONFIG_COMMANDS_POST([m4_define([okpost])])]) +AC_OUTPUT +m4@&t@_ifndef([okpre], [m4][_fatal([dropped nested AC_CONFIG_COMMANDS_PRE])]) +m4@&t@_ifndef([okpost], [m4][_fatal([dropped nested AC_CONFIG_COMMANDS_POST])]) +]]) +AT_CHECK_AUTOCONF([], [], [], [stderr]) + +AT_CLEANUP -- 1.7.8.6 _______________________________________________ Autoconf mailing list Autoconf@xxxxxxx https://lists.gnu.org/mailman/listinfo/autoconf