c++ linux 学习第二课
一、GCC的工作流程:
gcc编译器将C源文件到生成一个可执行程序中间一共经历四个步骤:
二、gcc常用参数:
-v 版本
-E 生成预处理文件
-S 生成汇编文件
-c 只编译,生成目标文件 .o文件
-I(大写的 i ) 指定头文件所在的路径
-L 指定库文件所在的路径
-l(小写的 L) 指定库的名字
-o指定生成目标的名字
-g包含调试信息,使用gdb调试必须要加-g参数
-On n=0~3 n越大优化等级越高
-Wall 提示更多警告信息
-D 编译时指定宏 例如:gcc -o test test.c -D MAX=10 或者 gcc -o test test.c -DMAX=10
三、静态库和动态库(共享库)
(头文件和库的区别:头文件一般而言是申明和定义,包含了库函数的声明,库文件是已经编译好的二进制代码,包含了库函数的代码实现)
【如果没有引用需要的头文件:函数未声明
如果没有库文件:找不到函数定义】
静态库:是在可执行程序运行前就已经加入到执行代码中,成为可执行程序的一部分。(可执行程序生成后把静态库文件删除没有影响)
静态库的命名:前缀lib 库名称 自定义,例如test 后缀 .a 最终组成 libtest.a
静态库的制作:
1.将.c文件编译成.o文件
gcc -c fun1.c fun2.c
2.使用ar命令将.o文件打包成.a文件 (在使用ar工具的时候需要添加参数rcs)
命令:ar rcs 静态库名 .o文件们
ar rcs libtest1.a fun1.o fun2.o
静态库的使用:
gcc -o main main.c -I./ -L./ -ltest1 (-L指定系统去哪里寻找这个静态库)
动态库的制作和使用:
共享库在程序编译时并不会被连接到目标代码中,在程序运行时才被载入。如果不同的可执行程序调用了相同的库,那么内存里只需要有一份该共享库的拷贝。
共享库的制作:
(1) 将.c文件编译成.o文件
gcc -fpic -c fun1.c fun2.c
【-fpic 产生位置无关代码(position-independent code),则产生的代码中没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存中的任意位置,都可以被正确的执行。共享库被加载时,在内存中的位置不是固定的】
(2) 使用gcc将.o文件编译成库文件
gcc -shared fun1.o fun2.o -o libtest2.so
上面的(1)和(2)可以合成一步:gcc -fpic -shared -o libtest2.so *.c
共享库的使用:
gcc -o main2 main.cpp -I./ -L./ -ltest2
动态库加载遇到的问题及解决:
运行上面的程序后发现报错了:
./main2: error while loading shared libraries: libtest2.so: cannot open shared object file: No such file or directory
ldd加载器,使用ldd加载刚刚生成的main2可执行文件,发现:libtest2.so not found
下面动态库not found的解决方法:
⭐分析:当系统加载可执行代码的时候,能够知道其所依赖库的名字,但是还要知道所依赖的库的绝对路径。 此时就需要系统动态载入器(dynamic linker/loader)【作用是把库加载到内存中】。
动态库没有被编译到可执行程序main2中,所以环境中必须提供相应的库地址,这就是出现上述问题的原因,也就是解决方法的入口。
-->ldd命令可以查看可执行文件依赖的库文件,执行ldd main2,就可以发现libtest2.so找不到。
解决方法:
1. 【不推荐 不要用】第一个方法是把生成的共享库复制到系统根目录的/lib目录下,这样程序就能够找到动态链接库了,但是会污染系统目录,不要用这种方法。
2. 【临时设置,个人简单测试时可以使用】linux 提供了" LD_LIBRARY_PATH "这样一个环境变量,用来告诉加载器去哪里搜索库。使用下面的命令把环境变量设置为当前目录,然后就能够执行了。
export LD_LIBRARY_PATH="." //此外 这样设置的搜索路径优先于/lib目录,先去设置的路径查找
//此外,这个设置是临时的,当终端退出重进后就会失效,换一个窗口也不能执行
echo $LD_LIBRARY_PATH 命令可以查看上述设置是否生效
3. 【永久设置,常用】把export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径,设置到~/.bashrc文件中,然后执行下列方法之一使配置文件生效:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径 这样写是在原有值之后追加,不会覆盖原有值。
⚪执行. ~/.bashrc 使配置文件生效,第一个.后面有空格
⚪执行source ~/.bashrc使配置文件生效
⚪退出当前终端,再次登录也可以使配置文件生效
/lib 和/usr/lib 是系统目录,不要把自己制作的库文件随便放到里面
更改用户级别的配置文件,(不要更改系统级别的配置文件)
其他补充:
标签:文件,gcc,第二课,LD,c++,LIBRARY,linux,PATH,加载 From: https://www.cnblogs.com/yz-lucky77/p/17477157.html