Как это достигается с помощью автоинструментов, следуя рекомендациям и соглашениям?
Есть две части:
- Определение требуемых подсистем / поддерживается и
- Ограничение сборки только выбранными подсистемами.
Идентификация подсистем для поддержки
Первая часть - это хлеб и масло Autoconf. Как правило, проверяет наличие библиотеки каждого подсистемы (-ies) через AC_CHECK_LIB()
или AC_SEARCH_LIBS()
, чтобы определить, доступна ли она, а также проверяет основной заголовочный файл (ы). ) через AC_CHECK_HEADER()
или AC_CHECK_HEADERS()
.
Было бы удобно также настроить механизм отказа от поддержки здания для некоторых доступных подсистем. Это могло бы принять форму установки --without
или --disable
аргументов (какой из них выбрать часто неоднозначен). Это не обязательно, но я бы посчитал это хорошим тоном. Тем не менее, обратите внимание, что это требует некоторого внимания и осторожности, чтобы не включать в ссылку все найденные библиотеки.
Версия Cadilla c, кроме того, предоставит поддержку пользователю, указывающему, где найти нужные библиотеки и заголовки. в случае, если они не находятся в пути поиска по умолчанию. Я часто вижу подобные вещи в хорошо поддерживаемых проектах, но это поднимает сложность на уровень, и я не считаю это никоим образом обязательным.
Детали реализации могут варьироваться довольно широко, но обычно конечный результат для каждой подсистемы будет
- переменной оболочки, указывающей, включать ли подсистему в сборку (например,
build_oss
) и - ( (необязательно) выходные переменные (созданные с помощью
AC_SUBST()
), передающие флаги препроцессора / компилятора / и / или компоновщика, которые будут использоваться для построения в соответствии с соответствующей внутренней библиотекой. Например, некоторые или все из OSS_CPPFLAGS
, OSS_CXXFLAGS
, OSS_LIBS
для части OSS.
Ограничение сборки выбранными подсистемами
Automake и Autoconf работают вместе на это. Ключевым инструментом является условное Automake . Automake предоставляет макрос Autoconf, AM_CONDITIONAL
, для их определения и назначения их значений, и поддерживает конструкцию if
/ then
/ else
в Makefile.am
файлах на их основе. (Обратите внимание, что они полностью отделены от условных выражений GNU make
, хотя и имеют сходный синтаксис.)
Раздел руководства Automake, который я связал, относится к нескольким другим, в которых обсуждается, как следует использовать условные выражения в различных Scenar ios, и не совсем понятно, какие из них относятся к вам. Однако я думаю, что все, что вам действительно нужно, это условные источники , поэтому я сосредоточусь на этом.
Часть Autoconf будет следовать из битов, которые я уже обсуждал. Это может быть так просто, как
AM_CONDITIONAL([oss], [test "$build_oss" = "1"])
AM_CONDITIONAL([alsa], [test "$build_alsa" = "1"])
AM_CONDITIONAL([jack], [test "$build_jack" = "1"])
В руководстве Automake приведены другие примеры.
На стороне Makefile.am
это может совпадать с чем-то вроде этого:
myprog_SOURCES = \
src/main.cc \
src/another.cc \
...
if oss
myprog_SOURCES += src/oss_output.cc
endif
if alsa
myprog_SOURCES += src/alsa_output.cc
endif
if jack
myprog_SOURCES += src/jack_output.cc
endif
Вам также необходимо позаботиться о применении флагов и библиотек для каждой подсистемы. Вы можете использовать тот же подход (и даже использовать те же самые if
блоки), что и для источников, и это было бы просто замечательно, или вы могли бы позволить configure
взять контроль над тем, как (независимо) ли он определяет какие-либо флаги для каждой подсистемы во-первых.
Вы заметите, что я замалчивал многие детали. Это довольно общий ответ на вопрос, который я должен принять как вопрос высокого уровня. Если я возьму вопрос по-другому, то он слишком широк для этого места.