Самый простой способ обрамить выход “AC_DEFINE_UNQUOTED” вокруг #ifndef и #endif?

Вопрос или проблема

Эта строка, к примеру

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 и настроить макрос для достижения желаемого результата.

Вот пошаговая инструкция, как сделать это в самом простом виде:

  1. Создание собственного макроса: Вам нужно создать собственный макрос, который будет встраивать #ifndef и #endif вокруг вызова AC_DEFINE_UNQUOTED. Это можно сделать в файле configure.ac.

  2. Определение нового макроса:

    В вашем 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] — комментарий.

  3. Использование нового макроса: Воспользуйтесь созданным макросом вместо стандартного вызова AC_DEFINE_UNQUOTED в вашем configure.ac.

    Пример вызова:

    AC_DEFINE_UNQUOTED_IFNDEF([SOME_MACRO_NAME], ["$SOME_VALUE"], [some comment])
  4. Генерация файла config.h: После выполнения этой настройки и запуска команды ./configure, в config.h будет сгенерирован следующий код:

    /* some comment */
    #ifndef SOME_MACRO_NAME
    #define SOME_MACRO_NAME "<значение переменной $SOME_VALUE здесь>"
    #endif

Таким образом, реализация данного подхода предоставит вам возможность удобно сохранять ваши определения макросов в виде, который вы хотите, и при этом избежать ручного редактирования файлов вывода конфигурации.

Это решение позволяет вам избежать использования неподходящих методов, таких как ручное добавление printf строк или создание сложных шаблонов. Создание простого макроса — это идиоматический способ достижения желаемого результата в Autoconf, который сохраняет чистоту и читаемость вашей конфигурации.

Оцените материал
Добавить комментарий

Капча загружается...