Изменение *FLAGS в configure.ac против кэширования с подпроектами

Скажем, я хочу добавить определенный флаг CFLAGS в моем configure сценарий, который должен распространяться на все подпроекты configure скрипты:

CFLAGS+=" -Dfoobar"
export CFLAGS
AC_CONFIG_SUBDIRS([sub])

Это работает когда configure вызывается тривиально. Как только произойдет одно из следующего:

  1. CFLAGS экспортируется в среду, когда configure вызывается
  2. CFLAGS установлен на configure командная строка
  3. используется кеширование (configure -C)

Этот подход больше не работает. В первых двух случаях экспортируемый CFLAGS просто игнорируется; и в последнем configure не удается с

configure: error: `CFLAGS'не был установлен в предыдущем запуске


Мне удалось надежно заставить это работать:

AM_CFLAGS+=" -Dfoobar"
export AM_CFLAGS
AC_SUBST([AM_CFLAGS]) # repeat this line in every configure.ac for each *FLAGS
AC_CONFIG_SUBDIRS([sub])

Учитывая, что есть несколько подпроектов, и несколько *FLAGS переменные, которые, возможно, должны быть установлены как это, это наполовину хорошо, но все еще неоптимально. Есть ли способ сделать эту работу, взломав только верхний уровень configure.ac?

2 ответа

Решение

Окончательное решение состояло в том, чтобы лишить драгоценности затронутые переменные:

Configure.ac верхнего уровня:

AC_INIT([test], [0.1])
AC_CONFIG_MACRO_DIR([m4]) # for ax_append_flag.m4
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

AC_PROG_CC
AC_PROG_SED

# Modify the CFLAGS. AX_APPEND_FLAG makes sure not to add the flag if it's already there
AX_APPEND_FLAG([-Dtop-configure], [CFLAGS])

AC_DEFUN([AX_UNPRECIOUS], [
    m4_define([_AC_PRECIOUS_VARS], m4_bpatsubst(_AC_PRECIOUS_VARS, [$1
], []))
])
AX_UNPRECIOUS([CFLAGS])
export CFLAGS

AC_CONFIG_SUBDIRS([sub])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

За шторами, CFLAGS никогда не рассматривается как драгоценный и, следовательно, никогда не кэшируется и не передается в подпакет configures - они видят ее исключительно как переменную окружения, а затем сами ее кешируют на общем верхнем уровне config.cache,

Это работает очень надежно и улучшает моё предыдущее решение, позволяя кэшировать значения даже во время прогонов конфигурирования верхнего уровня (и быть проще).

Я наконец получил это работать, за исключением кеширования на нескольких верхних уровнях configure пробеги. Идея состоит в том, чтобы взломать внутренние переменные autoconf, чтобы получить желаемую функциональность, и это было не слишком сложно:

  • модифицировать CFLAGS
  • мотыга ac_configure_args включить модифицированный CFLAGS вместо любого обнаруженного извне CFLAGS

Это сразу решило проблемы 1. и 2. из описания проблемы (внешние CFLAGS). Чтобы исправить кеширование, мне пришлось:

  • мотыга ac_cv_env_CFLAGS_{set,value} содержать set и модифицированный CFLAGSсоответственно

Это приводит к двум проблемам:

  1. с кешированием, ./config.status --recheck выполнит модификацию CFLAGS снова, даже если эта модификация уже была кэширована, что приводит к повторным флагам. Внесение изменений, только если это не было сделано, решило эту проблему.
  2. при вызове конфигурации верхнего уровня с существующим config.cacheкоррупция неизбежна, потому что config.cache проверка согласованности выполняется так рано, на нее нельзя повлиять. Только если мы должны были пройти CFLAGS в том числе configureмодификация в командной строке (или среде), эта проверка прошла бы, никак не обойтись. Единственным исправлением для этого было удалить config.cache после того, как все подпакеты были настроены. Поскольку кэширование во время настройки подпакета все еще работает, я нашел это приемлемым.

Верхний уровень configure.ac:

AC_INIT([test], [0.1])
AC_CONFIG_MACRO_DIR([m4]) # for ax_append_flag.m4
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

AC_PROG_CC
AC_PROG_SED

# Modify the CFLAGS. AX_APPEND_FLAG makes sure not to add the flag if it's already there
AX_APPEND_FLAG([-Dtop-configure], [CFLAGS])

# Replace/add CFLAGS in/to ac_configure_args
AS_CASE([$ac_configure_args],
    [*CFLAGS=*], [ac_configure_args=`AS_ECHO "$ac_configure_args" | $SED ["s|CFLAGS=[^']*|CFLAGS=$CFLAGS|"]`],
    [AS_VAR_APPEND([ac_configure_args],[" 'CFLAGS=$CFLAGS'"])]
)

# Fix the cache vars
ac_cv_env_CFLAGS_set=set
ac_cv_env_CFLAGS_value=$CFLAGS

# exporting CFLAGS is not needed for sub-packages: they get CFLAGS from ac_configure_args

AC_CONFIG_SUBDIRS([sub])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

AC_MSG_NOTICE([removing config.cache])
rm -f config.cache

Подуровень configure.ac:

AC_INIT([test-sub], [0.1])
AC_CONFIG_MACRO_DIR([../m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AX_APPEND_FLAG([-Dsub-configure], [CFLAGS])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

Makefiles печатать только значение $CFLAGS в all-local цель.

Вывод выглядит так:

$ autoconf && ./configure -C >/dev/null && make | grep CFLAGS # 1st run
sub CFLAGS: -g -O2 -Dtop-configure -Dsub-configure
top CFLAGS: -g -O2 -Dtop-configure
$ ./configure -C >/dev/null && make | grep CFLAGS # 2nd run
sub CFLAGS: -g -O2 -Dtop-configure -Dsub-configure
top CFLAGS: -g -O2 -Dtop-configure
$ touch configure.ac && make | grep CFLAGS # recheck run
running CONFIG_SHELL=/bin/sh /bin/sh ./configure -C CFLAGS=-g -O2 -Dtop-configure --no-create --no-recursion
sub CFLAGS: -g -O2 -Dtop-configure -Dsub-configure
top CFLAGS: -g -O2 -Dtop-configure
$ CFLAGS=-Dexternal ./configure -C >/dev/null && make | grep CFLAGS # 1st run
sub CFLAGS: -Dexternal -Dtop-configure -Dsub-configure
top CFLAGS: -Dexternal -Dtop-configure
$ CFLAGS=-Dexternal ./configure -C >/dev/null && make | grep CFLAGS # 2nd run
sub CFLAGS: -Dexternal -Dtop-configure -Dsub-configure
top CFLAGS: -Dexternal -Dtop-configure
$ touch configure.ac && make | grep CFLAGS # recheck run
running CONFIG_SHELL=/bin/sh /bin/sh ./configure -C CFLAGS=-Dexternal -Dtop-configure --no-create --no-recursion
sub CFLAGS: -Dexternal -Dtop-configure -Dsub-configure
top CFLAGS: -Dexternal -Dtop-configure
Другие вопросы по тегам