makefile的使用

makefile的使用

make是Linux内置指令,makefile是工程师自己要创建的文件。makefile为常用的工具,本文章从代码入手,学习makefile的用法,并理解其原理。

直接书写代码观察现象

  • 在当前目录创建code.c文件和makefile文件

  • 使用makefile书写gcc编译链接code.c过程

  • !!!一定要注意,实例代码中的gcc开头的空,是tab键,不是tab会报错

    code:code.o
    	gcc -o code code.o
    code.o:code.s
    	gcc -o code.o -c code.s
    code.s:code.i
    	gcc -o code.s -S code.i
    code.i:code.c
    	gcc -o code.i -E code.c
    
    .PHONY:clean
    clean:
    	rm -f code.i code.s code.o code
    
  • 使用makefile

    • ``shell中输入make指令,发现shell出现对应指令,生成code.i code.s code.o code`文件
    • shell中再次输入make指令,发现提示文件已经是最新
    • 修改code.c文件,再次输入make指令,发现系统会再次编译链接
    • shell中输入make clean指令,发现shell出现对应指令,code.i code.s code.o code文件被删除
    • shell中再次输入make clean指令,发现shell出现对应指令

代码原理讲解

  • shell中输入make指令,会自动运行当前文件夹makefileMakefile的内容。(makefileMakefile只是文件名字不同,使用时没有任何差异,按自己喜好命名即可)

  • code:code.o为例,我们把:左边的称为目标文件,右边的称为依赖文件列表,code:code.o叫做依赖关系。gcc -o code code.o叫做依赖方法。

  • makefile根据依赖关系进行正向解析,解析过程把依赖方法依次入栈,解析到出口后依次出栈,具体如下:

    • makefile拥有自动推导的功能,输入make后,发现code的依赖文件code.o不存在,把gcc -o code code.o入栈,向下寻找code.o的依赖;发现没有code.o的依赖文件code.s,把gcc -o code.o -c code.s入栈……直到发现有code.i的依赖文件code.c,执行gcc -o code.i -E code.c,依次出栈执行依赖方法,最终生成code.i code.s code.o code
  • 指令回显:

    • 想要取消指令回显,只需要在指令开始处加上@即可
  • shell中再次输入make指令,发现提示文件已经是最新——解释

    • 一个工程通常由数十上百个文件,如果只是修改其中一个文件,再把所有文件重新编译链接,有些太费时间。makefile为了提升编译链接的效率,会确认目标文件是否是最新的,如果是最新的就不会再进行依赖方法。那么,makefile是如何确定文件是否是最新的呢?

      • 我们首先要知道,文件的属性包括了文件的ACM——Access Change Modify。在修改文件内容时,Change Modify时间会改变;在修改文件权限、所属关系时,Change改变,Modify不变

      • 对比目标文件和依赖文件的时间,如果目标文件Modify比依赖文件Modify早,会判定其不是最新的,反之则是最新的。

    请添加图片描述

  • .PHONY

    • .PHONY会创建伪目标,伪目标总是被执行的,无视上文所说判断更新的规则
    • 为防止删不彻底,删除时通常使用伪目标

代码书写

下文设置变量,工程化规范性书写makefile文件

BIN=code
CC=gcc
LFLAG=-o
CFLAG=-c
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
RM=rm -f

$(BIN):$(OBJ)
	@$(CC) $(LFLAG) $@ $^
	@echo "链接$^成为$@"
%.o:%.c
	@$(CC) $(CFLAG) $<
	@echo "编译$<成为$@"

.PHONY:clean
clean:
	@$(RM) $(OBJ) $(BIN)
	@echo "清理工作完毕"

.PHONY:print
print:
	@echo $(SRC)
	@echo "-----------------"
	@echo $(OBJ)
  • $解析变量

  • @表示目标文件

  • ^表示依赖文件列表

  • SRC=$(wildcard *.c)表示当前路径所有*.c文件

  • OBJ=$(SRC:.c=.o)表示当前路径所有*.o文件

  •   %.o:%.c
      	@$(CC) $(CFLAG) $<
      	@echo "编译$<成为$@"
    

    负责把当前文件夹所有*.c文件编译生成对应*.o文件

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值