青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

tqsheng

go.....
隨筆 - 366, 文章 - 18, 評論 - 101, 引用 - 0
數據加載中……

關于Unix靜態庫和動態庫的分析

關于Unix靜態庫和動態庫的分析

基本概念

庫有動態與靜態兩種,動態通常用.so為后綴,靜態用.a為后綴。 例如:libhello.so libhello.a

為了在同一系統中使用不同版本的庫,可以在庫文件名后加上版本號為后綴,例如: libhello.so.1.0,由于程序連接默認以.so為文件后綴名。所以為了使用這些庫,通常使用建立符號連接的方式。

ln -s libhello.so.1.0 libhello.so.1
ln -s libhello.so.1 libhello.so

1、使用庫

當要使用靜態的程序庫時,連接器會找出程序所需的函數,然后將它們拷貝到執行文件,由于這種拷貝是完整的,所以一旦連接成功,靜態程序庫也就不再需要了。 然而,對動態庫而言,就不是這樣。動態庫會在執行程序內留下一個標記指明當程序執行時,首先必須載入這個庫。由于動態庫節省空間,linux下進行連接的 缺省操作是首先連接動態庫,也就是說,如果同時存在靜態和動態庫,不特別指定的話,將與動態庫相連接。

現在假設有一個叫hello的程序開發包,它提供一個靜態庫libhello.a 一個動態庫libhello.so,一個頭文件hello.h,頭文件中提供sayhello()這個函數

/* hello.h */
void sayhello();

另外還有一些說明文檔。

這一個典型的程序開發包結構 與動態庫連接 linux默認的就是與動態庫連接,下面這段程序testlib.c使用hello庫中的sayhello()函數

/*testlib.c*/
#include "hello.h"
int main()
{
    sayhello();
    return 0;
}

使用如下命令進行編譯

$gcc -c testlib.c -o testlib.o

用如下命令連接:

$gcc testlib.o -lhello -o testlib

連接時要注意,假設libhello.so 和libhello.a都在缺省的庫搜索路徑下/usr/lib下,如果在其它位置要加上-L參數。與靜態庫連接麻煩一些,主要是參數問題。還是上面的例 子:

$gcc testlib.o -o testlib -WI,-Bstatic -lhello

注:這個特別的”-WI,-Bstatic”參數,實際上是傳給了連接器ld. 指示它與靜態庫連接,如果系統中只有靜態庫當然就不需要這個參數了。如果要和多個庫相連接,而每個庫的連接方式不一樣,比如上面的程序既要和 libhello進行靜態連接,又要和libbye進行動態連接,其命令應為:

$gcc testlib.o -o testlib -WI,-Bstatic -lhello -WI,-Bdynamic -lbye

2、動態庫的路徑問題

為了讓執行程序順利找到動態庫,有三種方法:

  1. 把庫拷貝到/usr/lib和/lib目錄下。
  2. 在LD_LIBRARY_PATH環境變量中加上庫所在路徑。例如動態庫 libhello.so在/home/ting/lib目錄下,以bash為例,使用命令: $export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ting/lib
  3. 修改/etc/ld.so.conf文件,把庫所在的路徑加到文件末尾,并執行ldconfig刷新。這樣,加入的目錄下的所有庫文件都可見。

3、查看庫中的符號

有時候可能需要查看一個庫中到底有哪些函數,nm工具可以打印出庫中的涉及到的所有符號。庫既可以是靜態的也可以是動態的。nm列出的符號有很多, 常見的有三種,一種是在庫中被調用,但并沒有在庫中定義(表明需要其他庫支持),用U表示;一種是庫中定義的函數,用T表示,這是最常見的;另外一種是所 謂的“弱態”符號,它們雖然在庫中被定義,但是可能被其他庫中的同名符號覆蓋,用W表示。例如,假設開發者希望知道上文提到的hello庫中是否引用了 printf():

$nm libhello.so | grep printf U

其中printf U表示符號printf被引用,但是并沒有在函數內定義,由此可以推斷,要正常使用hello庫,必須有其它庫支持,再使用ldd工具查看hello依賴于哪些庫:

$ldd hello
libc.so.6=>/lib/libc.so.6(0x400la000)
/lib/ld-linux.so.2=>/lib/ld-linux.so.2 (0x40000000)

從上面的結果可以繼續查看printf最終在哪里被定義,有興趣可以go on

4、生成庫

第一步要把源代碼編繹成目標代碼。以下面的代碼為例,生成上面用到的hello庫:

/* hello.c */
#include "hello.h"
void sayhello()
{
    printf("hello,world ");
}

用gcc編繹該文件,在編繹時可以使用任何合法的編繹參數,例如-g加入調試代碼等:

$gcc -c hello.c -o hello.o

1.連接成靜態庫 連接成靜態庫使用ar工具,其實ar是archive的意思

$ar cqs libhello.a hello.o

2.連接成動態庫 生成動態庫用gcc來完成,由于可能存在多個版本,因此通常指定版本號:

$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o

另外再建立兩個符號連接:

$ln -s libhello.so.1.0 libhello.so.1
$ln -s libhello.so.1 libhello.so

這樣一個libhello的動態連接庫就生成了。最重要的是傳gcc -shared 參數使其生成是動態庫而不是普通執行程序。 -Wl 表示后面的參數也就是-soname,libhello.so.1直接傳給連接器ld進行處理。實際上,每一個庫都有一個soname,當連接器發現它正 在查找的程序庫中有這樣一個名稱,連接器便會將soname嵌入連結中的二進制文件內,而不是它正在運行的實際文件名,在程序執行期間,程序會查找擁有 soname名字的文件,而不是庫的文件名,換句話說,soname是庫的區分標志。這樣做的目的主要是允許系統中多個版本的庫文件共存,習慣上在命名庫 文件的時候通常與soname相同 libxxxx.so.major.minor 其中,xxxx是庫的名字,major是主版本號,minor 是次版本號

總結

通過對LINUX庫工作的分析,我們已經可以理解程序運行時如何去別的地方尋找“庫”。

附上針對這個工程的Makefile:

# xiejingquan@gmail.com
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/C/lib

BIN_DIR=bin
LIB_DIR=lib
INC_DIR=inc
SRC_DIR=src

BIN=${BIN_DIR}/testlib
LIB=${LIB_DIR}/libhello.a ${LIB_DIR}/libhello.so

CC=gcc
AR=ar
DOC=doxygen

CFLAGS=-g -Wall -c -Iinc
LFLAGS=-lhello -L${LIB_DIR} -o
ARFLAGS=cqs
SOFLAGS=-shared -Wl,-soname,

all: ${BIN}

lib: ${LIB}

run: all
@./bin/testlib

clean:
rm -f ${BIN_DIR}/* ${LIB_DIR}/*

${BIN_DIR}/testlib: ${LIB_DIR}/testlib.o ${LIB}
${CC} $< ${LFLAGS} $@

${LIB_DIR}/testlib.o: ${SRC_DIR}/testlib.c ${INC_DIR}/hello.h
${CC} ${CFLAGS} $< -o $@

${LIB_DIR}/libhello.a: ${LIB_DIR}/hello.o
${AR} ${ARFLAGS} $@ $<

${LIB_DIR}/libhello.so: ${LIB_DIR}/hello.o
${CC} ${SOFLAGS}libhello.so.1 -o ${LIB_DIR}/libhello.so.1.0 ${LIB_DIR}/hello.o
ln -s ${LIB_DIR}/libhello.so.1.0 ${LIB_DIR}/libhello.so.1
ln -s ${LIB_DIR}/libhello.so.1 ${LIB_DIR}/libhello.so

${LIB_DIR}/hello.o: ${SRC_DIR}/hello.c ${INC_DIR}/hello.h
${CC} ${CFLAGS} $< -o $@

附上文件的目錄結構:

|– bin
| `– testlib
|– doc
|– inc
| `– hello.h
|– lib
| |– hello.o
| |– libhello.a
| |– libhello.so -> lib/libhello.so.1
| |– libhello.so.1 -> lib/libhello.so.1.0
| |– libhello.so.1.0
| `– testlib.o
|– src
| |– hello.c
| `– testlib.c


說來也巧了,今天剛好在twitter上看到某大牛的推:

 

Linux下動態鏈接庫的查找順序:①DT_RPATH、②LD_LIBRARY_PATH環境變量、③/etc/ld.so.conf文件及/etc/ld.so.cond.d/目錄內的*.conf文件、④默認路徑/usr/lib,如果改動了/etc/ld.so.conf 需要使用 /sbin/ldconfig –v 來更新系統。


延伸閱讀:

 

  1. linux動態鏈接庫的使用;
  2. linux 下鏈接庫的生成使用;

本文來源:http://hi.baidu.com/fengmang0451/blog/item/0e74df1d3e22e000304e15ae.html

Printed from: http://xiaobin.net/200911/analytics-on-unix-static-and-dynamic-library/ .
© XiaoBiN.net 2013.

Trackbacks/Pingbacks

  1. 關于Unix靜態庫和動態庫的分析基本概念 | EvilCode 邪惡代碼

posted on 2013-01-04 16:40 tqsheng 閱讀(147) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产一区二区高清不卡| 久久综合一区| 蜜桃久久av| 欧美a级片一区| 亚洲激情视频网| 91久久极品少妇xxxxⅹ软件| 亚洲国产精品激情在线观看| 亚洲国产欧美一区二区三区同亚洲 | 久久久久免费| 麻豆精品在线播放| 欧美日本国产| 国产午夜精品一区理论片飘花| 狠狠色2019综合网| 亚洲精品乱码久久久久久久久| 亚洲免费播放| 久久成人精品视频| 亚洲日韩欧美视频一区| 午夜久久tv| 欧美激情偷拍| 国自产拍偷拍福利精品免费一| 亚洲精品视频一区| 久久www免费人成看片高清 | 亚洲综合国产| 麻豆成人小视频| 国产精品免费看| 亚洲人成网站精品片在线观看| 亚洲女人小视频在线观看| 欧美大片一区| 欧美在线啊v一区| 国产精品国产| 一本色道久久综合| 久久久久久久久久久成人| 久久久一二三| 一区二区三区四区五区视频| 久久精品综合一区| 国产精品婷婷| 亚洲天堂av高清| 欧美激情第3页| 久久久久久九九九九| 国产精品视频xxxx| 亚洲一级二级| 亚洲裸体俱乐部裸体舞表演av| 久久久青草婷婷精品综合日韩| 国产精品日日做人人爱| 在线一区视频| 亚洲精品国精品久久99热| 久久精品国产亚洲一区二区三区| 国产精品爱啪在线线免费观看| 日韩午夜精品视频| 亚洲国产精品久久久久秋霞不卡| 久久高清国产| 国产夜色精品一区二区av| 午夜免费久久久久| 亚洲在线观看视频| 国产精品视频九色porn| 亚洲综合999| 中日韩男男gay无套| 欧美精品午夜视频| 亚洲午夜av| 一区二区三区四区五区视频| 欧美日韩日日夜夜| 亚洲一区一卡| 亚洲一区二区三区乱码aⅴ| 欧美三级在线视频| 性欧美精品高清| 亚洲欧美日韩在线综合| 国产亚洲一区二区三区在线观看| 久久精品人人做人人爽电影蜜月| 亚洲欧美资源在线| 伊人男人综合视频网| 狂野欧美一区| 欧美高清在线视频| 亚洲愉拍自拍另类高清精品| 亚洲午夜视频在线| 国内精品久久久久影院色| 欧美不卡视频一区发布| 欧美激情一区在线| 亚洲一区二区在| 午夜在线精品偷拍| 亚洲第一伊人| 99国产精品99久久久久久| 国产精品免费一区豆花| 久久国产精品久久w女人spa| 午夜精品一区二区三区在线播放| 国语自产精品视频在线看抢先版结局| 欧美成人嫩草网站| 欧美视频一区在线观看| 久久久一二三| 欧美日韩精品在线| 久久精品盗摄| 欧美精品一区三区| 久久夜色精品一区| 午夜一级久久| 国产精品热久久久久夜色精品三区 | 欧美在线影院在线视频| 美女图片一区二区| 午夜国产精品视频免费体验区| 欧美影片第一页| 999亚洲国产精| 午夜欧美精品久久久久久久| 亚洲国产日日夜夜| 性伦欧美刺激片在线观看| 日韩一级不卡| 欧美在线一二三| 亚洲一区二区在线看| 麻豆精品一区二区综合av| 欧美一区二区精品| 欧美精品一级| 欧美国产亚洲另类动漫| 国产精品自拍小视频| 亚洲欧洲一区二区三区久久| 国产综合视频| 亚洲资源av| 亚洲天天影视| 欧美国产极速在线| 鲁大师成人一区二区三区| 国产精品久久久久久模特| 欧美激情精品久久久久| 韩日午夜在线资源一区二区| 亚洲午夜av电影| 亚洲视频一二| 欧美视频免费在线| 99精品欧美| 亚洲一区二区三区高清不卡| 欧美成人免费全部| 亚洲国产精品久久久| 亚洲国产女人aaa毛片在线| 亚洲欧美国产日韩天堂区| 亚洲自拍偷拍网址| 欧美天堂在线观看| 日韩午夜一区| 亚洲视频在线观看一区| 欧美日韩国产高清| 日韩视频一区二区三区| 一区二区三区鲁丝不卡| 欧美国产三区| 亚洲国产一区二区三区a毛片 | 亚洲第一精品夜夜躁人人躁| 欧美一区二区三区免费在线看| 欧美伊人久久久久久午夜久久久久 | 欧美中文字幕在线观看| 国产精品稀缺呦系列在线| 亚洲一级二级在线| 欧美亚洲在线观看| 国产日韩一区| 久久久久久久网站| 亚洲福利视频网| 日韩亚洲欧美一区| 国产精品wwwwww| 欧美一区在线视频| 欧美大片专区| 亚洲天堂av图片| 韩国成人精品a∨在线观看| 在线精品一区| 女主播福利一区| 亚洲国产精品v| 亚洲一区激情| 国产一区二区三区丝袜 | 国产精品入口麻豆原神| 亚洲一区三区电影在线观看| 欧美在线关看| 亚洲福利视频一区二区| 欧美日韩精品久久久| 亚洲欧美中日韩| 欧美大秀在线观看| 亚洲综合精品自拍| 合欧美一区二区三区| 欧美激情第三页| 亚洲欧美日本日韩| 亚洲国产精品视频一区| 午夜影视日本亚洲欧洲精品| 在线观看成人一级片| 国产精品高潮呻吟久久av黑人| 欧美一区二区三区免费看| 亚洲精品在线观看视频| 久久偷窥视频| 亚洲一区免费看| 亚洲风情亚aⅴ在线发布| 国产精品男女猛烈高潮激情| 欧美成人精品在线| 欧美一区影院| 亚洲视频观看| 亚洲高清不卡在线| 久久九九免费视频| 亚洲一区二三| 99re8这里有精品热视频免费 | 亚洲欧美日韩精品| 亚洲国产日韩一级| 国产视频在线观看一区二区三区| 久久亚洲图片| 性色av一区二区三区红粉影视| 日韩午夜在线视频| 亚洲国产综合91精品麻豆| 老司机免费视频一区二区| 亚洲一区欧美激情| 亚洲天堂成人| aa国产精品| 亚洲精品在线观| 亚洲国产经典视频| 国产综合色在线|