1. 程式人生 > >自己在linux上編譯、連結、動態庫和靜態庫的學習筆記

自己在linux上編譯、連結、動態庫和靜態庫的學習筆記

在平常的專案中,我們都是使用公司要求的makefile、makedebug一類的檔案,因此,在編譯、連結、生成和連結動態庫與靜態庫的時候,我們只是簡單的使用一些已經設定的變數,只是簡單的修改、新增一些檔名,或許這次我們編譯通過了,但是,在某一個時候,可能出現了一個問題,無論簡單與否,因為平常沒有留意,導致的結果可能是花了好長時間才能解決。而如果平常只是簡單的留一下心,或許這些問題都是可以避免的。
因此,今天我自己使用幾個檔案,編譯動態庫、靜態庫以及動態庫和靜態庫的巢狀呼叫等問題,儘量還原我在專案中遇到的問題,儘量讓自己明白平常沒有意識到的一些東西。


需要用到的檔案列表,如下:
/****showcoor.cpp****/
#include "showcoor.h"
//顯示某一座標
int showcoor(int x)
{
        cout<<"coordinate:"<<x<<endl;
        return 0;
}


/****showcoor.h****/
#include <iostream>
using namespace std;


int showcoor(int x);




/****showpoint.cpp****/
#include "showpoint.h"
//顯示點座標
int showpoint(int x,int y,int z)
{
        showcoor(x);
        showcoor(y);
        showcoor(z);
        return 0;
}


/****showpoint.h****/
#include "showcoor.h"
int showpoint(int x,int y,int z);


/****main.cpp****/
#include "showpoint.h"
int main()
{
        showpoint(1,2,3);
        return 0;
}




1、編譯生成可執行檔案
我們在單獨編譯的時候,只需要檢查標頭檔案,因為都放到了一個目錄,所以單獨編譯的時候,不需要依賴其他檔案,就可以生成目標檔案(*.o),如下:
g++ -c showcoor.cpp
g++ -c showpoint.cpp
g++ -c main.cpp



編譯完成之後,就生成了對應的目標檔案,如下:
[[email protected]]:/account/work/ymm/test/library/nest_call>ls *.o
main.o  showcoor.o  showpoint.o
[[email protected]]:/account/work/ymm/test/library/nest_call>



編譯的時候,沒有新增依賴的標頭檔案,是因為預設編譯的時候,在當前目錄下去找。


小測試1:
如果我們把showpoint.cpp單獨移動到一個目錄下,再去編譯一下。
[[email protected]]:/account/work/ymm/test/library/nest_call>mkdir temp
[[email protected]]:/account/work/ymm/test/library/nest_call>cp showpoint.cpp showpoint.h ./temp
[[email protected]]:/account/work/ymm/test/library/nest_call>cd ./temp
[
[email protected]
]:/account/work/ymm/test/library/nest_call>ls showpoint.cpp [[email protected]]:/account/work/ymm/test/library/nest_call/temp>g++ -c showpoint.cpp In file included from showpoint.cpp:1: showpoint.h:1:22: error: showcoor.h: No such file or directory showpoint.cpp: In function 'int showpoint(int, int, int)': showpoint.cpp:4: error: 'showcoor' was not declared in this scope



通過上面可以確定的是,在編譯的時候,因為標頭檔案裡包含了其他標頭檔案“showcoor.h”,而該標頭檔案不在當前目錄,而且不在系統指定的目錄,因此,才會提示找不到標頭檔案的錯誤。這個時候,我們就需要手動的指定標頭檔案所在的目錄,使用“-I路徑”
[[email protected]]:/account/work/ymm/test/library/nest_call/temp>g++ -I../ -c showpoint.cpp
[[email protected]]:/account/work/ymm/test/library/nest_call/temp>ls
showpoint.cpp  showpoint.h  showpoint.o






通過生成的目標檔案,最後進行連結,就可以生成最終的可執行檔案。
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -o main main.o showpoint.o showcoor.o
[[email protected]]:/account/work/ymm/test/library/nest_call>./main
coordinate:1
coordinate:2
coordinate:3




通過最後的連結,我們還可以看到函式的依賴關係。


小測試2:
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -o main main.o showpoint.o           
showpoint.o: In function `showpoint(int, int, int)':
showpoint.cpp:(.text+0x17): undefined reference to `showcoor(int)'
showpoint.cpp:(.text+0x21): undefined reference to `showcoor(int)'
showpoint.cpp:(.text+0x2b): undefined reference to `showcoor(int)'
collect2: ld returned 1 exit status



因為showpoint.cpp會呼叫`showcoor(int)'函式,因此,缺少“showcoor.o”檔案時,連結的時候,就會提示找不到該函式。


小測試3:
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -o main main.o showcoor.o            
main.o: In function `main':
main.cpp:(.text+0x14): undefined reference to `showpoint(int, int, int)'
collect2: ld returned 1 exit status



因為main.cpp會首先呼叫`showpoint(int, int, int)'函式,因此缺少“showpoint.o”檔案時,連結的時候,就會提示找不到“showpoint”函式。


小測試3:
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -o main showpoint.o showcoor.o        
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
[[email protected]]:/account/work/ymm/test/library/nest_call>



很明顯,因為找不到“main”函式,無法生成最終的可執行檔案。


2、生成靜態庫
靜態函式庫:
這類庫的名字一般是libxxx.a;利用靜態函式庫編譯成的檔案比較大,因為整個函式庫的所有資料都會被整合進目的碼中,他的優點就顯而易見了,即編譯後的執行程式不需要外部的函式庫支援,因為所有使用的函式都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函式庫改變了,那麼你的程式必須重新編譯。
擴充套件閱讀: http://tech.ccidnet.com/art/2583/20080303/1378433_1.html  


生成靜態庫需要使用“ar -cr”
c   Create the archive,也就是建立靜態庫
r   Insert the files member... into archive (with replacement),也就是沒有生成,有的話替換。


[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -c showcoor.cpp             
[[email protected]]:/account/work/ymm/test/library/nest_call>ar -cr libshowcoor.a showcoor.o 
[[email protected]]:/account/work/ymm/test/library/nest_call>ls *.a    
libshowcoor.a



當然,我們還可以直接通過“.cpp”檔案直接生成靜態庫。如下:
[[email protected]]:/account/work/ymm/test/library/nest_call>ar -cr libshowcoor.a showcoor.cpp
[[email protected]]:/account/work/ymm/test/library/nest_call>ls *.a           
libshowcoor.a




3、動態庫
動態函式庫:
這類庫的名字一般是libxxx.so;相對於靜態函式庫,動態函式庫在編譯的時候並沒有被編譯進目的碼中,你的程式執行到相關函式時才呼叫該函式庫裡的相應函式,因此動態函式庫所產生的可執行檔案比較小。由於函式庫沒有被整合進你的程式,而是程式執行時動態的申請並呼叫,所以程式的執行環境中必須提供相應的庫。動態函式庫的改變並不影響你的程式,所以動態函式庫的升級比較方便。
擴充套件閱讀: http://tech.ccidnet.com/art/2583/20080303/1378433_1.html 


生成動態庫的方式是:g++ -shared -fPCI -o libXXX.so *.o 
-fpic 使輸出的物件模組是按照可重定位地址方式生成的。
-shared指定把對應的原始檔生成對應的動態連結庫檔案。
下面是對於-fpic的詳細解釋:
在 Linux 下製作動態連結庫,“標準” 的做法是編譯成位置無關程式碼(Position Independent Code,PIC),然後連結成一個動態連結庫。
擴充套件閱讀: http://www.linuxidc.com/Linux/2011-06/37268.htm 


[[email protected]]:/account/work/ymm/test/library/nest_call>gcc -shared -fPIC -o libshowpoint.so showpoint.cpp
[[email protected]]:/account/work/ymm/test/library/nest_call>ls *.so
libshowpoint.so



上述方法是通過.cpp檔案直接生成動態庫。其實,也可以通過.o檔案生成動態庫,如下:
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -c showpoint.cpp
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -shared -fPIC -o libshowpoint.so showpoint.o  
/usr/bin/ld: showpoint.o: relocation R_X86_64_32 against `.bss' can not be used when making a shared object; recompile with -fPIC
showpoint.o: could not read symbols: Bad value
collect2: ld returned 1 exit status



上面錯誤產生的原因就是因為引數“-fPIC”的原因,因為最終生成該動態庫的時候,使用了引數“-fPIC”,表示生成的動態庫是“位置無關程式碼”,而在生成“showpoint.o”的時候,是位置相關性的,所以,錯誤資訊也提示了,讓使用“-fPIC”重新編譯(recompile with -fPIC)。
[[email protected]]:/account/work/ymm/test/library/nest_callg++ -fPIC -c showpoint.cpp                      
[[email protected]]:/account/work/ymm/test/library/nest_callg++ -shared -fPIC -o libshowpoint.so showpoint.op              
[[email protected]]:/account/work/ymm/test/library/nest_call>ls *.so
libshowpoint.so




測試4:
當然,我們通過上述方式,只是把函式“showpoint”函式封裝成了,如果我們在main函式只調用“libshowpoint.so”的話,會出現問題的,如下:
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ main.cpp -L./ -lshowpoint
.//libshowpoint.so: undefined reference to `showcoor(int)'
collect2: ld returned 1 exit status

注:-L後面跟的是要連線的庫的路徑


-l庫名,動態庫的命名為libXXX.so的話,就可以使用-lXXX的方式引用該庫,如果是靜態庫,並且命名為libXXX.a,則同樣可以使用lXXX的方式引用該庫。
這個時候,我們還需要使用函式“showcoor”所在的庫,因此,我們有必要把函式“showcoor”也封裝到動態庫中。
當然,我們在最後生成可執行檔案的時候,也可以連結同時連結生成的動態庫和靜態庫,如下:
[[email protected] nest_call]$ g++ -o main main.cpp -L./ -lshowpoint -lshowcoor
[[email protected] nest_call]$ ./main
coordinate:1
coordinate:2
coordinate:3



我們可以看到,呼叫動態庫和靜態庫的方式是一樣的,都是“-L路徑 -l庫名”。


4、庫的巢狀呼叫
既然我們已經把函式“showcoor”封裝成了靜態庫,因此我們完全可以通過使用靜態庫“libshowcoor.a”來生成我們最終的動態庫“libshowpoint.so”,因為靜態庫可以理解成是“目標檔案(*.o)的打包”。


測試5:動態庫呼叫靜態庫
我們通過已有的靜態庫生成最終的動態庫
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -fPIC -c showpoint.cpp
[[email protected]]:/account/work/ymm/test/library/nest_call>gcc -shared -fPIC -o libshowpoint.so showpoint.o  -L./ -lshowcoor
/usr/bin/ld: .//libshowcoor.a(showcoor.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
.//libshowcoor.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
[[email protected]]:/account/work/ymm/test/library/nest_call>



上述錯誤提示和原來的沒有新增“-fPIC”生成的“*.o”檔案生成動態庫出現的錯誤相同,而且也給給出瞭解決方法,靜態庫的生成重新使用“-fPIC”進行編譯。
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -fPIC -c showcoor.cpp
[[email protected]]:/account/work/ymm/test/library/nest_call>ar -cr libshowcoor.a showcoor.o
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -fPIC -c showpoint.cpp          
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -shared -fPIC -o libshowpoint.so showpoint.o -L./ -lshowcoor
[[email protected]]:/account/work/ymm/test/library/nest_call>ls *.so
libshowpoint.so



這樣最終生成的動態庫,就同時包含“showpoint”函式和“showoccr”函式,呼叫如下:
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ main.cpp -L./ -lshowpoint
[[email protected]]:/account/work/ymm/test/library/nest_call>./main
coordinate:1
coordinate:2
coordinate:3




5、使用靜態庫呼叫的順序問題
如果生成了多個動態庫,我們的呼叫順序對最終生成的檔案沒有影響,測試如下:
[[email protected] nest_call]$ g++ -fPIC -c showpoint.cpp
[[email protected] nest_call]$ g++ -shared -fPIC -o libshowpoint.so showpoint.o
[[email protected] nest_call]$ g++ -fPIC -c showcoor.cpp
[[email protected] nest_call]$ g++ -shared -fPIC -o libshowcoor.so showcoor.o
[[email protected] nest_call]$ ls *.so
libshowcoor.so  libshowpoint.so
[[email protected] nest_call]$ g++ -o main main.cpp -L./ -lshowcoor -lshowpoint
[[email protected] nest_call]$ ./main
coordinate:1
coordinate:2
coordinate:3


[[email protected] nest_call]$ g++ -o main main.cpp -L./ -lshowpoint -lshowcoor
[[email protected] nest_call]$ ./main
coordinate:1
coordinate:2
coordinate:3



但是,如果我們使用了靜態庫,呼叫順序就有影響了,否則的話,編譯的時候會因為找不到函式而出錯。


測試6:
[[email protected] nest_call]$ g++ -c showcoor.cpp
[[email protected] nest_call]$ ar -cr libshowcoor.a showcoor.o  
[[email protected] nest_call]$ g++ -c showpoint.cpp
[[email protected] nest_call]$ ar -cr libshowpoint.a showpoint.o  
[[email protected] nest_call]$ ls *.a
libshowcoor.a  libshowpoint.a
[[email protected] nest_call]$ g++ -o main main.cpp -L./ -lshowpoint -lshowcoor
[[email protected] nest_call]$ ./main
coordinate:1
coordinate:2
coordinate:3




調整靜態庫的呼叫順序:
[[email protected] nest_call]$g++ -o main main.cpp -L./ -lshowcoor -lshowpoint
.//libshowpoint.a(showpoint.o): In function `showpoint(int, int, int)':
showpoint.cpp:(.text+0x17): undefined reference to `showcoor(int)'
showpoint.cpp:(.text+0x21): undefined reference to `showcoor(int)'
showpoint.cpp:(.text+0x2b): undefined reference to `showcoor(int)'
collect2: ld returned 1 exit status



通過上面,我們可以知道,被呼叫的庫應該放到呼叫庫的後面。因為函式“showpoint”中呼叫了函式“showcoor”,因此,函式“showcoor”對應的庫應該放到後面才行。
因此,如果遇到了程式需要呼叫A庫,而A庫呼叫B庫,那麼我們應該寫成“g++ -o main main.cpp -L./ -libA.so -libB.so”,也就是網上所說的,呼叫靜態庫的時候,於是基礎的庫,越是放到最後。


6、庫內部函式的檢視
nm用來列出目標檔案的符號清單。
擴充套件閱讀: http://www.linuxidc.com/Linux/2011-05/35777.htm 
nm 命令使用以下符號(用同樣的字元表示弱符號作為全域性符號)之一來表示檔案符號型別:
A    Global absolute 符號。
a    Local absolute 符號。
B    Global bss 符號。
b    Local bss 符號。
D    Global data 符號。
d    Local data 符號。
f    原始檔名稱符號。
T    Global text 符號。
t    Local text 符號。
U    未定義符號。
擴充套件閱讀: http://blog.chinaunix.net/uid-28458801-id-3475711.html 


上述包含“showcoor”函式和“showpoint”函式時生成的動態庫,檢視內部函式:
[[email protected]]:/account/work/ymm/test/library/nest_call>nm -C libshowpoint.so |grep show
0000000000000a5f t global constructors keyed to showcoor.cpp
00000000000009ba t global constructors keyed to showpoint.cpp
00000000000009d0 T showcoor(int)
000000000000093c T showpoint(int, int, int)



如果採用只封裝“showpoint”函式的方式生成的動態庫,檢視內部函式:
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -fPIC -c showpoint.cpp
[[email protected]]:/account/work/ymm/test/library/nest_call>gcc -shared -fPIC -o libshowpoint.so showpoint.o  
[[email protected]]:/account/work/ymm/test/library/nest_call>nm -C libshowpoint.so |grep show
000000000000076a t global constructors keyed to showpoint.cpp
                 U showcoor(int)
00000000000006ec T showpoint(int, int, int)



我們可以看到,這個時候,雖然在“showpoint”函式中呼叫“showcoor”函式,但是該函式在庫中並未定義,所以型別是“U”。


7、庫依賴關係的檢視
ldd命令用於判斷某個可執行的 binary 檔案含有什麼動態函式庫。
但是ldd本身不是一個程式,而僅是一個shell指令碼:
$ which ldd
/usr/bin/ldd
$ file /usr/bin/ldd 
/usr/bin/ldd: Bourne-Again shell script text executable
擴充套件閱讀: http://blog.chinaunix.net/uid-23622436-id-3235778.html 


使用上述包含“showcoor”函式和“showpoint”函式時生成的動態庫,生成可執行檔案,檢視依賴庫:
[[email protected]]:/account/work/ymm/test/library/nest_call>gcc -shared -fPIC -o libshowpoint.so showpoint.cpp showcoor.cpp
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -o main main.cpp -L./ -lshowpoint
[[email protected]]:/account/work/ymm/test/library/nest_call>./main  
coordinate:1
coordinate:2
coordinate:3
[[email protected]]:/account/work/ymm/test/library/nest_call>ldd main |grep show
        libshowpoint.so => /account/work/ymm/test/library/nest_call/libshowpoint.so (0x00002ba77c1ad000)
[[email protected]]:/account/work/ymm/test/library/nest_call>



如果兩個函式分別生成一個動態庫的話,檢視依賴庫:    
[[email protected]]:/account/work/ymm/test/library/nest_call>gcc -shared -fPIC -o libshowpoint.so showpoint.cpp
[[email protected]]:/account/work/ymm/test/library/nest_call>gcc -shared -fPIC -o libshowcoor.so showcoor.cpp  
[[email protected]]:/account/work/ymm/test/library/nest_call>ls *.so
libshowcoor.so  libshowpoint.so
[[email protected]]:/account/work/ymm/test/library/nest_call>g++ -o main main.cpp -L./ -lshowpoint -lshowcoor
[[email protected]]:/account/work/ymm/test/library/nest_call>./main  
coordinate:1
coordinate:2
coordinate:3
[[email protected]]:/account/work/ymm/test/library/nest_call>ldd main|grep show
        libshowpoint.so => /account/work/ymm/test/library/nest_call/libshowpoint.so (0x00002abf7504a000)
        libshowcoor.so => /account/work/ymm/test/library/nest_call/libshowcoor.so (0x00002abf7524b000)



可以看到,通過這種方式,就引用了兩個庫。


通過這個簡單的例子,雖然不能說讓自己精通編譯、連結、靜態庫和動態庫,但是,我想,對於我的學習還是很有幫助的。最起碼,當我下次在遇到類似的問題的時候,我可以更容易的想到是因為什麼原因。而這,就夠了!


《完》——2014/2/20 15:39:16

相關推薦

自己linux編譯連結動態靜態學習筆記

在平常的專案中,我們都是使用公司要求的makefile、makedebug一類的檔案,因此,在編譯、連結、生成和連結動態庫與靜態庫的時候,我們只是簡單的使用一些已經設定的變數,只是簡單的修改、新增一些檔名,或許這次我們編譯通過了,但是,在某一個時候,可能出現了一個問題,無論

linux下g++ 編譯動態靜態連結標頭檔案問題

原來編譯的時候都是用的很隨意,沒用系統的總結一下,這幾天在編譯的時候遇到一些下問題,於是就總結一下,省得過幾天又給忘了。 1.動態庫和靜態庫簡介 靜態庫在程式連結的時候會自動的連結到程式裡,所以一旦編譯完成,靜態庫就不需要了,靜態庫以.a結尾。  動態庫在編譯時不會被連線到目的碼中,而是在程式執行

linux動態靜態的製作尋找比較及相關Makefile的編寫

一.庫的定義 什麼是庫,在windows平臺和linux平臺下都大量存在著庫。 本質上來說庫是一種可執行程式碼的二進位制形式,可以被作業系統載入記憶體執行。 由於windows和linux的本質不同,

Linux下RabbitMQ的編譯,生成動態靜態

執行 編譯 ast lin 目錄 off href apt-get span 一、步驟 1、代碼托管處下載代碼 最新:https://github.com/alanxz/rabbitmq-c/archive/master.zip 穩定:https://g

QtEmbedded-4.8.6-arm 編譯選擇從 動態變化到靜態 時,生成的Makefile連結路徑下如果有動態靜態,優先選擇動態編譯應用

問題:QtEmbedded-4.8.6-arm 編譯選擇從 動態庫到靜態庫 時,發現的一個疑惑:,生成的Makefile連結庫路徑下如果有動態庫和靜態庫,優先選擇動態庫編譯應用 具體現象: 我最初是使用動態庫的 QtEmbedded-4.8.6-arm (編譯器選擇時,是 ./co

Linux動態靜態連結

一、檢視連結了哪些指令 ldd 程式名字 二、在應用程式需要連線外部庫的情況下,linux預設對庫的連線是使用動態庫,在找不到動態庫的情況下再選擇靜態庫。使用方式為: gcc test.cpp -L. -ltestlib 如果當前目錄有兩個庫libtestlib.

Linux下用Makefile製作動態靜態編譯生成可執行程式

Makefile 一個工程中的原始檔不計其數,其按型別、功能、模組分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些檔案需要先編譯,哪些檔案需要後編譯,哪些檔案需要重新

Linux編譯安裝Bochs 2.6.9QEMU 4.0.0-rc0的方法

開發十年,就只剩下這套架構體系了! >>>   

Linux 動態靜態

Linux作業系統中,依據函式庫是否被編譯到程式內部,將其分為兩大類,靜態函式庫和動態函式庫。 Linux下的函式庫放在/lib或/usr/lib,標頭檔案放在/usr/include。 在既有靜態庫又有動態庫的情況下,預設使用動態庫,如果強制使用靜態庫則需要加-static選項支援。

Linux中的動態靜態(.a.la.so.o)

​ Linux中的動態庫和靜態庫(.a/.la/.so/.o) 原文地址:https://www.cnblogs.com/findumars/p/5421910.html 在windows下,一般可以通過檔案的字尾名來識別檔案的型別。在Linux下大致上也是可以的。但是要明

Linux下怎麼建立動態靜態

前言 linux下的生成的動態庫和靜態庫沒有windows下方便 linux下gcc編譯預設動態連結和release 程式執行後呼叫動態庫 動態庫: 程式在執行的時候才去連結動態庫的程式碼,多個程式

Linux系統的動態靜態

靜態庫 靜態庫:一些公共程式碼是需要反覆使用,就把這些程式碼編譯為“庫”檔案;在連結步驟中,聯結器將從庫檔案取得所需的程式碼,複製到生成的可執行檔案中的這種庫。 程式編譯一般需經預處理、編譯、彙編和連結幾個步驟。靜態庫特點是可執行檔案中包含了庫程式碼的一份完整拷貝;缺點就是被多次

gcc中動態靜態連結順序

so檔案:動態庫 a檔案: 靜態庫 exe檔案:可執行程式(linux下以檔案屬性來標示是否是可執行檔案,與字尾名無關) gcc中連結順序問題,總結出以下幾點: 1,動態庫中可以包含另一個靜態庫,通過引數 -lxxx 把靜態庫libxxx.a加入so檔案中,這樣so檔案中 &nbs

編譯時混合使用動態靜態

         編譯某個測試程式碼時,出現了下面的錯誤:# g++ -std=c++11 -o testlurkcli main.cpp -L. -llurkcli-lasl -static /us

linux c/c++ 動態靜態的生成與使用

二.介紹     從原始碼到可執行程式,通常要經過最重要的兩大步是:編譯,連結。編譯就是將原始檔生成中間檔案的過程,在linux下就是生成  .obj檔案。連結就是用連結器將,這些個中間檔案有序地”糅合“在一起,構成一個可執行檔案。通常,一個.c檔案或者.cpp原始檔編譯後,就會對應生成一個.obj檔案。  

gcc編譯工具生成動態靜態之一----介紹

 1.庫的分類 根據連結時期的不同,庫又有靜態庫和動態庫之分。 靜態庫是在連結階段被連結的(好像是廢話,但事實就是這樣),所以生成的可執行檔案就不受庫的影響了,即使庫被刪除了,程式依然可以成功執行。 有別於靜態庫,動態庫的連結是在程式執行的時候被連結的。所以,即使程式編譯完,庫仍須保留在系統上

Linux下的動態靜態

庫: 在c/c++裡,使用庫(library)的技術,可以將編譯好的符號提供給第三方使用。 1)共享庫(動態庫)share library 2)   靜態庫 static library 一:動態庫

編譯動態靜態的Makefile模板

# 1、準備工作,編譯方式、目標檔名、依賴庫路徑的定義。 CC = gcc CFLAGS := -w -g -Wall LIB = libltkc.so HDRS = \ versi

linux兩種:動態靜態(共享)說明

linux下有兩種庫:動態庫和靜態庫(共享庫) 二者的不同點在於程式碼被載入的時刻不同。 靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積比較大。 動態庫(共享庫)的程式碼在可執行程式執行時才載入記憶體,在編譯過程中僅簡單的引用,因此程式碼體積比較

linux c 語言程式設計環境:動態靜態的製作

庫: 庫用於將相似函式打包在一個單元中。然後這些單元就可為其他開發人員所共享,並因此有了模組化程式設計這種說法 — 即,從模組中構建程式。Linux 支援兩種型別的庫,每一種庫都有各自的優缺點。靜態庫包