Makefile用法介绍

Makefile常用写法


前言

      Makefile 十分强大,可以自动调用编译器和链接器,按照指定的依赖关系来编译源代码,极大地简化了编译过程;它能够定义源文件之间的依赖关系,确保在源文件被修改后,只有依赖于这些文件的目标文件会被重新编译,减少了不必要的编译工作,提高构建效率。C开源代码和大多数项目都使用makefile编译,学习makefile的使用也十分重要。

一、介绍

     程序编译首先是将.c文件编译成目标文件.o、再把这些中间文件链接起来,或者是多个.o文件打包为库文件.a .o .so,最终链接成为可执行文件。

    详细介绍可以看《GNU Make中文手册》

二、基本编译规则

1.基本规则

        target为可执行文件 或目标文件.o,prerequisites为编译依赖文件.c .h等,conmmod为编译命令,需要已TAB键为开头。

target:prerequisites
    commond

        如果我们编译多个.c多个.h文件,则makefile规则如下:其中.PHONY定义clean为伪目标文件,作为一个虚拟文件被执行,并且防止和其他文件重名。

a:main.o test1.o test2.o
    cc -o a main.o test1.o test2.o 
main.o:main.c
    cc -c main.c
test1.o:test1.c test1.h
    cc -c test1.c
test2.o:test2.c test1.h test2.h
    cc -c test2.c
.PHONY:clean
clean:
    rm a main.o test1.o test2.o

2.Makefile自动推导

        make能够自动推导文件依赖关系,对于每个.o都能自动识别对应的.c,并推导相应的编译cc命令:这也成为make的隐晦规则,使用make的自动推导后简化的Makefile如下

obj = main.o test1.o test2.o
a:$(obj)
    cc -o a $(obj) 
$(obj):test1.h test2.h

.PHONY:clean
clean:
    rm a $(obj)

        当项目工程添加新的.c文件时,仅需要在变量定义处新增:

obj = main.o test1.o test2.o
obj += test3.o
a:$(obj)
    cc -o a $(obj) 
$(obj):test1.h test2.h

.PHONY:clean
clean:
    rm a $(obj)

3.编译、引用Makefile文件

      make命令会自动编译名为Makefile的文件,如果给编译文件起名如test.mk,可以通过-f参数编译该文件:

make -f test.mk

     在makefile文件中也可以通过include引用其它mk文件来执行其它文件的编译命令,make会优先在当前文件中查找引用的文件,查找不到,则会在-I命令后的路径中查找,若查找不到再报错:

include test.mk
include *.mk

      如果其它makefile中想要使用某一已定义变量,需要在变量定义后,export变量。

a.mk
OBJECT = test.o
export OBJECT

b.mk
main.o: OBJECT

三、进阶用法

1.静态模式规则

        Targets:Target-Pattern:Prereq-Patterns

                Commonds

       其中,目标模式和依赖模式一般包含%,可以匹配目标文件,例如

obj = main.o test1.o test2.o test3.o
a:$(obj)

$(obj):%.o:%.c
    cc -c $< -o $@ 
若obj包含多格式目标文件,通过filter函数过滤:
$(filter %.o,$(obj)):%.o:%.c
    cc -c $< -o $@ 

其中$<表示依赖文件%.c,$@表示目标文件$(obj).

2.常用命令

 · cc -M main.c 寻找源文件包含的头文件,显示自动依赖关系;如果不需要标准库头文件,可以使用-MM参数;可以通过改命令生成依赖关系文件.d:

%.d:%.c
    cc -M $< > $@; \
    sed 's,\($*\)\.o[:]*,\1.o $@ :,g' < $@; \

        第二行命令把如main.o: main.c test.h的依赖关系输出,修改为main.o main.d: main.c test.h.

· @echo命令,不输出echo本身,输出make 日志

· $(MAKE) -C dir 嵌套执行dir子目录下的Makefile

·make -help 查看支持的make参数选项及说明。

四、常用函数

INCLUDE += $(strip $(foreach dir,$(CDIR),$(if $(wildcard $(CDIR)/$(dir)/include),-I$(CDIR)/$(dir)/include)))

strip函数,去掉CDIR中的多余空格;

foreach函数,把CDIR中的路径挨个存在dir变量中,依次执行后面的函数;

wildcard函数,获取匹配模型文件名dir;

if函数,判断CIDR/dir/include存在,则添加-I引用;

shell函数,可以在makefile里通过shell函数以sh命令格式获取信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值