Вопрос или проблема
Эта строка, к примеру
AC_DEFINE_UNQUOTED([SOME_MACRO_NAME], "$SOME_VALUE", [некоторый комментарий])
генерирует
printf "%s\n" "#define SOME_MACRO_NAME \"$SOME_VALUE\"" >>confdefs.h
как строку в configure
.
А что-то вроде следующего в config.h
после выполнения configure
:
/* некоторый комментарий */
#define SOME_MACRO_NAME "<расширенное значение $SOME_VALUE здесь>"
Как бы я мог сделать так, чтобы это вместо этого производило следующее?
/* некоторый комментарий */
#ifndef SOME_MACRO_NAME
#define SOME_MACRO_NAME "<расширенное значение $SOME_VALUE здесь>"
#endif
Конечно, я могу добавить некоторые строки printf
вручную или создать пользовательскую функцию, но разве не должно быть идиоматического способа сделать это уже? Любой из методов, о которых я упомянул, является хаком, так как я утверждаю, что confdefs.h
– это файл, который временно создается.
Я уже вижу, что люди могут предложить протестировать $SOME_VALUE
, возможно, через AS_IF
или m4_if
(или любые из их применимых вариантов), но это различные случаи использования. Я могу захотеть сделать переменную переопределяемой через autoreconf
, через ./configure
или через CFLAGS
с опцией -D
. Это зависит. Но сейчас я просто хочу ответ на это.
Также кто-то может предложить использовать шаблон. Пожалуйста, пожалуйста, нет.
Ответ или решение
Для того чтобы обернуть вывод команды AC_DEFINE_UNQUOTED
вокруг директив #ifndef
и #endif
, вам потребуется немного изменить логику в вашем файле конфигурации. В данной ситуации можно воспользоваться удобством расширяемости системы Autoconf
и настроить макрос для достижения желаемого результата.
Вот пошаговая инструкция, как сделать это в самом простом виде:
-
Создание собственного макроса: Вам нужно создать собственный макрос, который будет встраивать
#ifndef
и#endif
вокруг вызоваAC_DEFINE_UNQUOTED
. Это можно сделать в файлеconfigure.ac
. -
Определение нового макроса:
В вашем
configure.ac
добавьте следующий код:m4_define([AC_DEFINE_UNQUOTED_IFNDEF], [AC_DEFINE_UNQUOTED([$1], "$2", [$3]) AC_MSG_NOTICE([ Producing #ifndef directive for $1]) AC_MSG_RESULT([#ifndef $1 #define $1 "$2" #endif])])
Здесь
[$1]
— это имя макроса,[$2]
— значение, а[$3]
— комментарий. -
Использование нового макроса: Воспользуйтесь созданным макросом вместо стандартного вызова
AC_DEFINE_UNQUOTED
в вашемconfigure.ac
.Пример вызова:
AC_DEFINE_UNQUOTED_IFNDEF([SOME_MACRO_NAME], ["$SOME_VALUE"], [some comment])
-
Генерация файла
config.h
: После выполнения этой настройки и запуска команды./configure
, вconfig.h
будет сгенерирован следующий код:/* some comment */ #ifndef SOME_MACRO_NAME #define SOME_MACRO_NAME "<значение переменной $SOME_VALUE здесь>" #endif
Таким образом, реализация данного подхода предоставит вам возможность удобно сохранять ваши определения макросов в виде, который вы хотите, и при этом избежать ручного редактирования файлов вывода конфигурации.
Это решение позволяет вам избежать использования неподходящих методов, таких как ручное добавление printf
строк или создание сложных шаблонов. Создание простого макроса — это идиоматический способ достижения желаемого результата в Autoconf
, который сохраняет чистоту и читаемость вашей конфигурации.