makefile使用

makefile使用规则

1.make是linux自带的构建器,构建的规则在makefile中,编译器是使用gcc。 

 

2.makefile的命名规则 

- makefile 

- Makefile

 

3.makefile的规则 

gcc a.c b.c c.c -o app 

- 三部分:目标,依赖,命令 

- 目标:依赖 

- (tab缩进)命令 

接下来,我们就开始编写第一个makefile文件:

 

head.h:

  1 #include<stdio.h>

  2 

  3 int NUM(int a);

  4 void Prin(); 

 

a.c

  1 #include"head.h"                                                            

  2 

  3 int NUM(int a)

  4 {

  5     return a;

  6 }

~                                                                               

b.c

  1 #include"head.h"                                                            

  2 

  3 void Prin()

  4 {

  5     printf("hello\n");

  6 }

~       

 

 

1.由于他们是相互依赖的关系,所以第一个makefile的文件是:

 

  1 app:main.c a.c b.c

  2     gcc main.c a.c b.c -o app 

结果:

wz@wz-machine:~/linux/MK$ make

gcc main.c a.c b.c -o app

wz@wz-machine:~/linux/MK$ ./app

5

hello

 

2.我们发现第一个效率很低,而且修改一个文件,另外的文件也需要被修改。那么我们来编写第二个文件。

  1 app:main.o a.o b.o

  2     gcc main.o a.o b.o -o app

  3 

  4 main.o:main.c

  5     gcc main.c -c

  6 a.o:a.c

  7     gcc a.c -c

  8 b.o:b.c

  9     gcc b.c -c    

结果:

wz@wz-machine:~/linux/MK$ make

gcc main.c -c

gcc a.c -c

gcc b.c -c

gcc main.o a.o b.o -o app

wz@wz-machine:~/linux/MK$ ./app 

5

hello

说明: 

工作原理: 

检测依赖是否存在: 

1.向下搜索下边的规则,如果有规则是用来生成查找的依赖,执行规则中的命令 

2.依赖存在,判断是否需要更新 

原则:目标时间>依赖时间,反之,则更新

 

缺点是太冗余 

 

3.第三个文件 

自定义变量:obj = a.o b.o c.o 

变量的取值:aa = (obj)makefile自带的变量大写:−CPPFLAGS−CC自动变量:−(obj)makefile自带的变量大写:−CPPFLAGS−CC自动变量:−@ 规则中的目标 

- <规则中的第一个依赖−<规则中的第一个依赖−^ 规则中的所有的依赖 

$@          --代表目标文件(target)

$^            --代表所有的依赖文件(components)

$<           --代表第一个依赖文件(components中最左边的那个)。

只能在规则的命令中使用 

1 obj = main.o a.o b.o 

2 target = app 

4 $(target):$(obj) 

5 gcc $(obj) -o $(target) 

7 %.o:%.c 

8 gcc -c $< -o $@ 

结果:

wz@wz-machine:~/linux/MK$ make

gcc main.o a.o b.o -o app

wz@wz-machine:~/linux/MK$ ./app

5

hello

说明: 

模式匹配: 

%o:%.c 

第一次:main.o 

main.o:main.c 

gcc -c main.c -o main.o 

第二次:add.o 

add.o:add.c 

gcc -c add.c -o add.o

 

在 GNU Make 里有一个叫 ‘wildcard’ 的函 数,它有一个参数,功能是展开成一列所有符合由其参数描述的文 件名,文件间以空格间隔。你可以像下面所示使用这个命令:

 

    SOURCES= $(wildcard *.c)    

 

这行会产生一个所有以 ‘.c’ 结尾的文件的列表,然后存入变量 SOURCES 里。当然你不需要一定要把结果存入一个变量。 

notdir把展开的文件的路径去掉,只显示文件名而不包含其路径信息,例如:

 

    FILES =$(notdir $(SOURCES))

 

这行的作用是把上面以'.c'结尾的文件的文件列表中附带的路径去掉,只显示符合条件的文件名。

 

patsubst( patten substitude, 匹配替换的缩写)函数。它需要3个参数:第一个是一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔的字列。例如,处理那个经过上面定义后的变量,

    OBJS = $(patsubst %.c,%.o,$(SOURCES))

这行将处理所有在 SOURCES列个中的字(一列文件名),如果它的 结尾是 ‘.c’ ,就用’.o’ 把 ‘.c’ 取代。注意这里的 % 符号将匹配一个或多个字符,而它每次所匹配的字串叫做一个‘柄’(stem) 。在第二个参数里, % 被解读成用第一参数所匹配的那个柄。 

 

4.我们来编写一下文件:

  1 SOURCES = $(wildcard *.c) 

  2 OBJS = $(patsubst %.c,%.o,$(SOURCES))                                       

  3 target  = app

  4 $(target):$(OBJS)

  5     gcc $^ -o $(target)

  6 

  7 %.o:%.c

  8     gcc -c $< -o $@

~                              

结果:

wz@wz-machine:~/linux/MK$ make

gcc a.o b.o main.o -o app

wz@wz-machine:~/linux/MK$ ./app

5

hello

不能清理项目 

第五个版本:

 1 SOURCES = $(wildcard *.c) 

  2 OBJS = $(patsubst %.c,%.o,$(SOURCES))

  3 target  = app

  4 $(target):$(OBJS)

  5     gcc $^ -o $(target)

  6 

  7 %.o:%.c

  8     gcc -c $< -o $@

  9 

 10 clean:

 11     rm -f $(OBJS) $(target)

 12                              

 

声明伪目标: 

.PHONY:clean 

-f:强制执行 

命令前加- 

- 忽略执行失败的命令,继续执行向下执行其余的命令

 

代码:

  1 SOURCES = $(wildcard *.c) 

  2 OBJS = $(patsubst %.c,%.o,$(SOURCES))

  3 target  = app

  4 $(target):$(OBJS)

  5     gcc $^ -o $(target)

  6 

  7 %.o:%.c

  8     gcc -c $< -o $@

  9 

 10 .PHONY:clean

 11 clean:                                                                      

 12     rm -f $(OBJS) $(target)

 13 

~                              

结果:

wz@wz-machine:~/linux/MK$ make

gcc -c a.c -o a.o

gcc -c b.c -o b.o

gcc -c main.c -o main.o

gcc a.o b.o main.o -o app

wz@wz-machine:~/linux/MK$ ./app

5

hello

wz@wz-machine:~/linux/MK$ make clean

rm -f a.o b.o main.o app

wz@wz-machine:~/linux/MK$ 

着我们就介绍完了,但是大家一定会发现一个问题,就是我们上面编译的文件只有一个main函数,那我们怎么痛是编译两个有面函数的文件。大家看一下代码就知道了。

  1 all:app1 app2

  2 

  3 app1:a.c

  4     gcc a.c -o app1

  5 app2:b.c

  6     gcc b.c -o app2

  7 

  8 .PHONY:clean

  9 clean:

 10     rm -f app*      

结果:

wz@wz-machine:~/linux/MK2$ make

gcc b.c -o app2

wz@wz-machine:~/linux/MK2$ ./app1

hello

wz@wz-machine:~/linux/MK2$ ./app2

world

wz@wz-machine:~/linux/MK2$ make clean

rm -f app*

wz@wz-machine:~/linux/MK2$ ls

a.c  b.c  makefile

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值