1. 程式人生 > >linux 下編譯生成靜態庫和動態庫

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+庫名+.a

    1、首先將原始檔夾編譯成目標檔案 ( 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+庫名+.so

    1、生成目標檔案(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