Gcc/G++
1. 下载安装软件
ubuntu:
sudo apt update # 更新最新的下载地址
sudo apt install gcc g++
centos:
sudo yum update
sudo yum install gcc g++
- 查看gcc、g++版本:
gcc --version
g++ --version
2. gcc工作流程
预处理–> 编译和优化–> 汇编–> 链接
- 预处理:展开头文件、宏替换、去掉注释行
- 编译:对文件编译得到一个汇编文件
- 汇编:对文件进行汇编得到二进制文件
- 链接:对程序调用的库进行链接,最终得到可执行的二进制文件
文件名后缀 | 说明 | gcc参数 |
---|---|---|
.c | 源文件 | 无 |
.i | 预处理后的c文件 | -E |
.s | 编译后得到的汇编语言的源文件 | -S |
.o | 汇编后得到的二进制文件 | -c |
3.编译代码命令
- gcc编译代码.c
##**分阶段工作**
gcc -E test.c -o test.i #(生成.i文件)
gcc -S test.i -o test.s
gcc -c test.s -o test.o
./test
##**实际上只需要一步即可**
gcc test.c -o aa
./aa
##**或者使用下面的也可以**
gcc test.c #(默认生成的.o文件为a.out文件)
./a
## 多个源文件 其中的-o是指定生成的文件名(.o)
gcc *.c -o cale
## -I的作用
gcc *.c -I include -o cale # (-I是使用在头文件指定路径)
## -D的作用,提供宏git@gitee.com:wen-dongfang/socket_test.git定义满足的条件
gcc *.c -D DEBUG -o cale # 此时相当于程序有了DEBUG的宏定义,那么以此为条件的程序就会被执行。
- g++编译代码.cpp
g++ test.cpp -o test
g++ testspeaker.cpp speaker.cpp -o testspeaker
g++ *.cpp -o testspeaker
4.gcc和g++的区别
g++可以链接到标准的C++库,gcc如果要链接要c++库,需要添加参数-lstdc++
gcc和g++都可以直接链接到标准C库
gcc test.cpp -o test -lstdc++
g++ test.c -o test
不管是gcc还是g++都是支持_cplusplus宏定义的
5.典型应用
5.1 静态库
- 在linux中静态库以
lib
作为前缀,以.a
作为后缀,中间是库的名字,即是libXXX.a
- 在windows中静态库以
lib
作为前缀,以.lib
作为后缀,中间是库的名字,即是libXXX.lib
生成静态库
生产静态库,需要对源文件进行汇编操作(
使用参数-c
)的到二进制的目标文件(.o文件
),然后通过ar工具将目标文件打包就可以得到静态库(libXXX.a
)
gcc *.c -o tast1 -c
参数c:创建一个库
参数s:创建目标索引
参数r:在库中插入模块
#得到静态库
ar rsc 静态库的名字(libXXX.a) 原材料(所有的.o文件)
ar rsc libcalc.a *.o
#发布文件
*.h文件和linhello.a文件就可以了
#执行main文件(参数-L和-l用于指定编译库,注意-l后面接的是静态库去掉前缀后缀来的)
gcc main.c -L ./-lcalc -o cale
5.2 动态库
动态库我们又称之为共享库
- 在linux中静态库以
lib
作为前缀,以.so
作为后缀,中间是库的名字,即是libXXX.so
- 在windows中静态库以
lib
作为前缀,以.dll
作为后缀,中间是库的名字,即是`libXXX.dll生产动态库需要使用gcc 添加
-fpic
和-shared
两个参数。
生产动态库
参数-fpic: 使得gcc生产的代码与位置无关,也就是使用相对位置
参数-shared:告诉编译器生产一个动态库
#(获取.o文件)
gcc hello.c -c -fpic -I ./include/
#获取动态库
gcc -shared *.o -o 动态库(libXXX.so)
gcc -shared *.o -o libscal.so
#发布文件
*.h文件和libhello.so文件就可以了
#执行main文件(参数-L和-l用于指定编译库,注意-l后面接的是静态库去掉前缀后缀来的)
gcc main.c -L ./ -lhello -o aa
但是执行上面的shell会出现报错
dongfangedu@ubuntu:/opt$ ./aa
./aa: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
以上报错的解决办法
动态链接器是如何搜索某一个动态库的呢,在它内部有一个默认的搜索顺序,按照优先级从高到低的顺序分别是:
1.可执行文件内部的 DT_RPATH 段
2.系统的环境变量 LD_LIBRARY_PATH
3.系统动态库的缓存文件 /etc/ld.so.cache
4.存储动态库 / 静态库的系统目录 /lib/, /usr/lib 等
按照以上四个顺序,依次搜索,找到之后结束遍历,最终还是没找到,动态连接器就会提示动态库找不到的错误信息。
解决方法
dongfangedu@ubuntu:/opt$ ldd aa
linux-vdso.so.1 (0x00007ffedabcd000)
libhello.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5fb92a6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5fb94b0000)
解决方法