linux環境生成.so文件


$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 是次版本號

至於頭文件的使用 只要.c文件和.h文件在同一目錄下就能夠直接用#include "your.h" 若是在.c文件的上層目錄 那隻要作以下修改#include "../your.h" 就可以讓你的編譯器找到了!

這個也不錯
這個也至關詳細 html

1、建立共享庫
1 單獨編譯SList.cpp,編譯時須要傳入-fPIC選項,告訴編譯器生成位置無關代碼.
位置無關代碼能夠被加載到地址空間的任意位置而不須要修改. c++

[root@LEE src]# ls
main.cpp SList.cpp SList.h
[root@LEE src]# g++ -fPIC -g -c SList.cpp bash

2 當連接到庫時,爲連接器傳入-shared選項,把目標文件SList.o連接爲共享對象
libSList.so.1.0.1
每一個共享庫都有一個特定的搜索名(soname).搜索名約定以下:
lib+庫名+.so+.版本號
在文件系統中,搜索名是一個指向實名的符號鏈接.每一個共享庫也有一個特定的實名,約定以下:
搜索名+.子版本號+.發佈號
你可使用一個特殊的編譯器選項-Wl,option,將option傳給ld,用逗號分隔多個option,
爲了在全部的系統上獲得最好結果,連接libSList到標準C++庫上 .net

[root@LEE src]# g++ -g -shared -Wl,-soname,libSList.so.1 -o libSList.so.1.0.1 SList.o -lstdc++
[root@LEE src]# ls
libSList.so.1.0.1 main.cpp SList.cpp SList.h SList.o htm

libSList.so.1是搜索名,libSList.so.1.0.1是實名,SList.o是目標文件(也能夠是多個目標文件的列表)
,-lstdc++是庫須要訪問的庫(也能夠是庫的列表-llibrary,關於此選項參考附錄.) 對象

3 建立一個從soname連接到庫
[root@LEE src]# ln -fs libSList.so.1.0.1 libSList.so.1
[root@LEE src]# ln -fs libSList.so.1 libSList.so

4 使用-L使連接器在當前目錄中查找庫,而且使用-lSList告訴它要連接哪一個庫
[root@LEE src]# g++ -g -c main.cpp -o main.o
[root@LEE src]# g++ -g -o main main.o -L. -lSList
[root@LEE src]# ls
libSList.so    libSList.so.1.0.1 main.cpp SList.cpp SList.o
libSList.so.1 main               main.o    SList.h blog

5 運行命令
[root@LEE src]# LD_LIBRARY_PATH=$(pwd) ./main  [In the same line]
4->17->19->10->23->21->11->20 get

LD_LIBRARY_PATH
提供用來搜索庫的目錄路徑,以冒號做爲間隔.正常狀況下它不該該被設置,由於系統文件
/ect/ld.so.conf提供了默認的路徑. 編譯器

2、使用連接庫
當運行一個程序時,動態裝載器一般在/ect/ld.so.conf.d目錄查找程序所須要的庫.可是,若是
LD_LIBRARY_PATH 環境變量被設置,它首先掃描在LD_LIBRARY_PATH 中列出的目錄.對於上一節5,若是直接運行
命令 ./main,會出現找不到庫的現象.如:
[root@LEE src]# ./main
./main: error while loading shared libraries: libSList.so.1: cannot open shared object file: No such file or directory io

上述問題的解決方案有兩種(我能想到的):
1 若是LD_LIBRARY_PATH 沒設定:
拷貝libSList.so到目錄 /usr/local/lib (同理也能夠拷到/usr/lib下)
[root@LEE src]# cp libSList.so /usr/local/lib
[root@LEE src]# ldconfig /usr/local/lib
[root@LEE src]# ./main
4->17->19->10->23->21->11->20

2 若是LD_LIBRARY_PATH 設定:
編輯.bash_profile文件
添加LD_LIBRARY_PATH:=$LD_LIBRARY_PATH:/path/to/libSList.so(不包括 libSList.so)
執行.bash_profile 文件.
[root@LEE src]# . /root/.bash_profile
[root@LEE src]# ./main 4->17->19->10->23->21->11->20

相關文章
相關標籤/搜索