免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 984 | 回复: 0
打印 上一主题 下一主题

static与shared库的创建和使用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-28 16:52 |只看该作者 |倒序浏览
这个周末仔仔细细读了下David A. Wheeler的Program-Library-HOWTO,总结如下
静态库(static library)的生成和使用:
生成: ar rcs libmy_library.a file1.o file2.o
This sample command adds the object files file1.o and file2.o to the static library libmy_library.a,
creating libmy_library.a if it doesn't already exist
使用:
Once you've created a static library, you'll want to use it. You can use a static library by invoking it
as part of the compilation and linking process when creating a program executable. If you're using gcc(1)
to generate your executable, you can use the -l option to specify the library; see info:gcc for more
information.
在编译的时候使用 -Ldir -lmy_library 即可将已经编译好的静态库链接到自己的程序中
动态库(shared library)的生成和使用就比较复杂了
首先我们需要知道几个名字之间的区别:
soname 和real name 以及 linker name
A fully-qualified soname includes as a prefix the directory it's in; on a working system a fully-
qualified soname is simply a symbolic link to the shared library's ``real name''.
soname只是以real name为文件名的文件的符号链接
Every shared library also has a ``real name'', which is the filename containing the actual library code.
The real name adds to the soname a period, a minor number, another period, and the release number. The
last period and release number are optional. The minor number and release number support configuration
control by letting you know exactly what version(s) of the library are installed. Note that these numbers
might not be the same as the numbers used to describe the library in documentation, although that does
make things easier.
In addition, there's the name that the compiler uses when requesting a library, (I'll call it the
``linker name''), which is simply the soname without any version number.
解析:soname的形式:libname.so.2 它链接到 real name
      real name的形式:libname.so.2.1
      而实际在编译器直接使用的是 soname的简化形式 linker name
      linker name的形式:name
分清楚这几个名字之后我们来解释一下shared库的安装:
When you install a new version of a library, you install it in one of a few special directories and then
run the program ldconfig(8). ldconfig examines the existing files and creates the sonames as symbolic
links to the real names, as well as setting up the cache file /etc/ld.so.cache (described in a moment).
当我们安装一个新的版本的库的时候,我们将原始的库文件放在一个目录中,然后运行ldconfig
ldconfig将检查已经存在的库文件(根据/etc/ld.so.conf中的路径去查找)并且根据这些原始库文件的realname创建相应
的soname的链接文件,然后在/etc/ld.so.cache中做适当的修改(添加库的路径等)
ldconfig doesn't set up the linker names; typically this is done during library installation, and the
linker name is simply created as a symbolic link to the ``latest'' soname or the latest real name. I
would recommend having the linker name be a symbolic link to the soname, since in most cases if you
update the library you'd like to automatically use it when linking. I asked H. J. Lu why ldconfig doesn't
automatically set up the linker names. His explanation was basically that you might want to run code
using the latest version of a library, but might instead want development to link against an old
(possibly incompatible) library. Therefore, ldconfig makes no assumptions about what you want programs to
link to, so installers must specifically modify symbolic links to update what the linker will use for a
library.
注意:ldconfig并不创建linker name因此现在还不能使用已有的库 要将linkername链接到 soname或者 real name
      linker name链接文件必须由用户自己创建 一般我们将linker name文件链接到ldconfig已经为我们创建好的     
      soname上,这样我们就可以通过linker name访问原始的库文件了
      
库使用过程:
On GNU glibc-based systems, including all Linux systems, starting up an ELF binary executable
automatically causes the program loader to be loaded and run. On Linux systems, this loader is named
/lib/ld-linux.so.X (where X is a version number). This loader, in turn, finds and loads all other shared
libraries used by the program.
在所有的linux系统中,如果我们启动任何一个可执行的ELF形式的二进制代码都和先运行一个称为program loader的程
序(即/lib/ld-linux.so.X (where X is a version number)),这个程序负责加载可执行代码的所有shared库
The list of directories to be searched is stored in the file /etc/ld.so.conf. Many Red Hat-derived
distributions don't normally include /usr/local/lib in the file /etc/ld.so.conf. I consider this a bug,
and adding /usr/local/lib to /etc/ld.so.conf is a common ``fix'' required to run many programs on Red
Hat-derived systems
program loader所有搜索的路径记录在/etc/ld.so.conf中 我们可以在这个文件中添加和修改路径
The program ldconfig(8) by default reads in the file /etc/ld.so.conf, sets up the appropriate symbolic
links in the dynamic link directories (so they'll follow the standard conventions), and then writes a
cache to /etc/ld.so.cache that's then used by other programs
为了提高效率,ldconfig在缺省地读完/etc/ld.so.conf路径并建立适当的符号链接之后就将这些信息写
入/etc/ld.so.cache以被其他的程序使用 以提高访问库的速度
The implication is that ldconfig must be run whenever a DLL is added, when a DLL is removed, or when the
set of DLL directories changes; running ldconfig is often one of the steps performed by package managers
when installing a library. On start-up, then, the dynamic loader actually uses the file /etc/ld.so.cache
and then loads the libraries it needs.
这就意味着当无论是增加一个DLL,移除一个DLL或者改变了它的路径,我们要做的第一步就是运行ldconfig命令,我们
在安装库时也必须运行ldconfig命令
一旦运行起来那么program loader将使用/etc/ld.so.cache文件来加载动态库
环境变量(略)
创建shared库:
First, create the object files that will go into the shared library using the gcc -fPIC or -fpic flag
首先,我们要创建shared库需要的对象文件 使用gcc -fPIC 或者 gcc -fpic
如:我们要由源码a.c和b.c创建一个shared库,首先要执行如下命令
        gcc -fPIC -g -c -Wall a.c
        gcc -fPIC -g -c -Wall b.c
生成 a.o b.o文件
PIC和pic的区别如下:
Use -fPIC or -fpic to generate code. Whether to use -fPIC or -fpic to generate code is target-dependent.
The -fPIC choice always works, but may produce larger code than -fpic (mnenomic to remember this is that
PIC is in a larger case, so it may produce larger amounts of code). Using -fpic option usually generates
smaller and faster code, but will have platform-dependent limitations, such as the number of globally
visible symbols or the size of the code. The linker will tell you whether it fits when you create the
shared library. When in doubt, I choose -fPIC, because it always works.

然后:由a.o b.o生成库文件 执行如下命令
    gcc -shared -Wl,-soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc
-shared:指明生成shared库
-Wl,-soname,libmystuff.so.1:指明在安装库文件,执行ldconfig时生成的链接文件的名字为libmystuff.so(soname)
-o libmystuff.so.1.0.1:指明生成的库文件名(real name)
-l:链接c库
这样经过
         gcc -fPIC -g -c -Wall a.c
         gcc -fPIC -g -c -Wall b.c
         gcc -shared -Wl,-soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc
就生成了 libmystuff.so.1.0.1 shared库文件
下面来安装此库文件:
运行如下命令:
ldconfig -n directory_with_shared_libraries
directory_with_shared_libraries:为以上创建的库文件libmystuff.so.1.0.1所在的目录
运行以上命令后 ldconfig会为库文件自动创建一个符号链接libmystuff.so.1(这个名字就是所谓的soname在生成库文件
时候由-Wl,-soname,libmystuff.so.1选项指定了)
到现在我们已经有了一个名为 real name的库源文件 一个链接到库源文件的名为soname的链接文件libmystuff.so.1
但是这个时候还不能正常使用 我们还必须创建一个名为linker name的链接文件链接到libmystuff.so.1
运行
ln -sf libmystuff.so.1  libmystuff.so
创建完毕!!!!
以后就可以使用-lmystuff选项来调用这个shared库了

还要注意:
gcc -L指定路径只是告诉ld连接过程所需要搜索的目录路径,只能保证连接成功。
程序在执行时,就和编译过程无关了,程序使用loader(ld-linux.so.N)来加載到系统的,共享库是在执行之前根
据需要才被加載到内存中,并根据你的执行程序的调用进行地址重映射(动态连接过程)。ld-linux.so.N在依次
在/etc/ld.so.cache(使用ldconfig由文件/etc/ld.so.conf生成)文件所罗列的目录;lib:/usr/lib;这些目录下去寻
找执行程序所需要的共享库。如果存在变量LD_LIBRARY_PATH定义,那么首先会搜索他所指定的目录(多目录冒号分割)
执行ldconfig命令有两个作用:
1 将/etc/ld.so.conf中的路径写到/etc/ld.so.cache中(loader是根据这个文件中记录的路径来加载库文件的)
2 扫描/etc/ld.so.conf记录的路径中所有的以real name为文件名的库源文件,并为之生成一个以so name(so name由生成shared库时的-Wall,soname选项指定)为文件名的链接文件


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/50198/showart_409438.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP