Как избежать переопределения ВЕРСИИ, ПАКЕТА и т. д.
Вопрос
Я не видел вопросов, касающихся сборок GNU autoconf/automake, но надеюсь, что хотя бы некоторые из вас знакомы с этим.Вот оно:
У меня есть проект (я назову его myproject), который включает в себя другой проект (поставщика).Проект поставщика — это автономный проект, поддерживаемый кем-то другим.Включение такого проекта в список вполне справедливо. простой, но в этом случае есть маленькая загвоздка:каждый проект генерирует свой собственный config.h
файл, каждый из которых определяет стандартные макросы, такие как ПАКЕТ, ВЕРСИЯ и т. д.Это означает, что во время сборки, когда собирается вендор, я получаю множество таких ошибок:
... warning: "VERSION" redefined
... warning: this is the location of the previous definition
... warning: "PACKAGE" redefined
... warning: this is the location of the previous definition
Это всего лишь предупреждения, по крайней мере пока, но хотелось бы от них избавиться.Единственная релевантная информация, которую мне удалось найти с помощью поиска в Google, это этот в списке рассылки automake, что не очень-то поможет.Есть ли у кого-нибудь еще идеи получше?
Решение
Некоторые примечания:
- ты не упомянул, как
config.h
был включен - с кавычками или угловыми скобками.Видеть это другой вопрос для получения дополнительной информации о разнице.Суммируя,config.h
обычно включается в кавычки, а не в угловые скобки, и это должно заставить препроцессор предпочестьconfig.h
из собственного каталога проекта (обычно это то, что вам нужно) - Вы говорите, что подпроект должен включать в себя включающий его проект.
config.h
Обычно это совсем не то, что вам нужно.Подпроект является автономным, и его ПАКЕТ и ВЕРСИЯ должны быть такими же, как у этого подпроекта, а не у вас.Например, если вы включаете libxml в свой проект xmlreader, вы все равно захотите, чтобы код libxml был скомпилирован с PACKAGE libxml и VERSION (какой бы ни была версия libxml). - Обычно это большая ошибка иметь
config.h
включаться из общедоступных заголовков.config.h
всегда является личным для вашего проекта или подпроекта и должен включаться только из файлов .c.Итак, если в документации вашего поставщика указано, что необходимо включить «vendor.h», и этот общедоступный заголовок включаетconfig.h
почему-то, тогда это нет-нет.Аналогично, если ваш проект является библиотекой, не включайтеconfig.h
где угодно из ваших общедоступных заголовков.
Другие советы
Это определенно хак, но я обрабатываю автоген config.h
файл:
sed -e 's/.*PACKAGE_.*//' < config.h > config.h.sed && mv config.h.sed config.h
В нашей среде сборки это допустимо, но мне бы хотелось, чтобы это было более чисто.
Оказывается, в моем случае было очень простое решение.Проект поставщика объединяет несколько заголовочных файлов в один монолитный заголовочный файл, который затем #include
d из источников поставщика.Но правило make, создающее монолитный заголовок, случайно включило сгенерированный config.h
.Наличие ПАКЕТА, ВЕРСИИ и т.д.config в монолитном заголовке — вот что вызывало предупреждения о переопределении.Оказывается, продавец config.h
не имело значения, потому что "config.h" всегда разрешался $(top_builddir)/config.h
.
Я считаю, что именно так это и должно работать.По умолчанию подпроект должен включать в себя вложенный проект. config.h
вместо своего собственного, если только подпроект явно не включает свой собственный или не манипулирует путем INCLUDE так, чтобы его собственный каталог стоял перед $(top_builddir)
, или иным образом манипулирует файлами заголовков, как в моем случае.