跟我一起学makefile(新)知识点+案例

学习资料

跟我一起学makefile
准备vs code

gcc 参数详解

  • -c

-c”选项我们上面说了,是只编译不链接
他将生成 .o 的 obj 文件
例子用法:

gcc -c hello.c 
  • -S

只激活预处理和编译,就是指把文件编译成为汇编代码。

例子用法:

gcc -S hello.c
他将生成 .s 的汇编代码,你可以用文本编辑器察看。

  • -E

只激活预处理,这个不生成文件, 你需要把它重定向到一个输出文件里面。

例子用法:

gcc -E hello.c > pianoapan.txt
gcc -E hello.c | more
慢慢看吧, 一个 hello word 也要与处理成800行的代码。

  • -o

制定目标名称, 默认的时候, gcc 编译出来的文件是 a.out, 很难听, 如果你和我有同感,改掉它, 哈哈

例子用法:
 
gcc -o hello.asm -S hello.c

gcc编译流程-shell脚本去编译

gcc编译的四个过程
在这里插入图片描述
在这里插入图片描述
案例:hello.c编译一个可执行文件
shell.sh 文件内容如下

#!/bin/bash
# 使用-o 替换名称名称
gcc -E main.c -o main.i
gcc -S main.i -o main.s
gcc -c main.s -o main.o
gcc main.o -o main

在这里插入图片描述
编译完成后生产如上图文件。

makefile 介绍

把源文件编译成中间代码文件UNIX 下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的 Object File 合成执行文件,这个动作叫作链接(link)

makefile 规则介绍

target ... : prerequisites ... 
command
...
...
...
  • target :也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性
  • prerequisites: 就是,要生成那个 target 所需要的文件或是目标
  • command 也就是 make 需要执行的命令。(任意的 Shell 命令)

target 这一个或多个的目标文件依赖于prerequisites 中的文件,其生成规则定义在 command 中。

说白一点就是说,prerequisites中如果有一个以上的文件比 target 文件要新的话,command 所定义的命令就会被执行。

这就是 Makefile 的规则。也就是 Makefile 中最核心的内容。

“=”和“:=”的区别

object = yql
curname = $(object)
curname1 := $(object)
object = other
print:
	@echo curname:$(curname)
	@echo curname:$(curname1)

在这里插入图片描述

  • 赋值符“:=”不会使用后面定义的变量,只能使用前面已经定义好的

“?=”和“+=”案例

  • ?=:如果变量 curname 前面没有被赋值,那么此变量 yql
  • +=:变量追加
object = yql
curname ?= $(object)
curname += $(object)
print:
	@echo curname:$(curname)

案例3个.c和2个.- 使用makefile编译

代码如下

main.c

#include <stdio.h> 
#include "input.h"
#include "calcu.h"
int main(int argc, char *argv[])
{  
    int a, b, num; 
    input_int(&a, &b);
    num = calcu(a, b);
    printf("%d + %d = %d\r\n", a, b, num);
}

input.c

#include <stdio.h> 
#include "input.h"
void input_int(int *a, int *b) 
{ 
    printf("input two num:");
    scanf("%d %d", a, b);
    printf("\r\n");
}

calcu.c

#include "calcu.h"
int calcu(int a, int b) 
{ 
    return (a + b);
}

calcu.h

#ifndef _CALCU_H
#define _CALCU_H
int calcu(int a, int b);
#endif

input.h

#ifndef _INPUT_H
#define _INPUT_H
void input_int(int *a, int *b);
#endif

使用shell脚本编译

gcc -c main.c 
gcc -c input.c 
gcc -c calcu.c 
# 只激活预处理,编译,和汇编,也就是他只把程序做成obj文件**他将生成 .o 的 obj 文件**
gcc main.o input.o calcu.o -o main 

在这里插入图片描述

使用makefile 方式编译

main : main.o input.o calcu.o
	gcc -o main main.o input.o calcu.o
main.o: main.c 
	gcc -c main.c 
input.o: input.c 
	gcc -c input.c 
calcu.o: calcu.c 
	gcc -c calcu.c
clean : 
	rm *.o 
	rm main

在第一次编译的时候
由于 main 还不存在,因此第一条规则会执行,第一条规则依赖于文件 main.o、input.o 和 calcu.o这个三个.o 文件
这三个.o 文件目前还都没有,因此必须先更新这三个文件。make 会查找以这三个.o 文件为目标的规则并执行

makefile 变量

  • #使用"$"获取变量object的值为main.o input.o calcu.o
object = main.o input.o calcu.o
main : $(object)
	gcc -o main $(object) #使用"$"获取变量object的值为main.o input.o calcu.o
main.o: main.c 
	gcc -c main.c 
input.o: input.c 
	gcc -c input.c 
calcu.o: calcu.c 
	gcc -c calcu.c
clean : 
	rm *.o 
	rm main

在这里插入图片描述
注意:图片验证了这段话----第一条规则依赖于文件 main.o、input.o 和 calcu.o这个三个.o 文件
这三个.o 文件目前还都没有,因此必须先更新这三个文件。make 会查找以这三个.o 文件为目标的规则并执行

make 自动推导–优化一

GNU 的 make 很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必
要去在每一个[.o]文件后都写上类似的命令,因为,我们的 make 会自动识别,并自己推导
命令。

只要 make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果 make找到一个whatever.o,那么whatever.c,就会是 whatever.o 的依赖文件。

并且 cc -c whatever.c 也会被推导出来,于是,我们的 makefile 再不用写得这么复杂。我们的是新
的 makefile 又出炉了。

object = main.o input.o calcu.o
main : $(object)
	gcc -o main $(object) #使用"$"获取变量object的值为main.o input.o calcu.o

main.o: input.h calcu.h
input.o: input.h 
calcu.o: calcu.h 

.PHONY : clean
clean : 
	rm *.o 
	rm main

在这里插入图片描述
在这里插入图片描述

make 自动推导–优化二

object = main.o input.o calcu.o
main : $(object)
	cc -o main $(object) #使用"$"获取变量object的值为main.o input.o calcu.o

$(object): input.h calcu.h

.PHONY : clean
clean : 
	rm *.o 
	rm main

在这里插入图片描述

## make 自动推导–优化三(通配符)%

  • %:表示对文件名的匹配,“%”表示长度任意的非空字符串
  • 举例:比如“%.c”就是所有的以.c 结尾的文件
  • 举例a.%.c 就表示以 a.开头,以.c 结束的所有文件。
object = main.o input.o calcu.o
main : $(object)
	cc -o main $(object) 

%.o : %.c
	gcc -c $< #依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%)定义的,那么“$<”就是符合模式的一系列的文件集合。
.PHONY : clean
clean : 
	rm *.o 
	rm main

在这里插入图片描述

## make 自动推导–优化四(通配符)*

object = main.o input.o calcu.o
main : $(object)
	cc -o main $(object) 

*.o : *.c
	gcc -c $< #依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%)定义的,那么“$<”就是符合模式的一系列的文件集合。
.PHONY : clean
clean : 
	rm *.o 
	rm main

在这里插入图片描述

伪目标 .PHONY :clean

上述规则中并没有创建文件 clean 的命令,因此工作目录下永远都不会存在文件 clean,当我们输入“make clean”以后,后面的“rm *.o”和“rm main”总是会执行。可是如果我们“手贱”,在工作目录下创建一个名为“clean”的文件,那就不一样了,当执行“make clean”的时候,规则因为没有依赖文件,所以目标被认为是最新的,因此后面的 rm 命令也就不会执行

object = main.o input.o calcu.o
main : $(object)
	cc -o main $(object) 

%.o : %.c
	gcc -c $< #依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%)定义的,那么“$<”就是符合模式的一系列的文件集合。
.PHONY : clean
clean : 
	rm *.o 
	rm main

在这里插入图片描述
在这里插入图片描述

判断语句使用

关键字功能
ifeq判断参数是否不相等,相等为 true,不相等为 false。
ifneq判断参数是否不相等,不相等为 true,相等为 false。
ifdef判断是否有值,有值为 true,没有值为 false。
ifndef判断参数是否不相等,相等为 true,不相等为 false。

条件判断的使用方式如下:
ifeq (ARG1, ARG2)
ifeq ‘ARG1’ ‘ARG2’
ifeq “ARG1” “ARG2”
ifeq “ARG1” ‘ARG2’
ifeq ‘ARG1’ “ARG2”
案例说明

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
跟我一起Makefile 作者:陈皓 整理:祝冬华 来源网络,希望能与大家分享这份习资料,资源分数也设置了最低值,如有侵权,请联系我删除文件。 第一部分、概述 (6) 第二部分、关于程序的编译和链接 (6) 第三部分、Makefile 介绍 (7) 一、Makefile的规则 (7) 二、一个示例 (8) 三、make是如何工作的 (9) 四、makefile中使用变量 (10) 五、让make自动推导 (11) 六、另类风格的makefile (12) 七、清空目标文件的规则 (13) 第四部分、Makefile 总述 (13) 一、Makefile里有什么? (13) 1、显式规则。 (14) 2、隐晦规则。 (14) 3、变量的定义。 (14) 4、文件指示。 (14) 5、注释。 (14) 二、Makefile的文件名 (15) 三、引用其它的Makefile (15) 四、环境变量 MAKEFILES (16) 五、make的工作方式 (16) 第五部分、书写规则 (17) 一、规则举例 (17) 二、规则的语法 (17) 三、在规则中使用通配符 (18) 四、文件搜寻 (19) 五、伪目标 (20) 六、多目标 (22) 七、静态模式 (22) 八、自动生成依赖性 (24) 第六部分书写命令 (25) 一、显示命令 (26) 二、命令执行 (26) 三、命令出错 (27) 四、嵌套执行make (28) 五、定义命令包 (30) 第七部分使用变量 (30) 一、变量的基础 (31) 二、变量中的变量 (32) 三、变量高级用法 (34) 四、追加变量值 (37) 五、override 指示符 (37) 六、多行变量 (38) 八、目标变量 (39) 九、模式变量 (40) 第八部分使用条件判断 (40) 一、示例 (40) 二、语法 (42) 第九部分使用函数 (43) 一、函数的调用语法 (44) 二、字符串处理函数 (44) 1、subst (44) 2、patsubst (45) 3、strip (45) 4、findstring (46) 5、filter (46) 6、filter-out (46) 7、sort (47) 8、word (47) 9、wordlist (47) 10、words (47) 11、firstword (48) 12、字符串函数实例 (48) 三、文件名操作函数 (48) 1、dir (48) 2、notdir (48) 3、suffix (49) 4、basename (49) 5、addsuffix (49) 6、addprefix (49) 7、join (50) 四、foreach 函数 (50) 五、if 函数 (50) 六、call函数 (51) 七、origin函数 (51) “undefined” (52) “default” (52) “file” (52) “command line” (52) “override” (52) “automatic” (52) 八、shell函数 (53) 九、控制make的函数 (53) 1、error (53) 2、warning (54) 第十部分 make 的运行 (54) 二、指定Makefile (54) 三、指定目标 (55) “all” (56) “clean” (56) “install” (56) “print” (56) “tar” (56) “dist” (56) “TAGS” (56) “check”和“test” (56) 四、检查规则 (57) 五、make的参数 (57) 第十一部分隐含规则 (61) 一、使用隐含规则 (61) 二、隐含规则一览 (62) 1、编译C程序的隐含规则 (63) 2、编译C++程序的隐含规则 (63) 3、编译Pascal程序的隐含规则 (63) 4、编译Fortran/Ratfor程序的隐含规则 (63) 5、预处理Fortran/Ratfor程序的隐含规则 (63) 6、编译Modula-2程序的隐含规则 (63) 7、汇编和汇编预处理的隐含规则 (64) 8、链接Object文件的隐含规则 (64) 9、Yacc C程序时的隐含规则 (64) 10、Lex C程序时的隐含规则 (64) 11、Lex Ratfor程序时的隐含规则 (65) 12、从C程序、Yacc文件或Lex文件创建Lint库的隐含规则 (65) 三、隐含规则使用的变量 (65) 1、关于命令的变量。 (65) 2、关于命令参数的变量 (66) 四、隐含规则链 (67) 五、定义模式规则 (68) 1、模式规则介绍 (68) 2、模式

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值