Конфликт PACKAGE_NAME и других макросов при использовании автоинструментов - PullRequest
2 голосов
/ 03 апреля 2010

При использовании автоинструментов (с файлом config.h) как для библиотеки, так и для программного обеспечения, построенного на этой библиотеке, компилятор жалуется на переопределение некоторых макросов (PACKAGE_NAME, PACKAGE_TARNAME и т. Д.).

Как я могу предотвратить это?

Файл config.h необходим в библиотеке для распространения его настроек в программном обеспечении, которое его использует.

Прямо сейчас у меня есть скрипт-оболочка library_config.h, который включает в себя исходный config.h и предоставляет значения по умолчанию, когда пользователь не использует автоинструменты, но даже отменяет определение макросов в этом пакете. Я получаю предупреждение о переопределении от gcc.

#ifndef LIB_CONFIG_H
#define LIB_CONFIG_H
#ifdef HAVE_CONFIG_H
#  include "config.h"
#  undef PACKAGE
#  undef PACKAGE_BUGREPORT
#  undef PACKAGE_NAME
#  undef PACKAGE_STRING
#  undef PACKAGE_TARNAME
#  undef PACKAGE_VERSION
#  undef VERSION
#else
#  if defined (WIN32)
#    define HAVE_UNORDERED_MAP 1
#    define TR1_MIXED_NAMESPACE 1
#  elif defined (__GXX_EXPERIMENTAL_CXX0X__)
#    define HAVE_UNORDERED_MAP 1
#  else
#    define HAVE_TR1_UNORDERED_MAP 1
#  endif
#endif
#endif

Я считаю, что наилучшим вариантом было бы иметь библиотеку без этих макросов: как можно избежать определения PACKAGE, PACKAGE_NAME и т. Д. В библиотеке при использовании автоинструментов?

РЕДАКТИРОВАТЬ: попытаться объяснить лучше.

При использовании макроса AC_CONFIG_HEADER в библиотеке configure.ac я создаю файл config.h с множеством полезных определений. Это определение полезно для самой библиотеки (как для ее скомпилированной части, так и для ее заголовочных файлов) И для клиентского программного обеспечения. Жаль, однако, что AC_CONFIG_HEADER смешивает нужные мне полезные макросы с другими универсальными определениями с фиксированными именами (PACKAGE, PACKAGE_NAME), которые конфликтуют, когда autotools используются также для конфигурации клиентского программного обеспечения.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2010

Если ваше приложение может динамически связываться с библиотекой, не имеет смысла статически встраивать статические строки из библиотеки в приложение.

В противном случае вы можете искать ax_prefix_config_h.m4.

Я бы все-таки просто попытался избежать установки файла config.h и определить API библиотеки, не прибегая к config.h:

/* library.h */
const char library_version[];

/* library.c */
#include "library.h"
#include "config.h" /* the library's config.h */
const char library_version[] = PACKAGE_VERSION;

/* application.c */
#include "library.h"
#include "config.h" /* the application's config.h */
int main()
{
   print("This is app version %s.\n", PACKAGE_VERSION);
   print("The library is version %s\n", library_version);
   return 0;
}

Убедитесь, что заголовочные файлы публичной библиотеки не #include "config.h" и библиотека не устанавливает свои config.h.

1 голос
/ 04 апреля 2010

Вы должны иметь возможность обозначить библиотеку как «подпакет» программного обеспечения, вызвав AC_CONFIG_SUBDIRS([library]) в программном обеспечении configure.ac. Это должно устранить конфликты, и параметры конфигурации верхнего уровня будут по-прежнему распространяться до подпакета.

Вот ссылка на страницу руководства Autoconf, описывающую эту функцию: http://www.gnu.org/software/hello/manual/automake/Subpackages.html

...