c++ linux 学习第二课

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 是系统目录,不要把自己制作的库文件随便放到里面

更改用户级别的配置文件,(不要更改系统级别的配置文件) 

 其他补充:

 

posted @ 2023-06-16 22:54  阳光中的影子  阅读(23)  评论(0编辑  收藏  举报