【嵌入式入门学习笔记】-- 七、Makefile

1.Make简介

        指它能够根据文件时间戳自动发现更新过的文件而减少编译的工作量。

Make将只编译改动的代码文件,而不用完全编译

2.Makefile基本结构

Makefile是Make读入的唯一配置文件

        1.由make工具创建的目标体(target):通常是目标文件或可执行文件(生成什么)

        2.要创建的目标体所依赖的文件(dependency_file)(由谁生成)

        3.创建每个目标体时需要运行的命令(command)(怎么生成)

注意:命令行前面必须是一个”TAB键”,否则编译错误为:*** missing separator.  Stop.

Makefile格式:

target  :   dependency_files
<TAB>  command

例子
hello.o :  hello.c hello.h
	gcc  –c  hello.c  –o  hello.o
一个复杂一些的例子

sunq:kang.o yul.o
	gcc kang.o yul.o -o sunq
kang.o : kang.c kang.h 
	gcc –Wall –O -g –c kang.c -o kang.o
yul.o : yul.c 
	gcc - Wall –O -g –c yul.c -o yul.o

注释:-Wall:表示允许发出gcc所有有用的报警信息.
     -c:只是编译不链接,生成目标文件”.o”
     -o file:表示把输出文件输出到file里
关于更多的用man工具

3.创建和使用变量

创建变量的目的:

用来代替一个文本字符串:

 1.系列文件的名字
 2. 传递给编译器的参数
 3. 需要运行的程序
 4. 需要查找源代码的目录
 5. 你需要输出信息的目录 
 6. 你想做的其它事情。

变量定义的两种方式

递归展开方式VAR=var
简单方式 VAR:=var

变量使用 $(VAR)

用”$$”来表示”$”

例子
OBJS = kang.o yul.o  
CC = gcc
CFLAGS = -Wall -O -g
sunq : $(OBJS)
	$(CC) $(OBJS) -o sunq
kang.o : kang.c kang.h
	$(CC) $(CFLAGS) -c kang.c -o kang.o
yul.o : yul.c yul.h
	$(CC) $(CFLAGS) -c yul.c -o yul.o
递归展开方式 VAR=var
例子:
foo = $(bar) 
bar = $(ugh) 
ugh = Huh? 
$(foo)的值为?
echo $(foo)来进行查看

遍历整个makefile后,将值赋给VAR
优点:它可以向后引用变量
缺点:不能对该变量进行任何扩展,
例如  CFLAGS = $(CFLAGS) -O   会造成死循环
简单方式 VAR:=var
	m := mm 
    x := $(m) 
    y := $(x) bar 
    x := later 
    echo $(x) $(y) 
   看看打印什么信息?

用这种方式定义的变量,会在变量的定义点,按照被引用的变量的当前值进行展开 
这种定义变量的方式更适合在大的编程项目中使用,因为它更像我们一般的编程语言 
用?=定义变量 
    dir := /foo/bar
    FOO ?= bar  
含义是,如果FOO没有被定义过,那么变量FOO的值就是“bar”
如果FOO先前被定义过,那么这条语将什么也不做
为变量添加值 你可以通过+=为已定义的变量添加新的值 
Main=hello.o hello-1.o
Main+=hello-2.o

预定义变量

AR     库文件维护程序的名称,默认值为ar。
AS      汇编程序的名称,默认值为as。
CC      C编译器的名称,默认值为cc。
CPP    C预编译器的名称,默认值为$(CC) –E。
CXX    C++编译器的名称,默认值为g++。
FC       FORTRAN编译器的名称,默认值为f77
RM      文件删除程序的名称,默认值为rm -f
例子:
Hello: main.c main.h 
<tab> $(CC) –o hello main.c
clean:
<tab> $(RM) hello

预定义变量

 ARFLAGS 库文件维护程序的选项,无默认值。
 ASFLAGS 汇编程序的选项,无默认值。
 CFLAGS   C编译器的选项,无默认值。
 CPPFLAGS  C预编译的选项,无默认值。
 CXXFLAGS  C++编译器的选项,无默认值。
 FFLAGS  FORTRAN编译器的选项,无默认值。
OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g
sunq : $(OBJS)
	$(CC) $(OBJS) -o sunq
kang.o : kang.c kang.h
	$(CC) $(CFLAGS) -c kang.c -o kang.o
yul.o : yul.c yul.h
	$(CC) $(CFLAGS) -c yul.c -o yul.o

自动变量

$*	   不包含扩展名的目标文件名称
$+	   所有的依赖文件,以空格分开,并以出现的先后为序,可能 包含重复的依赖文件
$<	   第一个依赖文件的名称
$?	   所有时间戳比目标文件晚的的依赖文件,并以空格分开
$@     目标文件的完整名称
$^	   所有不重复的目标依赖文件,以空格分开
$%     如果目标是归档成员,则该变量表示目标的归档成员名称
OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g
sunq : $(OBJS)
	$(CC) $^ -o $@
kang.o : kang.c kang.h 
	$(CC) $(CFLAGS) -c $< -o $@
yul.o : yul.c yul.h
	$(CC) $(CFLAGS) -c $< -o $@

环境变量

    make在启动时会自动读取系统当前已经定义了的环境变量,并且会创建与之具有相同名称和数值的变量
    如果用户在Makefile中定义了相同名称的变量,那么用户自定义变量将会覆盖同名的环境变量

4.Make使用

直接运行make 
选项
-C dir读入指定目录下的Makefile
-f  file读入当前目录下的file文件作为Makefile
-I  忽略所有的命令执行错误
-I  dir指定被包含的Makefile所在目录
-n 只打印要执行的命令,但不执行这些命令
-p 显示make变量数据库和隐含规则
-s  在执行命令时不显示命令
-w 如果make在执行过程中改变目录,打印当前目录名

5.Makefile的隐含规则

隐含规则1:编译C程序的隐含规则

        “<n>.o”的目标的依赖目标会自动推导为“<n>.c”,并且其生成命令是 “$(CC) –c $(CPPFLAGS) $(CFLAGS)”  ,即,即使makefile写的是 file.o:file.c下面没有写命令行,系统依然会自动添加命令行执行编译。

隐含规则2:链接Object文件的隐含规则

        “<n>” 目标依赖于“<n>.o”,通过运行C的编译器来运行链接程序生成(一般是“ld”),其生成命令是:“$(CC) $(LDFLAGS) <n>.o $(LOADLIBES) $(LDLIBS)”。

        这个规则对于只有一个源文件(.c文件)的工程有效,同时也对多个Object文件(由不同的源文件生成)的也有效。例如如下规则:

x : x.o y.o z.o
并且“x.c”、“y.c”和“z.c”都存在时,隐含规则将执行如下命令:
cc -c x.c -o x.o
cc -c y.c -o y.o
cc -c z.c -o z.o
cc x.o y.o z.o -o x
如果没有一个源文件(如上例中的x.c)和你的目标名字(如上例中的x)相关联,那么,你最好写出自己的生成规则,不然,隐含规则会报错的。

6.Makefile的VPATH

VPATH : 虚路径

        在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。所以,当make需要去找寻文件的依赖关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make在自动去找。
        Makefile文件中的特殊变量“VPATH”就是完成这个功能的,如果没有指明这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。
        VPATH = src:/dev/headers
        上面的的定义指定两个目录,“src”和“../headers”,make会按照这个顺序进行搜索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)

7.Makefile的嵌套

参考:

简单的实例,多层嵌套Makefile(一)_sinat_29830917的博客-CSDN博客_makefile 嵌套

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DUANDAUNNN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值