Ожидаемый проект / структура каталогов для Automake?
Я занимаюсь разработкой статической библиотеки C и использую простой Makefile. Теперь нам приходится поддерживать установки вне офиса и все такое, и пришло время перейти к более надежному стандарту сборки. Я действительно хочу, чтобы это были автоинструменты - мне нравится автоматическое соответствие GNU Build System, и мне также было довольно легко работать с ним.
Тем не менее, у меня есть проблема.
Вот примерный план того, как проект был структурирован:
project/
common/
pkg/
inc/
src/
submodule1/
some_thing/
some_other_thing/
submodule2/
. . .
common
содержит файлы заголовков, которые будут установлены в целевой системе - один заголовок непосредственно в общем и некоторые другие вещи в общем /pkg. (Ну, это не совсем pkg, это всего лишь пример.) Все под common
является .h
,
inc
содержит внутренние включаемые файлы, которые строго относятся к реализации и не должны быть доступны. Все под inc
является .h
,
src
имеет каталог для каждого из нескольких подмодулей, и каждый из подмодулей может или не может быть разделен на части (субподмодули, если хотите). Все под src
является .c
,
Оригинальный make-файл установит SOURCES
переменная, состоящая из каждого .c
файл найден в src рекурсивно, добавить -I./common -I./inc
, создайте объектные файлы и заархивируйте их в библиотеку. Довольно просто.
Ну, с automake, это не так просто. Я разобрался с добавлением флагов к цели сборки, например `project_CPPFLAGS=-I./ Inc -I./common" - это решает часть проблемы, но я чувствую, что что-то делаю неправильно.
С этими (неоптимальными?) Настройками, я могу заставить сборку и связывание библиотеки автоматизировать, что уже достаточно интересно, но настоящая причина, по которой я здесь, - make install
,
Основная проблема заключается в следующем:
common
содержит публичный интерфейс к библиотеке, если хотите. Это необходимо для создания источников, но также необходимо установить. Если я включу это из project/
, то AutoMake увидит пути как common/thing.h
а также common/pkg/other.h
и ошибиться в путях includedir
по установке. Я думал о том, чтобы он вернул его в этот каталог для создания проекта, в котором есть только заголовки установки, но который не только плохо пахнет, но и не работал, когда я его пробовал. Заголовки библиотек нуждаются в особой древовидной структуре - как мне поддерживать древовидную структуру заголовков lib, сделать их доступными для всех исходных файлов и установить их как корневые common
?
Кроме того, есть ли более элегантный способ обработки включений, чем путем принудительного -I
? Я знаю, что должен указать их как HEADERS
чтобы получить их в дистрибутивах, но на самом деле это не делает их доступными для включения, и я немного растерялся.
Я чувствую, что automake (и, возможно, GNU в целом) ожидает некоторой структуры для моего проекта, которую я просто не вижу. Если это так, пожалуйста, скажите мне - я совершенно готов потратить некоторое время на рефакторинг / реорганизацию проекта. Я действительно чувствую, что мне не хватает какой-то философской мысли - нынешняя структура была разработана без руководства или опыта, и я никоим образом не привязан к ней.
Любая помощь приветствуется.
1 ответ
Я не вижу ничего плохого в использовании -I
, Это даже позволяет последовательно использовать #include <pkg/foo.h>
нотации как в вашем дереве, так и в сторонних проектах, использующих pkg/foo.h.
AM_CPPFLAGS = -I${top_srcdir}/common -I${top_srcdir}/inc
Чтобы установить файлы в common
Вы можете использовать SUBDIRS = common
(с верхнего уровня Makefile.am
),
# <top>/common/Makefile.am
nobase_include_HEADERS = pkg/foo.h pkg2/bar.h
или, если вы решите сделать нерекурсивный подход, что-то вроде
# <top>/Makefile.am
xxxpkgdir = ${includedir}/pkg
xxxpkg_HEADERS = common/pkg/foo.h
xxxpkg2dir = ${includedir}/pkg2
xxxpkg2_HEADERS = common/pkg2/bar.h