龙岗网站建设培训,乐清新闻,如何给网站做脚本,教做幼儿菜谱菜的网站目录 一.前言
二.源代码的翻译环境
三.gcc相关指令
四.动静态库
1.什么是库#xff1f;
2.库的命名
3.库的链接方式
4.动静态链接的优缺点
5.小结 一.前言
在Windows系统上我们常用VisualStudio来进行C/C开发#xff0c;VS并不是一款单一的软件#xff0c;而是集成…目录 一.前言
二.源代码的翻译环境
三.gcc相关指令
四.动静态库
1.什么是库
2.库的命名
3.库的链接方式
4.动静态链接的优缺点
5.小结 一.前言
在Windows系统上我们常用VisualStudio来进行C/C开发VS并不是一款单一的软件而是集成开发环境IDE其中包含编辑器编译器调试器等等功能很强大。而在LInux当中我们需要学会使用各项独立的工具才能进行开发例如用vim编辑代码用gcc编译代码用gdb调试代码。
今天我们就来讲讲如何使用gcc来得到我们需要的可执行程序并介绍编译过程中的动静态库问题。
二.源代码的翻译环境
我们编写的C语言是自然语言它是供我们人类阅读的计算机并不懂。所以需要将它翻译成计算机看得懂的二进制语言而这个翻译过程就是经常说的编译。
实际上一个或多个源文件变层可执行程序需要经历编译和链接两个阶段但我们日常所说的编译是把链接阶段也包含在内的下面我也不再刻意区分这两个阶段。 程序编译的过程包含以下四个阶段 预处理编译汇编链接 而gcc编译器就是来完成这四项工作的
【注想要进一步理解程序的翻译过程可参考我以前写的程序的编译(翻译)】
三.gcc相关指令 gcc -E code.c -o code.i -E表示从现在开始进行程序翻译等预处理完成就停下来不要继续往后走了。
-o表示把生成的文件重命名
预处理阶段做了四件事
头文件展开条件编译去注释宏替换
得到的code.i文件依然是C语言代码 gcc -S code.i -o code.s -S表示从现在开始进行程序翻译等编译完成就停下来不要继续往后走了。
这里的code.i是否可以换成code.c呢肯定是可以的但是没必要因为这样之前的工作又会被重复做一遍。
这时的code.s文件就是汇编代码了 gcc -c code.s -o code.o -S表示从现在开始进行程序翻译等汇编完成就停下来不要继续往后走了。
完成汇编后code.o就是一个二进制文件了但现在它并不能执行因为还差最后一个链接阶段 gcc code.o mybin 链接并不像前几个阶段一样有专门的选项因为链接就是翻译的最后一步通常情况下我们都是直接执行以下指令一步到位并不会傻傻地把这四个步骤分开做 gcc code.c -o mybin 细节问题
我们在test.c文件中写了这样一段代码 编译时发现不能通过 这是因为在for循环里定义临时变量c99标准里才支持的我现在的这款gcc编译器默认是不支持的要想采用c99标准编译代码只需在后面加上stdc99即可 gcc -stdc99 test.c -o test.out 四.动静态库
简而言之.o文件库可执行程序
故链接阶段就是将.o文件可重定位的二进制文件和库链接起来
那么接下来就有两个问题什么是库呢如何链接.o文件和库的呢
1.什么是库
下面介绍一个指令 ldd mybin ldd是用来查看一个可执行程序依赖的第三方库 可以看出来mybin依赖三个库其它两个不管我们把中间的那个拎出来 我们在LInux系统中找一下看是否有这个文件 果然有这个文件而且给普通用户开放的权限还挺高可读可写可执行。
注意库并不是头文件预处理阶段include过来的并不是它哟头文件这个路径下 头文件放的是函数的声明库提供方法实现。
故头文件库我们写的代码我们的可执行程序
“LInux下一切皆文件“所以库其实也就是个文件。系统中的头文件和库文件都是文件所以所谓的开发环境安装一定要做什么工作
安装下载并拷贝头文件和库文件到开发环境中的特定路径下一定要能被编译器自己找到
在下载VS时会让你选择安装C桌面版游戏开发等环境说白了就是不同的头文件和库文件嘛
2.库的命名
以libc.so.6这个库为例
库要求以lib开头so表示这个库是静态库6是版本号所以一个库的名字要去掉前缀和后缀所以这个库的名字就是c也就是传说中的C标准库。
库分为两类动态库和静态库在LInux当中so表示动态库a表示静态库。在常规的开发环境中动态库居多
3.库的链接方式 动态库是C/C或其它第三方提供的所有方法的集合被所有程序以链接的方式关联起来这种链接方式叫做动态链接 静态库是C/C或其它第三方提供的所有方法的集合被所有程序以拷贝的方式将需要的代码拷贝到自己的可执行程序中这种链接方式叫做静态链接 库中所有的函数都有入口地址所谓的动态链接其实就是把链接的库中的函数地址拷贝到我们的可执行程序中的特定位置。
4.动静态链接的优缺点 动态链接优点形成的可执行程序体积比较小比较节省资源。 缺点强依赖动态库动态库没了所有依赖这个库的程序都无法运行了 静态链接优点无视库可以独立运行 缺点体积太大浪费资源 LInux系统中的指令实际上就是一个个可执行程序 既然是可执行程序那我们就能查看它所依赖的库 可以看到pwd指令也是用C语言写的它也依赖C标准库。实际上LInux中的绝大多数指令都是用C/C写的如果我们将C标准库删掉那么这个系统基本也就挂了因为最基本的指令都无法运行更别说其它操作了。
接下来我们想看看动静态链接的可执行程序的大小差异如何做呢
gcc默认是采用动态链接的方式去找对应的动态库所以采用如下指令即可 要想静态链接只需在后面跟上一个-static 但有可能会报出这样的一个错误 这是因为我们的系统里默认是没有安装 C静态库的。我们可以手动安装一下C/C静态库 sudo yum install -y glibc-static libstdc-static 最终两个可执行程序都生成了可以看到它们的体积大小相差了将近100倍这还是我仅仅在里面写了一个helloworld的情况下。
所以这也能解释为什么编译器默认采用的是动态链接因为静态链接太浪费空间了。这里的空间不仅仅指磁盘上的空间还包括内存。你要知道一个可执行程序要想执行首先必须是要加载到内存中去的呀所以使用动态链接加载到内存会更快
5.小结 我们的开发环境编译器都要为我们做什么 下载开发环境头文件和库文件设置合理的查找路径设定好我们形成可执行程序的链接方式 所以编译时出现链接问题要么是库文件损毁了要么是路径没或者链接方式没有设定好。