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

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.库的作用

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第1张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第2张图片

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

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

#include 
int main()
{
  printf("hello world");
  return 0;
}

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

所以在程序的翻译阶段我们就要将我们的.o目标文件和库中的.o目标文件关联起来
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第3张图片
也就是说gcc是知道我们是肯定要用到C库的,而且gcc也知道C库在什么地方
所以gcc说:不用你给我指定了,反正我是知道你要用C库,而且C库在哪我一清二楚
下面我们来验证一下;
说明一下:

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

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第4张图片
我们在看这个libc.so.6的库之前要先补充一个内容
就是Linux中的库的后缀名

2.Linux和Windows中库的后缀名

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第5张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第6张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第7张图片

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

在Linux中,无论是动态库还是静态库
都是以lib开头的
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第8张图片
而且.so以及之后的内容都可以去掉不看
所以这个库就从
libc.so.6 被我们简化成了 c
也就是c标准库
因此我们就证明了C语言代码会跟C库关联起来

那么如果我现在生气了,main函数里面我只写一个return 0;
我看看它还跟不跟C库关联
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第9张图片
答案是:还是跟C库关联
因此只要你是一个C语言代码,你命中注定就要跟我C库关联

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

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第10张图片
这是Linux为我们提供的C语言的头文件
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第11张图片
在这里插入图片描述
这是Linux为我们提供的C语言的库文件
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第12张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第13张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第14张图片
所以我们就能更好地理解这句话了
在这里插入图片描述
其实库文件是二进制文件,也就是.o文件
因此库文件才能跟我们的.o目标文件进行链接

5.动静态库的概念

我们跟动态库形成的链接叫做动态链接
跟静态库形成的链接叫做静态链接
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第15张图片
因此,如果我今天在Linux中把我们C语言的C标准库给干掉
那么ls,pwd,whoami,who,su等等几乎所有用C语言写的指令都无法运行了
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第16张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第17张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第18张图片

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

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第19张图片

7.代码验证

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

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

Centos 7中使用yum安装

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

执行:

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

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第23张图片
然后我们回过头来继续使用静态链接进行编译
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第24张图片
在这里插入图片描述
关于动静态库的知识我们以后还会再进行介绍的,目前就先介绍到这里

二.make,makefile

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

1.功能

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第25张图片
既然这个make,makefile这么强大,那就让我们来一起探索一下吧

2.基本语法

1.快速使用

首先我们带大家快速使用一下makefile
我们先创建一个test.c
然后写了一个简单的hello world
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第26张图片
然后我们touch一个Makefile
然后用vim写了两行
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第27张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第28张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第29张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第30张图片

2.依赖关系和依赖方法

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第31张图片

3.补充:编译的特性

但是现在有这么一种情况,再生成刚才的可执行程序之后,我再次make,make,make
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第32张图片
也就是说它现在就不给我再去编译了
然后我修改一下这个test.c文件
我随便加上了几行hello world
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第33张图片
然后我再去make一下
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第34张图片
也就是说:

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

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第35张图片

4.补充:ACM时间

在这里插入图片描述
我们使用stat查看一下这个test.c的时间
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第36张图片
它上面给我显示了三种时间:
Access : 文件的"最近"访问时间
Modify: 文件的内容的最近修改时间
Change: 文件的属性的最近修改时间

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

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

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

1.具体比较的时间

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

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

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

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

首先我们先通过权限来改变Change时间
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第37张图片
然后我们通过cat修改文件的Access时间
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第38张图片
然后我们修改了一下这个文件的Modify时间
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第39张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第40张图片
经过排除法,我们验证了只有修改Modify时间后,这个文件才会重新编译,其实我们想一下也完全可以理解,这里只是验证了一下

2.Access时间的特点

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第41张图片

5.clean

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

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

当然可以啦
这就要用到clean了
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第42张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第43张图片
然后我们make clean
然后我们make
在这里插入图片描述
发现clean的清理工作很成功

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

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

6.makefile扫描特性

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第44张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第45张图片
怎么明明当我还没有mycmd这个可执行程序的时候
这个rm -f mycmd就能执行呢?
这里有一个小的知识点:
其实是因为我们加了-f选项
也就是说rm -f是不管你有没有mycmd这个文件我都会执行
如果你有,那么我强制删除,如果你没有,那我我执行了也相当于我什么都不执行

回到正题,为什么我现在make的时候不去给我编译源文件,反而给我删除可执行程序呢?
这就要说到makefile的扫描特性了:
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第46张图片
那我现在就是想要编译源文件生成可执行程序,怎么办?
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第47张图片
我们可以make mycmd来进行编译(其中这个mycmd就是我们想要生成的可执行程序的名字)
而这个clean也是我们自己起的名字,不过最好还是让他叫做clean就行

下面我们来验证一下:
我新建了一个目录test
这里我给这个想要生成的可执行程序随便起了一个名字wz
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第48张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第49张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第50张图片
可见make,make clean成功运行
下面我把clean改了
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第51张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第52张图片
总之:
我们再写makefile的时候,一般都是这样的:
1.clean放在后面,编译生成可执行程序放在前面
2.clean就让他叫做clean
3.想要编译就用make命令,想要清理可执行程序就用make clean命令

3.makefile语法补充

1…PHONY关键字

对于这个关键字:记住一点:总是被执行
怎么理解呢?
我们先用.PHONY来修饰一下我们这个可执行程序的编译
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第53张图片

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

然后我们发现:
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第54张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第55张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第56张图片

2.$ @ $ ^

下面一些makefile的拓展写法
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第57张图片
这个$@和$^是可以自动去推导的,类似于C++中的auto是可以自动推导类型的(我们可以这么理解,但是这两种语法完全扯不上边)

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

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

3.变量

下面也是makefile的一种拓展写法
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第58张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第59张图片
测试一下,发现正常运行

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

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

编写这个makefile,我们也可以这样去写
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第60张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第61张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第62张图片

4.多文件的makefile的书写

你前面跟我提的makefile都是单文件的
那么多文件的情况呢?
下面我们写了fun.h fun.c test.c
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第63张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第64张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第65张图片
成功运行
当然这里把.c改成.o,然后再去生成.o目标文件也是可以的
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第66张图片
Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile_第67张图片

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

你可能感兴趣的:(Linux学习之路,linux,动静态库,make,makefile,Linux基础开发工具)