IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> makefile快速应用 -> 正文阅读

[系统运维]makefile快速应用

同时编译多个xxx.c文件

参考文章

make

make是一个命令工具,是一个解释makefile中指令的命令工具,当执行 make 时,make 会在当前的目录下搜寻 Makefile (or makefile) 这个文本文件,执行对应的操作。make 会自动的判别原始码是否经过变动了,而自动更新执行档

为什么要使用make?

假设,现在一个项目里面包含了100个程序文件,如果要对这个项目进行编译,那么光是编译指令就有100条。如果要重新进行编译,那么就又得像之前一样重新来一遍。所以,用make来进行操作,间接调用gcc比较方便。如果我们更动过某些原始码档案,则make 也可以主动的判断哪一个原始码与相关的目标文件档案有更新过, 并仅更新该档案。这样可以减少重新编译所需要的时间,提高效率。

makefile

makefile其实就是一个文档,里面定义了一系列的规则指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,它记录了原始码如何编译的详细信息!
makefile一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

语法规则

[Target/目标文件][Dependeds/依赖文件] [Dependeds/依赖文件] [Dependeds/依赖文件]...
    [Command/命令]  (命令前面需要按一下tab键)
    
 //注意:命令前面不是空格,而是一个TAB键
 //在Makefile文件中,注释符号为"#"

假设有几个程序:
在这里插入图片描述

Demo:main.o add.o sub.o					## 目标文件为:Demo             依赖文件为:main.o add.o sub.o
    gcc main.o add.o sub.o -o Demo		## 使用gcc编译main.o add.o sub.o并生成名为Demo的可执行文件



add.o:add.c add.h						## 目标文件为:add.o            依赖文件为:add.c add.h
    gcc -c add.c						##使用gcc编译add.c并生成add.o文件(默认)



sub.o:sub.c sub.h						## 目标文件为:sub.o            依赖文件为:sub.c sub.h
    gcc -c sub.c						## 使用gcc编译sub.c并生成sub.o文件(默认)



main.o:main.c add.h sub.h				## 目标文件为:main.o           依赖文件为:main.c add.h sub.h
    gcc -c main.c						## 使用gcc编译main.c并生成main.o文件(默认)

创建一个名字为Makefile的文件夹编辑如下图内容
在这里插入图片描述
然后使用make去执行(同时会生成xxx.o文件)
在这里插入图片描述

如果我们自己写的头文件刚好和xxx.c文件在同一目录,可以在Makefile中省略头文件。

例如,我们所有的文件. h和. c都在同一目录下,我们可以省略掉头文件:
在这里插入图片描述

如何删除不需要的.o文件
在这里插入图片描述

注意:

make指令是默认执行再最前面的语句。所以我们输入make的时候,相当于默认执行make Demo,当我们需要清楚除.o文件的时候就需要执行 make clean

在这里插入图片描述
makefile其实可以更加简洁的—自动推导

自动推导
make会自动推导目标文件后面的依赖文件。例如: 目标文件add.o,make将会自动推导出它有源文件add.c。

在这里插入图片描述
用户自定义变量
我们可以自定义一个OBJS变量和RM变量来分别替换 “main.o add.o sub.o
”和“ rm -f *.o”

OBJS = main.o add.o sub.o
RM = rm -f *.o

当我们需要使用变量的时候就可以用$来引用

$(OBJS)
$(RM)

我理解成就是字符串替换的意思
在这里插入图片描述
makefile中已经定义的变量(默认)

————————————————————————————————————————————————————————————————————————————————————
变量名		|			含义			|	默认值
————————————————————————————————————————————————————————————————————————————————————
AR		|	生成静态库库文件程序的指令			|	ar
————————————————————————————————————————————————————————————————————————————————————
AS		|	汇编编译器的名称				|	as
————————————————————————————————————————————————————————————————————————————————————
CC		|	C语言编译器的名称				|	cc
————————————————————————————————————————————————————————————————————————————————————
CPP		|	C语言编译器的名称				|	$(CC)-E
————————————————————————————————————————————————————————————————————————————————————
CXX		|	C++语言编译器的名称			|	g++
————————————————————————————————————————————————————————————————————————————————————
FC		|	FORTRAM语言编译器的名称			|	f77
————————————————————————————————————————————————————————————————————————————————————
RM		|	删除文件程序的名称			|	rm -f
————————————————————————————————————————————————————————————————————————————————————
ARFLAGS		|	生成静态库库文件程序的选项			|	无默认值
————————————————————————————————————————————————————————————————————————————————————
ASFLAGS		|	汇编语言编译器的编译选择			|	无默认值
————————————————————————————————————————————————————————————————————————————————————
CFLAGS		|	C语言编译器的编译选项			|	无默认值
————————————————————————————————————————————————————————————————————————————————————
CPPFLAGS	|	C语言预编译的编译选项			|	无默认值
————————————————————————————————————————————————————————————————————————————————————
CXXFLAGS	|	C++语言编译器的编译选项			|	无默认值
————————————————————————————————————————————————————————————————————————————————————
FFLAGS		|	FORTRAN语言编译器的编译选项		|	无默认值
————————————————————————————————————————————————————————————————————————————————————

自动变量

Makefile中的变量除了用户自定义变量和预定义变量外,还有一类自动变量。

Makefile中的编译语句经常会出现目标文件和依赖文件,自动变量可以去代替目标文件和依赖文件。

—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
     变量	|				含义
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
      $*	| 表示目标文件的名称,不包含目标文件的扩展名
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
      $+	| 表示所有的依赖文件,这些依赖文件之间以空格分开,按照出现的先后顺序,其中可能包含重复的文件
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
      $<	| 表示依赖项中第一个依赖文件的名称
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
      $?	| 依赖文件中,所有目标文件时间戳晚的依赖文件,依赖文件之间以空格分开
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
      $@	| 目标项中目标文件的名称
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
      $^	| 依赖项中,所有不重复的依赖文件,这些文件之间空格分开
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————                 

示例

Demo:main.o add.o sub.o	
	gcc $^ -o $@				
    ## gcc main.o add.o sub.o -o Demo
    		
add.o:add.c add.h
	gcc -c $<						
    ## gcc -c add.c	
    					
sub.o:sub.c sub.h						
    gcc -c $<
    ## gcc -c sub.c	
    					
main.o:main.c add.h sub.h				
    gcc -c $<
    ## gcc -c main.c		

模式匹配

例如:对于模式规则 “%. o : %. c ”,它表示的含义是:所有的 . o 文件依赖于对应的 . c文件。我们可以使用模式规则来定义隐含规则。

%.o: %.c
上面一句等同于下面两句
add.o: add.c
sub.o: sub.c

当文件路径不同的情况,如何编译?

在这里插入图片描述

VPATH
可以在Makefile文件中指定VPATH变量,指定make从指定文件目录中去找文件

VPATH = [第一个路径][第二个路径]:[第三个路径]:....

在这里插入图片描述

但是make的时候会提示找不到头文件的错误
在这里插入图片描述

CFLAGS指定头文件的位置
在这里插入图片描述

如果makefile在路径~TEXT下,还可以简化写法
在这里插入图片描述
在这里插入图片描述

这里的VPATH,和CFLAGS可以这样简写是因为当前的路径就是~/TEXT。而且需要在VPATH中多指明
demo这个文件夹,因为主函数main.c是在这个目录里面的。

在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 13:11:55  更:2022-10-17 13:15:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:31:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码