A. linux杞浠跺紑鍙戞椂緇檊cc鎸囧畾澶存枃浠跺拰搴撴枃浠惰礬寰勭殑鏂規硶
鍦↙inux 涓嬪紑鍙戣蔣浠舵椂錛屽畬鍏ㄤ笉浣跨敤絎涓夋柟鍑芥暟搴撶殑鎯呭喌鏄姣旇緝灝戣佺殑錛岄氬父鏉ヨ查兘闇瑕佸熷姪涓涓鎴栧氫釜鍑芥暟搴撶殑鏀鎸佹墠鑳藉熷畬鎴愮浉搴旂殑鍔熻兘銆備粠紼嬪簭鍛樼殑瑙掑害鐪嬶紝鍑芥暟搴撳疄 闄呬笂灝辨槸涓浜涘ご鏂囦歡錛.h錛夊拰搴撴枃浠訛紙.so鎴栬.a錛夌殑闆嗗悎銆傝櫧鐒禠inux涓嬬殑澶у氭暟鍑芥暟閮介粯璁ゅ皢澶存枃浠舵斁鍒/usr/include/鐩褰曚笅錛岃屽簱 鏂囦歡鍒欐斁鍒/usr/lib/鐩褰曚笅錛屼絾騫朵笉鏄鎵鏈夌殑鎯呭喌閮芥槸榪欐牱銆傛e洜濡傛わ紝GCC鍦ㄧ紪璇戞椂蹇呴』鏈夎嚜宸辯殑鍔炴硶鏉ユ煡鎵炬墍闇瑕佺殑澶存枃浠跺拰搴撴枃浠躲
GCC閲囩敤鎼滅儲鐩褰曠殑鍔炴硶鏉ユ煡鎵炬墍闇瑕佺殑鏂囦歡錛-I 閫夐」鍙浠ュ悜GCC鐨勫ご鏂囦歡鎼滅儲璺寰勪腑娣誨姞鏂扮殑鐩褰曘備緥濡傦紝濡傛灉鍦/home/xiaowp/include/鐩褰曚笅鏈夌紪璇戞椂鎵闇瑕佺殑澶存枃浠訛紝涓轟簡璁〨CC鑳藉熼『鍒╁湴鎵懼埌瀹冧滑錛屽氨鍙浠ヤ嬌鐢-I閫夐」
鍚屾牱錛屽傛灉浣跨敤浜嗕笉鍦ㄦ爣鍑嗕綅緗鐨勫簱鏂囦歡錛岄偅涔堝彲浠ラ氳繃-L閫夐」鍚慓CC鐨勫簱鏂囦歡鎼滅儲璺寰勪腑娣誨姞鏂扮殑鐩褰曘備緥濡傦紝濡傛灉鍦/home/xiaowp/lib/鐩褰曚笅鏈夐摼鎺ユ椂鎵闇瑕佺殑搴撴枃浠秎ibfoo.so錛屼負浜嗚〨CC鑳藉熼『鍒╁湴鎵懼埌瀹冿紝鍙浠ヤ嬌鐢ㄤ笅闈㈢殑鍛戒護錛
鍊煎緱濂藉ソ瑙i噴涓涓嬬殑鏄-l閫夐」錛屽畠鎸囩ずGCC鍘昏繛鎺ュ簱鏂囦歡libfoo.so銆侺inux涓 鐨勫簱鏂囦歡鍦ㄥ懡鍚嶆椂鏈変竴涓綰﹀畾錛岄偅灝辨槸搴旇ヤ互lib涓変釜瀛楁瘝寮澶達紝鐢變簬鎵鏈夌殑搴撴枃浠墮兘閬靛驚浜嗗悓鏍風殑瑙勮寖錛屽洜姝ゅ湪鐢-l閫夐」鎸囧畾閾炬帴鐨勫簱鏂囦歡鍚嶆椂鍙浠ョ渷鍘 lib涓変釜瀛楁瘝錛屼篃灝辨槸璇碐CC鍦ㄥ-lfoo榪涜屽勭悊鏃訛紝浼氳嚜鍔ㄥ幓閾炬帴鍚嶄負libfoo.so鐨勬枃浠躲
Linux涓嬬殑搴撴枃浠跺垎涓轟袱澶х被鍒嗗埆鏄鍔ㄦ侀摼鎺ュ簱錛堥氬父浠.so緇撳熬錛夊拰闈欐侀摼 鎺ュ簱錛堥氬父浠.a緇撳熬錛夛紝涓よ呯殑宸鍒浠呭湪紼嬪簭鎵ц屾椂鎵闇鐨勪唬鐮佹槸鍦ㄨ繍琛屾椂鍔ㄦ佸姞杞界殑錛岃繕鏄鍦ㄧ紪璇戞椂闈欐佸姞杞界殑銆傞粯璁ゆ儏鍐典笅錛孏CC鍦ㄩ摼鎺ユ椂浼樺厛浣跨敤鍔ㄦ侀摼 鎺ュ簱錛屽彧鏈夊綋鍔ㄦ侀摼鎺ュ簱涓嶅瓨鍦ㄦ椂鎵嶈冭檻浣跨敤闈欐侀摼鎺ュ簱錛屽傛灉闇瑕佺殑璇濆彲浠ュ湪緙栬瘧鏃跺姞涓-static閫夐」錛屽己鍒朵嬌鐢ㄩ潤鎬侀摼鎺ュ簱銆備緥濡傦紝濡傛灉鍦 /home/xiaowp/lib/鐩褰曚笅鏈夐摼鎺ユ椂鎵闇瑕佺殑搴撴枃浠秎ibfoo.so鍜宭ibfoo.a錛屼負浜嗚 GCC鍦ㄩ摼鎺ユ椂鍙鐢ㄥ埌闈欐侀摼鎺ュ簱錛屽彲浠ヤ嬌鐢ㄤ笅闈㈢殑鍛戒護錛
澶嶅埗浠g爜
浠g爜濡備笅:
# gcc foo.c -L /home/xiaowp/lib -static -lfoo -o foo
B. linux 編譯怎麼連接動態庫
Linux的動態庫文件是以lib字樣開頭的.so文件,編譯鏈接動態庫有兩個要點:一個是需要用-L選項指定動態庫的搜索路徑,這個搜索路徑是需要連接的so文件的大致路徑,比如/usr/openssl/lib;另外還需要用-l(這個是小寫的L)選項指定動態庫的名字,比如下面這條編譯命令:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto
C. 關於linux下連接動態庫問題
gcc編譯時,當使用動態庫編譯可以按照幾種寫法
1.gcc test.c ./libSDL2-2.so
2.gcc test.c -lSDL2-2
3.gcc test.c -L/home/test -lSDL2-2
一般的編譯參數都是按照2或3去寫
2寫法的含義是從/lib或者/usr/lib目錄下尋找名稱為SDL2-2的庫,即尋找/lib/libSDL2-2.so或者/usr/lib/libSDL2-2.so文件進行鏈接,當然如果沒有動態庫就會去找靜態庫,再沒有應該就會在編譯時報錯
3寫法的含義是從-L參數首先從指定的目錄中尋找需要鏈接的庫文件,隨後再去尋找系統文件夾中是否存在需要的庫
1寫法的含義是將當前目錄下的./libSDL2-2.so.0文件鏈接進最終文件,因此執行readelf -a a.out後在動態庫部分所看到的路徑就是./libSDL2-2.so.0,進而在執行文件時僅會從當前目錄下尋找libSDL2-2.so.0文件,當執行文件時所在的目錄下沒有該文件時就會出現找不到庫文件的操作
你第二次操作時,因為function.so庫文件與a.out文件在同一個目錄,同時也是在該目錄下執行的ldd操作及運行a.out,a.out在載入動態庫時從當前目錄下找到了所需要的庫文件,此時能夠執行成功(ldd命令實質是一個腳本,通過設置環境變數運行動態庫鏈接器來輸出所有待鏈接的動態庫)。
你可以試試將a.out拷貝至其他目錄再次運行,將出現和第一次操作時一樣的現象,找不到function.so文件。
具體的解決方法就是修改編譯參數,將./libSDL2-2.so.0修改為-lSDL2-2並將libSDL2-2.so.0文件拷貝至/usr/lib目錄下,並且可能因為沒有修改鏈接器的緩存文件(將可能找不到帶版本號後綴的動態庫),需要在/usr/lib目錄下建立一個文件連接(ln -s libSDL2-2.so.0 libSDL2-2.so)或者直接修改名稱為libSDL2-2.so
D. linux怎樣實現c語言動態庫與靜態庫的鏈接
Linux系統中靜態庫是.a文件,編譯鏈接.a文件只需要加上.a文件的完整的文件路徑就可以了,比如:
gcc -o hello hello.c /usr/lib/libm.a
Linux系統的動態庫是系統中的.so文件,編譯鏈接動態庫需要用-L參數指定動態庫的搜索路徑,還要用-l(這個是小寫的L)指定動態庫的名字,比如:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto
E. 請問我有一個.so文件,如何在Linux下編程使用呢
-lxx
xx是你的.so文件名
其實使用方法和你使用數學庫函數是一樣的,源代碼中添加
#include <math.h>,編譯的時候,加上-lm參數。
註:linux下的.so文件為共享庫,相當於windows下的dll文件。
linux下編寫調用so文件實例
.so是Linux(Unix)下的動態鏈接庫. 和.dll類似.
比如:
文件有: a.c, b.c, c.c
gcc -c a.c
gcc -c b.c
gcc -c c.c
gcc -shared libXXX.so a.o b.o c.o
要使用的話也很簡單. 比如編譯d.c, 使用到libXXX.so中的函數, libXXX.so地址是MYPATH
gcc d.c -o d -LMYPATH -lXXX
注意不是-llibXXX
test.c文件和一個test.h,這兩個文件要生成libsotest.so文件。然後我還有一個testso.c文件,在這個文件裡面調用libsotest.so中的函數。
編寫的過程中,首先是編譯so文件,我沒有編寫makefile文件,而是參考的2裡面說的直接寫的gcc命令。
因為so文件裡面沒有main函數,所以是不可執行的,所以編譯的時候要加上-c,只生成目標文件。
F. (linux)動態鏈接庫找不到路徑
ld.so.conf只是在編譯時查找動態庫的路徑;
運行時動態庫的查找路徑默認在/usr/lib和/lib,所以找不到
可以設置LD_LIBRARY_PATH=/usr/local/ma(你動態庫的所在目錄)
或者把動態庫拷貝到/usr/lib或/lib下
G. 如何指定gcc的默認頭文件路徑
gcc指定頭文件路徑及動態鏈接庫路徑
本文詳細介紹了Linux 下gcc頭文件指定方法,以及搜索路徑順序的問題。另外,還總結了,gcc動態鏈接的方法以及路徑指定,同樣也討論了搜索路徑的順序問題。本文包含了很多的例子,具有很強的操作性,希望讀者自己去走一遍。
一.#include <>與#include 「」
#include <>直接到系統指定的某些目錄中去找某些頭文件。
#include 「」先到源文件所在文件夾去找,然後再到系統指定的某些目錄中去找某些頭文件。
二.gcc指定頭文件的三種情況:
1.會在默認情況下指定到/usr/include文件夾(更深層次的是一個相對路徑,gcc可執行程序的路徑是/usr/bin/gcc,那麼它在實際工作時指定頭文件頭徑是一種相對路徑方法,換算成絕對路徑就是加上/usr/include,如#include 就是包含/usr/include/stdio.h)
2.GCC還使用了-I指定路徑的方式,即
gcc -I 頭文件所在文件夾(絕對路徑或相對路徑均可) 源文件
舉一個例子:
設當前路徑為/root/test,其結構如下:
include_test.c
include/include_test.h
有兩種方法訪問到include_test.h。
1. include_test.c中#include 「include/include_test.h」然後gcc include_test.c即可
2. include_test.c中#include 或者#include 然後gcc –I include include_test.c也可
3. 參數:-nostdinc使編譯器不再系統預設的頭文件目錄裡面找頭文件,一般和-I聯合使用,明確限定頭文件的位置。
在編譯驅動模塊時,由於非凡的需求必須強制GCC不搜索系統默認路徑,也就是不搜索/usr/include要用參數-nostdinc,還要自己用-I參數來指定內核頭文件路徑,這個時候必須在Makefile中指定。
頭文件搜索順序:
1.由參數-I指定的路徑(指定路徑有多個路徑時,按指定路徑的順序搜索)
2.然後找gcc的環境變數 C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJC_INCLUDE_PATH
3.再找內定目錄
/usr/include
/usr/local/include
/usr/lib/gcc-lib/i386-linux/2.95.2/include
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g++-3
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include
庫文件,但是如果裝gcc的時候,是有給定的prefix的話,那麼就是
/usr/include
prefix/include
prefix/xxx-xxx-xxx-gnulibc/include
prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include
三.Linux指定動態庫路徑
眾所周知,Linux動態庫的默認搜索路徑是/lib和/usr/lib。動態庫被創建後,一般都復制到這兩個目錄中。當程序執行時需要某動態庫, 並且該動態庫還未載入到內存中,則系統會自動到這兩個默認搜索路徑中去查找相應的動態庫文件,然後載入該文件到內存中,這樣程序就可以使用該動態庫中的函 數,以及該動態庫的其它資源了。在Linux 中,動態庫的搜索路徑除了默認的搜索路徑外,還可以通過以下三種方法來指定。
1.在配置文件/etc/ld.so.conf中指定動態庫搜索路徑。
可以通過編輯配置文件/etc/ld.so.conf來指定動態庫的搜索路徑,該文件中每行為一個動態庫搜索路徑。每次編輯完該文件後,都必須運行命令ldconfig使修改後的配置生效。
舉一個例子:
所有源文件:
源文件1: lib_test.c
#include
void prt()
{
printf(「You found me!!!/n」);
}
源文件2: main.c
void prt();
int main()
{
prt();
return 0;
}
H. GCC中靜態連接和動態連接的區別
gcc中靜態連接和動態鏈接的方法:
1:GCC的靜態連接,直接把靜態庫的名字放在gcc後面
例如:gcc-otesttest.cstaticlib.a
2:GCC的動態連接,使用-l指定庫,-L指定庫的路徑,注意動態庫名必須是lib開頭,後綴名為.so
例如:gcc-otesttest.c-lpthread-L/usr/lib/
3:靜態庫也可以採用動態庫的連接方法,如果目錄中同時存在2種庫,gcc會優先選擇動態庫。如果一條gcc鏈接指令中既要鏈接動態庫又要鏈接靜態庫,可以用-Wl,-dn和-Wl,-dy參數選項來切換。
靜態連接和動態鏈接的主要區別:
1:靜態連接的時候,靜態庫的所有執行代碼被直接編譯到目標程序中。而動態連接的時候,僅僅把動態庫的函數和變數的符號名,地址偏移量等導入到目標程序。只有在目標程序運行的時候才把動態庫的執行代碼載入到內存中。
2:動態鏈接的項目容易管理,把不同模塊封裝成不同的動態庫,如果模塊功能修改,一般只需要重新生成該動態庫,不用重新編譯其他模塊和目標程序。而靜態鏈接的程序修改任何一個地方都必須重新編譯整個程序
3:靜態鏈接生成的目標程序體積比動態鏈接的大,但是載入速度更快,發布更容易,不需要檢查發布機器上是否有該動態庫或者動態庫版本是否符合要求。
4:如果多個程序使用一個動態庫,則該庫的執行代碼只會在內存中載入一次。而靜態庫是多次載入(事實上靜態庫連接完就沒用了,等於目標程序的一部分)。
5:從調試的角度來說,靜態連接的程序調試方法和獨立程序沒有任何區別,而動態庫的調試相對要復雜一些,因為庫裡面的符號地址都是相對地址。