Makefile实战

一、实际写出来一个makefile

         比较重要的一个是需要一个,生成a.o文件的时候不仅会依赖a.c还会依赖啊啊a.h,b.h,c.h

那么下面这个makefile文件就会出问题,因为没有依赖上.h文件。

test:a.o b.o c.o
        gcc -o test $^
%.o:%.c
        gcc -c -o $@ $<
clean:
        rm *.o test
.PHONY: clean

因为啥呢,当修改.h文件的时候,这个makefile,并不知道修改了.h这个依赖文件,所以要对,makefile文件进行修改。

test:a.o b.o c.o
        gcc -o test $^
b.o:b.c b.h

%.o:%.c
        gcc -c -o $@ $<
clean:
        rm *.o test
.PHONY: clean

把生成b.o文件的依赖都给加上  b.o:b.c b.h,,这样加上,当我们修改b.h的时候,就需要重新生成目标b.o了,.c也就重新被编译了,那修改的.h文件也就被找到编译了。

可是上面的写法还是有问题的,啥没问题呢,当这个b.c文件依赖的头文件比较多,不如说依赖成千上万个.h文件咋整,就一个一个写嘛,真实费劲。

所以还有其它办法。

就是有几个gcc命令很有意思,就是可以查找依赖,而且呢也可以把一个文件的所有依赖都写成一个文件。

比如说:

1、gcc -M b.c

root@wandzhang-virtual-machine:/home/book/makefile_test1# gcc -M b.c
b.o: b.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \
 /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
 /usr/include/x86_64-linux-gnu/bits/wordsize.h \
 /usr/include/x86_64-linux-gnu/bits/long-double.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \
 /usr/include/x86_64-linux-gnu/bits/types.h \
 /usr/include/x86_64-linux-gnu/bits/typesizes.h \
 /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \
 /usr/include/x86_64-linux-gnu/bits/types/FILE.h \
 /usr/include/x86_64-linux-gnu/bits/libio.h \
 /usr/include/x86_64-linux-gnu/bits/_G_config.h \
 /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \
 /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \
 /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h b.h
打印出b.c的所有依赖文件

2、 gcc -M -MF b.d b.c

root@wandzhang-virtual-machine:/home/book/makefile_test1# gcc -M -MF b.d b.c
把依赖写成b.d文件

3、gcc -c -o c.o c.c -MD -MF c.d

root@wandzhang-virtual-machine:/home/book/makefile_test1# gcc -c -o b.o b.c -MD -MF b.d

编译b.c文件生成b.o文件,并把所有依赖写进b.d文件中

现在可以用上述命令写makefile文件了

二、开始写makefile

上面工作做完了,就是如何写个makefile了,而且呢,这个makefile可以自己添加依赖。开始上难度了。

步邹:
1、简单的生成依赖命令

test:a.o b.o c.o
        gcc -o test $^
b.o:b.c b.h

%.o:%.c
        gcc -c -o $@ $< -MD -MF .$@.d
clean:
        rm *.o test
.PHONY: clean

root@wandzhang-virtual-machine:/home/book/makefile_test1# ls
a.c  a.o  b.c  b.d  b.h  b.o  c.c  c.d  c.o  Makefile  test
可以看出来,的确可以生成依赖文件,而且呢,这些依赖文件的命名还是有讲究的,$@可就是目标文件的意思,可能%这个通配符代表的啥,那么这个$@应该就是个啥名字。

2、makefile函数的作用

生成的这些依赖是有用的,makefile函数的作用就体现出来了

这些.d文件因该就是一些依赖的位置,应该就是头文件的位置

上一步,是生成了.d依赖文件,可是呢,这些依赖啥时候去用呢

objs = a.o b.o c.o

dep_files := $(patsubst %,.%.d,$(objs))
dep_files := $(wildcard $(dep_files))

test:a.o b.o c.o
        gcc -o test $^
ifneq ($(dep_files),)
include $(dep_files)
endif

%.o:%.c
        gcc -c -o $@ $< -MD -MF .$@.d
clean:
        rm *.o test
distclean:
        rm $(dep_files)
.PHONY: clean

这就很有意思了。

依赖是自己生成的文件,而且生成的依赖也不需要自己添加进去了,通过函数自动匹配加入。

dep_files := $(patsubst %,.%.d,$(objs))    #生成所有依赖的文件名

dep_files := $(wildcard $(dep_files))   #对文件名和生成的依赖进行匹配

ifneq ($(dep_files),)
include $(dep_files)
endif         
#如果匹配的不是空依赖,就把依赖添加到。。。。。?,想不起来添加到哪了,就是makefile能找到,能用的地方。

3、CFLAGS编译参数

可以说就是拿来报错的,也是拿来指定.h文件路径的

CFLAGS = -Werror

objs = a.o b.o c.o

dep_files := $(patsubst %,.%.d,$(objs))
dep_files := $(wildcard $(dep_files))

CFLAGS = -Werror

test:$(objs)
        gcc -o test $^

ifneq ($(dep_files),)
include $(dep_files)
endif

%.o:%.c
        gcc -c -o $@ $< -MD -MF .$@.d
clean:
        rm *.o test
distclean:
        rm $(dep_files)
.PHONY: clean


三、通用makefile写法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值