Makefile复习总结

001_Makefile的引入及规则

使用keil、mdk、avr 等工具开发程序时点点鼠标就可以编译了,

它的内部机制是什么?它怎么组织管理程序?怎么决定编译哪一个文件?

 

gcc -o  test   a.c  b.c     //简单

a.c ==>APP     执行编译(预处理、编译、汇编)、链接

a.c ==> xxx.s ==> xxx.o

b.c ==> xxx.s ==> xxx.o

再链接成test的执行程序。

缺点:若对其中一个文件进行修改,则对所有文件都再处理一次

Makefile通过比较时间来判断哪些文件被修改过。

 Makefile最基本的语法是规则;

编写文件:a.c   b.c   c.c

a.c
#include <stdio.h>

int main()
{
    func_b();
    func_c();
    return 0;
}


b.c
#include <stdio.h>

void func_b()
{
    printf("This is B\n");
}

c.c
#include <stdio.h>

void func_c()
{
    printf("This is C\n");
}

 

编写Makefile如下:

test:a.o b.o c.o
    gcc -o test a.o b.o c.o

a.o:a.c
    gcc -c -o a.o a.c

b.o:b.c
    gcc -c -o b.o b.c

c.o:c.c
    gcc -c -o c.o c.c

运行j结果:

 

从运行结果看:当我们利用touch命令(只更改文件时间,不修改内容)修改后,确实执行了修改后的命令,不做任何改动直接touch,会提示test已经是最新的了。

 总结:

Makefile的核心———规则:

目标: 依赖1  依赖2  。。。

【TAB】命令

 

当“目标文件”不存在,

某个依赖文件比目标文件“新”,

则:执行“命令”

002_Makefile的语法

 

a. 通配符: %.o

  $@    表示目标

  $<      表示第一个依赖文件

  $^       表示所有依赖文件

 通过通配符简化上面的Makefile为:

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

%.o:%.c
    gcc -c -o $@ $<

clean:
  rm *.o test

以上写法存在不足,若目录中存在以clean命名的文件时,则执行make操作的时候就无法执行删除操作。怎么办能?此时利用假想目标就能很好的解决这个问题。

b. 假想目标:.PHONY

通过假想目标操作,修改Makefile为:

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

%.o:%.c
    gcc -c -o $@ $<

clean:
  rm *.o test

.PHONY: clean

这样即使有同名文件也可以执行clean。

c. 即时变量、延时变量、export

简单变量(即时变量):

A:= xxx       # A 的值即刻确定,在定义时

B = xxx       #  B 的值使用到时才确定

 

Makefile如下:

A:= $(C)
B = $(C)
#C = abc

all:
    @echo A = $(A)
    @echo B = $(B)
C = abc

运行结果如下:

C = abc放在前面和放在后面对结果无影响,当执行make命令的时候,make程序本身会把整个Makefile读进去来分析,然后解析内部的变量,所以放前面和放后面不影响。

:=       # 即时变量

=   # 延时变量

?=  #延时变量,如果是第1次定义才有效,如果在前面该变量已定义则忽略这句

+=    # 附加,它是即时变量还是延时变量取决于前面的定义

 003_Makefile函数

a. $(foreach  var, list , text)

b. $(filter pattern... ,text)      # 在text中取出符合pattern格式的值

  $( filter-out   pattern ... ,text)   # 在text中取出不符合pattern格式的值

 

c.  $ (wildcard  pattern)        # pattern定义了文件名的格式,

                  # wildcard 取出其中存在的文件

d. $(patsubst  pattern,  replacement,  $(var) )      # 从列表中取出每一个值

                        #  如果符合pattern

                        #   则替换为replacement

 

004_Makefile实例

a. 改进:支持头文件依赖

b. 添加CFLAGS

c. 编写裸板Makefile

 

posted @ 2018-01-31 18:57  Liu_Jing  Views(303)  Comments(0Edit  收藏  举报