参照GNU/Linux 编程指南(第二版)一书第10章库的使用, 比较OS X 下的运行。
1. 静态归档库(static archive libraries):
page 148:
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.
$ 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.