http://www.360doc.com/content/11/0211/17/2118127_92192787.shtml
libtool常見於autoconf/automake,單獨用的例子很少,所以我想仔細研究一下,爲將來兄弟們看起來方便。
一。libtool的作用
offer a standard procedure for creating shared libraries on different platforms
libtool 是一個通用庫支持腳本,將使用動態庫的複雜性隱藏在統一、可移植的接口中,也就是說,你可以通過如下所示的標準方法,在不同平臺上創建並調用動態庫,我們可以認爲libtool是gcc的一個抽象,也就是說,它包裝了gcc或者其他的任何編譯器,用戶無需知道細節,只要告訴libtool說我需要要編譯哪些庫即可,並且,它只與libtool文件打交道,例如lo、la爲後綴的文件。
二。libtool的使用
1.Creating object files
# libtool --mode=compile gcc -g -O -c foo.c
gcc -g -O -c foo.c -fPIC -DPIC -o .libs/foo.o
gcc -g -O -c foo.c -o foo.o >/dev/null 2>&1
# libtool --mode=compile gcc -g -O -c hello.c
gcc -g -O -c hello.c -fPIC -DPIC -o .libs/hello.o
gcc -g -O -c hello.c -o hello.o >/dev/null 2>&1
【說明】libtool編譯出兩個版本的relocatable object,一個是fPIC(位置無關的),放在.libs目錄下;另一個則是普通的,放在本地。
2.linking shared library
# libtool --mode=link --tag=CC gcc -g -O -o libhello.la -rpath /usr/local/lib foo.lo
rm -fr .libs/libhello.a .libs/libhello.la .libs/libhello.lai .libs/libhello.so libs/libhello.so.0 .libs/libhello.so.0.0.0
gcc -shared .libs/foo.o -Wl,-soname -Wl,libhello.so.0 -o .libs/libhello.so.0.0.0
(cd .libs && rm -f libhello.so.0 && ln -s libhello.so.0.0.0 libhello.so.0)
(cd .libs && rm -f libhello.so && ln -s libhello.so.0.0.0 libhello.so)
ar cru .libs/libhello.a foo.o
ranlib .libs/libhello.a
creating libhello.la
(cd .libs && rm -f libhello.la && ln -s ../libhello.la libhello.la)
【說明】link出兩個共享庫,一個是static,一個則是dynamic;需要注意的是,-rpath必須有才能產生dynamic庫來,如果用-static,則只創建static庫。
ranlib的作用:
On some older UNIX systems, ranlib added a table of contents to archive libraries, which converted each archive to a form that could be linked more rapidly. This is no longer needed as the ar command automatically provides all the functionality ranlib used to provide.
在一些舊版本的系統上,ranlib負責把靜態庫轉換爲其他的某種格式,使得新的庫能夠更快的鏈接;現在ar命令已經包含了上述功能;
This command is provided as a convenience for software developers who need to maintain Makefiles that are portable across a variety of operating systems.
爲了兼容性,在makefile中還是保留ranlib
3.install shared library
libtool --mode=install cp libhello.la /usr/local/lib/libhello.la
libtool --mode=install install -c libhello.la /usr/local/lib/libhello.la
兩個命令都可以,效果相同
4.linking executable file
# libtool --mode=link gcc -g -O -o hello hello.lo -rpath /usr/local/lib libhello.la
gcc -g -O -o .libs/hello .libs/hello.o ./.libs/libhello.so
creating hello
-rpath項負責添加運行時庫路徑,否則只能手工修改LD_LIBRARY_PATH環境變量了。
驗證一下:
# ldd .libs/hello
linux-gate.so.1 => (0xffffe000)
libhello.so.0 => /usr/local/lib/libhello.so.0 (0x40019000)
libc.so.6 => /lib/tls/libc.so.6 (0x40031000)
/lib/ld-linux.so.2 (0x40000000)
5.install executable file
#libtool --mode=install cp hello /usr/local/bin/hello
安裝可執行程序。
6.運行
libtool --mode=execute hello
或直接運行hello
注意:此處hello已經安裝在/usr/local/bin下了,可以用which hello來查看
【附】源碼
foo.c
#include <stdio.h>
char msg[128]="Hello world";
void print()
{
printf("%s/n", msg);
}
hello.c:
#include <stdio.h>
extern char msg[128];
extern void print();
int main()
{
print();
}
Makefile:
LO_OBJS = foo.lo
PACKAGE_VERSION = 1:1:1
LIBDIR=/usr/local/lib
BINDIR=/usr/local/bin
all : hello
install : libhello.la hello
libtool --mode=install install -c libhello.la
${LIBDIR}/libhello.la
libtool --mode=install cp hello ${BINDIR}/hello
uninstall : ${LIBDIR}/libhello.la ${BINDIR}/hello
libtool --mode=uninstall /bin/rm ${LIBDIR}/libhello.la
libtool --mode=uninstall /bin/rm ${BINDIR}/hello
hello : libhello.la hello.o
libtool --mode=install install -c libhello.la
${LIBDIR}/libhello.la
libtool --mode=link gcc -g -O -o hello hello.o -rpath ${LIBDIR} libhello.la
libhello.la : $(LO_OBJS)
libtool --mode=link --tag=CC gcc -g -O -o libhello.la
$(LO_OBJS) -rpath ${LIBDIR} ${PACKAGE_VERSION}
foo.lo : foo.c
libtool --mode=compile gcc -g -O -c foo.c
hello.lo : hello.c
libtool --mode=compile gcc -g -O -c hello.c
clean :
rm -f lib*.a *~ *core *.lo *.o *.la hello
rm -rf .libs
這樣,用戶可以用make編譯,make install/uninstall安裝/卸載,make clean清除編譯臨時文件,安裝成功後,可以直接執行hello,不必指明路徑也不必再另設環境變量LD_LIBRARY_PATH,非常方便!