您好,登錄后才能下訂單哦!
個人博客首頁(點(diǎn)解查看詳情)-- https://blog.51cto.com/11495268
????
????程序編譯一般需要經(jīng)預(yù)處理、編譯、匯編和鏈接,在實(shí)際應(yīng)用中,有些公共代碼需要反復(fù)使用,就把這些代碼編譯成為 "庫" 文件,本文 主要 描述 Linux 平臺下 庫文件的 創(chuàng)建 和 鏈接 相關(guān)操作(既然都看 這么底層的內(nèi)容了,相信 也有一定的基礎(chǔ),所以本文 對相關(guān)命令 也不會進(jìn)行詳細(xì)解釋)
????
備注:
????linux平臺下,靜態(tài)鏈接庫是以 .a 的后綴文件,動態(tài)鏈接庫是以 .so 的后綴文件
????widows平臺下,靜態(tài)鏈接庫是以 .lib 的后綴文件,動態(tài)庫文件是以 .dll 的后綴文件
????
????庫是寫好的 現(xiàn)有的、成熟的 一種可執(zhí)行、可以復(fù)用代碼的二進(jìn)制形式(注,其本身不可執(zhí)行),可以被操作系統(tǒng)載入內(nèi)存執(zhí)行;分為 靜態(tài)鏈接庫 和 動態(tài)鏈接庫
????
????靜態(tài)鏈接庫可以簡單看成一組目標(biāo)文件.o 的集合,即很多目標(biāo)文件經(jīng)過壓縮打包后形成的一個文件
????
????鏈接器將從 靜態(tài)(鏈接)庫 取得所需的代碼,復(fù)制到生成的可執(zhí)行文件
????
????靜態(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í)行文件)
????
????
備注:
????linux下使用ar工具(windows下用lib.exe)將目標(biāo)文件壓縮到一起,并且對其進(jìn)行編號和索引,以便于查找和索引
????
????靜態(tài)鏈接庫的名稱 和 庫文件名稱不同但有聯(lián)系;例如,庫名稱為"static_library",那么起庫文件名為"libstatic_library.a"
????
????程序在開始運(yùn)行后調(diào)用 動態(tài)(鏈接)庫(Dynamic Link Library)中的函數(shù) 才被載入
????
????程序編譯是并不會被連接到目標(biāo)代碼中,而是在程序運(yùn)行時才被載入
????
????動態(tài)庫把對一些庫函數(shù)的鏈接載入推遲到程序運(yùn)行時期
????進(jìn)程之間的相同動態(tài)庫實(shí)現(xiàn)共享
????
????創(chuàng)建動態(tài)庫與創(chuàng)建靜態(tài)庫不同,不需要打包工具,直接使用編譯器創(chuàng)建動態(tài)庫
# g++ -fPIC -shared -o libxxx.so xx1.cpp xx2.cpp xx3.cpp
????
????動態(tài)鏈接庫的名稱 和 庫文件名稱不同但有聯(lián)系;例如,庫名稱為"dynamic_library",那么起庫文件名為"libdynamic_library.a"
????
# 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;
}
????
# 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
????
## -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
????
????為了便于測試比較,使用 與 靜態(tài)庫編譯相同的源碼
# g++ -fPIC -shared -o 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 ./ -l dynamic_gxx
????
## 共享路徑設(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"
????
## 查看 依賴庫,沒有問題 就執(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
????
# apt-get install make
????
# 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
????
## 創(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/
免責(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)容。