Linux编译器-gcc/g++使用 make/makefile最基础的功能

文章目录

  • 一.引例:
    • C语言
    • C++
  • 二.程序翻译的过程
    • 预处理
      • 条件编译
    • 编译
    • 汇编
    • 链接
  • 三.链接--动静态链接
    • 链接是什么?
    • 动静态库
    • 为什么要有库?
    • 怎么办?
      • 证明:
    • 优缺点
    • 静态链接的应用场景
  • 四.make/makefile
    • 原理:
    • 为什么makefile对最新的可执行程序,默认不想重新生成呢?
    • makefile怎么知道我的程序需要被编译了呢?
    • makefile中的内置符号

一.引例:

C语言

下面代码可能编不过去
在这里插入图片描述
因为编译器的版本没达到,需要手动改版本
在这里插入图片描述
默认形成的可执行文件是a.out
在这里插入图片描述
也可以更改形成的文件名-o 是object的意思,后缀随便加

gcc test.c -o my.exe -std=c99

在这里插入图片描述

C++

C++文件后缀不仅仅有.cpp和.cc,还有很少见到的.cxx
gcc不能编译C++的代码,但g++能编译C的代码

g++ test.cpp -o my.exe -std=c++11

二.程序翻译的过程

在这里插入图片描述

预处理

预处理把头文件直接展开,10来行变成800多行
在这里插入图片描述
Linux里面有库才能使用头文件,并且预处理之后文件展开的位置能之间看到库存在哪
在这里插入图片描述
预处理阶段宏会被替换,注释也被去掉
在这里插入图片描述

条件编译

引例:同样一种软件,有社区版,专业版,免费版。
那么维护代码的时候需要维护几份源代码?
维护一份代码即可,怎么做到的?
以以下代码为例
在这里插入图片描述
运行就会发现只打印了部分
在这里插入图片描述
预处理就被裁了
在这里插入图片描述
然后再做一下改变V1随便给个值

#include <stdio.h>                                                                                                2 #define V1 1                               3                                            4 int main()                                 5 {                                          6 #ifdef V1                                  7     printf("功能1\n");                     8 #elif V2                                   9     printf("功能1\n");                     10     printf("功能2\n");                     11 #else                                      12     printf("功能1\n");                     13     printf("功能2\n");                     14     printf("功能3\n");                     15 #endif                                     16     return 0;                              17 }    

运行
在这里插入图片描述
其中#ifdef #elif 等就是条件编译
这样裁剪可以定义出不同版本的软件
宏也可以在外面定义

gcc -D V1=1 proj.c -o filename

在这里插入图片描述

编译

gcc -S test.i -o test.s -std=c99

很明显,就是汇编语言
在这里插入图片描述

汇编

gcc -c test.s -o test.o

就是.obj结尾的文件
在这里插入图片描述
形成二进制的目标文件
在这里插入图片描述
还是运行不了
在这里插入图片描述

链接

gcc test.o -o my.exe

就可以直接运行了
在这里插入图片描述

三.链接–动静态链接

链接是什么?

程序与库结合的过程
引例:从零开始写代码,假设设计一个printf函数,设计好了大半个月过去了,效率比较低,所以语言设计者把一些公共的方法抽取出来,放进自己的标准库
下面的指令是查看文件掉用了哪些动态库

ldd filename

在这里插入图片描述
查看画横线的文件,没形成C语言库之前就是C语言的源代码,被顶级程序员打包成库
在这里插入图片描述
我们怎么知道C标准库里面有什么?所以就有一批对应的头文件,方便调用
在这里插入图片描述
所以安装开发环境:安装C标准库 + C头文件

动静态库

在这里插入图片描述

为什么要有库?

让个开发站在巨人的肩膀
提高开发效率

怎么办?

故事:

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

在这里插入图片描述
故事来到第二阶段:张三去不了网吧了(无法调用动态库),计划不能完整的执行了
在这里插入图片描述
第三阶段:
在这里插入图片描述

总结:所有动态链接都需要跑到库中执行,然后返回,静态链接不需要

证明:

C动态库,是默认提供的
gcc默认形成的可执行程序,默认采用动态链接
在这里插入图片描述
ls命令也是同理
在这里插入图片描述
要是删掉的话,就相当于上述故事中的警察查封网吧,大部分指令都运行不了了
静态库的位置,以.a结尾
在这里插入图片描述

优缺点

下面的指令是查看文件详细信息

file filename

在这里插入图片描述
动态库与动态链接的优缺点:
1.不能丢失(网吧不能去了就玩不了)
2.节省资源(网吧的电脑共用)
静态库与静态库的优缺点:
1.一旦形成就与库无关(自己有电脑就不用去网吧了)
2.浪费资源(自己的电脑自己用)
验证:
查看静态库的指令(mytest-static是形成test.c静态库的名称,名字随便取)

gcc -o mytest-static test.c -static -std=c99

会发现运行不了,找不到C语言的静态库
在这里插入图片描述
是因为默认情况下,Linux上一般静态库都是默认没有安装的
yum安装即可

sudo yum install -y glibc-static libstdc++-static

对比一下:
在这里插入图片描述
文件大小上静态比动态大很多
在这里插入图片描述

静态链接的应用场景

提高可移植性,比如直接把二进制代码从这个A机器到B机器,跨平台性提高,不依赖动态库,不用做过多的环境监测

四.make/makefile

原理:

make是一个命令
makefile是一个文件
创建makefile和创建普通文件的命令是一样的

touch makefile

以下代码为例
在这里插入图片描述
效果就是下面
在这里插入图片描述
在这里插入图片描述

关于依赖关系和依赖方法的理解,这里讲一个小故事:
月底了,身为大学生的你没钱了,拨通了父亲的电话:我是你儿子,然后你挂了电话。
我是你儿子这句话就表明了依赖关系,但是目的没达成,所以只有依赖关系没用
然后又打通电话:我是你儿子,没钱了打钱。你父亲就明白了
这就是表明了依赖关系又表明了依赖方法
发现在前面使用的时候,make是运行的第一段,make clean是第二段,同时make mytest也可以运行第一段
在这里插入图片描述
因为make是从上面向下运行的
在这里插入图片描述
把makefile反过来验证一下:
在这里插入图片描述
在这里插入图片描述
至于.PHONY是什么意思这里讲解一下:
以下面的makefile文件为例

mytest:test.cgcc -o mytest test.c                                                                                            
clean:rm -f mytest 

会发现第二次make的时候会说:此文件已经是最新的
在这里插入图片描述
但如果更改test.c的内容后,就可以再次make。
因为系统认为test.c已经编译过了,且没有最新的更改,所以没必要执行。
加了.PHONY后就可以一直执行

.PHONY:mytest                                                                                                     
mytest:test.cgcc -o mytest test.c
clean:rm -f mytest

在这里插入图片描述
.PHONY:XXX
表示XXX对应的方法,总要被执行的
一般写makefile的时候,形成可执行程序,源代码没有更新,没有必要编译
清理项目希望是被总是执行的,因为有些文件想要清理干净

为什么makefile对最新的可执行程序,默认不想重新生成呢?

假设一个项目有两千个源文件,很小的一部分需要做改动,如果全部编译效率很慢。
提高编译效率

makefile怎么知道我的程序需要被编译了呢?

源文件的更改时间和可执行程序更改的时间是不一样的
源文件:
在这里插入图片描述
可执行文件:
在这里插入图片描述
对比可执行文件的最近修改时间和源文件最近的修改时间,判断谁最新?
以此来判断是否需要编译文件

在这里插入图片描述
.PHONY的意思是直接编,不用比较
平时在写VS的时候,有时候会出错,清理重新编译后,就可以执行。原因就是不同的环境更新时间的策略不一样。

makefile中的内置符号

在这里插入图片描述
make的时候,他会自动替换目标文件
在这里插入图片描述
在makefile中注释是#
在这里插入图片描述
多个指令的实现也可以
引例:

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

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

相关文章

云资源管理系统-项目部署

云资源管理系统-项目部署 大家好&#xff0c;我是秋意零。 今天分享个人项目同时也是个人毕设项目&#xff0c;云平台资源管理系统。该系统具备对OpenStack最基本资源的生命周期管理&#xff0c;如&#xff1a;云主机、云盘、镜像、网络。 该篇主要介绍&#xff0c;项目在Li…

【LLM】PISSA:一种高效的微调方法

前言 介绍PISSA前&#xff0c;先简单过一下LLMs微调经常采用的LoRA&#xff08;Low-Rank Adaptation&#xff09;微调的方法&#xff0c;LoRA 假设权重更新的过程中有一个较低的本征秩&#xff0c;对于预训练的权重参数矩阵 W 0 ∈ R d k W_0 ∈ R^{dk} W0​∈Rdk&#xff0c…

Linux_内核缓冲区

目录 1、用户缓冲区概念 2、用户缓冲区刷新策略 3、用户缓冲区的好处 4、内核缓冲区 5、验证内核缓冲区 6、用户缓冲区存放的位置 7、全缓冲 结语 前言&#xff1a; Linux下的内核缓冲区存在于系统中&#xff0c;该缓冲区和用户层面的缓冲区不过同一个概念&#x…

数据结构与算法引入(Python)

华子目录 引入第一次尝试第二次尝试 算法的概念算法的五大特性 算法效率衡量执行时间单靠时间值绝对可信吗&#xff1f; 时间复杂度与 "大O记法"如何理解 “大O记法” 最坏时间复杂度时间复杂度的几条基本计算规则 算法分析常见的时间复杂度常见时间复杂度之间的关系…

2024最新版DataGrip安装教程-全网最全教程!!!

1.DataGrip下载安装 1.打开DataGrip官网&#xff0c;选择自己需要的版本下载即可&#xff1a; 2.进行安装&#xff1a; 3.重启打开&#xff1a; 我这个是正版激活码激活的&#xff0c;需要教程可以关注留言

[Redis]持久化机制

众所周知&#xff0c;Redis是内存数据库&#xff0c;也就是把数据存在内存上&#xff0c;读写速度很快&#xff0c;但是&#xff0c;内存的数据容易丢失&#xff0c;为了数据的持久性&#xff0c;还得把数据存储到硬盘上 也就是说&#xff0c;内存有一份数据&#xff0c;硬盘也…

RuoYi Swagger请求401

问题描述&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 使用ruoyi-vue分离版&#xff0c;访问swagger&#xff0c;发现接口都调用失败&#xff1a;401 解决方案&#xff1a; 最终解决问题如下步骤&#xff1a; 1、 调用swagger中的接口&#xff0c;报错&a…

【Mysql】DQL操作单表、创建数据库、排序、聚合函数、分组、limit关键字

DQL操作单表 1.1 创建数据库 •创建一个新的数据库 db2 CREATE DATABASE db2 CHARACTER SET utf8;•将db1数据库中的 emp表 复制到当前 db2数据库 ** 1.2 排序** 通过 ORDER BY 子句,可以将查询出的结果进行排序 (排序只是显示效果,不会影响真实数据) 语法结构&#xff1a;…

算法:渐进记号的含义及时间复杂度计算

渐进记号及时间复杂度计算 渐近符号渐近记号 Ω \Omega Ω渐进记号 Θ \Theta Θ渐进记号小 ο \omicron ο渐进记号小 ω \omega ω渐进记号大 O \Omicron O常见的时间复杂度关系 时间复杂度计算&#xff1a;递归方程代入法迭代法套用公式法 渐近符号 渐近记号 Ω \Omega Ω …

每天写java到期末考试--接口1--基础--6.22

规则&#xff1a; 练习&#xff1a; 抽象类的抽象方法 动物类Animal package 期末复习;public abstract class Animal {private String name;private int age;//1.空构造public Animal(){}public Animal(String name,int age){this.ageage;this.namename;}public String getNa…

【C++提高编程-11】----C++ STL常用集合算法

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

Nginx 负载均衡实现上游服务健康检查

Nginx 负载均衡实现上游服务健康检查 Author&#xff1a;Arsen Date&#xff1a;2024/06/20 目录 Nginx 负载均衡实现上游服务健康检查 前言一、Nginx 部署并新增模块二、健康检查配置2.1 准备 nodeJS 应用程序2.2 Nginx 配置负载均衡健康检查 小结 前言 如果你使用云负载均衡…

【Linux】 yum学习

yum介绍 在Linux系统中&#xff0c;yum&#xff08;Yellowdog Updater, Modified&#xff09;是一个用于管理软件包的命令行工具&#xff0c;特别适用于基于RPM&#xff08;Red Hat Package Manager&#xff09;的系统&#xff0c;如CentOS、Fedora和Red Hat Enterprise Linux…

【Arduino】实验使用ESP32单片机根据光线变化控制LED小灯开关(图文)

今天小飞鱼继续来实验ESP32的开发&#xff0c;这里使用关敏电阻来配合ESP32做一个我们平常接触比较多的根据光线变化开关灯的实验。当白天时有太阳光&#xff0c;则把小灯关闭&#xff1b;当光线不好或者黑天时&#xff0c;自动打开小灯。 int value;void setup() {pinMode(34…

音视频开发29 FFmpeg 音频编码- 流程以及重要API,该章节使用AAC编码说明

此章节的一些参数&#xff0c;需要先掌握aac的一些基本知识&#xff1a;​​​​​​aac音视频开发13 FFmpeg 音频 --- 常用音频格式AAC&#xff0c;AAC编码器&#xff0c; AAC ADTS格式 。_ffmpeg aac data数据格式-CSDN博客 目的&#xff1a; 从本地⽂件读取PCM数据进⾏AAC格…

【CARD】多变化字幕的上下文感知差异提炼(ACL 2024)

摘要 Multi-change captioning旨在用自然语言描述图像对中的复杂变化。和图像字幕相比&#xff0c;这个任务要求模型具有更高层次的认知能力来推理任意数量的变化。本文提出一种新的上下文感知差异提取网络&#xff08;CARD&#xff09;。给定一个图像对&#xff0c;CARD首先解…

Multigranularity and MultiscaleProgressive Contrastive Learning

这篇文章将一张图片划分为四个不同细粒度大小的图片&#xff0c;然后输出四个神经网络&#xff0c;这四个神经网络共享权重&#xff0c;得到四个输出&#xff0c;将这四个输出求交叉熵损失和对比学习损失&#xff0c;共同监督模型学习。 通过对比学习&#xff0c;最大化一个Bat…

Microsoft Edge无法启动搜索问题的解决

今天本来想清一下电脑&#xff0c;看到visual studio2022没怎么用了就打算卸载掉。然后看到网上有篇文章说进入C盘的ProgramFiles&#xff08;x86&#xff09;目录下的microsoft目录下的microsoft visual studio目录下的install目录中&#xff0c;双击InstallCleanup.exe&#…

Windows环境利用 OpenCV 中 CascadeClassifier 分类器识别人脸 c++

Windows环境中配置OpenCV 关于在Windows环境中配置opencv的说明&#xff0c;具体可以参考&#xff1a;VS2022 配置OpenCV开发环境详细教程。 CascadeClassifier 分类器 CascadeClassifier 是 OpenCV 库中的一个类&#xff0c;它用于实现一种快速的物体检测算法&#xff0c;称…

API接口技术开发分享;按关键字搜索淘宝、天猫商品API返回值接入说明

淘宝数据API的接入流程主要包括注册key账号、创建开发者应用、获取ApiKey和ApiSecret、申请API权限等步骤。淘通过这些接口可以获取商品、订单、用户、营销和物流管理等多方面的数据。以下是关于淘宝数据API接入流程的相关介绍&#xff1a; 注册key账号&#xff1a;进行账号注册…