我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Linux下怎么用GCC编译动态库

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Linux下怎么用GCC编译动态库

这篇文章主要讲解了“Linux下怎么用GCC编译动态库”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux下怎么用GCC编译动态库”吧!

本文主要解决以下几个问题
  1 为什么要使用库?
  2 库的分类
  3 创建自己的库
  或许大家对自己初学 Linux时的情形仍记忆尤新吧。如果没有一个能较好的解决依赖关系的包管理器,在Linux下安装软件将是一件及其痛苦的工作。你装a包时,可能会提示你要先装b包,当你费尽心力找到b包时,可能又会提示你要先安装c包。我就曾被这样的事搞的焦头烂额,至今一提起rpm仍心有余悸,头皮发麻。说是一朝被蛇咬,十年怕井绳怕也不为过。
  Linux下之所以有这许多的依赖关系,其中一个开发原则真是功不可没。这个原则就是:尽量不重复做别人已经做过的事。换句话说就是尽量充分利用别人的劳动成果。
  这就涉及到如何有效的进行代码复用。
  1 为什么要使用库?
  关于代码复用的途径,一般有两种。
  粘贴复制
  这是最没有技术含量的一种方案。如果代码小,则工作量还可以忍受,如果代码很庞大,则此法不可取。即便有人原意这样做,但谁又能保证所有的代码都可得到呢?
  而库的出现很好的解决了这个问题。
  库,是一种封装机制,简单说把所有的源代码编译成目标代码后打成的包。
  那么用户怎么能知道这个库提供什么样的接口呢?难道要用nm等工具逐个扫描?
  不用担心,库的开发者早以把一切都做好了。除了包含目标代码的库外,www.Linuxidc.com一般还会提供一系列的头文件,头文件中就包含了库的接口。为了让方便用户,再加上一个使用说明就差不多完美了。
  2 库的分类
  2.1 库的分类
  根据链接时期的不同,库又有静态库和动态库之分。
  静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行。
  有别于静态库,动态库的链接是在程序执行的时候被链接的。所以,即使程序编译完,库仍须保留在系统上,以供程序运行时调用。(TODO:链接动态库时链接阶段到底做了什么)
  2.2 静态库和动态库的比较
  链接静态库其实从某种意义上来说也是一种粘贴复制,只不过它操作的对象是目标代码而不是源码而已。因为静态库被链接后库就直接嵌入可执行文件中了,这样就带来了两个问题。
  首先就是系统空间被浪费了。这是显而易见的,想象一下,如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。
  再者,人非圣贤,即使是精心调试的库,也难免会有错。一旦发现了库中有bug,挽救起来就比较麻烦了。必须一一把链接该库的程序找出来,然后重新编译。
  而动态库的出现正弥补了静态库的以上弊端。因为动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。
  那么,是不是静态库就一无是处了呢?
  答曰:非也非也。不是有句话么:存在即是合理。静态库既然没有湮没在滔滔的历史长河中,就必然有它的用武之地。想象一下这样的情况:如果你用libpcap库编了一个程序,要给被人运行,而他的系统上没有装pcap库,该怎么解决呢?最简单的办法就是编译该程序时把所有要链接的库都链接它们的静态库,这样,就可以在别人的系统上直接运行该程序了。
  所谓有得必有失,正因为动态库在程序运行时被链接,故程序的运行速度和链接静态库的版本相比必然会打折扣。然而瑕不掩瑜,动态库的不足相对于它带来的好处在现今硬件下简直是微不足道的,所以链接程序在链接时一般是优先链接动态库的,除非用-static参数指定链接静态库。
  2.3 如何判断一个程序有没有链接动态库?
  答案是用file实用程序。
  file程序是用来判断文件类型的,在file命令下,所有文件都会原形毕露的。
  顺便说一个技巧。有时在 windows下用浏览器下载tar.gz或tar.bz2文件,后缀名会变成奇怪的tar.tar,到Linux有些新手就不知怎么解压了。但 Linux下的文件类型并不受文件后缀名的影响,所以我们可以先用命令file xxx.tar.tar看一下文件类型,然后用tar加适当的参数解压。
  另外,还可以借助程序ldd实用程序来判断。
  ldd是用来打印目标程序(由命令行参数指定)所链接的所有动态库的信息的,如果目标程序没有链接动态库,则打印“not a dynamic executable”,ldd的用法请参考manpage。
  3 创建自己的库
  3.1 创建动态库
  创建文件hello.c,内容如下:
  #include
  void hello(void)
  {
  printf("Hello World\n");
  }
  用命令gcc -shared hello.c -o libhello.so编译为动态库。可以看到,当前目录下多了一个文件libhello.so。
  [leo@leo test]$ file libhello.so
  libhello.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped
  看到了吧,文件类型是shared object了。
  再编辑一个测试文件test.c,内容如下:
  int
  main()
  {
  hello();
  return 0;
  }
  这下可以编译了:)
  [leo@leo test]$ gcc test.c
  /tmp/ccm7w6Mn.o: In function `main':
  test.c:(.text+0x1d): undefined reference to `hello'
  collect2: ld returned 1 exit status
  链接时gcc找不到hello函数,编译失败:(。原因是hello在我们自己创建的库中,如果gcc能找到那才教见鬼呢!ok,再接再厉。
  [leo@leo test]$ gcc test.c -lhello
  /usr/lib/gcc/i686-pc-Linux-gnu/4.0.0/../../../../i686-pc-Linux-gnu/bin/ld: cannot find -lhello
  collect2: ld returned 1 exit status
  [leo@leo test]$ gcc test.c -lhello -L.
  [leo@leo test]$
第一次编译直接编译,gcc默认会链接标准c库,但符号名hello解析不出来,故连接阶段通不过了。
  现在用gcc test.c -lhello -L.已经编译成功了,默认输出为a.out。现在来试着运行一下:
  [leo@leo test]$ ./a.out
  ./a.out: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
  咦,怎么回事?原来虽然链接时链接器(dynamic linker)找到了动态库libhello.so,但动态加载器(dynamic loader, 一般是/lib/ld-Linux.so.2)却没找到。再来看看ldd的输出:
  [leo@leo test]$ ldd a.out
  Linux-gate.so.1 => (0xffffe000)
  libhello.so => not found
  libc.so.6 => /lib/libc.so.6 (0x40034000)
  /lib/ld-Linux.so.2 (0x40000000)
  果然如此,看到没有,libhello.so => not found。
  Linux为我们提供了两种解决方法:
  1.可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig(要有root权限才行)。
  2.把当前路径加入环境变量LD_LIBRARY_PATH中
  当然,如果你觉得不会引起混乱的话,可以直接把该库拷入/lib,/usr/lib/等位置(无可避免,这样做也要有权限),这样链接器和加载器就都可以准确的找到该库了。
  我们采用第二种方法:
  [leo@leo test]$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
  [leo@leo test]$ ldd a.out
  Linux-gate.so.1 => (0xffffe000)
  libhello.so => ./libhello.so (0x4001f000)
  libc.so.6 => /lib/libc.so.6 (0x40036000)
  /lib/ld-Linux.so.2 (0x40000000)
  哈哈,这下ld-Linux.so.2就可以找到libhello.so这个库了。
  现在可以直接运行了:
  [leo@leo test]$ ./a.out
  Hello World
  3.2 创建静态库
  仍使用刚才的hello.c和test.c。
  第一步,生成目标文件。
  [leo@leo test]$ gcc -c hello.c
  [leo@leo test]$ ls hello.o -l
  -rw-r--r-- 1 leo users 840 5月 6 12:48 hello.o
  第二步,把目标文件归档。
  [leo@leo test]$ ar r libhello.a hello.o
  ar: creating libhello.a
  OK,libhello.a就是我们所创建的静态库了,简单吧:)
  [leo@leo test]$ file libhello.a
  libhello.a: current ar archive
  下面一行命令就是教你如何在程序中链接静态库的:
  [leo@leo test]$ gcc test.c -lhello -L. -static -o hello.static
  我们来用file命令比较一下用动态库和静态库链接的程序的区别:
  [leo@leo test]$ gcc test.c -lhello -L. -o hello.dynamic
  正如前面所说,链接器默认会链接动态库(这里是libhello.so),所以只要把上个命令中的 -static参数去掉就可以了。
  用file实用程序验证一下是否按我们的要求生成了可执行文件:
  [leo@leo test]$ file hello.static hello.dynamic
  hello.static: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.6, statically linked, not stripped
  hello.dynamic: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.6, dynamically linked (uses shared libs), not stripped
  不妨顺便练习一下ldd的用法:
  [leo@leo test]$ ldd hello.static hello.dynamic
  hello.static:
  not a dynamic executable
  hello.dynamic:
  Linux-gate.so.1 => (0xffffe000)
  libhello.so => ./libhello.so (0x4001f000)
  libc.so.6 => /lib/libc.so.6 (0x40034000)
  /lib/ld-Linux.so.2 (0x40000000)
  OK,看来没有问题,那就比较一下大小先:
  [leo@leo test]$ ls -l hello.[ds]*
  -rwxr-xr-x 1 leo users 5911 5月 6 12:54 hello.dynamic
  -rwxr-xr-x 1 leo users 628182 5月 6 12:54 hello.static
  看到区别了吧,链接静态库的目标程序和链接动态库的程序比起来简直就是一个庞然大物!
  这么小的程序,很难看出执行时间的差别,不过为了完整起见,还是看一下time的输出吧:
  [leo@leo test]$ time ./hello.static
  Hello World
  real 0m0.001s
  user 0m0.000s
  sys 0m0.001s
  [leo@leo test]$ time ./hello.dynamic
  Hello World
  real 0m0.001s
  user 0m0.000s
  sys 0m0.001s
  如果程序比较大的话,应该效果会很明显的。

感谢各位的阅读,以上就是“Linux下怎么用GCC编译动态库”的内容了,经过本文的学习后,相信大家对Linux下怎么用GCC编译动态库这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Linux下怎么用GCC编译动态库

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Linux下怎么用GCC编译动态库

这篇文章主要讲解了“Linux下怎么用GCC编译动态库”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux下怎么用GCC编译动态库”吧!本文主要解决以下几个问题   1 为什么要使用库?
2023-06-13

linux怎么安装gcc编译器

要在Linux上安装GCC编译器,你可以按照以下步骤进行操作:1. 打开终端窗口。2. 使用以下命令安装GCC编译器及相关的开发工具:- 对于Ubuntu或Debian系统:```sudo apt-get updatesudo apt-ge
2023-09-21

使用 gcc (mingw32) 编译带有静态库的 DLL

php小编百草为你介绍如何使用gcc (mingw32)编译带有静态库的DLL。在开发过程中,经常需要将静态库打包成DLL以便于在其他项目中调用。使用gcc (mingw32)编译带有静态库的DLL的方法相对简单,只需按照一定的步骤操作即可
使用 gcc (mingw32) 编译带有静态库的 DLL
2024-02-09

redhat linux怎么安装gcc编译器

本篇内容介绍了“redhat linux怎么安装gcc编译器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!分两种情况: Linux软件安装通
2023-06-13

GCC指令及动态库、静态库怎么使用

本文小编为大家详细介绍“GCC指令及动态库、静态库怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“GCC指令及动态库、静态库怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、GCC1.1 GCC
2023-07-04

GCC编译工具怎么使用

GCC是一款开源的编译器工具套件,可以用于编译C、C++、Objective-C等程序。下面是GCC编译工具的基本使用方法:1. 安装GCC:首先需要安装GCC编译工具。在Linux系统中,可以通过包管理器安装,例如在Ubuntu中可以使用
2023-09-12

linux中怎么使用gcc编译c语言程序

在Linux中使用gcc编译C语言程序,可以按照以下步骤操作:1. 打开终端窗口(Terminal)。2. 进入要编译的C语言程序所在的目录,例如:`cd /path/to/your/c_program`。3. 使用文本编辑器(如vi、na
2023-09-21

linux gcc编译CROSSTOOL时出现提示怎么办

linux gcc编译CROSSTOOL时出现提示怎么办,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。我目前使用的是UBUNTU的8.04,因为最近一直在升级LINUX,导致目
2023-06-17

Linux反编译中的动态链接库处理

在Linux中进行反编译时,如果遇到需要处理动态链接库(Dynamic Link Libraries,简称DLL)的情况,通常需要使用工具来处理动态链接库中的符号和函数。下面是一些常用的工具和方法:使用objdump命令查看动态链接库的符号
Linux反编译中的动态链接库处理
2024-08-22

linux下怎么安装编译网卡驱动

这篇文章主要介绍“linux下怎么安装编译网卡驱动”,在日常操作中,相信很多人在linux下怎么安装编译网卡驱动问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”linux下怎么安装编译网卡驱动”的疑惑有所帮助!
2023-06-12

Linux下Gcc命令怎么用

这篇文章主要介绍了Linux下Gcc命令怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。GCC 的意思也只是 GNU C Compiler 而已。经过了这么多年的发展,G
2023-06-27

Linux系统怎么编译Boost库

这篇文章的内容主要围绕Linux系统怎么编译Boost库进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!Boost库简介:Boost库是为C++语言标
2023-06-28

Linux中怎么利用wxWidgets实现静态编译

Linux中怎么利用wxWidgets实现静态编译,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1、编译静态版wxWidgets在Linux下配置wxWidgets的静态编
2023-06-13

linux怎么编译驱动程序

编译Linux驱动程序通常需要以下步骤:下载并安装适当的Linux内核源代码。您可以从Linux官方网站上下载所需的内核源代码。编写驱动程序代码。您可以使用C语言或其他支持的编程语言来编写驱动程序代码。在Linux内核源代码树中创建Make
linux怎么编译驱动程序
2024-03-06

linux怎么查看静态编译文件

要查看Linux系统中的静态编译文件,可以使用以下方法:1. 使用file命令:file命令可以用于确定文件类型。在终端中输入以下命令:```file ```其中,是你要查看的文件的路径。file命令会返回文件的类型信息,如果是静态编译文件
2023-09-08

Linux系统下gcc命令怎么使用

这篇文章主要讲解了“Linux系统下gcc命令怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux系统下gcc命令怎么使用”吧!1.gcc的安装(以Ubuntu为例) sudo
2023-06-22

Linux网卡驱动怎么编译安装

这篇文章主要讲解了“Linux网卡驱动怎么编译安装”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux网卡驱动怎么编译安装”吧!以D-Link530的网卡进行模块的编译.由于Linux的
2023-06-10

linux中怎么生成动态库和静态库

linux中怎么生成动态库和静态库,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。动态库的生成:1、代码如下:#include #in
2023-06-09

怎么用C写一个web服务器之GCC项目编译

这篇文章给大家分享的是有关怎么用C写一个web服务器之GCC项目编译的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言本想着接下来大概实现一下 CGI 协议,但是实现过程中被一个问题卡住了:C进程与php进程的交
2023-06-15

linux怎么查看动态库函数

在Linux系统中,可以通过以下命令查看动态库函数:1. 使用`nm`命令:`nm`命令可以列出目标文件或者动态库中的符号表,包括函数、变量等信息。使用以下命令可以查看动态库中的函数:```nm -D library.so```其中,`li
2023-09-22

编程热搜

目录