现在的位置: 首页 > 综合 > 正文

静态归档库和动态共享库

2014年03月11日 ⁄ 综合 ⁄ 共 2101字 ⁄ 字号 评论关闭
参照GNU/Linux 编程指南(第二版)一书第10章库的使用, 比较OS X 下的运行。

1. 静态归档库(static archive libraries):
 page 148:

$ gcc -c liberr.c -o liberr.o 
$ ar rcs liberr.a liberr.o 
同样可以使用libtool , 这是os x 下的工具。 
$ libtool 
-static -o liberr.a liberr.o 

$nm liberr.a
liberr.a(liberr.o):
         U ___error
         U ___sF
00000178 T _err_prn
00000064 T _err_quit
00000000 T _err_ret
         U _exit
         U _fclose
         U _fflush
         U _fopen
         U _fputs
         U _fwrite
00000120 T _log_quit
000000bc T _log_ret
         U _sprintf$LDBLStub
         U _strerror
         U _strlen
         U _vsprintf$LDBLStub
         U dyld_stub_binding_helper

ch. 10.3 Page 150

$ gcc -g  errtest.c -o errtest -static -L. -lerr
/usr/bin/ld: can't locate file for: -lcrt0.o
collect2: ld returned 1 exit status

-static  在mac os x 上无用, 因为os x 没有提供静态c 库,不支持用户空间应用程序的静态连接, 因为os x 下c 库和内核之间的接口是私有, 所以没有 ctro0.o 这个启动文件给连接器ld,无法生称静态连接的执行文件。

liberr.a 作为一个静态归档(archive) 库, 它仍然可以被连接到errtest。所以, 去掉 -static 选项, 进行编译:

$ gcc -g  errtest.c -o errtest  -L. -lerr

$ file errtest
errtest: Mach-O executable ppc

errtest 是Mach-O 可执行文件,ppc (我用iBook.)

再用 otool 显示errtest 用到的共享库:
$ otool errtest  -L
errtest:
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.4.1)

libSystem 包含了许多BSD库, 包括标准 c 库 (libc), math 库(libm) .通常这些库由符号连接指向libSystem. 如 /usr/lib/libc.dylib 只是/usr/lib/libSystem.dylib 的符号连接。

$ nm errtest
可以看到那些没有定义的符号(U), 再次表明可执行文件不是静态连接的。

2.动态共享库 (dynamic shared libraries)

Ch 10.4, Page 151

OS X 下创建动态共享库。
$ gcc -fPIC -g -c liberr.c -o liberr.o
 编译目标文件时,Mac OS X 下的 gcc 缺省使用 -fPIC 选项, 产生与位置无关的代码,所以,可以写成
$ gcc -g -c liberr.c -o liberr.o

连接:
$ gcc -g -shared -Wl,-soname,liberr.so -o liberr.so.1.0.0 liberr.o -lc
powerpc-apple-darwin8-gcc-4.0.1: unrecognized option '-shared'
/usr/bin/ld: unknown flag: -soname
collect2: ld returned 1 exit status

-shared 选项无用,OS X 下使用 -dynamiclib 选项, 调用Darwin 的 libtool 生成动态库,而不是生成可执行文件。
-soname 选项无用, 改为 -install_name;
-lc 可以忽略。
按照osx 惯例, 生成的动态库以 dylib 为后缀。

于是,OS X 下的命令:
$ gcc -g -dynamiclib -Wl,-install_name,liberr.dylib  -o liberr.1.0.0.dylib liberr.o

 $ ln -s liberr.1.0.0.dylib liberr.dylib
 $ gcc -g errtest.c -o errtest -L. -lerr
$ otool errtest -L
errtest:
        liberr.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.4.1)

可以看到errtest 不出意外的调用了先前创建的动态共享库 liberr.dylib.

抱歉!评论已关闭.