1.GUN make工具在当前目录下按如下顺序搜索Makefile
GUNmakefile
makefile
Makefile
2.make的命令行选项
命令格式 含义
-C dir 读入指定目录下的Makefile
-f file 读入当前目录下的file文件作为Makefile
-i 忽略所有的命令执行错误
-I dir 指定被包含的Makefile所在的目录
-n 只打印要执行的命令,但不执行这些命令
-p 显示Make变量数据库和隐含规则
-s 在执行命令时不显示命令
-w 如果Make在执行过程中改变目录,则打印当前目录名
3.Makefile的基本结构
target:dependency_files //目标体:依赖文件
<Tab>command //命令语句
每一个command之前必须要有Tab字符
#的行为是进行注释
4.Makefile变量(大小写敏感)
object=main.o
hello: $(object)
gcc $(object) -o hello
变量包含用户自定义的变量、预定义变量、自动变量及环境变量
常见的预定义变量
命令格式 含义
AR 归档维护程序的名称,默认值为 ar。
ARFLAGS 归档维护程序的选项。
AS 汇编程序的名称,默认值为 as。
ASFLAGS 汇编程序的选项。
CC C 编译器的名称,默认值为 cc。
CFLAGS C 编译器的选项。
CPP C 预编译器的名称,默认值为 $(CC) -E。
CPPFLAGS C 预编译的选项。
CXX C++ 编译器的名称,默认值为 g++。
CXXFLAGS C++ 编译器的选项。
FC FORTRAN 编译器的名称,默认值为 f77。
FFLAGS FORTRAN 编译器的选项。
RM 文件删除程序的名称,默认值为rm -f
自动变量
命令格式 含义
$* 不包含扩展名的目标文件名称。
$+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。
$< 第一个依赖文件的名称。
$? 所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。
$@ 目标的完整名称。
$^ 所有的依赖文件,以空格分开,不包含重复的依赖文件。
$% 如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为
- #makefile
- program:$(object)
- $(CC) $^ -o $@
使用隐含规则
如果要使用隐含规则生成你需要的目标,你所需要做的就是不要写出这个目标的规则。那么,make会试图去自动推导产生这个目标的规则和命令,如果make可以自动推导生成这个目标的规则和命令,那么这个行为就是隐含规则的自动推导。当然,隐含规则是make事先约定好的一些东西。例如,我们有下面的一个Makefile:
foo : foo.o bar.o
$(CC) foo.o bar.o –o foo
我们可以注意到,这个Makefile中并没有写下如何生成foo.o和bar.o这两目标的规则和命令。因为make的“隐含规则”功能会自动为我们自动去推导这两个目标的依赖目标和生成命令。
make会在自己的“隐含规则”库中寻找可以用的规则,如果找到,那么就会使用。如果找不到,那么就会报错。在上面的那个例子中,make调用的隐含规则是,把[.o]的目标的依赖文件置成[.c],并使用C的编译命令“cc –c $(CFLAGS) [.c]”来生成[.o]的目标。也就是说,我们完全没有必要写下下面的两条规则:
foo.o : foo.c
cc –c foo.c $(CFLAGS)
bar.o : bar.c
cc –c bar.c $(CFLAGS)
因为,这已经是“约定”好了的事了,make和我们约定好了用C编译器“cc”生成[.o]文件的规则,这就是隐含规则。
当然,如果我们为[.o]文件书写了自己的规则,那么make就不会自动推导并调用隐含规则,它会按照我们写好的规则忠实地执行。
还有,在make的“隐含规则库”中,每一条隐含规则都在库中有其顺序,越靠前的则是越被经常使用的,所以,这会导致我们有些时候即使我们显示地指定了目标依赖,make也不会管。如下面这条规则(没有命令):
foo.o : foo.p
依赖文件“foo.p”(Pascal程序的源文件)有可能变得没有意义。如果目录下存在了“foo.c”文件,那么我们的隐含规则一样会生效,并会通过“foo.c”调用C的编译器生成foo.o文件。因为,在隐含规则中,Pascal的规则出现在C的规则之后,所以,make找到可以生成foo.o的C的规则就不再寻找下一条规则了。如果你确实不希望任何隐含规则推导,那么,你就不要只写出“依赖规则”,而不写命令。
Makefile中常见的隐式规则目录
对应语言的后缀 规则
C编译:“.c”变为".o" $(CC) -c $(CPPFLAGS) $(CFLAGS)
C++编译:“.cc”或“.C”变为".o" $(CXX)-c $(CPPFLAGS) $(CXXFLAGS)
Pascal编译:“.p”变为“.o” $(PC)-c$(PFLAGS)
Fortran编译:“.r”变为“.o” $(FC)-c $(FFLAGS)
6.使用自动生成工具生成Makefile(使用autotools系列工具)
安装sudo apt-get install autoconf
参考网址:
http://blog.chinaunix.net/uid-25100840-id-271131.html
http://purpleroom.blog.sohu.com/133569892.html
例子
- //hello.c
- #include <stdio.h>
- int main()
- {
- printf("Hello world!");
- return 0;
- }
ming@ming-ThinkPad-Edge:~/workspace$ autoscan
ming@ming-ThinkPad-Edge:~/workspace$ ls
autoscan.log configure.scan hello.c
生成autoscan.log和configure.scan
一、创建configure.in文件
修改configure.scan文件
- #configure.scan文件内容
- # -*- Autoconf -*-
- # Process this file with autoconf to produce a configure script.
- AC_PREREQ([2.68]) #表示文件要求的autoconf的版本
- AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
- #定义了程序的名称、版本、和错误报告地址,一般情况下BUG-REPORT-ADDRESS可以省略,用户可以根据自己的要求进行定制
- #另外还需要添加AM_INIT_AUTOMAKE()语句
- AC_CONFIG_SRCDIR([hello.c]) #检查原文件是否存在
- AC_CONFIG_HEADERS([config.h]) #用来生成config.h文件 此句和上一句一般不用修改
- # Checks for programs.
- AC_PROG_CC
- # Checks for libraries.
- # Checks for header files.
- # Checks for typedefs, structures, and compiler characteristics.
- # Checks for library functions.
- AC_OUTPUT #用来指定生成的Makefile
修改后的configure.scan并将其改名为configure.in
- <strong># -*- Autoconf -*-
- # Process this file with autoconf to produce a configure script.
- AC_PREREQ([2.68])
- AC_INIT(hello, 1.0)
- AM_INIT_AUTOMAKE(hello, 1.0)
- AC_CONFIG_SRCDIR([hello.c])
- AC_CONFIG_HEADERS([config.h])
- # Checks for programs.
- AC_PROG_CC
- # Checks for libraries.
- # Checks for header files.
- # Checks for typedefs, structures, and compiler characteristics.
- # Checks for library functions.
- AC_OUTPUT(Makefile)</strong>
其内容如下
- <strong>AUTOMAKE_OPTIONS=foreign
- bin_PROGRAMS=hello
- hello_SOURCES=hello.c</strong>
AUTOMAKE_OPTIONS用来设置automake的软件等级,可用选项有foreign,gun,gnits. foreign表示只检测必要文件
bin_PROGRAMS用来指定生成的可执行文件,多个时用空格分开
hello_SOURCES用来指定生成可执行文件的依赖文件,多个依赖文件用空格分开
三、生成configure文件
运行autoreconf命令即可生成
ming@ming-ThinkPad-Edge:~/workspace$ autoreconf -fvi
autoreconf: Entering directory `.'
autoreconf: configure.in: not using Gettext
autoreconf: running: aclocal --force
autoreconf: configure.in: tracing
autoreconf: configure.in: not using Libtool
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
configure.in:6: installing `./install-sh'
configure.in:6: installing `./missing'
Makefile.am: installing `./depcomp'
autoreconf: Leaving directory `.'
四、生成Makefile文件
通过运行configure命令即可生成Makefile文件
ming@ming-ThinkPad-Edge:~/workspace$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
五、执行make命令,完成