1. make 命令与 Makefile 文件

在 Linux 平台,执行 make 命令时,会在当前目录下寻找 Makefile(或 makefile)文件,Makefile 文件说明了如何编译(compile)和链接程序(link)。

2. Makefile 语法规则

Makefile 结构分为三部分,

target : prerequisites 
    command
  • target:可以为一个 object file(目标文件,拓展名为 .o),也可以是一个可执行文件;
  • prerequisites:欲生成 target 所需的文件(比如欲生成 .o 目标文件,所需的 .c 文件和 .h 头文件,欲生成可执行文件所需的 .o 目标文件),可以有多个(以空格隔开)
  • command:
    • cc:c/c++ 的编译命令
    • -
  • Makefile 的这三部分结构,可以理解为:
    • prerequisites 为输入;
    • target 为输出;
    • command 为使输入变为输出的命令操作;

3. 一个示例

当前工程有 3 个头文件(defs.h,command.h,buffer.h),8 个 c 文件(main.c, kbd.c,display.c,insert.c,command.h,search.c,files.c,utils.c),根据上文所述规则,编写如下的 Makefile 文件:

edit : main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o       /*注释:如果后面这些.o文件比edit可执行文件新,那么才会去执行下面这句命令*/
    cc -o edit main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o

main.o : main.c defs.h
    cc -c main.c
kbd.o : kbd.c defs.h command.h
    cc -c kbd.c
command.o : command.c defs.h command.h
    cc -c command.c
display.o : display.c defs.h buffer.h
    cc -c display.c
insert.o : insert.c defs.h buffer.h
    cc -c insert.c
search.o : search.c defs.h buffer.h
    cc -c search.c
files.o : files.c defs.h buffer.h command.h
    cc -c files.c
utils.o : utils.c defs.h
    cc -c utils.c

clean :
    rm edit main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o
  • \:表示换行;

4. 使用变量

上文的 Makefile 文件未定义变量,使用变量对一些文件名进行重命名,可以简化 Makefile 文件的编写,比如对于第一条规则:

edit : main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o
    cc -o edit main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o

通过定义变量的方式可以重写为:

objects = main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o
edit : $(objects)
    cc -o edit $(objects)

...

clean : 
    rm edit $(objects)

5. 自动推导

GNU 的 make 很智能,其可以自动推导文件以及文件依赖关系后面的命令,我们便不必为每一个 .o 文件后都写上类似的命令,通过 make 的自动识别以及对命令的自动推导。

只要 make 看到一个 [.o] 文件,它就会自动的把同名 [.c] 文件加在依赖关系中,如果make找到一个whatever.o,那么 whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来,于是,我们的makefile 再也不用写得这么复杂。

objects = main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o
 cc = gcc

edit : $(objects)
    cc -o edit $(objects)

main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h

.PHONY : clean
clean :
    rm edit $(objects)
  • .PHONY:表示 clean 是一个伪目标文件;

6. Makefile 规则中的通配符

  • *:任意一个或任意多个字符;
  • ?:任意一个字符;
  • […]:ex. [abcd] 表示 a, b, c, d 中任意一个字符;
    • [^abcd]:表示除 a, b, c, d 以外的字符;
    • [0-9] 表示 0-9 中的任意一个数字;
  • ~:home 目录;
posted on 2017-07-27 18:42  未雨愁眸  阅读(263)  评论(0编辑  收藏  举报