基于gcc的动静态库用法简析

基于gcc的动静态库用法简析,第1张

前言

本文浅析gcc在构建多文件项目,使用静态链接库,动态链接库中,各个编译参数的含义和常见用法。

利用参数控制gcc的编译进度

这是gcc常处理的文件类型:

  • .c / .cpp:c,cpp源码
  • .s:汇编源码
  • .m:objective-c源码
  • .i:c预处理结果文件
  • .ii:cpp预处理结果文件
  • .S:汇编预处理结果文件
  • .h:头文件
  • .o:编译后得到的目标文件
  • .so:动态链接库文件(一种特殊的目标文件)
  • .a:静态链接库
  • .out:可执行文件。

    实际可执行文件没有统一的后缀,系统根据文件属性来区分可执行文件和不可执行文件。

    缺省情况下gcc生成的可执行文件名为a.out。

编译流程
  1. 预处理:生成.i或.ii文件
  2. 编译:将.i或.ii文件编译成为汇编语言,生成.s文件
  3. 汇编:将汇编语言进行汇编处理,生成目标文件,即.o文件
  4. 链接:将一个或多个.o文件链接,生成可执行程序文件

上述中间在用户指定分步进行时会得到保留,但在一次性完成编译时会被删除

编译选项

gcc的命令格式为"gcc [options][filenames]"。

其常用编译选项有:

options取值说明示例
-c编译并汇编指定的文件,但不进行链接。

生成.o文件,通常用于编译不包含主程序的子程序文件

gcc -c test1.c test2.c
-S编译指定的源文件,不进行汇编,生成.s汇编文件gcc -S circle.c,这将生成circle.s文件
-E预处理指定的源文件,不进行编译。

默认情况下预处理器的输出会被导入到标准输出流,可以通过-o选项将其导入到某个文件中

gcc -E circle.c -o circle.i
-o filename指定输出文件的名称。

如果不给出这个选项,gcc生成的可执行文件将名为a.out

gcc main.c func.c -o app.out
-g在可执行程序中包含调试信息
-L library_path在库文件的搜索路径列表中添加library_path路径
-llibrary链接时搜索指定的函数库library。

gcc会默认链接libc.a或者libc.so,但是要想链接到其它库则需要手动添加

使用-l选项链接数学库,gcc main.c -o main.out -lm
-I head_path在头文件的搜索路径列表中添加head_path路径
-static进行静态编译,且链接静态库,禁止链接动态库
-shared和-fPIC配合使用
-fPIC生成使用相对地址的位置无关的目标代码
创建静态链接库

创建静态链接库的技术栈相对动态链接库要简单。

首先我们需要生成一批目标文件:

gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc -c test3.c -o test3.o

然后利用ar对它们进行打包:

ar src libtest.a test1.o test2.o test3.o

这将生成一个名为libtest.a的静态链接库。

ar的命令格式是"ar 静态库文件名 目标文件列表"。


src参数的含义是:

  • s:创建目标文件索引,这再创建较大的库时能提高速度
  • r:替换库中已有的目标文件,或加入新的目标文件
  • c:创建一个库,不管库是否存在,都将创建它
创建动态链接库

一种选择,从源文件生成动态链接库:

gcc -fPIC -shared test.c -o libtest.so

另一种选择,从目标文件生成动态链接库:

gcc -fPIC -c test.c -o test.o
gcc -shared test.o -o libtest.so

链接到动态库的编译:

gcc main.c libtest.so -o app.out

直接执行app.out将触发链接失败,我们有这三种方式将链接器引导至我们的动态链接库:

  • 将动态库保存在标准目录下,比如/usr/lib
  • 把动态库所在的路径添加到环境变量LD_LIBRARY_PATH中,在shell中输入命令"export LD_LIBRARY_PATH=libraryDIR:$LD_LIBRARY_PATH"或
  • 把动态库所在的路径libraryDir添加到/etc/ld.so.conf中然后执行ldconfig或者以动态 库所在路径libraryDir为参数执行ldconfig
  • 修改~/.bashrc这个配置文件,对本用户有效。

    该配置文件将在bash启动时被运行

需要注意的是,上面第二种方式会再重启终端后失效。

另外我做了一点实验,这三条命令都可以短暂的让动态库的路径生效:

export LD_LIBRARY_PATH=libpath:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:libpath
export LD_LIBRARY_PATH=libpath
它们都是可行的。

此上即通过gcc创建动/静态链接库的基本流程,和动态库链接路径的正确引导方式。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/674959.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存