Linux gcc和make学习

news2024/11/24 10:56:41

文章目录

    • GCC
      • gcc的安装
      • gcc的工作流程
    • makefile
      • makefile的规则
      • 工作原理
      • 自动生成
      • makefile的变量
        • 自定义变量
        • 预定义变量
        • 自动变量
      • 模式匹配
      • 函数
        • wildcard函数
        • patsubst函数
      • 伪声明

GCC

gcc全程是(GNU compiler collection CNU编译器套件),是由GNU开发的编程语言编辑器,它包含有gcc、g++,但是不仅限于这两种编译器;gcc不仅可以编译c/c++,还可以编译其他的语言包括java等,gcc可以实现跨不同的硬件平台编译,也就是交叉编译,比如在a平台可以编译b平台上的程序,常用支持linux、windows等。

gcc的安装

# 安装必须有管理员程序
# ubuntu
$ sudo apt update # 更新本地下载列表,获取最新的下载地址
$ sudo apt install gcc g++

# centos
$ sudo yum update
$ sudo yum install gcc g++
# 查看gcc版本
$ gcc -v
$ gcc --version

$ g++ -v

gcc的工作流程

gcc编译器对程序的编译主要分为4个阶段:预编译(预处理)、编译和优化、汇编、链接,gcc的编译器可以将这4个步骤合并成一个,下面分别介绍这四个步骤做了什么事情

  • 预编译(预处理):在这个阶段主要做了三件事情:展开头文件、宏替换、去掉注释行,这一阶段由gcc的预处理器完成,最终得到的还是源文件,文本格式。
  • 编译:这个阶段需要调用gcc编译器对文件进行编译,最终得到一个汇编文件
  • 汇编:这个阶段需要调用gcc的汇编器对文件进行汇编,最终得到一个二进制文件
  • 链接:这个阶段需要调用gcc的链接器对程序需要调用的库进行链接,得到一个可以执行的文件

分步完成:比如有一个为file.c的源文件(麻烦版)

预处理 gcc -E file.c -o file.i
编译 gcc -S file.i -o file.s
汇编 gcc -c file.s -o file.o
链接 gcc file.o -o file
file.c
file.i
file.s
file.o
file可执行文件

一步到位:使用gcc file.c -o aa可以直接生成编译链接后的file的可执行文件aa,直接使用./aa就可以执行。

GCC用到的参数

  • -E:对文件进行预处理,不进行编译,生成的还是源文件
  • -S:对文件进行编译,生成一个汇编文件
  • -c:对文件进行汇编,生成一个二进制文件
  • -o:用来指定生成的文件的名称
  • -I:指定include包含文件的搜索目录

makefile

  • 一般来说,使用gcc的命令行进行程序的编译在单个文件下是非常方便的,但是在实际的应用中,一个工程总不会是由单个文件构成的,往往是由多个文件构成的,当工程的文件逐渐增多,甚至非常庞大,使用GCC进行编译就会变得力不从心,这个时候可以使用make构造工具来完成这个艰巨的任务。
  • make是一个解释makefile中指令的命令工具。make工具在构造项目的时候需要加载一个makefile的文件,makefile关系到整个工程的编译规则,当一个工程中的源文件不计其数,按照类型、功能、模块划分在若干目录中时,这些文件之间存在着各种的依赖关系,makefile可以定义一系列的规则来指定哪一些文件需要先编译,哪一些文件需要后编译,哪一些文件需要重新编译等。
  • mekefile类似于一个shell脚本,所以也可以执行操作系统的一些命令。
  • 使用makefile可以自动化编译,极大的提高了软件开发的效率
  • makefile文件有两种命名的方式makefileMakefile,构建的时候在哪一个目录下执行make命令,哪一个目录的makefile文件就会被加载,因此一个项目中可以有多个makefile文件,分别存放在不同的项目目录中。
# 比如当前目录下有以下文件:add.c,clean,dic.c,head.h,main.c,makefile,sub.c
# 如果是使用gcc来对文件进行编译可以执行一下命令,生成app可执行命令
$ gcc *.c -o app
# 如果使用make命令可以直接
$ make
# 如果编译完成,可以直接使用以下命令删掉所有的编译文件
$ make clean

makefile的规则

# 每条规则的语法格式为:
target1,target2,... : depend1.depend2,...
	command
	......
	......

每一条规则都有三个部分组成:目标(target)、依赖(depend)、命令(command)

  • 命令(command):当前这条规则的动作,一般情况下这个动作都是一个shell命令;动作可以是一个也可以是多个,每个命令前都必须有一个Tab缩进并且独占一行

  • 依赖(depend):规则所必须的依赖条件,如果规则不需要任何依赖,那么依赖可以为空;当前的规则可以是其规则的某一个目标,这就形成了规则之间的嵌套;依赖可以有多个

  • 目标(target):规则中的目标,目标与命令是对应的;规则中可以有多个命令,多条命令可以生成多个目标,所以目标可以有多个;通过规则中的命令值执行一个动作,不生成任何文件,这样的目标叫做伪目标

    举一个不太恰当的比喻,目标、依赖、命令的关系就好像是用材料做蛋糕的关系:目标就是我们要做的蛋糕,依赖就是做蛋糕原材料,命令就是用原材料做蛋糕的具体步骤,一个语法正确的规则,往往是一条shell命令对依赖关系的处理得到目标的过程。

# 规则中的嵌套关系
# 规则1
app:a.o b.o c.o
	gcc a.o b.o c.o -o app
# 规则2
a.o:a.c
	gcc -c a.c -o a.o
# 规则3
b.o:b.c
	gcc -c b.c -o b.o
# 规则4
c.0:c.c
	gcc -c c.c -o c.o

工作原理

  • 在调用make命令编译程序的时候,make会首先找到makefile文件的第1个规则,分析并执行相关的动作。但是需要注意的是,很多时候要执行的动作(命令)中的以来关系是不存在的,如果使用的以来关系不存在这个动作也不会被执行。
  • 遇到以上的情况,首先会将需要的依赖关系生成出来,以此类推,直到makefile的第一条规则的所有的依赖关系都被生成,第一条命令就可以基于这些依赖生成对应的目标,make任务也就结束了。
  • 换句话说,makefile的后续的规则,都是为了第一条命令来服务的。
  • 如果想要执行单条规则,可以使用make 目标名来执行单条规则。

情况1:依赖存在,但是目标不存在

  • 直接根据依赖生成目标

情况2:目标和依赖都不存在,目标时间戳>依赖时间戳,属于正常情况,不执行
情况3:依赖的时间戳>目标的时间戳,make重新生成目标

自动生成

make有自动推导能力,不会完全依赖与makefile。换句话说,make有一些隐藏的默认规则,这些规则就算不编写在makefile,make也会自动执行对应的规则,生产目标文件。

有的时候,我们可以不使用默认的规则生成目标,比如在编译一个多文件的程序中,如果只使用一条规则对多文件进行编译,当我们修改其中的一个文件时,通过make构建工具还是会把整个的文件全部编译一次,如果文件的数量很多,就会非常消耗时间;但是如果我们把默认规则都列举出来,就可以进行分步编译,当只修改其中一两个文件是,不需要对全部的依赖文件都编译一次,可以大大的提高编译的效率。

如果文件有修改,只编译修改的东西,可以加快编译的速度,只编译对应修改的以来关系的链条

makefile的变量

makefile的变量分为三种:自定义变量、预定义变量和自动变量

自定义变量

用户自己定义的变量叫做用户自定义变量,makefile的变量是没有类型的,直接创建变量的名字然后给其赋值即可

# 正确的定义自定义变量
变量名=变量值

在给makefile的变量赋值之后,可以使用$(变量的名字)来将变量的值取出来

# 用户自定义变量
# 定义一个变量
obj=a.o b.o c.o
# 规则1
app:$(obj)
	gcc $(obj) -o app
预定义变量

makefile中有一些已经定义的变量,用户可以直接使用这些变量,不用进行定义,在某一些条件下,makefile会使用这些预定义的值进行编译,这些预定义变量的名字一般都是大写,经常采用的预定义变量如下表所示:

在这里插入图片描述

  • CC:默认值为 cc ,是gcc的意思,一般用来编译c程序
  • CXX:默认值为 g++,一般用来编译c++程序
  • CFLAGS:c语言编译器的编译选项,没有默认值,要用户自己赋值
# 预定义变量
# 定义变量
target=app
obj=a.o b.o c.o
CFLAGS=-O3 # 代码优化(有四种优化级别分别是0-3)
# 规则1
$(target):$(obj)
	$(CC) $(obj) -o $(target) $(CFLAGS)
自动变量

自动变量用来代表这些规则中的目标文件和依赖关系,并且它们只能在规则的命令中使用

在这里插入图片描述

  • $@:表示目标文件的名称。包括扩展名
  • $^:在依赖项中,所有不重复的依赖文件,这些文件直接以空格分开
  • $<:在依赖项中的第一个依赖文件的名称
# 自动变量
# 定义变量
target=app
obj=a.o b.o c.o

# 规则1
$(target):$(obj)
	gcc $^ -o $@

模式匹配

通过一个公式来代表若干满足条件的规则,用于精简makefile

以下代码中可以使用通配符%来匹配名字

# 规则中的嵌套关系
# 规则1
app:a.o b.o c.o
	gcc a.o b.o c.o -o app
# 规则2
a.o:a.c
	gcc -c a.c -o a.o
# 规则3
b.o:b.c
	gcc -c b.c -o b.o
# 规则4
c.0:c.c
	gcc -c c.c -o c.o
# 规则中的嵌套关系
# 规则1
app:a.o b.o c.o
	gcc a.o b.o c.o -o app
%.o:%.c
	gcc -c $< -o $@

函数

makefile中有很多函数并且所有的函数都具有返回值,makefile中的函数写法如下:$(函数名 参数1,参数2,参数3,...)

wildcard函数

这个函数的主要作用是获取指定目录下指定类型的文件名,其返回值是以空格分割的,指定目录下所有符合条件的文件名列表

# 函数原型
$(wildcard PATTERN...)
	参数:指定某个目录,搜索这个路径下指定类型的文件,可以指定多个目录,每一个路径之间用空格隔开

# 返回值:得到若干文件的文件列表,文件名之间使用空格间隔
# 搜索三个不同目录下的.c源格式文件
src=$(wildcard *.c ./sub/*.c /home/robin/b/*.c)
patsubst函数

这个函数的功能是按照孩子定的模式替换指定的文件名的后缀

# 有三个参数,参数之间用逗号隔开
$(patsubst pattern,replacement.text)

# pattern:模式字符串。需要指出要被替换的文件名的后缀是什么,文件名和路径不需要关心,使用 % 即可,如 %.c
# replacement:模式字符串,致命pattern中的后缀最终要被替换为什么;还是使用 % 表示路径和名字,指定新的后缀名即可,比如 %.o
# text:该参数中存储要被替换的原始数据
# 返回值:返回被替换过后的字符串
# 把变量src中所有文件名的后缀从.c替换为.o
src=a.c b.c c.c
obj=$(patsubst %.c,%.o,$(src))

使用函数搜索当前的目录下的c文件,并且修改名字

# 规则中的嵌套关系
# 规则1
app:a.o b.o c.o
	gcc a.o b.o c.o -o app
%.o:%.c
	gcc -c $< -o $@
target=app
src=$(whilecard *.c)# 搜索当前目录下所有的.c文件
obj=$(patsubst %.c,%.o,$(src))
$(target):$(obj)
	gcc $^ -o $@

%.o:%.c
	gcc -c $<

伪声明

target=app
src=$(whilecard *.c)# 搜索当前目录下所有的.c文件
obj=$(patsubst %.c,%.o,$(src))
$(target):$(obj)
	gcc $^ -o $@

%.o:%.c
	gcc -c $<

# 这是一条伪声明,没有依赖,也不生成文件(伪目标)
clean:
	rm $(obj) $(target)

对伪目标的声明,以避免make对文件的时间戳进行检测,需要使用.PHONY关键字,声明方式为.PHONY:伪文件名称

# 最终版
target=app
src=$(whilecard *.c)# 搜索当前目录下所有的.c文件
obj=$(patsubst %.c,%.o,$(src))
$(target):$(obj)
	gcc $^ -o $@

%.o:%.c
	gcc -c $<

# 这是一条伪声明,没有依赖,也不生成文件(伪目标)
.PHONY:clean
clean:
	-rm $(obj) $(target) # 加-表示即使第一条命令执行失败,后面的命令也要继续执行
	...

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

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

相关文章

【汇编语言学习笔记】一、基础知识

引言 汇编语言是直接在硬件之上工作的编程语言&#xff0c;首先要了解硬件系统的结构&#xff0c;才能有效的应用汇编语言对其编程。 1.1机器语言 机器语言是机器指令的集合。 机器指令展开来讲就是一台机器可以正确执行的命令。 1.2汇编语言 汇编语言的主体是汇编指令。 …

2023年中国特高压绝缘子市场规模及特高压投资完成额统计[图]

绝缘子指一般由固体绝缘材料制成&#xff0c;安装在不同点位的导体之间或导体与接地构件之间&#xff0c;是同时起到电气绝缘和机械支撑作用的器件&#xff0c;绝缘子可分为瓷绝缘子、玻璃绝缘子与复合绝缘子。特高压绝缘子指用于交流1,000kV、直流800kV及以上电压等级的绝缘子…

基于SSM框架的安全教育平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

QT CmakeLists配置python

这是exe目录&#xff0c;要放到这里&#xff0c;要放到这里&#xff0c;要放到这里。 find_package(PythonLibs 3.6 REQUIRED) include_directories(${PYTHON_INCLUDE_DIRS})set(PY python/libs/) set(PY_LIBS ${PY}_tkinter ${PY}python3 ${PY}python36 ${PY}python36_d) targ…

1805_emacs org-mode的归档处理

全部学习汇总&#xff1a;GreyZhang/g_org: my learning trip for org-mode (github.com) 我使用org-mode其实很多年了&#xff0c;但是使用的org-mode功能非常少而且技术自然也是很浮于表面。很多org-mode本身的功能我了解不多&#xff0c;更谈不上能够掌握。就比如说通过org维…

【DRAM存储器十五】DDR介绍-关键技术之DLL和prefetch

&#x1f449;个人主页&#xff1a;highman110 &#x1f449;作者简介&#xff1a;一名硬件工程师&#xff0c;持续学习&#xff0c;不断记录&#xff0c;保持思考&#xff0c;输出干货内容 参考资料&#xff1a;《镁光DDR数据手册》 目录 DLL 预取 DDR SDRAM的几个新增时…

Centos下编译ffmpeg动态库

文章目录 一、下载ffmpeg安装包二、编译ffmpeg三、安装yasm 一、下载ffmpeg安装包 下载包 wget http://www.ffmpeg.org/releases/ffmpeg-4.4.tar.gz解压 tar -zxvf ffmpeg-4.4.tar.gz二、编译ffmpeg 进入解压的目录 cd ffmpeg-4.4编译动态库 ./configure --enable-shared…

MyBatisPlus之基本CRUD、常用注解

文章目录 前言一、MyBatisPlus简介1.简介2.特性 二、基本CRUD1.依赖2.搭建基本结构3.BaseMapper4.使用插入删除&#xff08;1&#xff09;通过id删除记录&#xff08;2&#xff09;通过id批量删除记录&#xff08;3&#xff09;通过map条件删除记录 修改查询&#xff08;1&…

python 爬虫与协同过滤的新闻推荐系统 计算机竞赛

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python 爬虫与协同过滤的新闻推荐系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&…

opencv跨平台arm交叉编译之ubuntu

目录 1. 安装交叉编译工具链2. 安装依赖3. 配置工具链3.1 新建build目录3.2 安装cmake-gui3.3 工具链配置界面进行配置3.3.1 终端输入以下命令3.3.2 点击Configure&#xff0c;弹出编译方式选择对话框&#xff1a;3.3.3 点击Next3.3.4 点击Finish3.3.5 点击Configure。3.3.6 Ge…

SAP PP cs62 提示 输入更改号 - BOM 有历史需求

以上是业务操作人员的 账户 但是IT aLL 这边是warning 不是error 遂去查OSS suim 找 C_STUE_NOH权限对象 赋予权限后 解决了

交通物流模型 | T-GCN:用于交通流预测的时序图卷积网络

交通物流模型 | T-GCN:用于交通流预测的时序图卷积网络 为了同时捕获空间和时间依赖性,本文提出了一种新的基于神经网络的交通流预测方法——时间图卷积网络(T-GCN)模型,该模型将图卷积网络(GCN)和门控循环单元(GRU)相结合。具体来说,GCN用于学习复杂拓扑结构以获取空间相关…

SystemVerilog Assertions应用指南 第一章(1.22章节 and运算符)

1.22“and”构造 进制运算符“and”可以用来逻辑地组合两个序列。当两个序列都成功时整个属性才成功。两个序列必须具有相同的起始点,但是可以有不同的结束点。检验的起始点是第一个序列的成功时的起始点,而检验的结束点是使得属性最终成功的另一个序列成功时的点。 序…

接口自动化测试_L2

目录&#xff1a; 接口请求体-文件 文件上传接口场景使用 requests 如何上传接口请求体-form表单 ​​​​​​​什么是 FORM 请求如何使用&#xff1f;接口请求体-xml​​​​​​​xml响应断言 ​​​​​​​​​​​​​​什么是 XMLXML 断言XPath 断言XML 解析cookie处理…

网络安全渗透测试工具AWVS14.6.2的安装与使用(激活)

AWVS介绍 Acunetix Web Vulnerability Scanner&#xff08;AWVS&#xff09;是一款用于检测网站和Web应用程序中安全漏洞的自动化工具。它的主要功能包括&#xff1a; 漏洞扫描&#xff1a;AWVS能够自动扫描目标网站和Web应用程序&#xff0c;以发现各种安全漏洞&#xff0c;如…

水质在线监测解决方案:数据采集终端的应用

​ 随着社会的发展,河流、湖泊等水环境的保护日益受到关注。但是传统的人工采样检测水质的方法低效且监测数据不连续,无法实时全面掌握水质动态。采用水质在线监测系统,可以实时监测水质参数,并将数据通过无线网络实时传输,以便水务部门监控水质变化,并快速采取应对措施,保护水…

网工配置命令基础总结(2)----VRRP配置

目录 1.配置VRRP主备备份 2.配置VRRP负载分担 3.配置VRRP域BFD联动实现快速切换 VRRP 虚拟路由冗余协议 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;通过把几台路由设备联合组成一台虚拟的路由设备&#xff0c;将虚拟网关设备的 IP 地址作为用户的默认…

推荐一款正在用的配音软件(免费)~

最近在做账号&#xff0c;遇到的最大的难题就是&#xff0c;口播的能力一般&#xff0c;用电脑收声以后&#xff0c;总有许多语气词&#xff0c;发音不标准或吞字的情况&#xff0c;而且念稿也是个非常消耗时间的事儿。身边的朋友给我推荐了悦音配音这款AI配音软件&#xff0c;…

向量化操作简介和Pandas、Numpy示例

Pandas是一种流行的用于数据操作的Python库&#xff0c;它提供了一种称为“向量化”的强大技术可以有效地将操作应用于整个列或数据系列&#xff0c;从而消除了显式循环的需要。在本文中&#xff0c;我们将探讨什么是向量化&#xff0c;以及它如何简化数据分析任务。 什么是向量…

appium---如何判断原生页面和H5页面

目前app中存在越来越多的H5页面了&#xff0c;对于一些做app自动化的测试来说&#xff0c;要求也越来越高&#xff0c;自动化不仅仅要支持原生页面&#xff0c;也要可以H5中进行操作自动化&#xff0c; webview是什么 webview是属于android中的一个控件&#xff0c;也相当于一…