本文的目的是测试各种类型库的编译后的使用效果,包括库又链接其他库的编译方法,使用方法,依赖性等。

太长不看版:请跳至文章最后的总结对比表。

一。内容包含:

①静态库libbb.a依赖静态库libaa.a的测试;

②静态库libbb.a依赖动态库libaa.so的测试;

③动态库libbb.so依赖静态库libaa.a的测试;

④动态库libbb.so依赖动态库libaa.so的测试;

所用到的文件列表:

aalib.cpp aalib.h        bblib.cpp bblib.h     main.cpp

二。源代码:

aalib.h

#ifndef AALIB_H
#define AALIB_H
#include "stdio.h"
void helloAA();

#endif

********分割线**************

aalib.cpp

#include "aalib.h"

void helloAA()
{
    printf(" lib AAAAAAAAAAAAA\n ");
}

********分割线**************

bblib.h

#ifndef BBLIB_H
#define BBLIB_H

void helloBB();
void helloAB();

#endif

********分割线**************

bblib.cpp

#include "bblib.h"
#include "aalib.h"

void helloBB()
{
    printf(" lib BBBBBBBBBBBBBBBB \n");
}

void helloAB()
{
    printf(" *a*******************\n");
    helloAA();
    helloBB();
    printf(" *b*******************\n");
}

********分割线**************

main.cpp

#include "bblib.h"

int main()
{
    helloBB();

helloAB();
}

三。测试过程

①静态库libbb.a依赖静态库libaa.a的测试

现在生成了静态库libaa.a和libbb.a,下面测试静态库的使用方法:

可以看到链接静态库的话要指定静态库依赖的静态库,否则编译不过去!由此可见轻易不要链接静态库,因为你也许不知道你要用的静态库还依赖着哪些库.......

那么将所依赖的静态库编译进静态库呢?试试

可以看到,使用命令ar rcs libbb.a bblib.o libaa.a并没有起到作用,亦即libaa.a并没有被编译进libbb.a,因此编译可执行程序时还需要链接libaa.a。

改用下面这种方式编译,可行:

即编译静态库libbb.a时不要链接libaa.a而是用aalib.o文件,亦即编译静态库链接静态库时不能直接链接静态库,而是用形成该静态库的那些.o文件,可以使用 ar -x libaa.a来获取静态库的所有.o文件(注意:所有.o文件的顺序要对,被依赖的要放后面)。

②静态库libbb.a依赖动态库libaa.so的测试

第一行命令:gcc -o libaa.so -shared -fPIC aalib.cpp

等价于:gcc -c -shared -fPIC aalib.cpp 加 gcc -o libaa.so -shared -fPIC aalib.o 这两条(注意编译.o时要加选项-shared -fPIC,否则无法生存.so)

可以看到,编译可执行程序时只链接静态库不链接动态库编译不过去!运行时也需要动态库libaa.so支持

那么将动态库编译进静态库中呢?试试

可以看到,虽然编译静态库libbb.a的时候链接了动态库libaa.so,编译可执行程序只链接静态库libbb.a也能编译过去,但是在执行时还是要libaa.so动态库支持。

③动态库libbb.so依赖静态库libaa.a的测试

可以看到编译libbb.so时链接静态库出错,提示静态库需要使用-fPIC选项来编译,那就按照提示的来修改编译命令:

静态库所需的.o文件使用-shared -fPIC编译,然后在编译动态库的时候链接静态库好用了。并且编译可执行文件时不用链接被依赖的静态库。

来看一下这个动态库libbb.so依赖哪些库:

可以看到没有依赖libaa.a这个静态库。

④动态库libbb.so依赖动态库libaa.so的测试

动态库链接动态库成功,并且编译可执行文件时也不用链接被依赖的库,但是运行时还是要两个动态库支持。

四。总结

被依赖的库aa 编译库aa的命令 直接库bb 编译库bb的命令 编译可执行程序的命令 编译时是否需要库aa 运行时是否需要库aa
libaa.a

gcc -c aalib.cpp

ar rcs libaa.a aalib.o

libbb.a gcc -c bblib.cpp                                ar rcs libbb.a bblib.o gcc -o out main.cpp libbb.a libaa.a 需要 不需要
libaa.a gcc -c aalib.cpp      ar rcs libaa.a aalib.o libbb.a gcc -c bblib.cpp                               ar rcs libbb.a bblib.o aalib.o gcc -o out main.cpp libbb.a  不需要 不需要
libaa.so gcc -o libaa.so -shared -fPIC aalib.cpp libbb.a gcc -c bblib.cpp                               ar rcs libbb.a bblib.o libaa.so gcc -o out main.cpp libbb.a 不需要 需要
libaa.a gcc -c aalib.cpp      ar rcs libaa.a aalib.o libbb.so gcc -o libbb.so -shared -fPIC bblib.cpp libaa.a 编译libbb.so就出错,无法编译成动态库    
libaa.a gcc -c -shared -fPIC aalib.cpp               ar rcs libaa.a aalib.o libbb.so gcc -o libbb.so -shared -fPIC bblib.cpp libaa.a gcc -o out main.cpp -L./ -lbb 不需要 不需要
libaa.so gcc -o libaa.so -shared -fPIC aalib.cpp libbb.so gcc -o libbb.so -shared -fPIC bblib.cpp -L./ -laa gcc -o out main.cpp -L./ -lbb 不需要 需要

其他说明:链接静态库时要注意顺序,使用第二行的方法编译直接库libbb.a的时候用到被依赖库的.o文件,注意些个.o文件的依赖顺序也很重要,不能错,被依赖的要放后面。另外:编译好的动态库要指定路径,否则运行时找不到动态库的位置。

五。结论

由于本测试的初衷是找出一种方法使得编译可执行程序时不链接那些被依赖的库,因此第二行和第五行的组合可以作为备选方案。

动态库、静态库编译测试:含静态库链接动态库、静态库,动态库链接静态库、动态库相关推荐

  1. libcurl linux 静态链接库_GCC 程序编译的静态链接和动态链接

    转自:Mr_Bluyee 在链接阶段中,所有对应于源文件的 .o 文件."-l" 选项指定的库文件.无法识别的文件名(包括指定的.o目标文件和.a库文件)按命令行中的顺序传递给链接 ...

  2. libcurl-windows下静态库版本的编译-编译和调用非常顺利

    1.编译之前先看一下基本准则:调用程序和库要尽量在以前几个方面相同: (1).两者的字符集要相同: (2).两者的平台工具集要相同: (3).两者debug/release版本和编译平台位数要一致: ...

  3. 防止静态反编译及动态反反调试,反外挂

    发布程序前一定要做加密,不然会被破的体无完肤.推荐几款加密产品. Virbox Protector Standalone 加壳工具 效果:代码加密,防止静态反编译 加密技术:代码混淆/虚拟化/代码加密 ...

  4. Linux动态加载共享库,Linux共享库的动态加载(附测试案例)

    共享库的动态加载是指可以在程序运行的过程中去加载所需的共享库.常用于某些系统或者应用程序的自动升级. 在C语言的源程序动态加载共享库,需要调用一组特殊的函数,它们被声明于一个专门的头文件dlfcn.h ...

  5. 【Groovy】Groovy 动态语言特性 ( Groovy 语言与 Java 语言执行效率对比 | 以动态特性编译的 Groovy 类 | 以静态特性编译的 Groovy 类 )

    文章目录 一.以动态特性编译的 Groovy 类 二.Groovy 语言与 Java 语言执行效率对比 三.以静态特性编译的 Groovy 类 一.以动态特性编译的 Groovy 类 Groovy 类 ...

  6. 在Ubuntu上安装NTL库以及编译测试

    文章目录 介绍: 步骤: 0. 下载前的准备 1. 下载GMP并解压 2. 下载NTL并解压 3. 对GMP进行编译 4. 对NTL进行编译 编译测试: 关于wsl下载和文件权限: 参考资料: 介绍: ...

  7. 可爱的python测试开发库及项目(python测试开发工具库汇总)

    转载: https://www.jianshu.com/p/ea6f7fb69501 可爱的python测试开发库及项目(python测试开发工具库汇总) github地址 相关书籍下载 Python ...

  8. 【C++进阶】详解C++开源网络传输库libcurl的编译过程

    目录 1.引言 2.直接编译libcurl工程,提示找不到ssh.h 3.下载并编译libssh2开源代码,部署到libcurl目录中 4.获取openssl开源库的头文件和库文件,部署到libcur ...

  9. python ctypes实现api测试_Python与C之间的相互调用(Python C API及Python ctypes库)

    2010-01-24 17:58 14237人阅读 评论(11) 我实现 Python C API 此部分可以参考我原来的文章< 准备工作: 闲话少说,看看Python C API.事实上,Py ...

最新文章

  1. inputstream怎么写给前端_写给“正在焦虑的设计师们”的一封信
  2. 用Python解“二分法求多项式单根 ”题
  3. docker安装并运行elasticsearch
  4. 更改Tomcat虚拟内存大小
  5. Visual Studio Online 东半球首秀,亮相 .NET Conf 2019 中国峰会
  6. 互联网为什么要版权,我支持资源共享。
  7. python中的关键函数_Python关键要素
  8. java简单增删改查_JAVA JDBC 简单的增删改查
  9. linux虚拟机怎么恢复出厂设置_Vmware安装linux后一些初始化配置
  10. java添加音乐_Java加入背景音乐
  11. 免费英文文献下载攻略
  12. Discuz注册页面的邮箱验证代码分析
  13. 获得一个字符串的汉语拼音码
  14. android多媒体框架介绍(一)整体架构
  15. PLC_自动化控制系统_1_简说自动化控制系统
  16. Ceres Solver实现简单的光束法平差
  17. Software defect prediction—— LSTM
  18. Hibernate的Disjunction和Conjunction
  19. 常见图片尺寸大小(厘米 cm,象素 px)
  20. socket编程之socket()

热门文章

  1. BugKu CTF(杂项篇MISC)--一切有为法如梦幻泡影
  2. 1月第2周全球域名总量TOP20:开曼群岛升至第九
  3. Coresight - Devicetree/ACPI简介
  4. uniapp 内嵌h5登录页面实现登录
  5. 教育机构招生小程序解决招生难题
  6. 如何在Ubuntu系统安装pycharm
  7. 【爆牙齿】微软的坟墓:Windows 7。(五)
  8. reflow与repaint
  9. Linux的长连接设置
  10. 把excel导入sqlserver外部表不是预期格式