八卦阵 发表于 2024-6-24 12:54:33

【Linux】Linux工具——gcc/g++

1.利用vim更改信用名单——sudo

我们这里来增补sudo的相关知识——添加信托白名单用户
利用sudo就必须将利用sudo的那个账号添加到信用名单里,而且啊,只有超级管理员才可以添加
信用名单在/etc/sudoers里
https://img-blog.csdnimg.cn/direct/9ed12134ed6943bf9511bf18105a4c2c.png
我们发现它的权限只是可读啊,所以我们怎么修改它呢?
我们可以利用vim
https://img-blog.csdnimg.cn/direct/aa65e419b1ea483ba7a8979fdb844bb8.png
https://img-blog.csdnimg.cn/direct/e4a25f870e944b73bbf41191678d95dd.png 注意此时不要滚动鼠标的滑轮
我们按hjkl来移动
找到下面这一行的
https://img-blog.csdnimg.cn/direct/26d87590204644f9af5054aa8a3599b5.png 我们这个时间照旧处于命令模式,我们移动到这一行,
https://img-blog.csdnimg.cn/direct/8c278fc357fb41378860035f54f3ba18.png
 yy+p
https://img-blog.csdnimg.cn/direct/8c83986cbe2c49dc9084bc0da79612c6.png
我们点击i切换到插入模式,将%wheel改成我们想添加的用户名
https://img-blog.csdnimg.cn/direct/6c7b5d59f5bc4266a56af243d553c58d.png
好了之后,我们先按Esc回到命令模式,然后我们输入:切换到底行模式,输入wq!强制保存退出
https://img-blog.csdnimg.cn/direct/89c63b206d5a4820a50c9e89fb2a44cc.png
https://img-blog.csdnimg.cn/direct/d96274ab5c754939836aedb8a3cb647e.png
https://img-blog.csdnimg.cn/direct/7aabf8f62d3c4f098529414f498b2897.png
2.Linux编译器-gcc/g++利用

gcc只能用于编译c语言,g++既可以编译c语言也可编译c++
我们只讲gcc,由于它和g++的用法基本一样
2.1.gcc利用示例

我们先创建
https://img-blog.csdnimg.cn/direct/46c8f0ddc72749e3b27b9ae68793052f.png
https://img-blog.csdnimg.cn/direct/4b34b30e159f43dbbff930a518043de8.png
我们点击i进入插入模式,输入下面这段代码
 https://img-blog.csdnimg.cn/direct/802f8bce836845e0816a66ff1bf3f2a5.png
我们按Esc,然后输入:进入底行模式,输入wq 
https://img-blog.csdnimg.cn/direct/9536c27ee1404d3b994ee3b332993607.png
https://img-blog.csdnimg.cn/direct/ee299115240742eea50fbc96582f4ec9.png 我们代码写好了,那我们怎么编译呢?
我们利用gcc
https://img-blog.csdnimg.cn/direct/2abac069fa4945daa62508e35c85d890.png
正常情况下我们编译完什么也不会有
固然我们的代码堕落的情况下,就会报错
https://img-blog.csdnimg.cn/direct/ce88a57e72b34a8f9ae2475054119ac2.png
https://img-blog.csdnimg.cn/direct/3b42c630c3004751a49b572b08595257.png
我们修改精确的代码后,编译代码 
我们看看当前目次有什么
https://img-blog.csdnimg.cn/direct/fa91975243c74728986271160356b32a.png
gcc在编译完成后默认形成的可执行文件a.out,它的名字和后缀是什么并不重要,由于后缀在linux体系没啥意义(我们之前讲过)
 我们只关注它的属性里是不是有x这个权限(可执行权限)
有x权限,我们可以直接运行这个程序
https://img-blog.csdnimg.cn/direct/1b8fea06a6e3442297be1d646d86c6bd.png
很完美
 2.2.g++利用示例

上面我们编译的是c语言,现在我们来编译一下c++的代码
https://img-blog.csdnimg.cn/direct/217639ff45e9442ea9ecb32666cb50a8.png
https://img-blog.csdnimg.cn/direct/7900755a891144ed81226b22c9ac25ba.png
https://img-blog.csdnimg.cn/direct/f9c3541e29db46e9a2e83d746955cea6.png
   注意:我们利用g++前要先确保我们安装了,假如没有安装,就要像下面这么做
https://img-blog.csdnimg.cn/direct/05c08a418b594f11ab4e8ab84add1c4d.png
我们编译一下 ,并运行
https://img-blog.csdnimg.cn/direct/52af98e009f44febb7218cfdbbaefe56.png 我丢,这个属性和上面那个gcc编译出来的不是千篇一律的吗!!!
阐明啊gcc/g++是同宗同源的啊
   gcc不能编译c++,g++可以编译c语言和c++
 2.3.gcc利用配景知识

https://img-blog.csdnimg.cn/direct/2998393869b1469c8fb12f0abf86d596.png
2.3.1.预处置惩罚部分(举行宏替换)

我们先看预处置惩罚
https://img-blog.csdnimg.cn/direct/477468ad90d6490fb841dc9b8c9d8514.png
我们利用gcc来一次性演示a,b,d的知识
 我们先准备我们的c语言代码
https://img-blog.csdnimg.cn/direct/998a5ccc43ed4337a8160953bb569373.png
https://img-blog.csdnimg.cn/direct/050806a70c344acb88ed7fd76b5261c9.png
https://img-blog.csdnimg.cn/direct/b19d8921b01444d0966b52c2b93f3a67.png
https://img-blog.csdnimg.cn/direct/1e79eca0101e4bbba74812fceb471aab.png
我们对比一下之前的mycode.i
https://img-blog.csdnimg.cn/direct/1bcbe0a3a9364f238e0cb6ef5b9d392c.png 我靠,直接预处置惩罚了七百多行
右边这么多都是从c语言库里拷贝过来的,这个就叫头文件展开
预处置惩罚后,就不需要头文件了,由于都拷贝过来了
翻到末了就是我们的代码,发现注释的内容已经被裁掉了,这个叫去注释
我们看到M已经被替换成100,这个就是宏替换(不做语法检查,在编译之前就替换了)
   我们为什么能在windows大概linux上举行c/c++或其他情势的开辟?

我们的体系中肯定要提前大概后续安装上,c/c++开辟相关的头文件,库文件
c/c++开辟环境不仅仅指的是vs,gcc,更重要的是c语言/c++的头文件

linux的这些头文件默认存在/usr/include/
https://img-blog.csdnimg.cn/direct/7c6205e110a847e694b779c02b755901.png

有没有眼熟的头文件啊

我们找到stdio.h,进去看看
https://img-blog.csdnimg.cn/direct/b7b8aa14e7954a1dabd546ce4fb5bd39.png
https://img-blog.csdnimg.cn/direct/00dee50480454e30b84c6b9f00e2216b.png
许多内容啊,在头文件展开阶段就是从这里拷贝相关的内容过去的

所以我们安装vs2022等开辟环境,其实我们在安装的时间,选择对应的开辟包——本质是同步下载c/c++的头文件和库文件

那么标题来了,我们既然要包括我们的头文件,那么我们为啥不像下面这样子写
https://img-blog.csdnimg.cn/direct/7b027d09c8e248cdab27b29886e25822.png
这个是由于,编译器知道我们的这个头文件放在哪里,所以就不消写路径了

c/c++的头文件和库文件在windows下也是存在的
我们可以利用everything来找
https://img-blog.csdnimg.cn/direct/5b72e7e04716428a85bfc9edda3c4b18.png
    我们看看c.条件编译 
https://img-blog.csdnimg.cn/direct/477468ad90d6490fb841dc9b8c9d8514.png
https://img-blog.csdnimg.cn/direct/82e9f1bee24b4945b60807a102867a4a.png
https://img-blog.csdnimg.cn/direct/0a3c11998c4f4efdbd6f1bea47004126.png
https://img-blog.csdnimg.cn/direct/9ff4c6ad229347b8a69e68687b2b6bce.png
https://img-blog.csdnimg.cn/direct/47ce25cab5214a58ba6bed913c5495e2.png
宏全不见了,只剩了printf("hello relese!"),这个是由于我们根本没有界说DEBUG

我们可以在gcc内里界说DEBUG
https://img-blog.csdnimg.cn/direct/ecb5b5b9a8a04c7c8a31facc29e41caf.png

编译器具有主动修改代码的功能,所以我们利用gcc在外部添加一个宏是没有任何标题的
https://img-blog.csdnimg.cn/direct/dd187133a94d41bf93dbb679b10e63f7.png
这个就叫条件编译

条件编译的运用场景
我们用软件的时间肯定听过社区版(免费),开辟版/专业版(收钱)


[*]社区版提供最基础的功能
[*]专业版提供最新,最好的功能
那么标题来了——提供这些软件的公司需要维护两份代码吗?

肯定不需要,公司根据不同的编译条件裁剪掉社区版不需要的功能即可实现社区版和专业版的区分
2.3.2.编译部分 (生成汇编)

    预处置惩罚完后,照旧c语言吗?
固然是啊,只不过是更简洁的c语言
https://img-blog.csdnimg.cn/direct/63c4e757659047e2b2f105ce5ae4cc4c.png
我们看看编译部分
https://img-blog.csdnimg.cn/direct/ee74917d64784f97b74f4cb2a4eb5be9.png 这样子我们就将c语言形成了汇编语言
https://img-blog.csdnimg.cn/direct/33f5d5bc1cdc459e8be644fbff453864.png
https://img-blog.csdnimg.cn/direct/3cebd4b2ea8b4014a70c6210790e64dc.png
 2.3.3.汇编部分(生成呆板可辨认代码)

我们接着将生成的汇编代码转成呆板可辨认代码
https://img-blog.csdnimg.cn/direct/6fb796b059374c5facd791ba0b929571.png
https://img-blog.csdnimg.cn/direct/4157cd1d5792490aae674a59ca35f065.png
https://img-blog.csdnimg.cn/direct/34484792f6144507a1f03b1f8706aff9.png
满是乱码,很正常 ——mycode.o是二进制的,vim是文本编辑器
所以我们得借助二进制查看工具
https://img-blog.csdnimg.cn/direct/bb7cae0c158b418f962db650c6b85cb4.png
https://img-blog.csdnimg.cn/direct/edf3a411825940babb47bbb7c82ff23e.png
2.3.4.链接部分( 生成可执行文件或库文件)

https://img-blog.csdnimg.cn/direct/63c4e757659047e2b2f105ce5ae4cc4c.png
https://img-blog.csdnimg.cn/direct/39172aa067e846bdb497a59b7c603719.png
我们就生成了一个可执行程序
https://img-blog.csdnimg.cn/direct/a6f999c25b9246a29a4a89a0f6276e6c.png
2.4.gcc选项的含义

   1.我们直接gcc不带任何选项,代表直接生成可执行程序
https://img-blog.csdnimg.cn/direct/64a0bd78d68443df81ac8e0b27159ba2.png
    2.-o 文件输出到 文件
-o反面永远跟着可执行文件
gcc 待编译的文件 -o 生成的可执行文化的名称生成可执行文件并自界说可执行文件的名字
https://img-blog.csdnimg.cn/direct/a9cc8ca8c33a4162a58e864579241c39.png
这个命名的后缀随便写,都能执行,由于linux的后缀没有什么意义
https://img-blog.csdnimg.cn/direct/e538d632d6964c79923de1911e3ce35a.png
甚至下面这种写法也可以
https://img-blog.csdnimg.cn/direct/953b0c4f14764a098a92b4409b458f1e.png

     3.-E 只激活预处置惩罚部分,这个不生成文件,你需要把它重定向到一个输出文件内里
https://img-blog.csdnimg.cn/direct/f5edc5481a544d949c2934cd56272b3f.png
https://img-blog.csdnimg.cn/direct/9e02ff4354534a5ca54f5ba73e05f49a.png
直接给你打印到显示屏幕来了

-E反面永远紧跟着要预处置惩罚的目的源,-o反面永远跟着要形成的目的文件
目的文件随便命名
https://img-blog.csdnimg.cn/direct/382d3e2fea7442ae853358ff1f65cc1b.png

    4.    -S  将c语言编译到汇编语言     (即完成编译部分,  但不举行汇编和链接 部分)
https://img-blog.csdnimg.cn/direct/972f845b7fdb4950961bf25b20f6f6e3.png
我们可以从.c文件开始再举行预处置惩罚,再到这里
但是我们有现成的已经预处置惩罚完了的mycode.i

文件名和后缀随便命名
汇编语言的后缀全用.s,文件名就设置成带.s后缀
https://img-blog.csdnimg.cn/direct/b3bc328bca31465c8ba112ea929022b2.png
https://img-blog.csdnimg.cn/direct/1b95a5629f494ed39fb1e649cd2bff2c.png

    5.  -c  生成呆板可辨认代码
从现在开始举行程序的翻译,将汇编工作做完就停下来
https://img-blog.csdnimg.cn/direct/16ca02e88e914837b0c644ffda45f2ae.png
我们可以从.c文件开始再举行预处置惩罚,再到这里
但是我们有现成的已经预处置惩罚完了的mycode.i

我们重定位目的二进制文件,简称目的文件,在windows下是.obj文件
这个文件不可以独立执行,固然已经是二进制了,它还需要举行链接,才能执行
https://img-blog.csdnimg.cn/direct/f089fd59c9974c8fbde5820992244db0.png
根本不让你运行,给了你x权限照旧不能执行

我们需要举行末了一步链接,才能执行
https://img-blog.csdnimg.cn/direct/56908bbfda5f4a518ef999fcd174d898.png
将可重定位目的二进制文件和库举行链接,形成可执行文件
     上面这个生成可执行文件的全过程怎么记忆呢?
我们看看键盘左上角的Esc键,就是这个顺序
记着ESc即可
2.5.库

库就是函数库的意思,只是简称了:库=函数库
当函数(代码块)实在太多太多了,放在一个文件已经公道的时间又会被拆分到许多许多文件中去。当这些充满函数的文件放在一起时就是就形象的称之为函数库或库了。所以这个库就是一个存满函数文件的仓库。
链接就是在链接库
   库,给我们提供方法的实现

库其实就是把源文件(.c/.cpp)颠末肯定的翻译,然后打包——只给你提供一个文件即可,不消给你提供太多的源文件,也可以达到潜伏源文件的目的
c尺度库在linux的这个目次里
https://img-blog.csdnimg.cn/direct/697ac20db9234b7b9b90968429aa0533.png
库的本质就是一个文件
   linux内里的库 :以.so末端的,叫动态库,有.a末端的,叫静态库 
windows内里的库:以.dll末端的(动态库),.lib(静态库)
上面那个就是c语言的动态库
库有本身的命名规则:(前缀)lib     名字   .so.XXX(后缀) 
https://img-blog.csdnimg.cn/direct/697ac20db9234b7b9b90968429aa0533.png
我们看回上面那个库libc.so.6,对应名字就只有一个c,那就是c语言的库了
   我们的呆板上默认安装了动态库,静态库默认没有安装的
https://img-blog.csdnimg.cn/direct/4083e81461a04263bb4bc1e3c2d4af09.png
     那就阐明一个事实,对于编译型语言,安装开辟包,肯定是下载安装对应的头文件+库文件

头文件提供方法的声明+库文件提供方法的实现+你的代码=你的软件
 库存在的价值就是不让我们做重复工作,站在巨人的肩膀上
2.6.   .o文件和库是怎么链接的

这个有两种方案,我们这里只讲原理
   2.6.1.动态链接

我们来看看动态库的界说

动态函数库就是存放在体系中的某个特定位置,提供了一些大部分程序都会利用到的功能集合。
这样主程序在编译的过程当中就不需要把这部分功能编译到本身的程序中。只需要到体系中特定的位置直接调用动态函数库的功能就行了。


[*]好处:动态库是共享库,有用的节约资源,程序自身的体积不会由于动态函数库变大
[*]缺点:就是程序运行过程中利用到了这些函数库内的功能时,万一体系特定的位置没有对应的动态库,就会造成程序崩溃大概各种奇怪的标题。影响的不止一个程序,大概会影响许多程序

我们在linux里来看看
https://img-blog.csdnimg.cn/direct/c400a391114648078b3c7c78b5547b85.png

ldd可以查看可执行程序所依赖的动态库
https://img-blog.csdnimg.cn/direct/542c693caa0e4854b083e5d59a55b850.png
假如我们把这个动态库删了,这个可执行程序就不能跑了
https://img-blog.csdnimg.cn/direct/e65a20286d1549558f6220e63e889108.png

linux体系的许多指令是用c语言/c++写的可执行程序,我们来看看它们依赖的动态库
https://img-blog.csdnimg.cn/direct/351694dace434c36927b2e0e565d2aa7.png
我们删掉了这个动态库就不能用pwd指令了
 
   2.6.2.静态链接

静态链接:在编译器利用静态库举行静态链接的时间,会将本身的方法拷贝到目的程序中,改程序以后不再用依赖于静态库

我们了看看静态库的界说
当一个程序照旧代码的时间,通过编译器把代码编译二进制文件以供计算机可以读取运行。那些繁芜的用于完成特定功能的函数代码仓库的文件随着程序代码文件一起被编译成二进制文件成为程序的一部分。这部分函数代码文件就叫做静态函数库。


[*]好处:就是程序可以独立运行,运行时不在依赖外部某些特定的功能。
[*]缺点:会造成程序的体积会变大,比较消耗资源。

    2.6.3.静态库和动态库的区别

1、他们在哪里?
动态库在体系中,有没有这个程序劳资就在这里,
静态库在程序中,程序到哪我到哪

2、更新
动态库更新:劳资要更新了,就更新了。
静态库更新,要向自身程序说老大,小弟要更新了。大佬复兴:晓得嘛,我更新时你才能更新,我不更新,你急啥子嘛。
所以假如程序运行时缺少某个库时,那就是动态库。只要到网上下载一个点点大的文件就行了。
静态库更新,只有程序要更新添加新的功能的时间,一般同时会本身更新静态库。

3、假如动态库版本差距太大,有大概和程序不兼容,这时间就需要看看,去下载一个对应版本的动态库文件,照旧更新本身的程序。由于最新的程序一般都和最新的动态库兼容。
 
 2.6.4.验证部分

 我们回到上面那个,gcc默认利用动态链接,动态链接默认利用动态库,不能利用静态库
https://img-blog.csdnimg.cn/direct/6de12bd981934497ae2f526f8fe531ba.png
我们要是想用静态链接,就要用
https://img-blog.csdnimg.cn/direct/c587d128b12145f7a8fe53c8e538a40c.png 
注意:我们利用这个还要安装一个东西---本身去搜
https://img-blog.csdnimg.cn/direct/d8c4b85f461343ad9e4199502d7d157e.png
我们看到这个动态链接的可执行程序所占内存明显更小,这个我们上面讲过这个原因了
基于这个原因,我们很少利用静态库
https://img-blog.csdnimg.cn/direct/6fba3d38eb0c4c2d87e264c152390774.png
   我们的云服务器默认只装了动态库,我们要装静态库——去百度
https://img-blog.csdnimg.cn/direct/00a5483bdd7048d8ad5df5abf58b596f.png
   
[*] 没有静态库,我们不能利用-static
[*]没有动态库,只有静态库,而且gcc/g++能找到,gcc默认优先动态链接,-static的本质就是改变优先级
[*]一个可执行程序不肯定是全都是动态链接,大概满是静态链接,假如加了-static,就会将所有的链接要求全设置为静态链接
2.7.debug和release

 好熟悉是不是!!!!
debug程序是可以被追踪,由于它添加了debug信息
gcc默认生成可执行程序是release,我们可以利用选项-g来生成debug版本
https://img-blog.csdnimg.cn/direct/0b832b5ffa2f4304be9b2ae8630d9bd8.png
    拓展:可执行程序形成的时间,不是无顺序的二进制构成,有本身的格式——可执行程序有本身的二进制格式——ELF格式
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【Linux】Linux工具——gcc/g++