定制企业网站费用,辽宁省建设工程质量监督总站网站,手机端 网站 模板,阜新旅游网站建设文章目录 一、解决sudo命令的问题二、Linux编译器-gcc/g1.gcc的使用2.g的使用 三、gcc编译链接过程1.预处理2.编译#xff08;生成汇编#xff09;3.汇编#xff08;生成机器可识别代码#xff09;4.链接#xff08;生成可执行文件或库文件#xff09;5.一些选项的意义 四… 文章目录 一、解决sudo命令的问题二、Linux编译器-gcc/g1.gcc的使用2.g的使用 三、gcc编译链接过程1.预处理2.编译生成汇编3.汇编生成机器可识别代码4.链接生成可执行文件或库文件5.一些选项的意义 四、库1.关于库的一些认识2.与库的链接1动态链接2静态链接 3.验证4.一些问题5. file指令6.动静态链接的优缺点 五、debug和release 一、解决sudo命令的问题
当我们使用一个新的普通用户想要对一条指令进行提权的时候我们会遇到如下问题显示不被信任 所以我们现在需要做的就是将我们的该用户添加到系统的白名单中
这个白名单在下面这个路径下
/etc/sudoers当然我们不可以用普通用户去访问因为我们可以看到这个文件的权限是这样的 所以我们需要用root账号去进行修改 进入以后我们在第100行可以看到这个 然后我们只需要修改添加一行即可 然后我们在回到这个普通账号我们就可以使用sudo进行提权了以root的身份进行创建文件我们也可以看到我们创建的文件的拥有者就是root 二、Linux编译器-gcc/g
gcc智能用来编译c语言g即可用来编译c语言又可用来编译c
但我们一般用gcc编译c,g编译c
1.gcc的使用
当我们写好代码以后直接
gcc test.c然后它会自动生成一个可执行程序a.out这个可执行程序的名字不重要关键是它的属性具有可执行权限
然后我们直接使用如下命令就可以进行运行了
./a.out如下所示 2.g的使用
g的使用与gcc是十分类似的
不过我们需要先安装一下g
yum install gcc gcc-c安装以后我们就可以使用g编译c代码了它默认生成的就是a.out文件 三、gcc编译链接过程 我们知道执行一个c程序需要经过一下几个步骤 预处理编译生成汇编汇编生成机器可识别代码链接生成可执行文件或库文件 1.预处理 在预处理过程中会有如下操作 去掉注释头文件展开宏替换条件编译 我们先来展示前三点
我们需要先输入如下指令
gcc -E test.c -o test.i选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。 选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。 最后我们就可以观察到了前三点的现象 这里我们还需要了解的一点是我们为什么可以在windows或者linux上进行C/C或者其他形式的开发呢 这是因为我们的系统中一定要提前或者后序安装上C/C开发相关的头文件库文件 而这些文件就在下面的路径中
/usr/include然后我们可以打开一下比如stdio.h
vim /usr/include/stdio.h我们可以看到大概有900多行的代码 而我们前面的头文件展开就是将这里面的内容全部拷贝到test.i中 其实我们在安装vs2022的时候还在安装的时候就要选择对应的开发包同步也在下载C的头文件和库文件 也就是说在windows也同步有着对应的文件 还有条件编译也会在预处理阶段给解决掉
gcc -E test.c -o test.i不过对于宏我们也可以在编译时候去定义的
gcc -E test.c -o test.i -DDEBUG而条件编译的作用就是
比如vs2022有社区版和专业版而公司不可能会专门维护两份代码所以社区版只是专业版裁剪掉了某些功能得到的而这个裁剪用的就是条件编译
2.编译生成汇编
在我们与预处理完以后我们的代码其实还是C语言
所以我们下一步就是生成汇编
gcc -S test.i -o test.s不过我们也可以从test.c直接生成汇编
gcc -S test.c -o test.s生成以后里面就是这个东西 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言 3.汇编生成机器可识别代码 汇编阶段是把编译阶段生成的“.s”文件转成目标文件 在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
gcc -c test.s -o test.o不过我们可以看到里面全是乱码 这是因为这个.o文件是二进制文件而vim是文本编辑器。
所以我们可以使用二进制查看工具比如od 4.链接生成可执行文件或库文件
我们直接将所有的目标文件进行链接起来即可
gcc test.o -o mytest最终这个mytest就是我们的可执行文件 对于生成可执行程序这里还有很多种方式
首先就是直接生成
gcc test.c这种方式最终生成的可执行程序是a.out
第二种方式是这样的
gcc test.c -o test这种方式就和前面比较相似直接将.c文件变成一个可执行程序test
这种方式我们也是最为推荐的
不过也可以这样写无论如何-o后面跟的永远都是最终的可执行程序
gcc -o test test.c5.一些选项的意义
gcc -E test.c -o test.i这个-E的意思是告诉gcc从现在开始进行程序的翻译将预处理工作做完就停下来不要往后走了
gcc -S test.i -o test.s从现在开始进行程序的翻译将编译工作做完就停下来
gcc -c test.s -o test.o从现在开始进行程序的翻译将汇编工作做完就停下来
我们最终形成的这个test.o文件就是可重定位目标二进制文件简称目标文件在windows下他就是.obj文件还需要注意的是这个文件不可以独立执行虽然已经是二进制文件了但是还需要经过链接才能执行
gcc test.o -o test上面就是链接的过程可将重定位目标二进制文件和库进行链接形成可执行程序
四、库
1.关于库的一些认识
我们知道我们写完程序后最终要有链接过程链接要与我们的头文件进行链接而头文件的一些方法是由库给提供的
比如我们C语言的标准库在这里路径下
/usr/lib64/libc.so所以这个C语言标准存在的本质就是一个文件它有自己的路径
在linux种这个库有以.so结尾的也有以.a结尾的 LInux.so动态库 .a静态库 windows : .dll动态库 .lib静态库 所以我们上面的就是Linux系统默认的动态库
一般我们这个库是有自己的命名规则的libname.so.XXX
这个命名中只有最开头的name这四个是不同的所以我们只需要它就可以了
注意我们现在的机器上默认只会安装动态库静态库是默认没有安装的
所以现在回过头来 方法的实现就是在库当中的 库其实就是把源文件.c经过一定的翻译然后打包只给你提供一个文件即可不用给你提供给太多的源文件也可以达到隐藏源文件的目的 头文件提供方法的声明 库文件提供方法的实现 我们自己的代码 我们的软件 有了库就可以不用做很多重复的工作可以站在巨人的肩膀上了 而我们在使用gcc的时候是不用手动的去链接它的库的gcc天生就是链接c语言的里面早已经处理好了 对于gcc它默认找的是c语言的库所以它无法编译c代码 2.与库的链接
我们的.o文件和库是如何链接的呢
我们的链接方式有两种 动态链接静态链接 1动态链接 假如小明今年刚刚考上了高中它比较喜欢玩游戏。 所以他问他的学长哪里有网吧。 小明在某一天个自己列了一个清单完成物理作业、数学作业、语文作业、玩游戏… 然后小明就像一个可执行程序一样一条一条的完成当遇到玩游戏的时候由于之前学长编译器告诉过他网吧在哪里所以他就可以去网吧玩游戏。然后打完以后再返回原来的程序中继续执行 在这个过程中学长就像一个编译器存储着地址告诉小明去哪里找小明就像一个可执行程序网吧就像一个库当去执行游戏的操作时候就会跳转到对应的库执行执行完毕以后返回到代码调用出这个过程就是动态链接的过程。 网吧这个库也就是一个动态库也称作共享库因为可以有很多人去像小明一样所以网吧只要一个就可以了 假如有一天网吧被查封了那么就糟糕了所有人都玩不了游戏了 所以说动态库不能缺失一旦对应的动态库缺失影响的不止一个程序可能导致很多程序都无法正常运行 我么可以用ldd指令去查看某一个可执行程序它所依赖的动态库 如果一旦我们将这个库给删掉了那么我们这个程序就无法跑了
其实我们系统中的很多指令就是用C/C写的因为他们本身就是可执行程序大部分的指令都是用c语言写的 2静态链接 继续前面的故事网吧被查封了以后 大家都没法上网了于是这个老板开始了卖电脑 于是很多人都去自己买了电脑。 这时候当我们想要去上网的时候直接用自己的电脑就可以了再也不用去网吧了 上面的这种方式其实就是静态链接 这个电脑店就是静态库 并不像之前的动态一样给一个地址然后去找动态库而是直接将静态库里面的方法给拷贝过来。 当未来这个电脑店再次被查封的时候也不会影响到我们了。我们也不关心它 在编译器使用静态库链接的时候会使自己的方法拷贝到目标程序中该程序以后不用再依赖静态库了 3.验证
如下所示是关于动态链接的验证 在linux中编译形成可执行程序默认采用的就是动态链接–需要提供动态库 如下是关于静态链接的验证
静态链接时需要加上-static选项
gcc test.c -o test_static -static在linux中如果要按照静态链接的方式进行形成可执行程序需要给添加static选项 — 也要提供静态库 不过在我们的系统中一般是默认没有安装静态库的
我们可以用如下命令去安装
sudo yum install -y glibc-static我们可以明显的感觉到静态链接以后体积变大了。 如果使用ldd会显示不是动态的可执行程序 前面是关于c语言的静态库我们也可以装一下c的静态库
sudo yum install -y libstdc-static4.一些问题 如果我们没有静态库但是我们就要-static行不行呢 其实是不行的 如果我们没有动态库只有静态库而且gcc能找到静态库能成功编译吗 是可以的因为gcc默认优先动态链接。-static的本质其实是改变优先级 注意我们的程序不一定是纯的全部动态链接或者静态链接的有可能是混合的 -static可以使得所有的链接要求全部变为静态链接即只适配一次 5. file指令
我们可以直接使用file指令去查看是动态链接还是静态链接 6.动静态链接的优缺点 动态库的优点 动态库因为是共享库有效的节省资源节省磁盘空间内存空间网络空间等 动态库的缺点 动态库一旦缺失导致各个程序都无法运行 静态库的优点 静态库不依赖库程序可以独立运行 静态库的缺点 体积大比较消耗资源 五、debug和release
我们已经很清楚debug可以被追踪调试
这是因为在形成可执行程序的时候添加了debug信息
而release就无法进行调试
这就注定了debug的体积比较大
我们的gcc默认是release版本的如果我们要生成debug版本的要加上-g选项 我们可以看到无论是静态的还是动态的在debug下都是要大一点的
我们可以去验证一下
我们可以用如下指令去将我们的可执行程序给以一种格式呈现出来
readelf -S test_debug然后我们结合管道就可以看到原来的是没有debug信息而用debug的是有debug信息的 扩展 可执行程序形成的时候不是无序的二进制构成是有自己的格式的—可执行程序有自己的二进制格式—ELF格式