gcc 編譯動態庫和靜態庫

2021-09-07 11:19:04 字數 3910 閱讀 3982

cheungmine

2012

c程式編譯過程**

windows7+cygwin+gcc

在同乙個目錄下準備好下面3個檔案,其中3-2,3-3用來生成動態庫或靜態庫:

主呼叫程式源**3-1:main.c

[cpp]view plain

copy

print?

/** 

* main.c 

*/  

#include 

#include 

#include "hello_fn.h"  

int  

main ()    

庫源**3-2:hello_fn.c

[cpp]view plain

copy

print?

/** 

* hello_fn.c 

*/  

#include 

void hello(const char *msg)    

庫標頭檔案源**3-3:hello_fn.h

[cpp]view plain

copy

print?

/** 

* hello_fn.h 

*/  

void hello(const char *msg);  

[plain]view plain

copy

print?

$ gcc -w -wall -ansi -pedantic -i. -c main.c  

$ gcc -w -wall -ansi -pedantic -i. -c hello_fn.c  

[plain]view plain

copy

print?

$ gcc -shared hello_fn.o -o libhello.so  

或者直接從源**編譯:  

$ gcc -shared -i. hello_fn.c -o libhello.so  

編譯靜態庫相對簡單,就是相當於目標檔案歸檔:  

$ ar r libhello.a hello_fn.o  

[plain]view plain

copy

print?

$ gcc main.o -o main  

或者  

$ gcc -c main.c -o main  

但是由於我們在main.c的**中寫固定了呼叫庫的**(hello函式),所以,必須鏈結到這個庫才行。

[plain]view plain

copy

print?

$ gcc main.o -o main ./libhello.so  

這樣在當前目錄下就生成了:main.exe(我的cygwin環境,linux環境下沒有副檔名)

執行這個main.exe:

[plain]view plain

copy

print?

$ ./main.exe  

刪除libhello.so,再執行main.exe會報錯誤:error while loading shared libraries: libhello.so: cannot open shared object...

[plain]view plain

copy

print?

$ gcc main.o -o main2 ./libhello.a  

刪除libhello.a,執行main2.exe,一切正常。說明程式的確鏈結到靜態庫了。

[plain]view plain

copy

print?

$ file main.exe main2.exe  

$ ldd main.exe main2.exe  

如果我們的動態庫libhello.so與主程式不在同乙個目錄下,怎麼辦?

複製libhello.so和libhello.a到另外乙個目錄,比如:/cygdrive/c/temp,那麼編譯主程式為:

[plain]view plain

copy

print?

$ gcc main.o -o main /cygdrive/c/temp/libhello.so  

執行:  

$ export path=/cygdrive/c/temp:$path  

$ ./main.exe   

修改main.c檔案為如下清單:

[cpp]view plain

copy

print?

/** 

* main.c 

*/  

#include 

#include 

#include 

#include "hello_fn.h"  

void dl_hello()  

fn_hello = dlsym(dp, "hello");  

if(!fn_hello)   

fn_hello("cheungmine: load library when running");  

dlclose(dp);  

}  int  

main ()    

然後重新編譯main.exe和libhello.so如下:

[cpp]view plain

copy

print?

編譯原始檔  

$ gcc -wall -i. -c main.c  

$ gcc -wall -i. -c hello_fn.c  

編譯動態庫  

$ gcc -shared hello_fn.o -o libhello.so  

鏈結主程式,但不鏈結到動態庫。  

$ gcc main.o -o main.exe  

執行下面的**可以看到libhello.so並不在main.exe的依存之列:  

$ ldd main.exe  

移動庫到其他目錄,通過修改環境變數,程式main.exe執行正確:   

$ mv libhello.so /cygdrive/c/temp  

$ export path=.:/cygdrive/c/temp:$path  

$ ./main.exe  

通過上面的練習,基本清楚了如何用gcc編譯程式,包括靜態鏈結庫和動態鏈結庫。通過下面的**可以看到

linux和windows的區別:

windows                      unix/linux

靜態鏈結庫              hello.lib                            libhello.a

動態鏈結庫              hello.dll                            libhello.so

延遲載入                  loadlibrary                    dlopen

getprocaddress            dlsym

freelibrary                     dlclose

本文全部內容在cygwin上執行的,和真實的linux環境還是存在差異的。gcc版本3.4.4。

原文:

gcc編譯動態庫和靜態庫

如果動態庫與靜態庫同時存在,未指明鏈結方式時,首先使用動態庫進行鏈結。我的 目錄 一 具體 1 include void a void b 2 lib include void a include void b 3 src include include include a.h include in...

gcc 編譯動態庫和靜態庫 2

在windows下動態鏈結庫是以.dll字尾的檔案,而在linux中,是以.so作字尾的檔案。動態鏈結庫的好處就是節省記憶體空間。1 linux下建立動態鏈結庫 在使用gcc編譯程式時,只需加上 shared選項即可,這樣生成的執行程式即為動態鏈結庫。例如有檔案 hello.c x.h main.c...

GCC編譯動態和靜態鏈結庫

我們通常把一些公用函式製作成函式庫,供其它程式使用。函式庫分為靜態庫和動態庫兩種。靜態庫在程式編譯時會被連線到目標 中,程式執行時將不再需要該靜態庫。動態庫在程式編譯時並不會被連線到目標 中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在。本文主要通過舉例來說明在linux中如何建立靜態...