編譯靜態鏈接庫
『壹』 如何生成靜態庫和動態庫
靜態庫
靜態庫的後綴是.a,它的產生分兩步
Step 1.由源文件編譯生成一堆.o,每個.o里都包含這個編譯單元的符號表
Step 2.ar命令將很多.o轉換成.a,成為靜態庫
動態庫的後綴是.so,它由gcc加特定參數編譯產生。具體方法參見後文實例。123123
在 GNU/Linux 系統中靜態鏈接文件實際上就是多個 .o 文件的壓縮包。假設我們有 cool.h cool.c 和 some.c 文件,要得到靜態鏈接庫 libcool.a。首先使用如下指令得到相應的 object 文件 cool.o 和 some.o:
gcc -c cool.c
gcc -c some.c1212
用這種方法生成的 object 文件稱為 PDC 即位置相關代碼(position-dependence code)。再使用如下指令可以得到靜態鏈接文件 libcool.a:
ar -r libcool.a cool.o some.o
ranlib libcool.a1212
靜態鏈接庫 libcool.a 遵從 GNU/Linux 規定的靜態鏈接庫命名規范,必須是」libyour_library_name.a」
動態庫
在 GNU/Linux 中動態鏈接文件,必需通過鏈接器 ld 生成。假設我們有 hot.c other.c 等文件要生成動態鏈接庫 libhot.so 。首先使用如下指令得到相應的 object 文件 hot.o 和 some.o
gcc -fPIC -c hot.c
gcc -fPIC -c other.c1212
參數 -fPIC 指定生成的 object 文件為位置無關代碼(position-independence code),只有 PIC 可以被用作生成動態鏈接庫。然後使用如下指令得到動態庫:
ld -Bshared -o libhot.so hot.o other.o11
或者可以使用編譯器的ld wrapper:
gcc -shared -o libhot.so hot.o other.o11
也可以使用編譯器直接生成動態庫:
gcc -fPIC -shared -o libhot.so hot.c other.c11
這里選項 -shared 指示目標文件的類型是動態鏈接庫,動態庫的命名規范是」libyour_library_name.so」
『貳』 編譯時為什麼要指定鏈接庫
因為有些運行時代碼,是預先存在「鏈接庫」里的。沒有這些庫,程序無法運行。所以編譯時需要指定。
「鏈接庫」分動態和靜態兩種。靜態的庫,編譯時就把相應的代碼「嵌入」可執行文件中。這種可執行文件可以單獨運行,基本不需要「運行時間庫」支持。
而對於動態的庫,編譯時只獲取必要的介面信息,而在運行時根據介面信息,找到對應的動態鏈接庫,並裝入內存。這種可執行文件的大小會小一些。但是需要「運行時間庫」才能正常運行。
有問題繼續交流,謝謝。
『叄』 OpenCV靜態庫編譯與鏈接
以OpenCV-4.0.0為例說明在Ubuntu環境下的靜態庫編譯與鏈接方法:
opencv依賴第三方的庫,所以當把opencv編譯成靜態庫的時候,注意要把它運行時必要的依賴庫也編譯進來,opencv源碼內有自己的3rdparty,主要有:libjpeg、libpng、libtiff、libzlib、libwebp、libprotobuf、ffmpeg(用到video時編譯)、libgtk(用於顯示界面顯示,伺服器部署不會用到),可以通過cmake -LA來查看配置的編譯信息,再根據信息考慮把opencv的哪些mole編譯進來。
鏈接時指定opencv的靜態庫以及依賴的庫。另外需要注意頭文件的問題,通過CMakeLists把opencv加入項目編譯時,由於opencv編譯完成後要install才會把所用的頭文件集中拷貝到一個地方,所以事先將頭文件拷貝到了項目的opencv目錄下。
『肆』 為什麼要把SNMP++開發包編譯為靜態鏈接庫文件
靜態編譯:就是在編譯可執行文件的時候,將可執行文件需要調用的對應動態鏈接庫(.so)中的部分提取出來,鏈接到可執行文件中去,使可執行文件在運行的時候不依賴動態鏈接庫。
編譯方式:
第1種:
設置:
1、項目->配置屬性->常規->MFC的使用:在靜態庫中使用MFC
2、項目 -> 配置屬性->C/C++->代碼生成->運行庫 :選擇 多線程調試(/MTd)。
編譯時,選擇的是debug,win32
然後執行編譯生成方案,在該工程目錄下的debug文件中,找到該.exe文件,即可在其他電腦運行。
第2種:
一般可以配置一下兩項:
1.項目 -> 配置屬性->常規->MFC的使用 :在靜態庫中使用MFC。
2.項目 -> 配置屬性->C/C++->代碼生成->運行庫 :選擇 多線程調試(/MT)。
編譯時,選擇的是release,win32(這個選擇項在工具欄的debug選框中,一般我們使用debug方式)
『伍』 如何編譯C/Fortran動態/靜態鏈接庫
首先,傳統的編譯,也就是靜態編譯是把 源文件 翻譯成目標文件,這個是一次性過程,也就是你所謂的靜態編譯。
後來的Java和.NET等語言,首先編譯成中間形式,然後運行過程中根據需要編譯成本地代碼(注意這個過程不是一次性的,下次運行重新編譯),這個就是JIT(即時編譯)技術,從即時編譯發展出了動態編譯技術
————————————
(傳統的)編譯完成後,像C/C++、Fortran、匯編等語言,可以把多個目標文件合並到一個庫文件中,這個就是靜態庫。比如常說的庫函數printf就是libc裡面的函數。
如果有了啟動函數(main),main裡面使用了printf,就可以通過靜態鏈接技術,從libc中提取出printf所在的文件加入到可執行文件中,如果printf還需要其它函數,就繼續搜索並加入列表,直到形成一個閉包。這個就是靜態鏈接。
可是靜態鏈接有個明顯的缺點,如果每個程序都需要printf,那麼printf這個函數的代碼就會同時存在在每個程序中,這樣也太佔地方了吧。所以發明了動態連接技術,其實有兩種形式。無論哪一種,都是首先記錄下需要調用printf這個函數以及所在的動態庫,等到運行的時候再載入動態庫,從動態庫中找到真正的printf去執行。
由於,動態鏈接技術需要一些額外的信息,傳統的靜態庫是不具備的,這些額外信息主要是重復載入和卸載時所需要的一些代碼,因此需要動態鏈接庫。
『陸』 Linux編譯靜態鏈接庫出現如圖錯誤,求救!
1.
只表明
庫文件
路徑,未說明庫文件名稱。選項再加一條
-l
count
2.
庫文件命名錯誤,應該為"libxxx.a"(靜態庫),此處名稱應為libcount.a
3.
重要:記得不清了,可能我上面說的都是錯的!!!