目录
八.Linux项目自动化构建工具-make/Makefile
一.间接完成可执行程序(过程)
🎓-o选项
- -o命令代表的都是完成该步骤的目标文件
- -o后面跟的文件名是可以自定义的
- -o选项后面跟的必须是目标文件
🚩源文件 -o 目标文件
mycode.c是源文件,-o生成目标文件,my.exe是目标文件
将mycode.c用-o选择生成了名字不唯一的可执行程序,改成my.exe;test.txt都是可以最终编译出来(自定义命名的话就带上-o)
🚩-o 目标文件 源文件
🎓背景知识
- -o命令代表的都是完成该步骤的目标文件
🎓预处理(进行宏替换)
- a.去注释
- b.头文件展开
- c.条件编译
条件编译:【社区版(免费)】 和【专业版(100)】 —— 提供这些软件的公司需要维护2份代码嘛?
根据不同的编译条件,裁减掉社区版不需要的功能即可。(条件编译的应用场景)
- 宏替换
-E选项告诉gcc从现在开始进行程序的翻译,将预处理工作做完就停下来,不要往后走了。否则就将全过程都进行完了
🎓编译(生成汇编)
-S选项从现在开始进行程序的翻译,将编译的工作做完,就停下来
🎓汇编(形成机器可识别代码)
汇编语言翻译成可识别的二进制程序(.o)
- -c从现在开始进行程序翻译,将汇编工作做完,就停下来
- mycode.o 可重定向目标二进制文件,简称目标文件,不可以独立执行,虽然已经二进制了,需要(链接)才可以执行
mycode.o 文本文件,所以打出来都是乱码
od mycode.o可以查看二进制码内容(汇编码成为二进制机器程序)
🎓链接(生成可执行文件或库文件)
将可重定位二进制文件,和库进行链接形成可执行程序
将mycode.o二进制文件,利用-o选项链接形成可执行程序文件mytest(文件名自定义)
二.直接生成可执行程序
c语言用gcc c++语言用g++
三.直接和间接四过程总结
- 生成的mycode.c 直接gcc mycode.c或者g++ mycode.cpp编译,之后直接就是生成了可执行程序./a.out
- -o命令代表的都是完成该步骤的目标文件,后面必须跟目标文件,目标文件名称自定义
- 预处理: mycode.c -E 表示停止编译过程,-o表示生成目标文件 mycode.i
- 编译(生成汇编) :mycode.i -S只进行编译,不进行汇编,生成汇编代码 -o表示生成目标文件 mycode.s
- 汇编(形成机器可识别的代码): mycode.s -c汇编代码转换为二进制目标代码 -o二进制目标文件 mycode.o
- 链接(生成可执行程序): mycode.o -o mytest.c -o选项后的文件名是自定义的
- 选项:看看键盘的左上角esc按键,我们只要记住ESc就可以了。
- 文件名后缀:.c .i .s .o (iso镜像文件的后缀)
四.函数库
库函数(Library function)是将函数封装入库,供用户使用的一种方式。方法是把一些常用到的函数编完放到一个文件里,供不同的人进行调用。调用的时候把它所在的文件名用#include<>加到里面就可以了。一般是放到lib文件里的。
库,给我们提供方法的实现
函数库一般分为静态库和动态库两种
c语言的标准库,本质就是一个文件,有路径
- Linux: .so(动态库) .a(静态库)
- windows: .dll(动态库) .lib(静态库)
- 我们使用的机器上,默认只会安装动态库(.so),静态库(.a)默认是没有安装的
- 库有自己的命名规则的:libname.so.XXX(库真正的名字只有name那一小块)
这个库就一个c文件。
编译型语言,安装开发包,必定是下载了安装头文件库文件。
- 库其实就是把源文件(.c),经过一定的翻译,然后打包----只给你提供一个文件即可,不用给你提供太多的源文件,也可以达到隐藏源文件的目的。
- 头文件提供方法的声明,库文件提供方法的实现 + 你的代码=可执行程序
库文件存在的价值就是不让我们做重复作用,站在巨人的肩膀上。
我们的.o和库是如何链接的?
1.动态链接 2.静态链接
五.动态库和静态库理论:
动态库(Dynamic Link Library)和静态库(Static Link Library)都是可重用的代码库,它们之间的主要区别在于:
👉静态函数库:
一般扩展名为(.a
或.lib
),这类的函数库通常扩展名为libxxx.a
或xxx.lib
。
这类库在编译的时候会直接整合到目标程序中,所以利用静态函数库编译成的文件会比较大,这类函数库最大的优点就是编译成功的可执行文件可以独立运行,而不再需要向外部要求读取函数库的内容;但是从升级难易度来看明显没有优势,如果函数库更新,需要重新编译。
静态库--在编译器使用静态库进行静态链接的时候,会将自己的方法拷贝到目标程序中,该程序以后就不用再依赖静态库了。
👉动态函数库:
动态函数库的扩展名一般为(.so
或.dll
),这类函数库通常名为libxxx.so
或xxx.dll
。
与静态函数库被整个捕捉到程序中不同,动态函数库在编译的时候,在程序里只有一个“指向”的位置而已,也就是说当可执行文件需要使用到函数库的机制时,程序才会去读取函数库来使用;也就是说可执行文件无法单独运行。这样从产品功能升级角度方便升级,只要替换对应动态库即可,不必重新编译整个可执行文件。
动态库不能缺失,一旦对应的动态库缺失,影响的不止一个程序,可能导致很多程序无法进行正常运行
👉动vs静的优缺点
动:
- 动态库因为是共享库,有效的节省资源(磁盘空间,内存空间,网络空间等)【优点】
- 动态库一旦缺失导致整个各个程序都无法运行【缺点】
静:
- 静态库不依赖库,程序可以独立运行【优点】
- 静态库体积大,比较消耗资源【缺点】
如果需要多个程序共享同一个库,或者需要较少的内存占用,则使用动态库可能更为合适。如果需要保持部署和更新的稳定性,则静态库可能更为适合。
六.静态库和动态库实操
动态链接使用时只能使用动态库,静态链接使用只能使用静态库
👩💻动态链接
- 首先ldd不是一个可执行程序,而只是一个shell脚本
- ldd命令显示一个可执行文件或共享库所依赖的动态链接库列表。它会递归地检查文件所依赖的所有库,并显示它们的路径。通过ldd命令可以了解一个程序运行所需的库文件,以及这些库文件是否存在、版本是否匹配等信息。
👩💻静态链接
在Linux中,如果要按照静态链接进行形成可执行程序,我们需要添加-static选项————提供静态库
就生成了mytest-static文件,代入了选项-static
👩💻静态库和动态库大小
静态库和动态库文件大小不一样,静态库文件大小大,动态库文件大小小
通俗易懂的说:动态库只给你安排电脑就行了,
静态库既要给你电脑还要给你安排桌子放电脑。
所以一般静态方式很少使用,因为占内存大。
👩💻安装静态库
我们Linux机器中默认只安装了动态库,没有安装静态库,不管是c还是c++都是没有安装静态库
👩🏻💻c语言静态库安装
sudo yum install -y glibc-static
👩🏻💻c++语言静态库安装
sudo yum install -y libstdc++-static
- 如果我们没有静态库,但是我们就要进行-static 行不行? ——不行
- 如果我们没有动态库,只有静态库,而且gcc能找到 ——能的,gcc默认优先动态链接(有静态库就用静态库,有动态库就用动态库,如果都没有就报错)
- -static的本质:改变优先级
- 不一定是纯的全部动态链接或者静态链接,混合的(但是加了-static选项就将所有的连接要求都变成静态链接)
👩💻file指令
可以查看自己的可执行程序是静态链接还是动态链接。
- statically linked静态链接
- dynamically linked动态链接
七.debug&release
- Debug:调试版本,包含调试信息,所以容量比Release大很多,并且不进行任何优化(优化会使调试复杂化,因为源代码和生成的指令间关系会更复杂),便于程序员调试。
- Release:发布版本,不对源代码进行调试,编译时对应用程序的速度进行优化,使得程序在代码大小和运行速度上都是最优的。(调试信息可在单独的PDB文件中生成)。
动态链接 形成mytest_debug文件时需要加个-g选项
静态链接 加个-static选项,就可以形成
g++和gcc编译都是一样的。
八.Linux项目自动化构建工具-make/Makefile
🔑背景知识
- make:是一个指令
- makefile:是一个当前目录下的文件
创建makcfile文件,vim进入makefile文件.
第一行冒号左右是依赖关系:
第二行依赖方法:
清理项目:
🔑make/makefile工作模式
make和makefile的工作模式:运行代码就用make,清除代码就用make clean
1.在Makefile中写上依赖关系和依赖方法,然后用make来运行代码
2.make clean清空项目中的代码和依赖关系。
3.将mycode.c文件里面的代码变动,然后用make指令,更改了新的代码样式,所以make clean删除了源文件代码内容,然后再更改之后用make指令后打开可执行程序就是修改后的代码
看起来自由也是自由的一种。