makefile教程(1)

makefile教程

makefile是什么:

makefile是用户自行完成的IDE(integrated development environment集成开发环境)程序,与传统的操作系统下的编译不同,makefile可以通过用户自行安排,决定文件的编译顺序,决定哪些文件需要编译,哪些文件需要重复编译等各种复杂的操作

使用makefile的好处:

可自由编译的好处,能够指定文件编译,将繁杂的编译方法集成到一个makefile文件中,然后使用make进行一键编译,极大的提高了开发效率

关于程序的编译和链接:

关于gcc编译成可执行文件的命令,以及对应命令下生成的文件后缀

命令文件
gcc -E 预处理(宏展开)*.i
gcc -S 编译(生成汇编代码)*.s
gcc -c 汇编(生成机器码)*.o(unix下)
gcc -o 链接(把大量的.o文件合成生成可执行文件) (主要链接的是函数和全局变量)对于a.out文件的重命名可执行文件
  • 链接 link

把大量的.o文件合并生成可执行文件

主要链接的就是函数和全局变量,而存放函数和全局变量的地方通常称为库文件 .lib文件

在unix下也叫做.a文件

  • 编译

在编译时,编译器只会管你程序的语法是否正确,函数和变量是否已经声明,函数如果没有声明也没关系,只会报警告,而在链接这一步,链接器会在所有的.o文件中寻找这个函数,如果没有找到,就报链接错误码

makefile内核

所有的makefile的实际都是:编译+链接

只要记住编译+链接就行

  1. 如果这个工程没有被编译过,那么所有的.c文件都要编译并被链接
  2. 如果这个工程已经编译,但是修改了.c文件,我们需要编译修改的.c文件,并连接目标程序
  3. 如果这个工程已经编译,但是修改了.h文件,我们需要编译修改的.h文件,并连接目标程序

makefile的使用规则:

一共有五大原则:显示规则、隐式规则、变量定义、文件指示、注释说明

显示规则

目标…:依赖…

命令

  • 目标:可以是个文件(object文件或者是可执行文件),也可以是个标签label

  • 依赖:要生成target目标的所需要文件或者是目标

  • 命令:就是使用make之后所要执行的命令(shell命令)

当依赖中的文件比目标中的文件要新的话,就必须执行命令中的内容,这就是makefile的核心

请添加图片描述

请添加图片描述

其中“ \ ”表示换行符

clean不是一个文件,而是一个动作名,我们要使用clean,就需要make clean。而且clean后面也不需要出现依赖。

所以我们也可以在makefile中定义不用的编译或者与编译无关的命令,比如程序的打包,程序的备份等

怎么使得make时会判断哪些是不需要makefile的命令呢,例如clean这个动作写入makefile时当我们使用make时不会自动执行,其中的原理在哪

这就谈到make是如何工作的

make是如何工作的

  1. make会首先在当前文件夹中搜寻makefile或者是Makefile文件
  2. 读入被include的其他makefile
  3. 初始化定义的变量
  4. 为所有的目标建立依赖关系链
  5. 顺序执行第一个target,并且把target作为最终的目标文件,也就是一切都是为了第一个target
  6. make会比较依赖和目标的文件时间戳,如果依赖比目标的文件时间新,则会重新生成target文件
  7. 根据最终目标文件的依赖,首先会查找是否存在这些依赖,如果不存在则会按照是否makefile中存在依赖文件的生成方式,有的话就会执行下去,没有的话就直接退出报错
  8. 为什么要单独对clean进行make,是因为:

第一个target并没有直接或间接利用clean

clean之后没有存在依赖

如果我们改变了“command.h”,那么,kdb.o、command.o 和 files.o

都会被重编译,并且,edit 会被重新链接。

makefile中使用变量(变量定义)

  • 变量的定义
  1. 就好比C语言中宏的作用,当我们在添加或者修改依赖时,至少要修改三遍以上,所以干脆用个宏,修改一处就可以,一般宏设置为 “OBJ、OBJECT、OBJS ”
  • 变量的使用
  1. 一般是变量 = 依赖,首先先把变量声明好
  2. 调用变量时使用 $(OBJ)
  • 自动化变量

$< 和 $@称为自动化变量

$@表示目标文件

$<表示依赖文件

makefile自动推导(隐式规则)

一般来说make会自动推导出依赖文件,例如我们的main.o文件就是由main.c得到的,但我们没必要去写:

main.o:main.c defs.h

​ cc -c main.c

直接用 main.o:defs.h

也只是.o对于.c,其余依赖也要补充

请添加图片描述

引用其余的makefile(文件指示)

  • 使用include关键字

include + Makefilename(路径或者通配符)

路径如果没有设置,将会选择是当前文件夹下的makefile

“如果 make 执行时,有“-I”或“–include-dir”参数,那么 make 就会在这个参数所指定”

这个后面再说

  • 环境变量MAKRFILES

如果在当前环境中使用了环境变量MAKEFILES

那么make时会把这个变量MAKEFILES中的值做一个inlcude的动作

但是这个环境变量中的值如果是其他的makefile文件,则会用空格分开

这个变量中的target值在make时也不会起作用,依赖文件发生错误也不会管

通配符的使用

如果要使用一系列的类似的文件,一般使用通配符(* ,?,[…])来概括:

如果文件名中有通配符,我们可以使用 “\ *”来表示真正的“ * ”字符

object = *.o 表示的就是 *.o文件,而没有展开

object = $(wildcard *.o) 就可以得到一个展开后的变量合集

文件搜寻

  • 特殊变量 VPATH

VPATH表示目标或者依赖文件的寻找目录

比如:VPATH = src:…/header

表示目标或者依赖文件寻找的目录为src 或者上一层的header目录

其中:表示目录的分隔

  • 关键字 vpath

可以指定某个文件在哪个目录下寻找:vpath < pattern模式> < directories>

vpath %.h …/header

表示所有的.h文件都可以在上一层的header目录下找到

vpath %.h

表示符合模式%.h的文件目录

vpath

表示清除所有已被设置好了的文件搜索目录

当然目录的优先级最高的还是当前目录下的

连续使用vpath关键字来指定不同的搜索方式:

vpath %.c first

vpath % second

vpath %.c third

其表示“.c”结尾的文件,先在“first”目录,然后是“second”,最后是“third”目录

这里second比较特殊,什么文件都可以在second中搜索,比较浪费时间

可以通过改写成:

vpath %.c first:third

vpath % second

而上面的语句则表示“.c”结尾的文件,先在“first”目录,然后是“third”目录,最后才是“second”目录

伪目标

什么是伪目标

伪目标不是一个文件,所以无法使用依赖关系,我们必须使用一个特殊的标签来注明,使用时也得使用make+标签来表示

伪目标的使用要求

  • 不能与其他目标名重复,我们可以使用.PHONY来指明这是个伪目标

.PHONY:clean

  • 总是被执行的

伪目标同样可作为默认目标,就可以放在开头

all : prog1 prog2 prog3

.PHONY : all

由于伪目标总是被执行的,all作为一个伪目标,如果说prog1更新了,或者是prog3更新了,all也会更新

  • 伪目标也可以成为依赖

.PHONY : cleanall cleanobj cleaniff

cleanall : cleanobj cleaniff

多目标 涉及到函数后续

有时候多个目标可以共同使用一个依赖,这个叫做多目标

静态模式

更好的服务于多目标的使用

目标集合:目标集模式 依赖目标集模式

targets:%.o :%.c

表示对所有的.o文件进行了二次定义,也就是说去掉了.o的结尾,加上了.c的这个结尾

eg1:

objects = first.o second.o

$(object) : %.o : %.c

$(CC) -c $(CFLAGS) $< -o $@

也就是在objects这个变量中 将所有的.o文件修改成.c文件,所以修改之后我们的依赖目标集就是 first.c second.c

所以 < 表示依赖目标集, < 表示依赖目标集, <表示依赖目标集,@表示目标集

eg2:

file = 1.o 2.o 3.elc

( f i l t e r (filter %.o, (filter(file)) : %.o : %.c

gcc -c $< -o $@

$(filter %.elc,%(file)) : %.elc : %.el

emacs -f batch-byte-compile $<

filter是个函数,第一个参数是过滤条件,第二个参数过滤源

自动生成依赖性

对于每个.c文件,我们都得清楚包含了哪些头文件,这就大大增加了压力,但GNU编译器存在自动搜索头文件功能,使用 -MM参数

gcc -MM main.c = main.o : main.c defs.h

我们要为每个文件生成.d 文件之后才能自动化生成依赖关系

%.d : %.c

gcc -M $< > @ . @. @.$$$

书写命令

  • @

我们用“@”字符在命令行前,那么,这个命令将不被 make 显示出来

如果你要让上一条命令的结果应用在下一条命令时,你应该使用分号分隔这两条命令。比如你的第一条命令是 cd 命令,你希望第二条命令得在 cd 之后的基础上运行,那么你就不能把这两条命令写在两行上,而应该把这两条命令写在一行上,用分号分隔。

加一个减号“-”(在 Tab 键之后),标记为不管命令出不出错都认为是成功的

嵌套执行make

在不同的文件夹中编写不同的makefile,再由总控的makefile进行控制,可以有效的进行模块化的维护

例如我们在subdir下有个makefile,如果我们要在总控makefile中使用:

subsystem:

​ cd subdir && $(MAKE)

我们的make需要一点参数,所以定义成变量比较合适

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第 377 场周赛虚拟参赛记录及补题

最小数字游戏 3 题目 - 思路 模拟代码 class Solution { public:vector<int> numberGame(vector<int>& nums) {sort(nums.begin(),nums.end());vector<int> ans;for (int i 0;i < nums.size();i ) if (i&1)ans.push_back(nums[i-1]);else ans.…

postman的下载安装和使用

第一章、使用postman向后端发送请求 1.2&#xff09;postman下载与安装使用 我的百度网盘postman点击下载 提取码&#xff1a;bybp 下载后双击.exe文件直接安装 点击此次创建集合 点击此处创建请求 1.2&#xff09;发送get请求 选择自己的请求方式&#xff0c;输入请求…

Uboot

这里写目录标题 什么是Bootloader?Bootloader启动流程NAND Flash uboot是怎么和内核完成参数传递的&#xff1f; 什么是Bootloader? Linux系统要启动就必须需要一个 bootloader程序&#xff0c;也就说芯片上电以后先运行一段bootloader程序。 这段 **bootloader程序会先初始…

使用 FFmpeg 清除文件夹下所有 .mp4 文件声音

运行以下命令来清除声音&#xff1a; ffmpeg -i input.mp4 -c copy -an output.mp4这个命令会将 “input.mp4” 替换为你要处理的 .mp4 文件名。它会生成一个新的文件名为 “output.mp4” 的文件&#xff0c;该文件是没有声音的副本。 如果你想要直接替换原始文件&#xff0c;…

【网络编程】基于UDP数据报实现回显服务器程序

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 前言 我们如果…

互联网+建筑工地:技术革新引领建筑行业的未来

随着科技的飞速发展&#xff0c;互联网正日益渗透到建筑工地的方方面面。从设计、施工到管理&#xff0c;互联网建筑工地的深度融合不仅推动了建筑行业的数字化转型&#xff0c;还为工地管理、信息交流、安全监控等带来了全新的解决方案。本文将介绍互联网建筑工地的几个关键技…

java.lang.EnumConstantNotPresentException

枚举常量不存在异常。当应用试图通过名称和枚举类型访问一个枚举对象&#xff0c;但该枚举对象并不包含常量时&#xff0c;抛出该异常 1.遇到的问题是我删除了带有CustomAnnotation注解的类,启动服务器还是会抛出异常 2.首先全局搜索了相关的枚举名字 确认没有引用。后发现项目…

keras 人工智能之VGGNet神经网络的图片识别训练

上期文章我们分享了如何使用LetNet体系结构来搭建一个图片识别的神经网络: 人工智能Keras的第一个图像分类器(CNN卷积神经网络的图片识别) 本期我们基于VGGNet神经网络来进行图片的识别,且增加图片的识别种类,当然你也可以增加更多的种类,本期代码跟往期代码有很大的相…

【MySQL】:超详细MySQL完整安装和配置教程

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; MySQL从入门到进阶 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. MySQL数据库1.1 版本1.2 下载1.3 安装1.4 客户端连接 &#x1f324;️全篇总…

LaTex设置标题页、修改文字颜色和文字高亮

目录 一、标题页 1&#xff09;常用的代码 2&#xff09;添加脚注 二、修改文字颜色和文字高亮 1&#xff09;设置文本的颜色 2&#xff09;添加文本高亮 3&#xff09;给文本添加有颜色的方框 一、标题页 主要的代码&#xff1a; \begin{titlepage} \noindent\fonts…

如何实现https密钥对登录方式

先安装docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo systemctl start docker.service systemctl enable docker.service yum install -y docker…

Kali Linux—借助 SET+MSF 进行网络钓鱼、生成木马、获主机shell、权限提升、远程监控、钓鱼邮件等完整渗透测试(一)

社会工程学—世界头号黑客凯文米特尼克在《欺骗的艺术》中曾提到&#xff0c;这是一种通过对受害者心理弱点、本能反应、好奇心、信任、贪婪等心理陷阱进行诸如欺骗、伤害等危害手段。 SET最常用的攻击方法有&#xff1a;用恶意附件对目标进行 E-mail 钓鱼攻击、Java Applet攻…

nosql-redis整合测试

nosql-redis整合测试 1、创建项目并导入redis2、配置redis3、写测试类4、在redis中创建key5、访问80826、在集成测试中测试方法 1、创建项目并导入redis 2、配置redis 3、写测试类 4、在redis中创建key 5、访问8082 6、在集成测试中测试方法 package com.example.boot3.redis;…

SpringMVC之跨域请求

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 SpringMVC之跨域请求 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、什么是同源策略…

doris基本操作,04-表结构的变更

整体思路 因为doris完全兼容mysql协议&#xff0c;因此操作上基本与mysql没有太大区别&#xff0c; 之需要注意与doris相关的关键字即可&#xff0c;如&#xff1a;预聚合&#xff0c;key等 当前表结构 create table table1 {siteid int default 10,citycode smallint,usern…

HarmonyOS 签名打包Hap(s)、App(s)

1. 基本概念 HarmonyOS应用通过数字证书&#xff08;.cer文件&#xff09;和Profile文件&#xff08;.p7b文件&#xff09;来保证应用的完整性&#xff0c;数字证书和Profile文件可通过申请发布证书和Profile文件获取。   申请数字证书和Profile文件前&#xff0c;首先需要通…

渗透测试——1.2被动扫描

一、概念 目标无法觉察的情况下进行的信息收集。公开渠道可获得的信息&#xff0c;与目标系统不产生直接交互&#xff0c;尽量避免留下一切痕迹。 二、CDN&#xff08;content delivery netword内容分发网路&#xff09; 多台边缘服务器提供网络服务&#xff0c; 三、WAF&am…

docker-compose 安装Sonar并集成gitlab

文章目录 1. 前置条件2. 编写docker-compose-sonar.yml文件3. 集成 gitlab4. Sonar Login with GitLab 1. 前置条件 安装docker-compose 安装docker 创建容器运行的特有网络 创建挂载目录 2. 编写docker-compose-sonar.yml文件 version: "3" services:sonar-postgre…

地图导航测试点总结

地图导航是我们经常使用的工具&#xff0c;能帮助我们指引前进的方向。 接下来&#xff0c;会从功能测试、UI测试、兼容测试、安全测试、网络测试、性能测试、易用性测试、文档和国际化语言测试8个方面来编写地图导航测试用例。 一、功能测试 1. 输入起点和终点&#xff0c;…

CSS样式斜切边

html部分 <div class"rectangle"></div> 样式一&#xff1a; .rectangle { width: 251px; height: 75px; background: linear-gradient(-135deg, transparent 52px, #ffffff 0) top right; background-size: 100% 100%; background-repeat: no-repeat; b…