Linux修炼之路之gcc/g++,动静态链接及动静态库

目录

一:Linux编译器-gcc/g++ 

 预处理-编译-汇编-链接

1.预处理

2.编译 (生成汇编)

3.汇编(生成机器可识别代码)

4.链接(生成可执行文件或库文件)

 三:动静态链接和动静态库

动静态库

动静态链接

1.动态链接 

2.静态链接

3.注意点

4.各自优缺点

5.ldd和file指令

四:debug和release,readelf指

接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧

一:Linux编译器-gcc/g++ 

1.对于gcc只能编译c语言代码,g++既能编译c语言代码也能编译c++代码,但g++主要编译c++

2.常用形式 gcc/g++ 文件名,此时就会形成a.out的可执行文件,再./a.out

3.也可以根据以下方式来书写

gcc 源文件名 -o 目标文件名(推荐写法)(一步到位,下面的是分步处理)

 gcc -o 目标文件名  源文件名 

 

4.对于为啥我们直接能够在windows/Linux中进行 c/c++等的开发呢?

最重要的是我们的系统中一定要提前或者后续安装上c/c++开发相关的头文件,库文件

对于c/c++中起始的几行都是c/c++的头文件,这些头文件在预处理时会全部展开,而对于具体的调用的函数如printf,就得调用c/c++标准库的库函数来完成对应的操作

所以只要系统安装了相关的头文件和库文件就可以完成c/c++的开发,具体的来说就是c/c++开发环境不仅仅指的是vs,gcc,g++这些,更重要的是语言本身的头文件和库文件

因此对于编译型的语言,安装开发包,必定是下载安装包对应的头文件和库文件

Linux下的头文件路径 --gcc/g++编译时的默认搜索路径

 预处理-编译-汇编-链接

1.预处理

预处理阶段完成的是宏调换,去注释,头文件展开,条件编译等操作,仍是c代码

gcc表示格式:gcc -E 源文件名 -o 以.i结尾的目标文件

-E:告诉gcc,从现在开始进行程序的翻译,将预处理工作做完就停下来,不用往后继续执行

2.编译 (生成汇编)

在这个阶段gcc要检查代码的规范性,是否有语法错误等,在检查无误后,将c代码翻译为汇编语言

gcc表示格式:gcc -S 源文件名 -o 以.s结尾的目标文件

 -S:告诉gcc,从现在开始进行程序的翻译,将编译工作做完就停下来,不用往后继续执行

3.汇编(生成机器可识别代码)

gcc表示格式:gcc -c 源文件名 -o 以.o结尾的目标文件

 -c:告诉gcc,从现在开始进行程序的翻译,将汇编工作做完就停下来,不用往后继续执行

.o结尾的这个文件叫做可重定位目标二进制文件,简称目标文件,就是windows中的.obj文件

不需要独立执行,虽然是二进制的但仍需要经过连接才能执行

4.链接(生成可执行文件或库文件)

将可重定位目标二进制文件和库进行链接形成可执行程序

作用:在我们的c程序中,对于printf 这样的库函数,在预编译时的展开的头文件里也只有函数的声明,没有实现,那么是在哪里实现的呢?----------答案是系统把这些函数实现都被做到名为libc.so.6的库文件中去了,在没有特别指定时,gcc会到系统的默认搜索路径/usr/lib下查找,也就是链接到libc.so.6库函数中去,这样便实现了printf函数

gcc表示格式:gcc -c 源文件 -o 目标文件

 三:动静态链接和动静态库

1.库的理解

库其实是给我们提供方法的实现,如上面的对于printf函数的实现就是在库中实现的,而这个库也就是c标准库,本质也是文件,也有对应的路径

动静态库

1.在Linux和windows都将库分为静态库和动态库,两者只有命名方式上的不同

       Linux中:.so(动态库)    .a(静态库)     windows :     .dll(动态库)    .lib(静态库)

       静态库是指编译链接时,把库文件的代码全部加入到可执行文件中

       动态库:在程序执行时由运行时链接文件加载库,只加载所需要的,节省空间大小

2.命名规则:libname.so.xxx,name为c就是c库,c++就是c++库

3.在Linux中只会安装动态库,而静态库需要自己安装

      sudo yum install -y glibc-static(c静态库)    sudo yum install -y libstdc++-static(c++静态库)

 4.库的作用

根据上面得知,方法的实现就在库当中,库就是将源文件(.c)经过一定的翻译,然后打包,封装然后只提供一个所需的文件,而将其他源文件隐藏

具体的软件的实现=头文件中的方法声明+库文件提供的方法实现+具体代码

5.由于gcc编译时默认使用的是动态库,完成的是动态链接,如要实现静态链接就要添加-static

动静态链接

这里先举个鲜明的例子来帮助铺垫和理解

1.动态链接 

动态链接就是当可执行程序自己完成不了时,就需要跳转到库中,执行库中的方法,执行完后再进行返回

特点:拷贝的是在哪里实现,不拷贝具体的实现方法;动态库只需要一个;可执行程序依旧依赖库;一旦缺失动态库,会影响很多的可执行程序无法正常运行

2.静态链接

编译器使用静态库进行静态链接时,会将静态库的所有方法实现拷贝到可执行程序中,使该程序不再依赖静态库

3.注意点

  1.如果我们没有静态库,但就要-static  ,是不行的

  2.如果没有动态库,但有静态库,而且gcc能找到,这个是可以的; 因为gcc默认优先动态链接,       而-static的本质就是改变优先级,使所有链接要求变为静态链接,并且只能适配一次

3.所有的链接都是静态链接和动态链接混合使用的

4.各自优缺点

动态库:优:因为是共享库,可以有效的节省资源(磁盘空间,内存空间,网络空间等)

              缺:一旦缺失,导致各个程序都无法运行

静态库:优:不依赖库,程序可以独立运行

              缺:体积大,比较消耗资源

5.ldd和file指令

ldd 是查询文件依赖的动态库  ldd 文件名

file 查询可执行程序是动态链接还是静态链接 file 文件名

四:debug和release,readelf指令

1.gcc默认编译出来的是release版本

2.对于debug版本因为在形成可执行程序时,添加了debug信息,是可以被追踪调试

3.debug版本 只需添加-g 选项即变为debug版本

4. readlf指令

readelf -S 文件名 | grep -i debug    查看添加的debug信息

readelf -S 文件名    读取可执行程序的对应二进制构成 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值