gcc/g++

文章目录

  • 重点
    • sudo 提权添加白名单
    • gcc / g++
        • 预处理 -E后生成 .i文件,是直接 -S .i 还是.c?
      • 预处理
      • 编译
      • 汇编
        • 二进制查看工具 od + 文件名
      • 连接
        • 为什么能在windows or linux进行C/C++开发?
        • 验证
        • 安装静态库
        • 我和同学
    • 问题
    • file指令
    • 动vs静
    • debug && release
      • readelf
      • 扩展:
    • g++ 和 gcc 选项一摸一样
    • make/Makefile

重点

什么叫头文件,库文件在哪里?
动静态库的命名问题
动静态库原理
动静态库优缺点特征
动静态库使用策略和安装
debug release

sudo 提权添加白名单

1.寻找root用户 在 /etc/sudoers 文件中修改 添加普通用户的白名单
在这里插入图片描述
:/root找到root的白名单所在行数
gcc/g++_第1张图片
2.wq!强制保存退出,即可添加成功

gcc / g++

推荐写法

gcc mycode.c -o mytest
gcc -o mytest mycode.c  //-o后面跟目标文件  源文件放后面也行

甚至可以写成如下,但是后缀应该具有意义,.txt能运行是因为它具有可执行能力,有x权限属性却不一定都能运行

gcc -o test.txt mycode.c 

gcc -E code.c 如果不加-o
会把文件直接输出在bash中,我们不想这样
-E后面永远跟着 .c 源文件
gcc/g++_第2张图片

预处理 -E后生成 .i文件,是直接 -S .i 还是.c?

预处理 -E后生成 .i文件,直接 -S .i 或者.c都是可以的,只不过.c从预处理再走一遍

预处理

gcc/g++_第3张图片

gcc -E code.c -o code.i

运行此行代码可以看到预处理后的宏替换,头文件包含,注释删除
gcc/g++_第4张图片
头文件所在目录
ls /usr/include/

ls /usr/include/stdio.h
/usr/include/stdio.h

windows中也存在C的头文件和库文件,在安装VS时候也会安装C的库和头文件,所以#include 直接就可以找到
而不是#include <之类

在命令行添加宏定义
编译器在预处理阶段对.c文件进行修改,再添加一个宏定义,也不是什么难事

gcc -E code.c -o code.i -DDEBUG   //-D+宏名

gcc/g++_第5张图片
条件编译应用场景

vs社区版本和专业版并不需要维护两份代码,而是只维护一份,利用条件编译进行代码裁剪,删除了专业版中社区版不需要的内容

编译

gcc -S code.c -o code.s

gcc/g++_第6张图片

汇编

gcc -c code.s -o code.o

code.o
可重定位目标二进制文件,简称目标文件, .obj文件不可以独立执行,虽然已经是二进制了
需要经过链接才能执行

gcc/g++_第7张图片

vim是文本编辑器,只认文本,汇编文件code.o都是二进制

二进制查看工具 od + 文件名

od code.o

gcc/g++_第8张图片

连接

头文件提供方法的声明,库文件提供方法的实现+你的代码=你的软件

C的库 命名规则 libname.so.XXX
你们的机器上,默认只会安装动态库,静态库默认是没有安装的
gcc/g++_第9张图片

在这里插入图片描述
系统内置安装了多个动态库,在lib64里面也有一份
在这里插入图片描述
疑问:这个lib64 和usr 目录是啥关系?
gcc/g++_第10张图片

有了头文件和库文件再加上自己写的代码,就可以进行连接

为什么能在windows or linux进行C/C++开发?

gcc/g++_第11张图片

头文件是方法声明,方法的实现在哪呢?
方法的实现就是在库当中!
库其实就是把源文件(.c),经过一定的翻译,然后打包–只给你提供一个文件即可,不用给你提供太多的源文件,也可以达到隐藏源文件的目的

gcc默认 天然的去寻找c的库 所以不用显示去调用

gcc code.o -o mycode

g++默认 去寻找c++的库

我们的.o和库是如何链接的?
1.动态链接
可执行程序进行顺序运行,当程序运行到自己执行不了,需要库中方法的时候,它就会跳转到库中执行,得到结果再返回到代码调用处。
它是怎么知道调转到哪里有一个库的呢?—编译器的帮助
gcc/g++_第12张图片
多个可执行程序 共享 同一个动态库(共享库),就像网吧只需要一个
如果对应的动态库缺失,影响的不止一个程序,可能会导致很多程序都无法进行正常运行!

验证

在Linux中,编译形成可执行程序,默认采用的就是动态链接–提供动态库

ldd mytest      

gcc/g++_第13张图片

在Linux中,如果要按照静态链接的方式,进行形成可执行程序,需要添加-static选项–提供静态库

gcc mycode.c -o mytest-static -static

gcc/g++_第14张图片

安装静态库


sudo yum install -y glibc-static  //c语言静态库
sudo yum install -y libstdc++-static  //c++静态库

我和同学

meyest是我,一个可执行程序
gcc/g++_第15张图片

ls /usr/bin //同学所处的位置(linux中的命令 也是可执行程序 用C写的 )


gcc/g++_第16张图片

⒉静态链接

将库(静态库)中的方法 类似于上网的电脑 拷贝到可执行程序当中(导致可执行程序体积变大),这种方式就叫做静态链接

在编译器使用静态库进行静态链接的时候,会将自己的方法拷贝到目标程序中,该程序以后不用再依赖静态库!

gcc/g++_第17张图片

问题

1.如果我们没有静态库,但是我们就要-static,行不行呢?不行
2.如果我们没有动态库,只有静态库,而且gcc能找到–能的,gcc默认优先动态链接,-static的本质:改变优先级 只适配一次
3.不一定是纯的全部动态链接或者静态链接,混合的!

file指令

查看可执行程序是动态连接还是静态链接

file mytest

在这里插入图片描述

动vs静

动态库因为是共享库,有效的节省资源(磁盘空间,内存空间,网络空间等)[优]动态库一旦缺失,导致各个程序都无法运行(缺点)

静态库,不依赖库,程序可以独立运行[优点],体积大,比较消耗资源[缺]

debug && release

默认gcc生成的文件是 动态链接 + release (不带有debug信息)

gcc code.c -o mytest_debug -g   //-g生成带有debug信息的可执行程序

我们看到带有debug信息 的可执行程序 大小比release大
gcc/g++_第18张图片

readelf

 readelf -S mytest_debug

将可执行程序以段的形式显示
gcc/g++_第19张图片

readelf -S mytest_debug | grep -i debug    

查找到了 debug信息
gcc/g++_第20张图片

扩展:

可执行程序形成的时候,不是无顺的二进制构成,有自己的格式的–可执行程序有自己的二进制格式–ELF格式
《程序员的自我修养》
《深入理解计算机系统》

g++ 和 gcc 选项一摸一样

make/Makefile

如果有多个可执行程序,会很烦人
能使我们从冗余的gcc /g++ 的命令中解脱

make:是一条指令

makefile:是一个当前目录下的文件
gcc/g++_第21张图片
使用 make 直接gcc 出可执行程序(这里只有一个可执行程序) 类似于VS的F5
gcc/g++_第22张图片
清理
gcc/g++_第23张图片

你可能感兴趣的:(Linux,linux)