Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile

news2024/7/4 23:51:46

Linux基础环境开发工具的使用[二]

  • 一.动静态库的初步理解
    • 1.库的作用
    • 2.Linux和Windows中库的后缀名
    • 3.如何在Linux中看一个的库名字
    • 4.Linux中和Windows平台怎样支持开发的?
    • 5.动静态库的概念
    • 6.动静态库的优缺点与补充
    • 7.代码验证
  • 二.make,makefile
    • 1.功能
    • 2.基本语法
      • 1.快速使用
      • 2.依赖关系和依赖方法
      • 3.补充:编译的特性
      • 4.补充:ACM时间
        • 1.具体比较的时间
        • 2.Access时间的特点
      • 5.clean
      • 6.makefile扫描特性
    • 3.makefile语法补充
      • 1..PHONY关键字
      • 2.$ @ $ ^
      • 3.变量
      • 4.make和makefile语法理解(递归)
    • 4.多文件的makefile的书写

一.动静态库的初步理解

1.库的作用

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

书接上次我们提到的程序的翻译过程中的链接阶段
以C语言代码为例
在链接阶段,我们的.c源文件经过预处理,编译,汇编之后形成了.o目标文件
我们的这个.o文件如果想要形成可执行程序

就一定会用到我们的C库
比如说以最简单的C语言代码为例:

#include <stdio.h>
int main()
{
  printf("hello world");
  return 0;
}

在这里这个printf函数就不是我们实现的,而是使用的C语言官方库里面的stdio.h头文件中所声明出来的printf这个函数

所以在程序的翻译阶段我们就要将我们的.o目标文件和库中的.o目标文件关联起来
在这里插入图片描述
也就是说gcc是知道我们是肯定要用到C库的,而且gcc也知道C库在什么地方
所以gcc说:不用你给我指定了,反正我是知道你要用C库,而且C库在哪我一清二楚
下面我们来验证一下;
说明一下:

ldd命令可以查看一个可执行程序所依赖的库文件

在这里插入图片描述
我们在看这个libc.so.6的库之前要先补充一个内容
就是Linux中的库的后缀名

2.Linux和Windows中库的后缀名

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

3.如何在Linux中看一个的库名字

在Linux中,无论是动态库还是静态库
都是以lib开头的
在这里插入图片描述
而且.so以及之后的内容都可以去掉不看
所以这个库就从
libc.so.6 被我们简化成了 c
也就是c标准库
因此我们就证明了C语言代码会跟C库关联起来

那么如果我现在生气了,main函数里面我只写一个return 0;
我看看它还跟不跟C库关联
在这里插入图片描述
答案是:还是跟C库关联
因此只要你是一个C语言代码,你命中注定就要跟我C库关联

4.Linux中和Windows平台怎样支持开发的?

在这里插入图片描述
这是Linux为我们提供的C语言的头文件
在这里插入图片描述
在这里插入图片描述
这是Linux为我们提供的C语言的库文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以我们就能更好地理解这句话了
在这里插入图片描述
其实库文件是二进制文件,也就是.o文件
因此库文件才能跟我们的.o目标文件进行链接

5.动静态库的概念

我们跟动态库形成的链接叫做动态链接
跟静态库形成的链接叫做静态链接
在这里插入图片描述
因此,如果我今天在Linux中把我们C语言的C标准库给干掉
那么ls,pwd,whoami,who,su等等几乎所有用C语言写的指令都无法运行了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.动静态库的优缺点与补充

在这里插入图片描述

7.代码验证

gcc -o mycmd1 test.c  使用动态链接进行编译(动态链接是gcc的默认行为)
gcc -o mycmd2 test.c -static 使用静态链接进行编译(需要在gcc命令后面加上-static选项)

下面我们来演示一下:
我们就以这个代码为例,分别用动态链接和静态链接去编译,来对比一下所分别形成的可执行程序的大小
在这里插入图片描述
1.动态链接进行编译
在这里插入图片描述
动态链接生成的可执行程序的大小:8360
在这里插入图片描述
2.静态链接进行编译
在这里插入图片描述
可是报错了,为什么呢?因为我们在前面说过,我们的云服务或者是虚拟机默认是没有给我们安装C语言的静态库的,那么我们现在自己来安装

Centos 7中使用yum安装

C语言静态库:glibc-static 
C++静态库:libstdc++-static

执行:

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

在这里插入图片描述
然后我们回过头来继续使用静态链接进行编译
在这里插入图片描述
在这里插入图片描述
关于动静态库的知识我们以后还会再进行介绍的,目前就先介绍到这里

二.make,makefile

make/makefile是Linux项目自动化构建工具
其中make是一个命令,makefile是一个文件(这个文件当中所写的是依赖关系和依赖方法)

1.功能

在这里插入图片描述
既然这个make,makefile这么强大,那就让我们来一起探索一下吧

2.基本语法

1.快速使用

首先我们带大家快速使用一下makefile
我们先创建一个test.c
然后写了一个简单的hello world
在这里插入图片描述
然后我们touch一个Makefile
然后用vim写了两行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.依赖关系和依赖方法

在这里插入图片描述

3.补充:编译的特性

但是现在有这么一种情况,再生成刚才的可执行程序之后,我再次make,make,make
在这里插入图片描述
也就是说它现在就不给我再去编译了
然后我修改一下这个test.c文件
我随便加上了几行hello world
在这里插入图片描述
然后我再去make一下
在这里插入图片描述
也就是说:

如果我没有改动源文件
那么make一次之后的每次make时都不会再去重新编译

在这里插入图片描述

4.补充:ACM时间

在这里插入图片描述
我们使用stat查看一下这个test.c的时间
在这里插入图片描述
它上面给我显示了三种时间:
Access : 文件的"最近"访问时间
Modify: 文件的内容的最近修改时间
Change: 文件的属性的最近修改时间

其中文件的属性包括:文件名,文件类型,文件权限(rwx,拥有者,所属组,Other,大小,等等等等)

你这个Modify好理解,Change也挺好理解,你这个Access的"最近"为什么要加双引号呢?
还有我这个比较到底是要比较那个时间呢?

我们先来探索一下第二个问题

1.具体比较的时间

首先我们先明确一点:
我们修改一个文件的内容是会影响到它的大小的,绝大多数情况下是会改变这个文件的大小的,无论是这个文件最后变大还是最后变小了
大小不变的概率很低

因此绝大多数情况下:改变这个文件的Modify时间时,这个Change时间也会随之变动

那么我们就用一下排除法吧:

我们先只去改变这个文件的Change时间和Access时间,然后看看这个文件会不会重新编译

首先我们先通过权限来改变Change时间
在这里插入图片描述
然后我们通过cat修改文件的Access时间
在这里插入图片描述
然后我们修改了一下这个文件的Modify时间
在这里插入图片描述
在这里插入图片描述
经过排除法,我们验证了只有修改Modify时间后,这个文件才会重新编译,其实我们想一下也完全可以理解,这里只是验证了一下

2.Access时间的特点

在这里插入图片描述

5.clean

然后我们回到make和makefile中,你这个make和makefile的确是能够让我进行快速便捷地编译形成可执行程序

但是如果我今天想要把我的这个可执行程序删除,你make和makefile能搞定吗?

当然可以啦
这就要用到clean了
在这里插入图片描述
在这里插入图片描述
然后我们make clean
然后我们make
在这里插入图片描述
发现clean的清理工作很成功

所以以后当我们想要
1.编译这个源代码生成可执行程序,只需要make
2.删除这个可执行程序,只需要make clean

那么如果我把clean放到前面会怎么样呢?

6.makefile扫描特性

在这里插入图片描述
在这里插入图片描述
怎么明明当我还没有mycmd这个可执行程序的时候
这个rm -f mycmd就能执行呢?
这里有一个小的知识点:
其实是因为我们加了-f选项
也就是说rm -f是不管你有没有mycmd这个文件我都会执行
如果你有,那么我强制删除,如果你没有,那我我执行了也相当于我什么都不执行

回到正题,为什么我现在make的时候不去给我编译源文件,反而给我删除可执行程序呢?
这就要说到makefile的扫描特性了:
在这里插入图片描述
那我现在就是想要编译源文件生成可执行程序,怎么办?
在这里插入图片描述
我们可以make mycmd来进行编译(其中这个mycmd就是我们想要生成的可执行程序的名字)
而这个clean也是我们自己起的名字,不过最好还是让他叫做clean就行

下面我们来验证一下:
我新建了一个目录test
这里我给这个想要生成的可执行程序随便起了一个名字wz
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可见make,make clean成功运行
下面我把clean改了
在这里插入图片描述
在这里插入图片描述
总之:
我们再写makefile的时候,一般都是这样的:
1.clean放在后面,编译生成可执行程序放在前面
2.clean就让他叫做clean
3.想要编译就用make命令,想要清理可执行程序就用make clean命令

3.makefile语法补充

1…PHONY关键字

对于这个关键字:记住一点:总是被执行
怎么理解呢?
我们先用.PHONY来修饰一下我们这个可执行程序的编译
在这里插入图片描述

注意:在makefile中:注释使用#表示的

然后我们发现:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.$ @ $ ^

下面一些makefile的拓展写法
在这里插入图片描述
这个$@和$^是可以自动去推导的,类似于C++中的auto是可以自动推导类型的(我们可以这么理解,但是这两种语法完全扯不上边)

我们就可以理解为这是一种固定写法,没有为什么

然后我们make一下测试测试
在这里插入图片描述
发现的确成功运行了

3.变量

下面也是makefile的一种拓展写法
在这里插入图片描述
在这里插入图片描述
测试一下,发现正常运行

4.make和makefile语法理解(递归)

下面我们在这个依赖关系和依赖方法的上面来深层次的去理解一下make和makefile的执行逻辑

编写这个makefile,我们也可以这样去写
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.多文件的makefile的书写

你前面跟我提的makefile都是单文件的
那么多文件的情况呢?
下面我们写了fun.h fun.c test.c
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
成功运行
当然这里把.c改成.o,然后再去生成.o目标文件也是可以的
在这里插入图片描述
在这里插入图片描述

以上就是我们Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile的全部内容,希望能对大家有所帮助!

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

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

相关文章

SV-704LW 无线WIFI网络音柱

SV-704LW 无线WIFI网络音柱(工业级) 一、描述 SV-704LW是深圳锐科达电子有限公司的一款壁挂式WIFI无线网络音柱&#xff0c;通过WIFI无线接入到WIFI覆盖的网络中&#xff0c;可将网络音源通过自带的功放和喇叭输出播放&#xff0c;其采用防水设计&#xff0c;功率可以从30W到6…

品牌如何长期占领小红书市场,小红书投放复盘怎么规划?

想要实现产品种草与品牌营销&#xff0c;达人投放成了很多品牌的选择。然而随着达人协助成本的水涨船高&#xff0c;提高达人投放结果&#xff0c;就变得迫在眉睫。今天我们将为大家分享下&#xff0c;品牌如何长期占领小红书市场&#xff0c;小红书投放复盘怎么规划&#xff1…

找不到x3daudio1_7.dll的解决方法,快速修复x3daudio1_7.dll缺失问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到x3daudio1_7.dll”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;这个文件是与音频设备相关的动态链接库文件&#xff0c;如果缺失或损坏&#xff0c;可能会导致软件游戏…

RabbitMQ(高级特性):限流

消费端限流 在rabbitmq中&#xff0c;使用消费端限流必须开启手动签收信息 过MQ可以对请求进行“削峰填谷”&#xff0c;即通过消费端限流的方式限制消息的拉取速度&#xff0c;达到保护消费端的目的。 生产者批量发送消息&#xff1a; Test public void testSendBatch() {…

聊聊 Python 的单元测试框架:unittest!

前言 说到 Python 的单元测试框架&#xff0c;想必接触过 Python 的朋友脑袋里第一个想到的就是 unittest。 的确&#xff0c;作为 Python 的标准库&#xff0c;它很优秀&#xff0c;并被广泛用于各个项目。但你知道吗&#xff1f;其实在 Python 众多项目中&#xff0c;主流的…

【SQL篇】一、Flink动态表与流的关系以及DDL语法

文章目录 1、启动SQL客户端2、SQL客户端常用配置3、动态表和持续查询4、将流转为动态表5、用SQL持续查询6、动态表转为流7、时间属性8、DDL-数据库相关9、DDL-表相关 1、启动SQL客户端 启动Flink&#xff08;基于yarn-session模式为例&#xff09;&#xff1a; /opt/module/f…

PubDef:使用公共模型防御迁移攻击

对抗性攻击对机器学习系统的可靠性和安全性构成了严重威胁。通过对输入进行微小的变动&#xff0c;攻击者就可以导致模型生成完全错误的输出。防御这种攻击是一个很活跃的研究领域&#xff0c;但大多数提议的防御措施都存在重大的缺点。 这篇来自加州大学伯克利分校研究人员的…

全光谱大面积氙光灯太阳光模拟器老化测试

氙灯光源太阳光模拟器广泛应用于光解水产氢、光化学催化、二氧化碳制甲醇、光化学合成、光降解污染物、 水污染处理、生物光照,光学检测、太阳能电池研究、荧光材料测试(透射、反射、吸收) 太阳能电池特性测试&#xff0c;光热转化&#xff0c;光电材料特性测试&#xff0c;生物…

Docker Compose安装milvus向量数据库单机版-milvus基本操作

目录 安装Ubuntu 22.04 LTS在power shell启动milvus容器安装docker desktop下载yaml文件启动milvus容器Milvus管理软件Attu python连接milvus配置下载wget示例导入必要的模块和类与Milvus数据库建立连接创建名为"hello_milvus"的Milvus数据表插入数据创建索引基于向量…

docker容器技术基础入门

docker容器技术基础入门 容器(Container) 容器是一种基础工具&#xff1b;泛指任何可以用于容纳其他物品的工具&#xff0c;可以部分或完全封闭&#xff0c;被用于容纳、储存、运输物品&#xff1b;物体可以被放置在容器中&#xff0c;而容器则可以保护内容物&#xff1b;容器…

AVL树性质和实现

AVL树 AVL是两名俄罗斯数学家的名字&#xff0c;以此纪念 与二叉搜索树的区别 AVL树在二叉搜索树的基础上增加了新的限制&#xff1a;需要时刻保证每个树中每个结点的左右子树高度之差的绝对值不超过1 因此&#xff0c;当向树中插入新结点后&#xff0c;即可降低树的高度&…

数据结构:AVL树的实现和全部图解

文章目录 为什么要有AVL树什么是AVL树AVL树的实现元素的插入平衡因子的更新AVL树的旋转 AVL树的检查完整实现 本篇总结的是AVL树中的全部内容&#xff0c;配有详细的图解过程 为什么要有AVL树 前面对map/multimap/set/multiset进行了简单的介绍&#xff0c;在其文档介绍中发现…

计算机毕业设计java+springboot+vue的旅游攻略平台

项目介绍 本系统结合计算机系统的结构、概念、模型、原理、方法&#xff0c;在计算机各种优势的情况下&#xff0c;采用JAVA语言&#xff0c;结合SpringBoot框架与Vue框架以及MYSQL数据库设计并实现的。员工管理系统主要包括个人中心、用户管理、攻略管理、审核信息管理、积分…

Go 接口-契约介绍

Go 接口-契约介绍 文章目录 Go 接口-契约介绍一、接口基本介绍1.1 接口类型介绍1.2 为什么要使用接口1.3 面向接口编程1.4 接口的定义 二、空接口2.1 空接口的定义2.2 空接口的应用2.2.1 空接口作为函数的参数2.2.2 空接口作为map的值 2.3 接口类型变量2.4 类型断言 三、尽量定…

Day22力扣打卡

打卡记录 替换子串得到平衡字符串&#xff08;滑动窗口&#xff09; 链接 由于是以后统计替换的子串&#xff0c;不可以直接使用hash表统计的每个次数大于 n / 4 的字符&#xff0c;再将其次数减去平衡数来得到答案&#xff0c;根据字符串的连贯性&#xff0c;使用 滑动窗口 …

MySQL 8.0 如何修改密码安全策略!!!

目录 安全策略参数和常见等级:1.Mysql8.X常见安全策略参数指定密码的强度验证等级validate_password.policy 取值&#xff1a; 解决步骤1.登录mysql2.修改安全策略(1)语法如下:(2)修改完可以看一下&#xff1a; 3.改完密码策略&#xff0c;就可以根据自己修改的策略&#xff0c…

pytorch复现_UNet

什么是UNet U-Net由收缩路径和扩张路径组成。收缩路径是一系列卷积层和汇集层&#xff0c;其中要素地图的分辨率逐渐降低。扩展路径是一系列上采样层和卷积层&#xff0c;其中特征地图的分辨率逐渐增加。 在扩展路径中的每一步&#xff0c;来自收缩路径的对应特征地图与当前特征…

什么是分治算法?

分治算法(divide and conquer algorithm)是指把大问题分割成多个小问 题&#xff0c;然后把每个小问题分割成多个更小的问题&#xff0c;直到问题的规模小到能够 轻易解决。这种算法很适合用递归实现&#xff0c;因为把问题分割成多个与自身相 似的小问题正对应递归情况&#x…

Java —— 类和对象(一)

目录 1. 面向对象的初步认知 1.1 什么是面向对象 1.2 面向对象与面向过程 2. 类定义和使用 2.1 认识类 2.2 类的定义格式 3. 类的实例化(如何产生对象) 3.1 什么是实例化 3.2 访问对象的成员 3.3 类和对象的说明 4. this引用 4.1 为什么要有this引用 4.2 什么是this引用 4.3 th…

无线发射芯片解决方案在智能家居中的应用

随着物联网的发展&#xff0c;智能家居已经成为一个热门话题。智能家居利用无线技术来实现设备之间的互联互通&#xff0c;提供更智能、更便利的生活体验。无线发射芯片解决方案在智能家居中扮演着关键的角色&#xff0c;它们为智能家居设备之间的通信提供了稳定、高效的连接&a…