Linux 環(huán)境下 gcc 鏈接庫 編譯猪腕、鏈接(概覽) 以及 自動化工具Makefile的編寫

1冗澈、簡介
程序編譯一般需要經預處理、編譯陋葡、匯編和鏈接渗柿,在實際應用中,有些公共代碼需要反復使用脖岛,就把這些代碼編譯成為 "庫" 文件,本文 主要 描述 Linux 平臺下 庫文件的 創(chuàng)建 和 鏈接 相關操作(既然都看 這么底層的內容了颊亮,相信 也有一定的基礎柴梆,所以本文 對相關命令 也不會進行詳細解釋)


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

2雹有、庫文件
庫是寫好的 現(xiàn)有的偿渡、成熟的 一種可執(zhí)行、可以復用代碼的二進制形式(注霸奕,其本身不可執(zhí)行)溜宽,可以被操作系統(tǒng)載入內存執(zhí)行;分為 靜態(tài)鏈接庫 和 動態(tài)鏈接庫

2.1 靜態(tài)庫
2.1.1 簡介
靜態(tài)鏈接庫可以簡單看成一組目標文件.o 的集合质帅,即很多目標文件經過壓縮打包后形成的一個文件

2.1.2 原理
鏈接器將從 靜態(tài)(鏈接)庫 取得所需的代碼适揉,復制到生成的可執(zhí)行文件


Linux 環(huán)境下 gcc 鏈接庫 編譯、鏈接(概覽) 以及 自動化工具Makefile的編寫

2.1.3 特點
靜態(tài)庫對函數(shù)庫的鏈接是放在程序編譯時期完成
程序在運行時對函數(shù)庫再無瓜葛(因為所有相關的目標文件和牽涉到的函數(shù)庫被鏈接合成一個可執(zhí)行文件)
浪費空間和資源(因為所有相關的目標文件和牽涉到的函數(shù)庫被鏈接合成一個可執(zhí)行文件)

2.1.4 創(chuàng)建流程


Linux 環(huán)境下 gcc 鏈接庫 編譯煤惩、鏈接(概覽) 以及 自動化工具Makefile的編寫

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

2.1.5 命令規(guī)則
靜態(tài)鏈接庫的名稱 和 庫文件名稱不同但有聯(lián)系魄揉;例如剪侮,庫名稱為"static_library",那么起庫文件名為"libstatic_library.a"

2.2 動態(tài)庫
2.2.1 簡介
程序在開始運行后調用 動態(tài)(鏈接)庫(Dynamic Link Library)中的函數(shù) 才被載入

2.2.2 原理
程序編譯是并不會被連接到目標代碼中洛退,而是在程序運行時才被載入


Linux 環(huán)境下 gcc 鏈接庫 編譯瓣俯、鏈接(概覽) 以及 自動化工具Makefile的編寫

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

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

# gcc -fPIC -shared -o libxxx.so xx1.c xx2.c xx3.c

2.2.5 命名規(guī)則
動態(tài)鏈接庫的名稱 和 庫文件名稱不同但有聯(lián)系降铸;例如在旱,庫名稱為"dynamic_library",那么起庫文件名為"libdynamic_library.a"

3推掸、庫文件 編譯桶蝎、鏈接(實戰(zhàn)操作)
3.1 靜態(tài)庫 編譯、鏈接
3.1.1 靜態(tài)庫 源碼

# cat gcc_lib_header.h
#ifndef __GCC_LIB_HEADER_H_ 
#define __GCC_LIB_HEADER_H_

#include <stdio.h>

void gcc_lib_one();
void gcc_lib_two();
void gcc_lib_three();

#endif
# cat gcc_lib_first.c 
/* 
    filename : gcc_lib_first.c 
*/
#include "gcc_lib_header.h"

void gcc_lib_one(){
    printf("call gcc_lib_one() function\n");
}

# cat gcc_lib_sec.c
/* 
    filename : gcc_lib_sec.c 
*/
    #include "gcc_lib_header.h"

void gcc_lib_two(){
    printf("call gcc_lib_two() function\n");
}
# cat gcc_lib_third.c
/* 
    filename : gcc_lib_third.c
*/
#include "gcc_lib_header.h"

void gcc_lib_three(){
    printf("call gcc_lib_three() function\n");
}
# cat gcc_lib_main.c
/* 
    filename : gcc_lib_main.c
*/
#include "gcc_lib_header.h"

int main(int argc, char *argv[])
{
    gcc_lib_one();
    gcc_lib_two();
    gcc_lib_three();

    return 0;
}

3.1.2 靜態(tài)庫 編譯

# gcc -c gcc_lib_first.c
# gcc -c gcc_lib_sec.c
# gcc -c gcc_lib_third.c

# ar  cqs  libstatic_gcc.a  gcc_lib_first.o gcc_lib_sec.o gcc_lib_third.o

3.1.3 靜態(tài)庫 鏈接

## -L ./ 等同于 -L.
# gcc -o gcc_lib_main_static gcc_lib_main.c -L. -static -l static_gcc

# ./gcc_lib_main_static 
call gcc_lib_one() function
call gcc_lib_two() function
call gcc_lib_three() function

3.2 動態(tài)庫 編譯谅畅、鏈接
3.1.1 動態(tài)庫 源碼
為了便于測試比較登渣,使用 與 靜態(tài)庫編譯相同的源碼

3.1.2 動態(tài)庫 編譯

# gcc -fPIC -shared -o libdynamic_gcc.so  gcc_lib_first.c gcc_lib_sec.c gcc_lib_third.c

3.1.3 動態(tài)庫 鏈接

# gcc -o gcc_lib_main_dynamic gcc_lib_main.c -L ./ -l dynamic_gcc

3.1.4 共享路徑設置(不詳細解釋)

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

## 重新讀取 庫文件信息(需root用戶執(zhí)行)
# ldconfig

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

3.1.5 執(zhí)行

## 查看 依賴庫胜茧,沒有問題 就執(zhí)行
# ldd gcc_lib_main_dynamic
    linux-vdso.so.1 =>  (0x00007fff241e9000)
    libdynamic_gcc.so => /usr/local/lib/libdynamic_gcc.so (0x00007fe587990000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe5875c6000)
    /lib64/ld-linux-x86-64.so.2 (0x000055b1d62ea000)

# ./gcc_lib_main_dynamic 
call gcc_lib_one() function
call gcc_lib_two() function
call gcc_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_gcc仇味、dynamic_gcc\""

gcc_lib_first.o : gcc_lib_first.c gcc_lib_header.h
    gcc -c gcc_lib_first.c 

gcc_lib_sec.o : gcc_lib_sec.c gcc_lib_header.h
    gcc -c gcc_lib_sec.c

gcc_lib_third.o : gcc_lib_third.c gcc_lib_header.h
    gcc -c gcc_lib_third.c  

static_gcc : gcc_lib_first.o gcc_lib_sec.o gcc_lib_third.o
    ar  cqs  /tmp/libstatic_gcc.a  gcc_lib_first.o gcc_lib_sec.o gcc_lib_third.o
    gcc -o gcc_lib_main_static gcc_lib_main.c  -L /tmp -static -l static_gcc

dynamic_gcc :
    gcc -fPIC -shared -o /tmp/libdynamic_gcc.so  gcc_lib_first.c gcc_lib_sec.c gcc_lib_third.c 
    gcc -o gcc_lib_main_dynamic gcc_lib_main.c -L /tmp -l dynamic_gcc
    cp /tmp/libdynamic_gcc.so /usr/local/lib/
    ldconfig

4.3 執(zhí)行

## 創(chuàng)建 靜態(tài)庫 鏈接的 可執(zhí)行文件
# make static_gcc
ar  cqs  /tmp/libstatic_gcc.a  gcc_lib_first.o gcc_lib_sec.o gcc_lib_third.o
gcc -o gcc_lib_main_static gcc_lib_main.c  -L /tmp -static -l static_gcc

## 創(chuàng)建 動態(tài)庫 鏈接的 可執(zhí)行文件
# make dynamic_gcc
gcc -fPIC -shared -o /tmp/libdynamic_gcc.so  gcc_lib_first.c gcc_lib_sec.c gcc_lib_third.c 
gcc -o gcc_lib_main_dynamic gcc_lib_main.c -L /tmp -l dynamic_gcc
cp /tmp/libdynamic_gcc.so /usr/local/lib/
ldconfig

最后

針對于上面的面試題我總結出了互聯(lián)網(wǎng)公司java程序員面試涉及到的絕大部分面試題及答案做成了文檔和架構視頻資料免費分享給大家(包括Dubbo呻顽、Redis、Netty丹墨、zookeeper廊遍、Spring cloud、分布式贩挣、高并發(fā)等架構技術資料)喉前,希望能幫助到您面試前的復習且找到一個好的工作,也節(jié)省大家在網(wǎng)上搜索資料的時間來學習.

資料領取方式:

Qq-u-n:****219--571--750王财,lingqu****往期Java高級架構資料卵迂、源碼、筆記绒净、視頻

Dubbo见咒、Redis、設計模式疯溺、Netty论颅、zookeeper、Spring cloud囱嫩、分布式恃疯、

高并發(fā)等架構技術


?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市墨闲,隨后出現(xiàn)的幾起案子今妄,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盾鳞,死亡現(xiàn)場離奇詭異犬性,居然都是意外死亡,警方通過查閱死者的電腦和手機腾仅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門乒裆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人推励,你說我怎么就攤上這事鹤耍。” “怎么了验辞?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵稿黄,是天一觀的道長。 經常有香客問我跌造,道長杆怕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任壳贪,我火速辦了婚禮陵珍,結果婚禮上,老公的妹妹穿的比我還像新娘违施。我一直安慰自己撑教,他們只是感情好,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布醉拓。 她就那樣靜靜地躺著,像睡著了一般收苏。 火紅的嫁衣襯著肌膚如雪亿卤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天鹿霸,我揣著相機與錄音排吴,去河邊找鬼。 笑死懦鼠,一個胖子當著我的面吹牛钻哩,可吹牛的內容都是我干的。 我是一名探鬼主播肛冶,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼街氢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了睦袖?” 一聲冷哼從身側響起珊肃,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后伦乔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厉亏,經...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年烈和,在試婚紗的時候發(fā)現(xiàn)自己被綠了爱只。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡招刹,死狀恐怖恬试,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情蔗喂,我是刑警寧澤忘渔,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站缰儿,受9級特大地震影響畦粮,放射性物質發(fā)生泄漏。R本人自食惡果不足惜乖阵,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一宣赔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瞪浸,春花似錦儒将、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蹈矮,卻和暖如春砰逻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背泛鸟。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工蝠咆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人北滥。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓刚操,卻偏偏與公主長得像,于是被迫代替她去往敵國和親再芋。 傳聞我的和親對象是個殘疾皇子菊霜,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內容