Makefile工程管理

Makefile概述

在Windows下,程序员会使用各种IDE去编译自己的工程,Linux 环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序员。在 Linux(unix)环境下使用GNU 的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投入一些时间去完成一个或者多个称之为Makefile 文件的编写。
所要完成的Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的唯一的一件事就是在shell 提示符下输入make命令。整个工程完全自动编译,极大提高了效率。

Makefile语法:

target ... : prerequisites ... 
  command 
  ... 
  ... 

target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。
prerequisites就是,要生成那个target所需要的文件或是目标。,这个文件可以是一个也可以是多个。
command也就是make需要执行的命令。(任意的Shell命令)
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

一个实例

all: start.o main.o mmu.o led.o button.o interrupt.o mem.o nand.o uart.o
    arm-linux-ld -Tgboot.lds -o gboot.elf $^
    arm-linux-objcopy -O binary gboot.elf gboot.bin

%.o : %.S
    arm-linux-gcc -g -c $^

%.o : %.c
    arm-linux-gcc -g -fno-builtin -c $^

.PHONY: clean
clean:
    rm *.o *.elf *.bin

第一行的all代表最终目标,也就是target,剩下的.o文件都为依赖文件。
第二行和第三行都为command命令行,注意,在写command的时候,前面不是打空格而是一个TAB键。
这里第二行arm-linux-ld -Tgboot.lds -o gboot.elf $^意思是生成链接器脚本文件,在此简单介绍一下什么 是链接器,链接器主要有两个作用,一是将若干输入文件(.o文件)根据一定规则合并为一个输出文件(例如ELF格式的可执行文件);一是将符号与地址绑定(当然加载器也要完成这一部分工作)。关于链接器的工作机制可以参考《Linker and Loader》一书,本文只关心它的第一个功能,即如何根据一定规则将一个或多个输入文件合并成输出文件。这里的“一定规则”是通过链接脚本描述的。链接器有一个编译到其二进制代码中的默认链接脚本,大多数情况下使用它链接输入文件并生成目标文件。当然,我们也可以提供自定义的脚本以精确控制目标文件的格式,如同Linux内核做得那样,链接器“- T”参数用于指定自定义的脚本文件。

其中 $^是变量的简化写法,代表所有的依赖文件的字符,还有另外两个比较常见的替代符

$@:代表目标
$<:代表第一个依赖文件

第三行arm-linux-objcopy -O binary gboot.elf gboot.bin是将elf文件转换为二进制可执行文件bin。
接下来%.o : %.S是什么意思呢?由于文件在编译过程中需要格式转化,在一个Makefile中若有多个依赖文件,例如这里会产生start.S,main.S…….就需要一个一个将它们转化成以.o后缀的文件,显而这种方式效率比较低,所以这里采取的是将所有的.S文件转换成.o文件,%代表所有相对应同一个转换规则,所以%.o : %.S就是将所有.S文件转换成.o 文件。

arm-linux-gcc -g -c $^中-c意为将所有的依赖文件只编译不链接。
arm-linux-gcc -g -fno-builtin -c $^中-fno-builtin意为不依赖原有库文件
.PHONY: clean
clean:
    rm *.o *.elf *.bin

.PHONY意思表示clean是一个“伪目标”。rm .o .elf *.bin意为删除 .o、.elf、.bin的文件。当然,clean的规则不要放在文件的开头,不然,这就会变成make的默认目标,相信谁也不愿意这样。不成文的规矩是——“clean从来都是放在文件的最后”。

本文水平有限,作为初学者的理解还不深入,欢迎指出本文的错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值