automake Makefile.am语法
加载库
lib库加载其他库
#共享库的名称
lib_LTLIBRARIES = libxxx.la
#源文件
libxxx_la_SOURCES = xxx.cpp
#指定需要加载的lib库路径和库名称,与下面的LDADD区分
libxxx_la_LIBADD = -Lccc/lib -laaa
#编译的时候c++的环境变量,指定头文件加载路径。c语言的可以用c语言的标识
libxxx_la_CPPFLAGS = -Ibbb/include -std=c++11
可执行文件加载其他库
#可执行文件名称
bin_PROGRAMS = yyy
#源文件
yyy_SOURCES = yyy.cpp
#需要加载的lib,与编译库文件不同
yyy_LDADD = -Lccc/lib64 -lxxx
规则语法
区分c和c++
automake通过后缀区分,如果文件是x.c,那么就认为是c语言,使用c语言的环境,如果是x.cpp,就使用c++的环境(比如用g++编译)。
引入另一个mk文件
-include xxx.mk
sysconf_DATA
sysconf_DATA = aaa bbb ccc
把指定的文件aaa bbb ccc复制到编译输出目录
xxx_CFLAGS
指定c语言的flag,比如引入头文件的目录
xxx_CPPFLAGS
指定c++的flag。
输出日志调试
如果遇到了问题,比如定义的宏没有起作用,可以通过打印日志查看具体信息。在makefile中可以直接调用shell的命令,而makefile.am中则需要使用对应的函数。
automake提供了error warning info三种级别。error会退出。
$(error text…)
$(warning text…)
$(info text…)
ifdef ERROR1
$(error error is $(ERROR1))
endif
https://www.gnu.org/software/make/manual/make.html#Make-Control-Functions
AUTOMAKE_OPTIONS
在makefile.am开头可以定义automake的特性,多个设置用空格分开
AUTOMAKE_OPTIONS=xxx xxx xxx
AUTOMAKE_OPTIONS=foreign
定义生成的makefile尽可能通用,放弃一些gun的特性,一般用作跨平台编译
AUTOMAKE_OPTIONS=subdir-objects
如果有多个子目录,会把编译产物放到子目录中。默认是放到当前目录。这样可以编译维护,提高编译速度。放在子目录可以多个模块一起编译。
https://www.gnu.org/software/automake/manual/html_node/List-of-Automake-options.html
SUBDIRS
很多时候,我们的工程是有多个模块组成的,那么当编译不同模块时,需要指定不同的makefile文件。比如有类库,lib1 lib2,然后可执行文件需要依赖类库。编译的时候就需要先编译lib1 lib2,然后再编译bin文件,再链接。
如何实现嵌套分组编译和编译顺序呢?SUBDIRS提供了该功能。
SUBDIRS用于指定当前makefile.am目录下,那么子目录需要单独编译。
注意
- automek只能指定下一级目录,如果还有,就需要在下一级目录的makefile.am中再次指定
- 指定的子目录,必须有makefile.am文件,也就是必须是一次独立的编译模块。如果是当前编译模块需要的源代码,只不过放在不同目录便于管理,则不需要指定
SUBDIRS = lib src . test
编译的顺序就是按照书写顺序,比如上面,先编译lib,再编译src,再编译当前目录,再编译test
https://www.gnu.org/software/automake/manual/html_node/Subdirectories.html
遇到的问题
cd进入目录
在Makefile.am或者Makefile中,cd只针对当前行生效,所以如果想进入某个目录执行,需要写成
cd xxx && bash test.sh
makefile:4: *** missing separator. Stop
makefiel使用tab作为层级表示,不可以使用空格
https://www.gnu.org/software/make/manual/make.html#Rule-Introduction