溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Linux g++ 鏈接庫 編譯、鏈接 以及 Makefile編寫

發(fā)布時間:2020-07-22 18:46:29 來源:網(wǎng)絡(luò) 閱讀:3556 作者:堅(jiān)韌的石頭 欄目:編程語言

個人博客首頁(點(diǎn)解查看詳情)-- https://blog.51cto.com/11495268
????

1、簡介

????程序編譯一般需要經(jīng)預(yù)處理、編譯、匯編和鏈接,在實(shí)際應(yīng)用中,有些公共代碼需要反復(fù)使用,就把這些代碼編譯成為 "庫" 文件,本文 主要 描述 Linux 平臺下 庫文件的 創(chuàng)建 和 鏈接 相關(guān)操作(既然都看 這么底層的內(nèi)容了,相信 也有一定的基礎(chǔ),所以本文 對相關(guān)命令 也不會進(jìn)行詳細(xì)解釋)
Linux g++ 鏈接庫 編譯、鏈接 以及 Makefile編寫
????

備注:
????linux平臺下,靜態(tài)鏈接庫是以 .a 的后綴文件,動態(tài)鏈接庫是以 .so 的后綴文件
????widows平臺下,靜態(tài)鏈接庫是以 .lib 的后綴文件,動態(tài)庫文件是以 .dll 的后綴文件
????

2、庫文件

????庫是寫好的 現(xiàn)有的、成熟的 一種可執(zhí)行、可以復(fù)用代碼的二進(jìn)制形式(注,其本身不可執(zhí)行),可以被操作系統(tǒng)載入內(nèi)存執(zhí)行;分為 靜態(tài)鏈接庫 和 動態(tài)鏈接庫
????

2.1 靜態(tài)庫

2.1.1 簡介

????靜態(tài)鏈接庫可以簡單看成一組目標(biāo)文件.o 的集合,即很多目標(biāo)文件經(jīng)過壓縮打包后形成的一個文件
????

2.1.2 原理

????鏈接器將從 靜態(tài)(鏈接)庫 取得所需的代碼,復(fù)制到生成的可執(zhí)行文件
Linux g++ 鏈接庫 編譯、鏈接 以及 Makefile編寫
????

2.1.3 特點(diǎn)

????靜態(tài)庫對函數(shù)庫的鏈接是放在程序編譯時期完成
????程序在運(yùn)行時對函數(shù)庫再無瓜葛(因?yàn)樗邢嚓P(guān)的目標(biāo)文件和牽涉到的函數(shù)庫被鏈接合成一個可執(zhí)行文件)
????浪費(fèi)空間和資源(因?yàn)樗邢嚓P(guān)的目標(biāo)文件和牽涉到的函數(shù)庫被鏈接合成一個可執(zhí)行文件)
????

2.1.4 創(chuàng)建流程

Linux g++ 鏈接庫 編譯、鏈接 以及 Makefile編寫
????

備注:
????linux下使用ar工具(windows下用lib.exe)將目標(biāo)文件壓縮到一起,并且對其進(jìn)行編號和索引,以便于查找和索引
????

2.1.5 命令規(guī)則

????靜態(tài)鏈接庫的名稱 和 庫文件名稱不同但有聯(lián)系;例如,庫名稱為"static_library",那么起庫文件名為"libstatic_library.a"
????

2.2 動態(tài)庫

2.2.1 簡介

????程序在開始運(yùn)行后調(diào)用 動態(tài)(鏈接)庫(Dynamic Link Library)中的函數(shù) 才被載入
????

2.2.2 原理

????程序編譯是并不會被連接到目標(biāo)代碼中,而是在程序運(yùn)行時才被載入
Linux g++ 鏈接庫 編譯、鏈接 以及 Makefile編寫
????

2.2.3 特點(diǎn)

????動態(tài)庫把對一些庫函數(shù)的鏈接載入推遲到程序運(yùn)行時期
????進(jìn)程之間的相同動態(tài)庫實(shí)現(xiàn)共享
????

2.2.4 創(chuàng)建

????創(chuàng)建動態(tài)庫與創(chuàng)建靜態(tài)庫不同,不需要打包工具,直接使用編譯器創(chuàng)建動態(tài)庫

# g++ -fPIC -shared -o libxxx.so xx1.cpp xx2.cpp xx3.cpp

????

2.2.5 命名規(guī)則

????動態(tài)鏈接庫的名稱 和 庫文件名稱不同但有聯(lián)系;例如,庫名稱為"dynamic_library",那么起庫文件名為"libdynamic_library.a"
????

3、庫文件 編譯、鏈接(實(shí)戰(zhàn)操作)

3.1 靜態(tài)庫 編譯、鏈接

3.1.1 靜態(tài)庫 源碼

# cat g++_lib_header.h
#ifndef __GXX_LIB_HEADER_H_ 
#define __GXX_LIB_HEADER_H_

#include <iostream>

using namespace std;
void gxx_lib_one();
void gxx_lib_two();
void gxx_lib_three();

#endif

????

# cat g++_lib_first.cpp  
/* 
    filename : g++_lib_first.cpp 
*/
#include "g++_lib_header.h"

void gxx_lib_one(){
    cout << "call gxx_lib_one() function" << endl;
}

????

# cat g++_lib_sec.cpp
/* 
    filename : g++_lib_sec.cpp 
*/
#include "g++_lib_header.h"

void gxx_lib_two(){
    cout << "call gxx_lib_two() function" << endl;
}

????

# cat g++_lib_third.cpp
/* 
    filename : g++_lib_third.cpp 
*/
#include "g++_lib_header.h"

void gxx_lib_three(){
    cout << "call gxx_lib_three() function" << endl;
}

????

# cat g++_lib_main.cpp 
/* 
    filename : g++_lib_main.cpp 
*/
#include "g++_lib_header.h"

int main(int argc, char *argv[])
{
    gxx_lib_one();
    gxx_lib_two();
    gxx_lib_three();

    return 0;
}

????

3.1.2 靜態(tài)庫 編譯

# g++ -c g++_lib_first.cpp
# g++ -c g++_lib_sec.cpp
# g++ -c g++_lib_third.cpp

# ar  cqs  libstatic_gxx.a  g++_lib_first.o g++_lib_sec.o g++_lib_third.o

????

3.1.3 靜態(tài)庫 鏈接

## -L ./ 等同于 -L.
# g++ -o g++_lib_main_static g++_lib_main.cpp -L. -static -l static_gxx

# ./g++_lib_main_static 
call gxx_lib_one() function
call gxx_lib_two() function
call gxx_lib_three() function

????

3.2 動態(tài)庫 編譯、鏈接

3.1.1 動態(tài)庫 源碼

????為了便于測試比較,使用 與 靜態(tài)庫編譯相同的源碼

3.1.2 動態(tài)庫 編譯

# g++ -fPIC -shared -o libdynamic_gxx.so  g++_lib_first.cpp g++_lib_sec.cpp g++_lib_third.cpp

????

3.1.3 動態(tài)庫 鏈接

# g++ -o g++_lib_main_dynamic g++_lib_main.cpp -L ./ -l dynamic_gxx

????

3.1.4 共享路徑設(shè)置(不詳細(xì)解釋)

## 共享路徑設(shè)置 :
##     1@:LD_LIBRARY_PATH 修改 這個全局變量
##     2@:修改 /etc/ld.so.conf 配置
## 本文 就 詳細(xì)描述了,直接把 生成的共享庫 cp 至 系統(tǒng)默認(rèn)路徑下
# cp libdynamic_gxx.so /usr/local/lib/

????

備注:
????如果 不設(shè)置 共享路徑 或者 共享路徑下 找不到 指定的 庫文件,系統(tǒng) 就會 提示相關(guān)的錯誤信息:"./g++_lib_main_dynamic: error while loading shared libraries: libdynamic_gxx.so: cannot open shared object file: Error 40"
????

3.1.5 執(zhí)行

## 查看 依賴庫,沒有問題 就執(zhí)行
# ldd g++_lib_main_dynamic 
    linux-vdso.so.1 =>  (0x00007ffcf73c1000)
    libdynamic_gxx.so => /usr/local/lib/libdynamic_gxx.so (0x00007effbb5d0000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007effbb24e000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007effbae84000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007effbab7a000)
    /lib64/ld-linux-x86-64.so.2 (0x000056545a3cb000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007effba964000)

????

# ./g++_lib_main_dynamic 
call gxx_lib_one() function
call gxx_lib_two() function
call gxx_lib_three() function

????

4、自定義工具(Makefile)

4.1 安裝 make

# apt-get install make

????

4.2 編寫 Makefile

# cat Makef
default_target : help

help :
    @echo "usage : make [opt]"
    @echo "\topt arguement is one of \"static_gxx、dynamic_gxx\""

g++_lib_first.o : g++_lib_first.cpp g++_lib_header.h
    g++ -c g++_lib_first.cpp 

g++_lib_sec.o : g++_lib_sec.cpp g++_lib_header.h
    g++ -c g++_lib_sec.cpp 

g++_lib_third.o : g++_lib_third.cpp g++_lib_header.h
    g++ -c g++_lib_third.cpp 

static_gxx : g++_lib_first.o g++_lib_sec.o g++_lib_third.o
    ar  cqs  /tmp/libstatic_gxx.a  g++_lib_first.o g++_lib_sec.o g++_lib_third.o
    g++ -o g++_lib_main g++_lib_main.cpp -L /tmp -static -l static_gxx

dynamic_gxx :
    g++ -fPIC -shared -o /tmp/libdynamic_gxx.so  g++_lib_first.cpp g++_lib_sec.cpp g++_lib_third.cpp
    g++ -o g++_lib_main_dynamic g++_lib_main.cpp -L /tmp -l dynamic_gxx
    cp /tmp/libdynamic_gxx.so /usr/local/lib/
    ldconfig 

????

4.3 執(zhí)行

## 創(chuàng)建 靜態(tài)庫 鏈接的 可執(zhí)行文件
# make static_gxx
ar  cqs  /tmp/libstatic_gxx.a  g++_lib_first.o g++_lib_sec.o g++_lib_third.o
g++ -o g++_lib_main g++_lib_main.cpp -L /tmp -static -l static_gxx

## 創(chuàng)建 動態(tài)庫 鏈接的 可執(zhí)行文件
# make dynamic_gxx
g++ -fPIC -shared -o /tmp/libdynamic_gxx.so  g++_lib_first.cpp g++_lib_sec.cpp g++_lib_third.cpp
g++ -o g++_lib_main_dynamic g++_lib_main.cpp -L /tmp -l dynamic_gxx
cp /tmp/libdynamic_gxx.so /usr/local/lib/
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI