仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 6403|回复: 20
打印 上一主题 下一主题

[其他Linux] Linux制作之Linux平台gcc和静态共享库的基本常识仓酷云

[复制链接]
精灵巫婆 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:38:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
开发linux发行版的人都是通读过linux内核代码,对linux原理极其精通的人。
对年夜多半不处置Linux平台C言语开辟的人来讲,GNUgcc的一套工具和Linux平台的共享库的利用仍是非常生疏的,实在我也不太熟习,临时写点基本常识,权当作备忘吧。

1、GNUgcc的编译工具用法

我们先来写一个复杂的C程序:hello.c
C代码

<br>

  • #include<stdio.h>

  • voidprint_hello(){
  • printf("HelloWorld");
  • }

  • intmain(intargc,charargv[]){
  • print_hello();
  • return0;
  • }
  1. #include<stdio.h>voidprint_hello(){printf("HelloWorld");}intmain(intargc,charargv[]){print_hello();return0;}
复制代码
界说了一个print_hello函数,挪用main函数打印HelloWorld。

怎样编译它呢?
C代码

<br>

  • gcc-ohello-O2hello.c
  1. gcc-ohello-O2hello.c
复制代码
-o参数指定天生的可实行程序的文件名,-O2是优化级别。该命令会编译天生hello可实行程序,看看这个文件:ls-lhello
C代码

<br>

  • -rwxr-xr-x1robbinusers119392008-11-0213:48hello
  1. -rwxr-xr-x1robbinusers119392008-11-0213:48hello
复制代码
有11KB巨细。

看看他链接了哪些体系静态链接库,用ldd命令:
C代码

<br>

  • lddhello
  1. lddhello
复制代码
输入信息为:
C代码

<br>

  • libc.so.6=>/lib64/tls/libc.so.6(0x0000002a9566d000)
  • /lib64/ld-linux-x86-64.so.2(0x0000002a95556000)
  1. libc.so.6=>/lib64/tls/libc.so.6(0x0000002a9566d000)/lib64/ld-linux-x86-64.so.2(0x0000002a95556000)
复制代码
libc是C言语尺度函数库,ld是静态链接器。

接着我们看看hello这个程序内里有哪些标记,用nm命令:
C代码

<br>

  • nmhello
  1. nmhello
复制代码
输入:
C代码

<br>

  • 00000000005008f8A__bss_start
  • 000000000040043ctcall_gmon_start
  • ......
  • 00000000004004f0Tmain
  • 0000000000500658dp.0
  • 00000000004004e0Tprint_hello
  • Uputs@@GLIBC_2.2.5
  • 0000000000400410T_start
  1. 00000000005008f8A__bss_start000000000040043ctcall_gmon_start......00000000004004f0Tmain0000000000500658dp.000000000004004e0Tprint_helloUputs@@GLIBC_2.2.50000000000400410T_start
复制代码
两头省略了一些,不外我们仍是能够在标记内外面找到函数界说。

hello有11KB,体积偏年夜,去向标记表能够给它瘦身,我们用strip命令:
C代码

<br>

  • striphello
  1. striphello
复制代码
然后再ls-lhello,输入为:
C代码

<br>

  • -rwxr-xr-x1webuserusers44642008-11-0213:56hello
  1. -rwxr-xr-x1webuserusers44642008-11-0213:56hello
复制代码
只要4.4KB了,瘦身效果分明!不外此次标记表再也看不到了,nmhello,输入为:nm:hello:nosymbols。

最初假如我们想从可实行程序内里提掏出来一点甚么文本信息的话,还能够用strings命令:
C代码

<br>

  • stringshello
  1. stringshello
复制代码
输入信息为:
C代码

<br>

  • /lib64/ld-linux-x86-64.so.2
  • SuSE
  • libc.so.6
  • puts
  • __libc_start_main
  • __gmon_start__
  • GLIBC_2.2.5
  • tfff
  • HelloWorld
  1. gcc-ohello-O2hello.c0
复制代码
友谊提示一下,假如你用Java写一个HelloWorld.java,编译今后你也能够用strings窥伺一番。

2、静态共享库怎样利用

此次我们把hello.c拆开成为两个文件:hello.c和main.c。hello.c的代码是:
C代码

<br>

  • #include<stdio.h>

  • voidprint_hello(){
  • printf("HelloWorld");
  • }
  1. gcc-ohello-O2hello.c1
复制代码
而main.c的代码是:
C代码

<br>

  • intmain(intargc,charargv[]){
  • print_hello();
  • return0;
  • }
  1. gcc-ohello-O2hello.c2
复制代码

hello.c是我们的静态共享库,在hello.c内里我们声明和完成了各类公用的函数,最初main.c能够往挪用这些公用函数。起首我们要把hello.c编译成为静态共享库:
C代码

<br>

  • gcc-olibhello.so-O2-fPIC-sharedhello.c
  1. gcc-ohello-O2hello.c3
复制代码
-fPIC参数声明链接库的代码段是能够共享的,-shared参数声明编译为共享库。请注重此次我们编译的共享库的名字叫做libhello.so,这也是Linux共享库的一个定名的常规了:后缀利用so,而称号利用libxxxx格局。

然后编译main.c的时分,我们必要更多的参数让gcc晓得怎样寻觅共享库:
C代码

<br>

  • gcc-omain-O2-L.-lhellomain.c
  1. gcc-ohello-O2hello.c4
复制代码
-L参数指定到哪一个附加路径上面往寻觅共享库,如今我们指定在以后目次上面寻觅;
-l参数指定链接到哪一个共享库下面,我们传的参数hello,那末gcc就会主动链接到libhello.so这个共享库下面(注重我们下面说的libXXXX.so定名划定规矩);
-I参数指定到哪一个附加路径上面往寻觅h文件,这个我们没有利用。

最初我们乐成编译好了main,实行一下,报错:
援用./main:errorwhileloadingsharedlibraries:libhello.so:cannotopensharedobjectfile:Nosuchfileordirectory

找不到libhello.so这个共享库,怎样回事?这是由于libhello.so其实不在操纵体系默许的共享库的路径上面,我们能够一时指定一下链接路径:
C代码

<br>

  • exportLD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
  1. gcc-ohello-O2hello.c5
复制代码
如许就乐成了。我们用lddmain看一下:
C代码

<br>

  • libhello.so=>./libhello.so(0x0000002a9566d000)
  • libc.so.6=>/lib64/tls/libc.so.6(0x0000002a9576e000)
  • /lib64/ld-linux-x86-64.so.2(0x0000002a95556000)
  1. gcc-ohello-O2hello.c6
复制代码
此次main程序链接到了libhello.so这个共享库下面。

3、关于Linux的静态共享库的设置

可实行程序找不到要链接的静态共享库,这是Linux下面编译和运转程序很简单碰着的成绩,经由过程下面的小例子,我们已大抵懂得共享库的一点基础道理,接上去我们要切磋一下怎样设置程序寻觅静态共享库的举动。

Linux操纵体系下面的静态共享库大抵分为三类:

1、操纵体系级其余共享库和基本的体系工具库

例如说libc.so,libz.so,libpthread.so等等,这些体系库会被放在/lib和/usr/lib目次上面,假如是64位操纵体系,还会有/lib64和/usr/lib64目次。假如操纵体系带有图形界面,那末还会有/usr/X11R6/lib目次,假如是64位操纵体系,另有/usr/X11R6/lib64目次。别的还大概有其他特定Linux版本的体系库目次。

这些体系库文件的完全和版本的准确,确保了Linux下面各类程序可以一般的运转。

2、使用程序级其余体系共享库

并不是操纵体系自带,可是大概被良多使用程序所共享的库,一样平常会被放在/usr/local/lib和/usr/local/lib64这两个目次上面。良多你自行编译安装的程序城市在编译的时分主动把/usr/local/lib到场gcc的-L参数,而在运转的时分主动到/usr/local/lib上面往寻觅共享库。

以上两类的静态共享库,使用程序会主动寻觅到他们,其实不必要你分外的设置和忧虑。这是为何呢?由于以上这些目次默许就被到场到静态链接程序的搜刮路径内里了。Linux的体系共享库搜刮路径界说在/etc/ld.so.conf这个设置文件内里。这个文件的内容格局大抵以下:

C代码

<br>

  • /usr/X11R6/lib64
  • /usr/X11R6/lib
  • /usr/local/lib
  • /lib64
  • /lib
  • /usr/lib64
  • /usr/lib
  • /usr/local/lib64
  • /usr/local/ImageMagick/lib
  1. gcc-ohello-O2hello.c7
复制代码

假定我们本人编译安装的ImageMagick图形库在/usr/local/ImageMagick目次上面,而且但愿其他使用程序都可使用ImageMagick的静态共享库,那末我们只必要把/usr/local/ImageMagick/lib目次到场/etc/ld.so.conf文件内里,然后实行:ldconfig命令便可。

ldcofig将搜刮以上一切的目次,为共享库创建一个缓存文件/etc/ld.so.cache。为了确认ldconfig已搜刮到ImageMagick的库,我们能够用下面先容的strings命令从ld.so.cache内里抽取文本信息来反省一下:
C代码

<br>

  • strings/etc/ld.so.cache|grepImageMagick
  1. gcc-ohello-O2hello.c8
复制代码
输入了局为:
C代码

<br>

  • /usr/local/ImageMagick/lib/libWand.so.10
  • /usr/local/ImageMagick/lib/libWand.so
  • /usr/local/ImageMagick/lib/libMagick.so.10
  • /usr/local/ImageMagick/lib/libMagick.so
  • /usr/local/ImageMagick/lib/libMagick++.so.10
  • /usr/local/ImageMagick/lib/libMagick++.so
  1. gcc-ohello-O2hello.c9
复制代码
已乐成了!

3、使用程序独享的静态共享库

有良多共享库只被特定的使用程序利用,那末就没有需要到场体系库路径,以避免使用程序的共享库之间产生版本抵触。因而Linux还能够经由过程设置情况变量LD_LIBRARY_PATH光降时指定使用程序的共享库搜刮路径,就像我们下面举的谁人例子一样,我们能够在使用程序的启动剧本内里事后设置LD_LIBRARY_PATH,指定本使用程序附加的共享库搜刮路径,从而让使用程序找到它。本文出自:http://robbin.javaeye.com/blog/261176
如果你让他去用linux搭建一个web服务器,做一个linux网关,他就什么都不会了.他们把时间都浪费在了版本的转换上了.
变相怪杰 该用户已被删除
沙发
发表于 2015-1-19 21:05:19 | 只看该作者
Linux只是个内核!这点很重要,你必须理解这一点。只有一个内核是不能构成一个操作系统的。
精灵巫婆 该用户已被删除
板凳
 楼主| 发表于 2015-1-19 23:24:18 | 只看该作者
首先Linux是开源的,这也是最主要的原因,想学windows,Unix,对不起我们没源代码。也正是因为这样,Linux才能够像滚雪球一样越滚越大,发展到现在这种规模。
再现理想 该用户已被删除
地板
发表于 2015-1-20 15:40:47 | 只看该作者
熟悉操作是日常学习Linux中的三大法宝。以下是作者学习Linux的一些个人经验,供参考:
小女巫 该用户已被删除
5#
发表于 2015-1-25 17:01:03 | 只看该作者
请问谁有Linux的学习心得的吗?简单的说说?
谁可相欹 该用户已被删除
6#
发表于 2015-2-3 11:53:58 | 只看该作者
随着实验课程的结束,理论课也该结束了,说实话教OS的这两位老师是我们遇到过的不错的老师(这话放这可能不太恰当).
飘灵儿 该用户已被删除
7#
发表于 2015-2-8 20:34:41 | 只看该作者
应对Linux的发展历史和特点有所了解,Linux是抢占式多任务多用户操作系统,Linux最大的优点在于其作为服务器的强大功能,同时支持多种应用程序及开发工具。
8#
发表于 2015-2-26 05:57:42 | 只看该作者
以前觉得Linux就跟dos一样,全是用命令窗口,相对于窗口界面来说多麻烦呀。
金色的骷髅 该用户已被删除
9#
发表于 2015-3-7 03:20:26 | 只看该作者
选择一些适于初学者的Linux社区。
山那边是海 该用户已被删除
10#
发表于 2015-3-14 05:48:20 | 只看该作者
感谢老师和同学们在学习上对我的帮助。
爱飞 该用户已被删除
11#
发表于 2015-3-21 00:39:34 | 只看该作者
学习Linux,应该怎样学,主要学些什么,一位Linux热心学习者,一段学习Linux的风云经验,历时十二个小时的思考总结,近十位网络Linux学习者权威肯定,为您学习Linux指明方向。
兰色精灵 该用户已被删除
12#
发表于 2015-4-5 15:37:08 | 只看该作者
对我们学习操作系统有很大的帮助,加深我们对OS的理解。?
冷月葬花魂 该用户已被删除
13#
发表于 2015-4-11 13:24:02 | 只看该作者
通过一条缓慢的调制解调器线路,它也能操纵几千公里以外的远程系统。
再见西城 该用户已被删除
14#
发表于 2015-4-15 06:47:15 | 只看该作者
熟悉系统的基本操作,Linux的图形界面直观,操作简便,多加上机练习就可熟悉操作,在Linux下学习办公软件等常用软件。
乐观 该用户已被删除
15#
发表于 2015-4-27 19:32:53 | 只看该作者
其中不乏很多IT精英的心血。我们学透以后更可以做成自己的OS!?
分手快乐 该用户已被删除
16#
发表于 2015-5-1 20:10:41 | 只看该作者
然我们对Linux的学习首先是通过对它的产生,发展,到今天仍然在不断完善开始的。
深爱那片海 该用户已被删除
17#
发表于 2015-5-1 21:43:33 | 只看该作者
随着实验课程的结束,理论课也该结束了,说实话教OS的这两位老师是我们遇到过的不错的老师(这话放这可能不太恰当).
若相依 该用户已被删除
18#
发表于 2015-6-12 06:57:16 | 只看该作者
这种补充有助于他人在邮件列表/新闻组/论坛中搜索对你有过帮助的完整解决方案,这可能对他们也很有用。
不帅 该用户已被删除
19#
发表于 2015-6-13 22:22:59 | 只看该作者
选择一些适于初学者的Linux社区。
飘飘悠悠 该用户已被删除
20#
发表于 2015-7-11 00:58:37 | 只看该作者
如果上面的措施没有解决问题,此时你就需要Linux社区的帮助了。 Linux的使用者一般都是专业人士,他们有着很好的电脑背景且愿意协助他人。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-22 17:02

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表