8.构建程序和库
8.1 构建一个程序¶
为了构建一个程序,需要告知Automake哪些源是它的一部分,和它应该链接哪些库。
8.1.1 定义程序源¶
在一个包含了要被构建进程序的资源(非库或脚本)的文件夹,使用PROGRAMS
。
程序可以被安装到bindir, sbindir, libexecdir, pkglibexecdir
,或者根本不安装(noinst_),或者只在make check
的时候构建(check_)。
bin_PROGRAMS = hello
与每个程序相关联的是以程序命名的几个辅助变量。这些变量是可选的,并且有合理的默认值。下面以hello为例做出说明。
hello_SOURCES 用于指定哪些源文件被构建进入一个可执行文件:
hello_SOURCES = hello.c version.c getopt.c getopt1.c getopt.h system.h
改变量的默认变量是单个文件hello.c
。
一个文件夹可以构建多个程序。多个程序也可以共享一个单个的源文件。
8.1.2 链接程序¶
如果你想链接没有被configure发现的库,使用LDADD
变量,链接标志则使用AM_LDFLAGS
变量。
有时,多个程序在一个目录下构建,但是链接需求不同。这种情况下,可以使用 prog_LDADD 变量来覆盖LDADD
。
例如,cpio、pax、mt 与库文件 libcpio.a 链接,但是同一个目录下还有另一个程序 rmt 被构建,它不需要这个库文件。并且,mt 和 rmt 只会在特定架构下被构建。下面是 cpio 的src/Makefile.am 文件的写法:
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_LDFLAGS 传递链接标志。
8.1.3 源文件的条件编译¶
你不能放置一个配置替换(e.g., ‘@FOO@’ or ‘$(FOO)’ where FOO is defined via AC_SUBST)到_SOURCES
变量中。
但是有两个方法可以达到同样的目的:1、在_LDADD
中使用配置替换;2、使用Automake的条件语句。
1.使用_LDADD
¶
Automake必须知道所有的可能用到的源文件。任何条件构建的文件都应放到合适的EXTRA_
变量中。
例如,相要 hello-linux.c 或 hello-generic.c 有条件地构建到 hello 中:
Makefile.am:
bin_PROGRAMS = hello
hello_SOURCES = hello-common.c
EXTRA_hello_SOURCES = hello-linux.c hello-generic.c
hello_LDADD = $(HELLO_SYSTEM)
hello_DEPENDENCIES = $(HELLO_SYSTEM)
configure.ac:
case $host in
*linux*) HELLO_SYSTEM='hello-linux.$(OBJEXT)' ;;
*) HELLO_SYSTEM='hello-generic.$(OBJEXT)' ;;
esac
AC_SUBST([HELLO_SYSTEM])
hello_DEPENDENCIES and hello_LDADD保证了构建和链接。
2.使用Automake的条件语句¶
这种方式更简单。还是上述的例子:
Makefile.am:
bin_PROGRAMS = hello
hello_SOURCES = hello-common.c
if LINUX
hello_SOURCES += hello-linux.c
else
hello_SOURCES += hello-generic.c
endif
configure.ac:
AM_CONDITIONAL([LINUX],[
case $host in
*linux*) HELLO_SYSTEM='hello-linux.$(OBJEXT)' ;;
*) HELLO_SYSTEM='hello-generic.$(OBJEXT)' ;;
esac
])
你不需要定义EXTRA_
变量。
8.1.3 程序的条件编译¶
_PROGRAMS
同样可以使用 替换或条件语句
来实现目的。
1.使用configure来替换¶
bin_PROGRAMS = cpio pax $(MT)
libexec_PROGRAMS = $(RMT)
EXTRA_PROGRAMS = mt rmt
note:As explained in EXEEXT, Automake will rewrite bin_PROGRAMS, libexec_PROGRAMS, and EXTRA_PROGRAMS, appending ‘$(EXEEXT)’ to each binary. 但是如果使用了变量替换,则不会扩展后缀。
2.使用条件语句¶
bin_PROGRAMS = cpio pax
if WANT_MT
bin_PROGRAMS += mt
endif
if WANT_RMT
libexec_PROGRAMS = rmt
endif
这种方式不必担心 ‘$(EXEEXT)’ or EXTRA_PROGRAMS。
8.4 程序与库 的变量¶
有一组变量和每个程序相关,可用于修改程序的构建方式。库也类似。它们的名字呗用于命名这些变量的基础。
下面,我使用名字maude
代表程序或者库来说明这些变量。
- maude_SOURCES
- EXTRA_maude_SOURCES
- maude_LDADD
- maude_LDFLAGS
- maude_DEPENDENCIES
- EXTRA_maude_DEPENDENCIES
8.5 默认的 _SOURCES¶
_SOURCES variables are used to specify source files of programs (see A Program), libraries (see A Library), and Libtool libraries (see A Shared Library).
该变量没有被指定的时候,默认值是单个的同名 C文件 ,带有任何被AM_DEFAULT_SOURCE_EXT
替换的后缀,默认的后缀是.c
。
check_PROGRAMS = test1 test2 test3
AM_DEFAULT_SOURCE_EXT = .cpp
8.20 可执行扩展的支持¶
在一些平台,比如windows,可执行程序会被扩展成含有.exe的程序。
Automake支持大部分这种转换。
One thing you must be aware of is that, internally, Automake rewrites something like this:
bin_PROGRAMS = liver
to this:
bin_PROGRAMS = liver$(EXEEXT)
TESTS and XFAIL_TESTS
也会被重写如果在同一个Makefile中他们包含了已经被声明为程序的文件名。
但是,这个技术不能应用于configure变量替换。这意味着如果你使用了条件构建,那么你必须自己在configure.ac中添加$(EXEEXT)
扩展其后缀。
no-exeext
选项可以关闭这个特性,它会覆盖foo$(EXEEXT)
规则。