Изменение *FLAGS в configure.ac против кэширования с подпроектами
Скажем, я хочу добавить определенный флаг CFLAGS
в моем configure
сценарий, который должен распространяться на все подпроекты configure
скрипты:
CFLAGS+=" -Dfoobar"
export CFLAGS
AC_CONFIG_SUBDIRS([sub])
Это работает когда configure
вызывается тривиально. Как только произойдет одно из следующего:
CFLAGS
экспортируется в среду, когдаconfigure
вызываетсяCFLAGS
установлен наconfigure
командная строка- используется кеширование (
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
никогда не рассматривается как драгоценный и, следовательно, никогда не кэшируется и не передается в подпакет configure
s - они видят ее исключительно как переменную окружения, а затем сами ее кешируют на общем верхнем уровне config.cache
,
Это работает очень надежно и улучшает моё предыдущее решение, позволяя кэшировать значения даже во время прогонов конфигурирования верхнего уровня (и быть проще).
Я наконец получил это работать, за исключением кеширования на нескольких верхних уровнях configure
пробеги. Идея состоит в том, чтобы взломать внутренние переменные autoconf, чтобы получить желаемую функциональность, и это было не слишком сложно:
- модифицировать
CFLAGS
- мотыга
ac_configure_args
включить модифицированныйCFLAGS
вместо любого обнаруженного извнеCFLAGS
Это сразу решило проблемы 1. и 2. из описания проблемы (внешние CFLAGS
). Чтобы исправить кеширование, мне пришлось:
- мотыга
ac_cv_env_CFLAGS_{set,value}
содержатьset
и модифицированныйCFLAGS
соответственно
Это приводит к двум проблемам:
- с кешированием,
./config.status --recheck
выполнит модификацию CFLAGS снова, даже если эта модификация уже была кэширована, что приводит к повторным флагам. Внесение изменений, только если это не было сделано, решило эту проблему. - при вызове конфигурации верхнего уровня с существующим
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
Makefile
s печатать только значение $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