linux 下編譯生成靜態庫和動態庫
我們此處為了說明靜態庫和動態庫的編譯,會使用示例程式碼。建立 test.h, hello.cpp 和 world.cpp, 在兩個原始檔中分別實現兩個函式( 此處都是示例程式碼,檔案命名不規範,理解意思即可 )。
test.h (靜態庫標頭檔案)
#ifndef _TEST_
#define _TEST_
void hello();
void world();
#endif
hello.cpp:
#include <iostream> #include "test.h" using namespace std; void hello() { cout << "this is hello" << endl; }
world.cpp:
#include <iostream>
#include "test.h"
using namespace std;
void world()
{
cout << "this is world" << endl;
}
靜態庫編譯:
linux 下靜態庫的命名規則為 lib+庫名+.a1、首先將原始檔夾編譯成目標檔案 ( hello.o, world.o )
g++ -c hello.cpp world.cpp
注意 -c 引數是必須帶,生成目的碼(機器程式碼),如果不帶該引數,則是編譯連結,由於沒有main 函式,編譯時會報錯。編譯完成之後生成 hello.o 和 world.o
2、用ar 工具將目標檔案打包成 .a 靜態庫 ( libtest.lib )
ar -crv libtest.lib hello.o world.o
動態庫編譯:
linux 下動態庫的命名規則為 lib+庫名+.so1、生成目標檔案(hello.o world.o),此時需要加編譯器 選項 -fpic
g++ -fpic -c hello.cpp world.cpp
2、生成動態庫,
g++ -share -o libtest.so hello.o world.o
也可以將上面兩步合併為一步
g++ -fpic -share -o libtest.so hello.pp world.cpp
如果生成的動態庫不在 /lib 或者 /usr/lib 目錄下,則需要將動態庫的路徑新增到 /etc/ld.so.cache 檔案中,只有這樣程式在執行時才能找到動態庫, 新增步驟如下:
1、編輯 /etc/ld.so.conf 檔案,將動態庫路徑加入該檔案
2、呼叫 ldconfig 命令,重建 /etc/ld.so.cache 檔案。
更為專業的生成動態庫方式如下:
g++ -shared -Wl, -soname, libtest.so.1 -o libtest.so.1.10 hello.o world.o
編譯完成之後生成 libtest.so.1.10 庫檔案,這是庫的 realname
此時還需要將庫路徑新增入 /etc/ld.so.conf 中,然後 ldconfig -v 命令更新配置檔案
更新完之後,生成了 libtest.so.1 檔案,是庫的 soname (執行時的時候用 soname,只記錄主版本號,檢查主版本是否正確)
呼叫如下命令,生成 linkname (linkname 在編譯連結階段使用,方便 makefile)
ln -s libtest.so libtest.so.1.10
動態庫和靜態庫的呼叫
動態庫和靜態庫的呼叫方式相同, 以 main.cpp 中呼叫庫函式說明:
g++ -o main.exe main.cpp -L . -ltest
其中 -L 選項指明庫函式的位置
-ltest 為庫名的縮寫,只有完全按照linux 庫命名規則命名的庫才能採用縮寫。全名為 libtest.a 或 libtest.so