基本功能

格式:

1
2
目标文件名: 依赖列表
命令

直接上代码解释

1
2
3
4
5
6
7
8
9
10
11
main:main.o test1.o test2.o
gcc main.o test1.o test2.o -o main

main.o:main.c xxoo.h
gcc -c main.c -o main.o

test1.o:test1.c test.h
gcc -c test1.c -o test1.o

test2.o:test2.c test.h
gcc -c test2.c -o test2.o

要生成的最终目标main【可以是其它名字】;生成main需要main.o test1.o test2.o这三个依赖

  • 则需要写到第一行main: main.o test1.o test2.o

  • 编译命令写到第二行:gcc main.o test1.o test2.o -o main

其中-o表示输出

因为main.o test1.o test2.o这三个依赖已经编译过了,不需要-c

生成中间文件main.o,需要main.c xxoo.h 这两个依赖

  • 则需要写到第一行main.o:main.c xxoo.h

  • 编译命令:gcc -c main.c -o main.o

-c表示编译,对main.c进行编译

-o表示输出,输出到main.o。如果不指定输出名字,会保存到a.o这个文件

有时候,如果生成依赖文件需要经常变化,就直接赋值给个变量,如OBJ=main.o test.o test1.o test2.o。以此方便增添或删除依赖文件

赋值时,不需要加$符号;

调用时,需要加$()符号;【参考shell编程】

1
2
3
OBJ=main.o test.o test1.o test2.o
test:$(OBJ)
gcc -o test $(OBJ)

有时候,如果需要调用不同的gcc/g++编译器,一个个的替换很麻烦,也可以赋值给个变量,如CC=gcc

1
2
3
4
CC=gcc
OBJ=main.o test.o test1.o test2.o
test:$(OBJ)
$(CC) -o test $(OBJ)

自动化变量

自动化变量 说明
$@ 表示规则的目标文件名。如果目标是一个文档文件(Linux 中,一般成 .a 文件为文档文件,也成为静态的库文件), 那么它代表这个文档的文件名。在多目标模式规则中,它代表的是触发规则被执行的文件名。
$% 当目标文件是一个静态库文件时,代表静态库的一个成员名。
$< 规则的第一个依赖的文件名。如果是一个目标文件使用隐含的规则来重建,则它代表由隐含规则加入的第一个依赖文件。
$? 所有比目标文件更新的依赖文件列表,空格分隔。如果目标文件时静态库文件,代表的是库文件(.o 文件)。
$^ 代表的是所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的只能是所有的库成员(.o 文件)名。 一个文件可重复的出现在目标的依赖中,变量“$^”只记录它的第一次引用的情况。就是说变量“$^”会去掉重复的依赖文件。
$+ 类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库的交叉引用场合。
$* 在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“%”所代表的部分(当文件名中存在目录时,

举例

1
2
3
4
5
6
7
8
main:main.o test1.o test2.o
gcc -o $@ $^
main.o:main.c test.h
gcc -o $@ $<
test1.o:test1.c test1.h
gcc -o $@ $<
test2.o:test2.c test2.h
gcc -o $@ $<