Большая часть функциональности Automake направлена на то, чтобы облегчить компиляцию программ и библиотек.
В каталоге, содержащем исходные тексты, из которых будет построена
программа (в отличие от библиотеки), в основном используется
макрос `PROGRAMS'. Программы могут быть установлены в каталоги
bindir
, sbindir
, libexecdir
, pkglibdir
, или же
вообще не устанавливаться (`noinst').
Например:
bin_PROGRAMS = hello
В этом простом примере результирующий `Makefile.in' будет
содержать код для генерации программы с именем hello
. Переменная
hello_SOURCES
используется для указания того, какие файлы
исходных текстов будут использованы для компиляции исполняемого файла:
hello_SOURCES = hello.c version.c getopt.c getopt1.c getopt.h system.h
В результате этого каждый упомянутый в этой переменной файл `.c' будет скомпилирован в соответствующий файл `.o'. Затем все они компонуются для создания `hello'.
Если переменная `prog_SOURCES' необходима, но не указана, то она получает значение по умолчанию, равное единственному файлу `prog.c'.
В одном каталоге могут компилироваться несколько программ. Эти программы могут совместно использовать один и тот же исходный файл, который должен быть указан в каждом определении `_SOURCES'.
Заголовочные файлы, перечисленные в определении `_SOURCES', включаются в дистрибутив, а в других случаях игнорируются. В том случае, если это не очень удобно, вы не должны включать файл, созданный `configure' в переменную `_SOURCES'; этот файл не должен распространяться. Файлы Lex (`.l') и Yacc (`.y') также должны быть перечислены; смотрите раздел section Поддержка Yacc и Lex.
Automake должен знать все файлы исходных текстов, которые могут
участвовать в компиляции программы, даже если не все файлы будут
использоваться в каждом конкретном случае. Файлы, которые компилируются
только при выполнении определенных условий, должны быть перечислены в
соответствующей переменной `EXTRA_'. Например, если
`hello-linux.c' будет, в зависимости от условий, включен в
программу hello
, то файл `Makefile.am' должен содержать:
EXTRA_hello_SOURCES = hello-linux.c
Иногда также полезно аналогичным образом определить во время
конфигурации, какие программы будут скомпилированы. Например, GNU cpio
создает программы mt
и rmt
только при выполнении определенных
условий.
В этом случае вы должны уведомить Automake обо всех программах, которые
могут быть построены, но в то же время заставить сгенерированный файл
`Makefile.in' использовать программы, заданные при выполнении
configure
. Это делается подстановкой значений при выполнении
configure
в каждом определении `_PROGRAMS'. А все
программы, которые можно создать, перечисляются в переменной
EXTRA_PROGRAMS
.
Если вы хотите скомпоновать программу с библиотеками, которые не найдены
configure
, то для этого вы должны использовать переменную
LDADD
. Эта переменная может использоваться для добавления ключей
в командную строку компоновщика.
Иногда несколько программ компилируются в одном каталоге, но при этом у
них различные требования к компоновке. В этом случае для
переопределения глобальной переменной LDADD
вы можете
использовать переменную `prog_LDADD' (где prog является
именем программы, как оно появляется в некоторых переменных
`_PROGRAMS', и обычно записывается буквами в нижнем регистре). Если
эта переменная существует для заданной программы, то программа
компонуется без использования LDADD
.
Например, в GNU cpio, pax
, cpio
и mt
компонуются с
библиотекой `libcpio.a'. Однако, программа rmt
, создаваемая в том же
каталоге, не имеет такого требования к компоновке. Более того, программы
mt
и rmt
создаются только на определенных типах машин. Вот
как выглядит `src/Makefile.am' из поставки cpio (в сокращенном
виде):
bin_PROGRAMS = cpio pax @MT@
libexec_PROGRAMS = @RMT@
EXTRA_PROGRAMS = mt rmt
LDADD = ../lib/libcpio.a @INTLLIBS@
rmt_LDADD =
cpio_SOURCES = ...
pax_SOURCES = ...
mt_SOURCES = ...
rmt_SOURCES = ...
`prog_LDADD' не подходит для передачи специфических для программы флагов компоновщика (за исключением `-l' и `-L'). Для передачи таких флагов используйте переменную `prog_LDFLAGS'.
Также иногда полезно собирать программу, в зависимости от цели, которая не является частью этой программы. Это может быть сделано с использованием переменной `prog_DEPENDENCIES'. Каждая программа зависит от содержимого такой переменной, но никакой дополнительной интерпретации не производится.
Если переменная `prog_DEPENDENCIES' не определена, то она будет вычислена Automake. Автоматически присвоенная ей величина является содержимым переменной `prog_LDADD' с большинством подстановок configure. Ключи `-l' и `-L' удаляются. Остающимися подстановками configure являются только `@LIBOBJS@' и `@ALLOCA@'; они остаются потому, что они заведомо не приведут к генерации неправильных значений для `prog_DEPENDENCIES'.
Построение библиотеки по большей части аналогично построению программы.
В этом случае именем основной переменной является `LIBRARIES'. Библиотеки могут
быть установлены в каталоги libdir
или в pkglibdir
.
Смотрите See section Построение разделяемых библиотек, для получения информации о том, как компилировать разделяемые библиотеки, используя программу Libtool и основную переменную `LTLIBRARIES'.
Каждая переменная `_LIBRARIES' является списком библиотек, которые
должны быть построены. Например, для того, чтобы создать библиотеку с
именем `libcpio.a', но не устанавливать ее, вы должны написать:
noinst_LIBRARIES = libcpio.a
Файлы исходных текстов для библиотек определяются точно так же, как и для программ, через переменные `_SOURCES'. Заметьте, что имя библиотеки является канонизированным (see section Как именуются порожденные переменные), так что переменная `_SOURCES' для `liblob.a' является равной `liblob_a_SOURCES', а не `liblob.a_SOURCES'.
Дополнительные объекты могут быть добавлены в библиотеку, используя
переменную `library_LIBADD'. Это можно использовать для
объектов, определенных configure
. Опять пример из cpio
:
libcpio_a_LIBADD = @LIBOBJS@ @ALLOCA@
Automake явно распознает использование переменных @LIBOBJS@
и
@ALLOCA@
, и использует эту информацию вместе со списком файлов
LIBOBJS
, полученным из `configure.in', для автоматического
включения соответствующих файлов исходных текстов в дистрибутив
(see section Что войдет в дистрибутив). Эти файлы исходных текстов также обрабатываются для
автоматического определения зависимостей; смотрите раздел
See section Автоматическое отслеживание зависимостей.
Использование @LIBOBJS@
и @ALLOCA@
распознается в
переменных `_LDADD' и `_LIBADD'.
Построение разделяемой библиотеки является относительно сложной задачей. Для помощи в платформонезависимом построении разделяемых библиотек была создана программа GNU Libtool (see section `Introduction' in Libtool Manual).
Automake использует Libtool для построения библиотек, указанных в
переменной `LTLIBRARIES'. Каждая переменная `_LTLIBRARIES'
является списком разделяемых библиотек, которые нужно
построить. Например, для создания библиотеки с именем
`libgettext.a' и соответствующей ей разделяемой библиотеки, а также
их установки в `libdir', вы должны написать:
lib_LTLIBRARIES = libgettext.la
Заметьте, что разделяемые библиотеки должны быть установлены, так
что использование check_LTLIBRARIES
не разрешено. Однако же,
разрешено использование переменной noinst_LTLIBRARIES
. Эта
возможность должна быть использована для "готовых библиотек" libtool.
Для каждой библиотеки переменная `library_LIBADD' содержит имена дополнительных объектов libtool (файлы `.lo'), которые будет добавляться в разделяемую библиотеку. Переменная `library_LDFLAGS' содержит любые дополнительные флаги libtool, такие как `-version-info' или `-static'.
В то время как обычные библиотеки могут включать @LIBOBJS@
,
библиотеки, использующие libtool, должны использовать
@LTLIBOBJS@
. Это требуется, поскольку имена объектных файлов,
над которыми работает libtool, не обязательно оканчиваются на
`.o'. Руководство по libtool содержит более детальное описание этой
темы.
Для библиотек, устанавливаемых в некоторый каталог, Automake будет
автоматически снабжать их соответствующим ключом `-rpath'. Однако
для библиотек, определенных во время конфигурации (и таким образом
перечисленных в переменной EXTRA_LTLIBRARIES
), Automake не знает
возможных каталогов установки; для таких библиотек вы должны сами
добавить ключ `-rpath' в соответствующую переменную
`_LDFLAGS'.
Для подробного описания смотрите @xref{Использование Automake, Использование Automake с Libtool, libtool, Libtool Manual}.
Иногда полезно знать, какие переменные `Makefile' Automake использует для компиляции; например, вам в некоторых случаях может быть необходимо использовать ваш собственный способ компиляции.
Некоторые переменные наследуются от Autoconf: это CC
,
CFLAGS
, CPPFLAGS
, DEFS
, LDFLAGS
и
LIBS
.
Также есть некоторые дополнительные переменные, определенные самим Automake:
INCLUDES
AC_CONFIG_HEADER
или
AM_CONFIG_HEADER
).
INCLUDES
может быть использован для других ключей cpp
, а
не только для `-I'. Например, эта переменная используется для
передачи специальных ключей `-D' вашему компилятору.
COMPILE
LINK
В Automake есть некоторая поддержка Yacc и Lex.
Automake предполагает, что файлы с расширением `.c', которые
создаются yacc
(или lex
) должны называться точно так же, как
и входной файл. Это значит, что при использовании исходного yacc-файла
`foo.y' Automake будет считать, что промежуточный файл будет
называться `foo.c' (а не более традиционно, `y.tab.c').
Расширение имени yacc-файла используется для определения расширения имени готового файла на языках `C' или `C++'. Файлы с расширением `.y' будут превращены в файлы с расширением `.c'; аналогично `.yy' станут `.cc'; `.y++' станут `c++'; и `.yxx' станут `.cxx'.
Подобным образом исходные тексты на lex
могут быть использованы для
создания файлов на `C' или `C++'; распознаются файлы с
расширениями `.l', `.ll', `.l++' и `.lxx'.
Вы не должны явно упоминать промежуточные файлы (на `C' или `C++') в переменных `SOURCES'; вы должны указывать только список исходных файлов.
Промежуточные файлы, созданные yacc
(или lex
), будут
включены в созданный дистрибутив. Таким образом, пользователю
не обязательно иметь у себя yacc
или lex
.
Если был обнаружен исходный текст на yacc
, то ваш файл
`configure.in' должен определить переменную `YACC'. Это легко
делается макросом `AC_PROG_YACC' (see section `Проверка отдельных программ' in Руководство Autoconf).
Аналогичным образом, если есть исходный текст lex
, то в
`configure.in' должна быть определена переменная `LEX'. Вы
можете использовать для этого макрос `AC_PROG_LEX'
(see section `Проверка отдельных программ' in Руководство Autoconf). Поддержка lex
в Automake также требует
использования макроса `AC_DECL_YYTEXT' -- automake необходимо знать
значение `LEX_OUTPUT_ROOT'. Все эти тонкости обрабатываются при использовании
макроса AM_PROG_LEX
(see section Макросы Autoconf, поставляемые с Automake).
Automake делает возможным включение в одну программу нескольких исходных
файлов yacc
(или lex
). Для запуска yacc
(или
lex
) в подкаталогах Automake использует небольшую программу,
ylwrap
. Это необходимо, поскольку имя выходного файла
yacc является фиксированным, а параллельное выполнение make может
одновременно запустить несколько экземпляров yacc
. Программа
ylwrap
распространяется вместе с Automake. Она должна быть в
каталоге, указанном переменной `AC_CONFIG_AUX_DIR' (see section `Нахождение ввода `configure'' in Руководство Autoconf) или в
текущем каталоге, если данный макрос не используется в
`configure.in'.
Для yacc
, недостаточно просто управлять блокировками.
Результирующий файл
yacc
всегда использует внутри одни и те же
имена символов, так что невозможно скомпоновать два парсера yacc
в одну и ту же программу.
Мы рекомендуем использование следующего приема с переименованием
объектов, который используется в gdb
:
#define yymaxdepth c_maxdepth
#define yyparse c_parse
#define yylex c_lex
#define yyerror c_error
#define yylval c_lval
#define yychar c_char
#define yydebug c_debug
#define yypact c_pact
#define yyr1 c_r1
#define yyr2 c_r2
#define yydef c_def
#define yychk c_chk
#define yypgo c_pgo
#define yyact c_act
#define yyexca c_exca
#define yyerrflag c_errflag
#define yynerrs c_nerrs
#define yyps c_ps
#define yypv c_pv
#define yys c_s
#define yy_yys c_yys
#define yystate c_state
#define yytmp c_tmp
#define yyv c_v
#define yy_yyv c_yyv
#define yyval c_val
#define yylloc c_lloc
#define yyreds c_reds
#define yytoks c_toks
#define yylhs c_yylhs
#define yylen c_yylen
#define yydefred c_yydefred
#define yydgoto c_yydgoto
#define yysindex c_yysindex
#define yyrindex c_yyrindex
#define yygindex c_yygindex
#define yytable c_yytable
#define yycheck c_yycheck
#define yyname c_yyname
#define yyrule c_yyrule
Для каждого `#define' замените префикс `c_' на то, что вы
хотите использовать. Эти определения работают для программ bison
,
byacc
и традиционных yacc
. Если вы обнаружили, что какой-нибудь
генератор парсеров использует символы, не указанные в этом списке, то
сообщите нам новое имя, чтобы мы добавили его.
Automake полностью поддерживает C++.
Любой пакет, содержащий код на C++, должен определить переменную
`CXX' в файле `configure.in'; самым простым способом сделать
это является использование макроса AC_PROG_CXX
(see section `Проверка отдельных программ' in Руководство Autoconf).
Несколько дополнительных переменных определяются при обнаружении исходных файлов на C++:
CXX
CXXFLAGS
CXXCOMPILE
CXXLINK
Automake полностью поддерживает Fortran 77.
Любой пакет, содержащий исходные тексты на языке Fortran 77, должен
определить выходную переменную `F77' в файле `configure.in';
самым простым способом является использование макроса AC_PROG_F77
(see section `Проверка отдельных программ' in Руководство Autoconf). See section Использование Fortran 77 с Autoconf.
При использовании исходных текстов на Fortran 77 определяются несколько дополнительных переменных:
F77
FFLAGS
RFLAGS
F77COMPILE
FLINK
Automake может вдобавок к компиляции выполнять предварительную обработку исходных файлов на Fortran 77 и Ratfor(1). Automake также содержит некоторую поддержку для создания программ и разделяемых библиотек, которые написаны на смеси Fortran 77 и других языков (see section Использование Fortran 77 с C и C++).
Это описывается в следующих разделах.
Файл `N.f' автоматически создается из файла `N.F' или `N.r'. Это правило запускает препроцессор для преобразования исходных текстов Fortran 77 или Ratfor с директивами препроцессора в строгий исходный текст Fortran 77. Вот точные команды, которые используются для этого:
$(F77) -F $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_FFLAGS) $(FFLAGS)
$(F77) -F $(AM_FFLAGS) $(FFLAGS) $(AM_RFLAGS) $(RFLAGS)
`N.o' автоматически создается из `N.f', `N.F' или `N.r' запуском компилятора Fortran 77. Для компиляции используются следующий команды:
$(F77) -c $(AM_FFLAGS) $(FFLAGS)
$(F77) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_FFLAGS) $(FFLAGS)
$(F77) -c $(AM_FFLAGS) $(FFLAGS) $(AM_RFLAGS) $(RFLAGS)
В настоящее время Automake предоставляет ограниченную поддержку создания программ и разделяемых библиотек, которые являются смесью Fortran 77 и C и/или C++. Однако существует много других вопросов, возникающих при смешивании кода на Fortran 77 с кодом на других языках, которые в настоящее время не обрабатываются Automake, но обрабатываются другими пакетами(2).
Automake может предоставить вам помощь двумя способами:
FLIBS
макросом Autoconf AC_F77_LIBRARY_LDFLAGS
,
который поставляется со свежими версиями Autoconf (Autoconf версии 2.13
и выше). See section `Характеристики компилятора Fortran 77' in Autoconf.
Если Automake определяет, что программа или разделяемая библиотека
(упомянутые в каких-либо основных переменных _PROGRAMS
или
_LTLIBRARIES
) содержит исходный код, который является смесью
Fortran 77 и C и/или C++, то он требует вызова макроса
AC_F77_LIBRARY_LDFLAGS
в файле `configure.in', и чтобы в
соответствующей переменной _LDADD
(для программ) или
_LIBADD
(для разделяемых библиотек) появились ссылки либо на
$(FLIBS)
, либо на @FLIBS@
. От человека, пишущего
`Makefile.am', требуется убедиться, что переменные
$(FLIBS)
или @FLIBS@
находятся в соответствующих
переменных _LDADD
или _LIBADD
.
Например, рассмотрим следующий `Makefile.am':
bin_PROGRAMS = foo
foo_SOURCES = main.cc foo.f
foo_LDADD = libfoo.la @FLIBS@
pkglib_LTLIBRARIES = libfoo.la
libfoo_la_SOURCES = bar.f baz.c zardoz.cc
libfoo_la_LIBADD = $(FLIBS)
В этом случае Automake будет настаивать, чтобы макрос
AC_F77_LIBRARY_LDFLAGS
был упомянут в `configure.in'. Более
того,
если переменная @FLIBS@
не была упомянута в переменной
foo_LDADD
и libfoo_la_LIBADD
, то Automake выдаст
предупреждение.
Следующая диаграмма показывает, как Automake производит выбор соответствующего компоновщика.
Например, если используемый код на Fortran 77, C и C++ компонуется в
одну программу, то выбирается компоновщик C++. В этом случае, если
компоновщики C или Fortran 77 требуют какие-либо специальные библиотеки,
которые не подключаются компоновщиком C++, то они должны быть вручную
добавлены пользователем в переменные _LDADD
или _LIBADD
файла `Makefile.am'.
\ Linker
source \
code \ C C++ Fortran
----------------- +---------+---------+---------+
| | | |
C | x | | |
| | | |
+---------+---------+---------+
| | | |
C++ | | x | |
| | | |
+---------+---------+---------+
| | | |
Fortran | | | x |
| | | |
+---------+---------+---------+
| | | |
C + C++ | | x | |
| | | |
+---------+---------+---------+
| | | |
C + Fortran | | | x |
| | | |
+---------+---------+---------+
| | | |
C++ + Fortran | | x | |
| | | |
+---------+---------+---------+
| | | |
C + C++ + Fortran | | x | |
| | | |
+---------+---------+---------+
Имеющаяся в Automake поддержка Fortran 77 требует наличия свежей версии Autoconf, которая поддерживает Fortran 77. Полная поддержка Fortran 77 была добавлена в Autoconf 2.13, так что вы можете использовать эту версию Autoconf или более позднюю.
В настоящее время Automake включает в себя полную поддержку только C, C++ (see section Поддержка C++) и Fortran 77 (see section Поддержка Fortran 77). Поддержка других языков находится в зачаточном состоянии и будет улучшена по требованию пользователей.
Хотя стандарты GNU позволяют использование ANSI C, это может привести к ограничению переносимости пакета на некоторые старые компиляторы (особенно SunOS).
Automake позволяет вам обойти проблему с такими машинами путем де-ANSI-фикации каждого исходного файла перед компиляцией.
Если в `Makefile.am' переменная AUTOMAKE_OPTIONS
(see section Изменение поведения Automake) содержит ключ ansi2knr
, то в генерируемый
файл `Makefile.in' будет вставлен код для де-ANSI-фикации.
Это заставит считать каждый исходный текст на языке C соответствующим
ANSI C. Если доступен компилятор, соответствующий ANSI C,
то он будет использован. В противном случае для
преобразования исходных файлов в стандарт K&R будет использована
программа ansi2knr
, а затем преобразованные файлы будут
скомпилированы.
Программа ansi2knr
совершенно бесхитростна. Она предполагает, что
исходный текст будет отформатирован определенным способом; подробное
описание находится на странице руководства по ansi2knr
.
Поддержка де-ANSI-фикации требует наличия файлов `ansi2knr.c' и
`ansi2knr.1' в том же пакете, где находятся и исходные тексты на
ANSI C; эти файлы поставляются в комплекте Automake. Файл
`configure.in' должен также содержать вызов макроса
AM_C_PROTOTYPES
(see section Макросы Autoconf, поставляемые с Automake).
Automake также работает в тех случаях, когда файлы ansi2knr
находятся в другом подкаталоге текущего пакета. Это делается добавлением
в опцию ansi2knr
относительного пути к соответствующему
каталогу. Например, предположим, что исходные тексты на ANSI C
располагаются в подкаталогах `src' и `lib'. Файлы
`ansi2knr.c' и `ansi2knr.1' находятся в подкаталоге
`lib'. Вот что должно быть написано в `src/Makefile.am':
AUTOMAKE_OPTIONS = ../lib/ansi2knr
Если никакой префикс не задан, то считается, что файлы находятся в текущем каталоге.
Файлы, перечисленные в переменной LIBOBJS
и нуждающиеся в
де-ANSI-фикации, не будут обрабатываться автоматически. Это происходит
из-за того, что configure
будет генерировать имена объектных
файлов в виде `regex.o', в то время как make
будет искать
`regex_.o' (при выполнении де-ANSI-фикации). В конечном счете эта
проблема может быть решена с помощью методов autoconf
, но для
этого вы должны поместить следующий код в ваш файл `configure.in',
как раз перед вызовом макроса AC_OUTPUT
:
# This is necessary so that .o files in LIBOBJS are also built via
# the ANSI2KNR-filtering rules.
LIBOBJS=`echo $LIBOBJS|sed 's/\.o /\$U.o /g;s/\.o$/\$U.o/'`
Для разработчика зачастую мучительно бывает постоянно обновлять файл `Makefile.in' при изменении зависимостей включаемых в проект файлов. Automake предоставляет возможность автоматического отслеживания изменения зависимостей и записи информации о них в сгенерированный `Makefile.in'.
В настоящее время эта поддержка требует использования GNU make
и
gcc
. В будущем может быть возможным поставка другой программы
генерации зависимостей, если это будет требоваться. По умолчанию этот
режим разрешен, если в текущем каталоге определена любая программа или
библиотека на C, так что вы можете получить от не-GNU make ошибку
`Должен быть разделитель'.
Когда вы решаете создать дистрибутив, то цель dist
перезапустит
automake
с ключом `--include-deps' и другими
ключами. See section Создание файла `Makefile.in', и section Изменение поведения Automake. При этом предварительно
сгенерированные зависимости будут помещены в созданный
`Makefile.in' и, таким образом, они окажутся в дистрибутиве. При
этом в дистрибутив код генерации зависимостей не будет включен в
дистрибутив, так что человек, загрузивший ваш дистрибутив и не
использующий GNU make
и gcc
, не получит ошибки.
При добавлении зависимостей в `Makefile.in', из них автоматически удаляются все специфические для данной системы зависимости. Это может быть сделано перечислением файлов в переменной `OMIT_DEPENDENCIES'. Например, Automake удаляет все ссылки на системные заголовочные файлы. Иногда полезно указать, чтобы были удалены отдельные заголовочные файлы. Например, если ваш файл `configure.in' использует макрос `AM_WITH_REGEX', то любая зависимость от файла `rx.h' или `regex.h' должны быть удалена, потому что правильное значение не может быть известно до того, как пользователь выполнит конфигурацию пакета.
Оказывается, Automake достаточно умен для обработки именно этого случая использования заголовочных файлов библиотеки регулярных выражений. Он также автоматически убирает зависимость от `libintl.h' при использовании `AM_GNU_GETTEXT'.
Автоматическое отслеживание зависимостей может быть запрещено помещением
no-dependencies
в переменную AUTOMAKE_OPTIONS
.
Если вы распаковываете дистрибутив, созданный make dist
, и
хотите включить отслеживание зависимостей, то просто перезапустите
automake
.
Файлы зависимостей помещаются в подкаталог с именем `.deps' каталога, где происходит построение. Эти зависимости являются специфическими для машины. Можете удалить их, если хотите; они будут автоматически пересозданы при следующей сборке.
Go to the first, previous, next, last section, table of contents.