make工具

1、什么是make?

make是个命令,是个可执行程序,是个工具,用来解析Makefile文件的命令,这个命令存放在/usr/bin/目录下

-rwxr-xr-x 1 root root 250K  2月 15  2022 make
-rwxr-xr-x 1 root root 4.8K  2月 15  2022 make-first-existing-target        //Perl脚本编写的程序会由make命令触发执行,用来检测文件是否被修改,没有修改跳过编译

Debian系安装make工具:sudo apt install make

2、什么是makefile?

Makefile是个文件,这个文件中描述了咱们程序的编译规则,咱们执行make命令的时候,make命令会在当前目录下寻找Makefile文件,根据Makefile文件里的规则,编译咱们的程序。

        注意Makefile文件是咱们程序员根据自己的程序,编写的编译规则文件。

3、make的主要好处

一、大量代码的关系维护,大项目中源代码比较多,手工维护、编译时间比较长而且编译命令比较复杂,难以记忆和维护,把代码维护命令和编译命令写在Makefile文件中,然后再用make工具解析编好规则的Makefile文件,自动执行相应命令,可实现代码的合理编译。

二、减少重复编译时间,在改动其中一个文件的时候,能判断哪些文件被修改过,可以只对该文件进行重新编译,然后重新链接所有的目标文件,节省编译时间。

4、一张图解释:make和:Makefile关系

5、Makefile的编写语法规则

 目标:依赖文件列表

        命令列表

1、目标:通常是要产生的文件名称,目标可以是可执行文件或其他object文件,也可是一个动作的名称

2、依赖文件列表:由多个依赖文件组成,每个依赖文件是用来输入而产生目标的文件,一个目标通常有几个依赖文件(也可以没有)

3、命令列表:由多个命令组成(也可以没有),代表make执行的动作,注意一个规则可以包含多个命令,存在多个命令时,每个命令占一行

举例:将gcc -o hello main.c hello.c hi.c good.c编写成Makefile内容

Makefile文件内容:

main:main.c hello.c hi.c good.c

        gcc -o main main.c hello.c hi.c good.c

clean:

        rm main

5.1、Makefile变量
5.1.1、Makefile变量

Makefile变量类似C语言的宏Makefile被make工具解析时,其中的变量会被展开。变量的作用:保存文件名列表,保存文件目录列表保存编译器名,保存编译参数,保存编译输出。

Makefile变量分为三种:系统环境变量、自定义变量、预定义变量

系统环境变量:make工具解析Makefile前,读取系统环境变量并设置为Makefile的变量

自定义变量:在Makefile文件中定义的变量,make工具传给Makefile的变量都是自定义变量

预定义变量:自动变量,都是设置好的变量(可以理解为规则)

5.1.2、Makefile变量编写规则

变量名=变量值        引用变量:${变量名}       

注意:

        1、注意Makefile的变量名字允许以数字开头

        2、变量区分大小写

        3、变量通常在Makefile文件的头部定义

        4、变量可在Makefile的任何地方使用

5.1.3、预定义变量

Makefile中我们通常只需要定义自定义变量和重新定义系统环境变量,而不需要定义预定义变量。

预定义变量通常是通用的,像正则表达式的元字符,具有特殊的含义。

$@        # 目标名

$<        # 依赖文件列表的第一个文件

$^        # 依赖文件列表中去除重复文件的部分

%        # 通配符

AR        # 归档维护程序的程序名,默认值为ar

ARFLAGS        # 归档维护程序的选项

AS        # 汇编程序的程序名,默认值为as

ASFLAGS        # 汇编程序的选项

CC        # C编译器的名称,默认为cc

CFLAGS        # C编译器的选项

CPP        # C预编译器的名称,默认值为$(CC) -E

CPPFLAGS        # C预编译器的选项

CXX        # C++编译器的名称,默认为g++

CXXFLAGS        # c++编译器的选项

6、make命令格式

make [-f file] [targets] [target] ...

1、通常我们把Makefile文件编写好规则,直接敲make,make默认从工作目录中寻找名为GNUmakefile或makefile或Makefile的文件内容的第一个目标(也有人称规则)进行解析编译。而 -f选项可以指定以上名字以外的文件作为Makefile输入文件。

2、[target]:若使用make命令时没有指定目标,则make工具默认会实现Makefile文件内的第一个目标,然后退出。若指定了目标,目标可以是一个或多个,多个目标之间默认用空格隔开。

7、makefile案例

源代码目录结构

.
├── main.c
├── Makefile
├── myfunc.c
└── myfunc.h

0 directories, 4 files

其中除Makefile以外的文件,我写在上一章csdn博文,参考gcc的编译C语言的过程-CSDN博客

7.1、简单级别

touch创建Makefile文件,写入如下内容

Makefile

my_execfile:main.o myfunc.o
        gcc -o my_execfile main.o myfunc.o
main.o:main.s
        gcc -c main.s -o main.o
my_func.o:myfunc.s
        gcc -c myfunc.s -o myfunc.o
main.s:main.i
        gcc -S main.i -o main.s
my_func.s:myfunc.i
        gcc -S myfunc.i -o myfunc.s
main.i:main.c
        gcc -E main.c -o main.i
myfunc.i:myfunc.c
        gcc -E myfunc.c -o myfunc.i
clean:
        rm my_execfile *.i *.s *.o

这里我把上一章的预处理、编译、汇编、链接的产物和过程集中写在Makefile文件中,并使用clean命令规则清理临时产物包括最终的可执行文件my_execfile。通过简单的把以上步骤汇总在Makefile文件中,只需要敲make就可以输出所有临时产物包括可执行文件,敲make clean可以清理所有中间产物和可执行文件,这对于代码维护很方便,不仅简洁美观,编译也省时。

效果

输出所有中间产物:*.i *.s *.o和可执行文件my_execfile

清理所有产物

7.2、普通级别

 Makefile

  1 #自定义变量
  2 EXEC=my_execfile        #我们的最终想要的可执行文件
  3 CC=gcc  #这里对gcc编译器也定义变量,是因为Makefile可以处理多种编译器的规则
  4 OBJ=main.o myfunc.o     #我们的目标文件
  5 OBJ1=main.o
  6 OBJ2=myfunc.o
  7 OBJ3=main.s
  8 OBJ4=myfunc.s
  9 OBJ5=main.i
 10 OBJ6=myfunc.i
 11 SOUR=main.c
 12 SOUR1=myfunc.c
 13 FLAGS=-Wall     # 这里输出gcc编译的所有warning和error
 14
 15 $(EXEC):$(OBJ)
 16         $(CC) -o $(EXEC) $(OBJ)
 17 $(OBJ1):$(OBJ3)
 18         $(CC) -c $(OBJ3) -o $(OBJ1) $(FLAGS)
 19 $(OBJ2):$(OBJ4)
 20         $(CC) -c $(OBJ4) -o $(OBJ2) $(FLAGS)
 21 $(OBJ3):$(OBJ5)
 22         $(CC) -S $(OBJ5) -o $(OBJ3) $(FLAGS)
 23 $(OBJ4):$(OBJ6)
 24         $(CC) -S $(OBJ6) -o $(OBJ4) $(FLAGS)
 25 $(OBJ5):$(SOUR)
 26         $(CC) -E $(SOUR) -o $(OBJ5) $(FLAGS)
 27 $(OBJ6):$(SOUR1)
 28         $(CC) -E $(SOUR1) -o $(OBJ6) $(FLAGS)
 29 clean:
 30         rm $(EXEC) $(OBJ5) $(OBJ6) $(OBJ3) $(OBJ4) $(OBJ)

        相对于简单处理编写Makefile文件的工作,这里我把部分编译命令通过变量的形式替换,只需要修改2~12行的数据名称,gcc的四个编译过程就可以被执行输出。clean命令进一步的缩小删除范围,可以精准到具体要删除的文件,防止其他非该Makefile的输出产物被删除。

效果

输出所有产物

清理所有产物

 7.3、升级

Makefile

# 自定义变量
EXEC=my_execfile       # 最终的可执行文件名
OBJ=main.o myfunc.o    # 目标文件
CC=gcc                 # 编译器
FLAGS=-Wall            # 编译选项,输出所有警告和错误信息

# 生成最终可执行文件
$(EXEC): $(OBJ)
        $(CC) -o $@ $^ $(FLAGS)

# 从汇编文件生成目标文件
%.o: %.s
        $(CC) -c $< -o $@ $(FLAGS)

# 从汇编文件生成汇编代码文件
%.s: %.i
        $(CC) -S $< -o $@ $(FLAGS)

# 从预处理文件生成汇编文件
%.i: %.c
        $(CC) -E $< -o $@ $(FLAGS)

# 清理生成的文件
clean:
        rm -f $(EXEC) $(OBJ) $(OBJ:.o=.s) $(OBJ:.o=.i)

# 生成所有中间文件的伪目标
all: $(OBJ:.o=.s) $(OBJ:.o=.i)

# 默认的伪目标
.PHONY: all clean

使用预定义变量和自定义变量结合,并加额外的伪目标以生成所有的中间产物和清理所有的中间产物,使用变量替换技巧将$(OBJ)的.o替换为其他中间产物,并使用.PHONY声明all和clean为伪目标,防止出现同名文件而产生歧义。

效果

输出所有产物

 清理所有产物

8、小结

实际上,中间产物并不是我们最终需要的目标文件,我们需要可执行文件文件就可以了。希望以上步骤对于了解make的编译原理有所帮助。

# 自定义变量
EXEC=my_execfile       # 最终的可执行文件名
OBJ=main.c myfunc.c    # 目标文件
CC=gcc                 # 编译器
FLAGS=-Wall            # 编译选项,输出所有警告和错误信息

# 生成最终可执行文件
$(EXEC): $(OBJ)
        $(CC) -o $@ $^ $(FLAGS)

# 清理生成的文件
clean:
        rm $(EXEC)
# 默认的伪目标
.PHONY: clean

效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/780960.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux_实现简易日志系统

目录 1、认识可变参数 2、解析可变参数 3、打印可变参数 3.1 va_list 3.2 va_start 3.3 va_arg 3.4 va_end 3.5 小结 4、实现日志 4.1 日志左半部分 4.2 日志右半部分 4.3 日志的存档归类 结语 前言&#xff1a; 在Linux下实现一个日志系统&#xff0c;该日…

Open3D 删除点云中重叠的点(方法二)

目录 一、概述 1.1原理 1.2应用 二、代码实现 三、实现效果 3.1原始点云 3.2处理后点云 3.3数据对比 一、概述 在点云处理中&#xff0c;重叠点&#xff08;即重复点&#xff09;可能会对数据分析和处理的结果产生负面影响。因此&#xff0c;删除重叠点是点云预处理中常…

一招解决找不到d3dcompiler43.dll,无法继续执行代码问题

当您的电脑遇到d3dcompiler43.dll缺失问题时&#xff0c;首先需要了解d3dcompiler43.dll文件及其可能导致问题的原因&#xff0c;之后便可以选择合适的解决方案。在此&#xff0c;我们将会为您提供寻找d3dcompiler43.dll文件的多种处理方法。 一、d3dcompiler43.dll文件分析 d…

【C++第十课 - stack_queue】stack、queue的使用、适配器模型stack、queue和priority_queue的底层实现、deque

目录 一、stack使用1、push2、pop3、empty4、top题目1、最小栈2、栈的压入、弹出序3、逆波兰表达式求值 二、queue的使用priority_queue习题 三、适配器stack的底层实现queue的底层实现priority_queue的底层实现仿函数/函数对象函数指针 四、deque 一、stack使用 stack是个容器…

【74LS163做24进制计数器】2021-11-19

缘由用74LS163做24进制计数器-其他-CSDN问答,仿真multisim两个74LS163芯片如何构成47进制计数器-吐槽问答-CSDN问答 参考74ls163中文资料汇总&#xff08;74ls163引脚图及功能_内部结构图及应用电路&#xff09; - 电子发烧友网

1.pwn的汇编基础(提及第一个溢出:整数溢出)

汇编掌握程度 能看懂就行&#xff0c;绝大多数情况不需要真正的编程(shellcode题除外) 其实有时候也不需要读汇编&#xff0c;ida F5 通常都是分析gadget&#xff0c;知道怎么用&#xff0c; 调试程序也不需要分析每一条汇编指令&#xff0c;单步执行然后查看寄存器状态即可 但…

【Python机器学习】模型评估与改进——多分类指标

多分类问题的所有指标基本是上都来自于二分类问题&#xff0c;但是要对所有类别进行平均。多分类的精度被定义为正确分类的样本所占的比例。同样&#xff0c;如果类别是不平衡的&#xff0c;精度并不是很好的评估度量。 想象一个三分类问题&#xff0c;其中85%的数据点属于类别…

Java(七)——多态

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

Go语言如何入门,有哪些书推荐?

Go 语言之所以如此受欢迎&#xff0c;其编译器功不可没。Go 语言的发展也得益于其编译速度够快。 对开发者来说&#xff0c;更快的编译速度意味着更短的反馈周期。大型的 Go 应用程序总是能在几秒钟之 内完成编译。而当使用 go run编译和执行小型的 Go 应用程序时&#xff0c;其…

VMware虚拟机搭建CentOS7环境

相关资料 安装VMware 双击VMware-workstation(16.1.1软件安装包.exe安装文件,点下一步 激活码文件复制激活码激活安装linux 1、点击创建虚拟机

Open3D 删除点云中重叠的点(方法一)

目录 一、概述 二、代码实现 三、实现效果 3.1原始点云 3.2处理后的点云 3.3计算结果 一、概述 在点云处理中&#xff0c;重叠点&#xff08;即重复点&#xff09;可能会对数据分析和处理的结果产生负面影响。因此&#xff0c;删除重叠点是点云预处理中常见且重要的步骤。…

【网络安全】实验一(网络拓扑环境的搭建)

一、本次实验的实验目的 学习利用 VMware 创建虚拟环境 学习利用 VMware 搭建各自网络拓扑环境 二、创建虚拟机 三、克隆虚拟机 选择克隆的系统必须处于关机状态。 方法一&#xff1a; 方法二&#xff1a; 需要修改克隆计算机的名字&#xff0c;避免产生冲突。 四、按照要求完…

机器学习原理之 -- 神经网络:由来及原理详解

神经网络&#xff08;Neural Networks&#xff09;是受生物神经系统启发而设计的一类计算模型&#xff0c;广泛应用于图像识别、语音识别、自然语言处理等领域。其基本思想是通过模拟人脑神经元的工作方式&#xff0c;实现对复杂数据的自动处理和分类。本文将详细介绍神经网络的…

Scrapy框架的基本使用教程

1、创建scrapy项目 首先在自己的跟目录文件下执行命令&#xff1a; PS D:\BCprogram\python_pro\bigdata> scrapy startproject theridion_grallatorscrapy startproject 项目名 具体执行操作如下&#xff1a;1、创建项目目录&#xff1a;Scrapy会在当前工作目录下创建一…

【python中级】图像从从笛卡尔坐标系转换为极坐标系

【python中级】图像从从笛卡尔坐标系转换为极坐标系 1.背景2.生成二维图3.极坐标转换1.背景 笛卡尔坐标系就是我们常说的直角坐标系。 笛卡尔坐标系,也称为直角坐标系,是由法国数学家和哲学家勒内笛卡尔(Ren Descartes)发明的一种二维或三维坐标系统。它使用两个或三个相互…

【Qt】Qt开发环境搭建

目录 一. Qt SDK的下载&安装 二. Qt相关工具介绍 Qt的常用开发工具有&#xff1a; Qt CreatorVisual StudioEclipse 一. Qt SDK的下载&安装 Qt 下载官网&#xff1a; http://download.qt.io/archive/qt/ 国内清华源: https://mirrors.tuna.tsinghua.edu.cn/qt/arc…

C# WinForm —— 37 TabControl 控件介绍

1. 简介 管理一个TabPages集合的控件&#xff0c;也是一个分组控件 如果一个模块有多个子页面&#xff0c;可以使用TabControl控件进行页面切换 2. 属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到Enabled控件是否启用Alignment确定选项卡是否显示在控件的…

扩散模型笔记2

Ref:扩散模型的原理及实现&#xff08;Pytorch&#xff09; 在扩散模型中&#xff0c;每一步添加的噪声并不是完全一样的。具体来说&#xff0c;噪声的添加方式和量在每一步是根据特定的规则或公式变化的。这里我们详细解释每一步添加噪声的过程。 正向过程中的噪声添加&…

两种转5V的DCDC电路:

最大电流&#xff1a;5A 最大电流&#xff1a;3A 验证通过&#xff1a;RT8289GSP性能更佳&#xff0c;带载能力更强&#xff1a;

前端JS特效第22波:jQuery滑动手风琴内容切换特效

jQuery滑动手风琴内容切换特效&#xff0c;先来看看效果&#xff1a; 部分核心的代码如下&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xm…