国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù)

這篇具有很好參考價(jià)值的文章主要介紹了Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器

本文已收錄至《Linux知識(shí)與編程》專(zhuān)欄!
作者:ARMCSKGT
演示環(huán)境:CentOS 7

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器


前言

當(dāng)我們安裝一款軟件成功后,桌面會(huì)多一個(gè)圖標(biāo),如果我們點(diǎn)擊圖標(biāo)就能啟動(dòng)軟件,但那個(gè)圖標(biāo)就是軟件本身嗎?顯然不是!圖標(biāo)只是軟件啟動(dòng)程序的一個(gè)快捷方式,在Linux中可以通過(guò)軟硬鏈接來(lái)創(chuàng)建類(lèi)似于Windows下的軟件快捷方式,Windows下創(chuàng)建快捷方式一般相當(dāng)于Linux中的軟連接;當(dāng)Windows中的一個(gè)軟件啟動(dòng)之后會(huì)加載各種文件,一般我們看到的軟件啟動(dòng)程序都很小,但是軟件安裝包卻很大,例如游戲,其實(shí)軟件中大部分都是庫(kù)文件,關(guān)于Linux下的庫(kù),本節(jié)將會(huì)詳細(xì)為您介紹!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器


正文

軟硬鏈接

關(guān)于軟硬鏈接,其中涉及Linux文件系統(tǒng)的知識(shí),如果有疑問(wèn),請(qǐng)先移步:Linux文件系統(tǒng)概述


原理


軟鏈接
軟鏈接又稱(chēng)為符號(hào)鏈接,軟鏈接是一個(gè)單獨(dú)的文件,啟動(dòng)這個(gè)軟鏈接程序會(huì)跳轉(zhuǎn)啟動(dòng)這個(gè)軟鏈接指向的程序,既然是一個(gè)單獨(dú)的文件,那么軟鏈接文件就擁有獨(dú)立的inode和文件屬性,軟鏈接的主要存儲(chǔ)內(nèi)容是源文件的地址,所以軟連接一般很小且依賴(lài)源文件!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
因?yàn)檐涍B接非常依賴(lài)源文件,所以源文件一旦不存在或被源文件路徑出錯(cuò),再次啟動(dòng)該軟鏈接(快捷方式)則會(huì)出現(xiàn) No such file or directory 的錯(cuò)誤提示,表示系統(tǒng)沒(méi)有找到對(duì)應(yīng)文件!

當(dāng)我們刪除軟鏈接文件時(shí),并不會(huì)對(duì)源文件產(chǎn)生任何影響,就像我們刪除Windows桌面上的快捷方式并不是清除了該軟件一樣,想刪除該軟件必須刪除該軟件所在的安裝目錄!


硬鏈接
硬鏈接與軟鏈接不同,硬鏈接沒(méi)有獨(dú)立的inode和文件屬性,其只是在目錄中創(chuàng)建了與源文件inode和硬鏈接名的映射關(guān)系,并在源文件的文件屬性中引用計(jì)數(shù)進(jìn)行+1,表示增加了一個(gè)硬鏈接!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
當(dāng)我們刪除一個(gè)硬鏈接時(shí),文件系統(tǒng)會(huì)判斷該鏈接的inode源文件ret_count計(jì)數(shù)是否為0,如果減去1后引用為0則刪除該文件,否則只是刪除該目錄下的一個(gè)硬鏈接映射關(guān)系且源文件引用計(jì)數(shù)-1,所以刪除硬鏈接文件,只有刪除最后一個(gè)硬鏈接才是真正刪除文件,否則也不會(huì)對(duì)源文件產(chǎn)生影響!

所以,硬鏈接并不在意源文件,因?yàn)橹灰叉溄哟嬖冢募痛嬖?,而軟鏈接的源文件被刪除則軟鏈接失效!

普通文件可以建立硬鏈接和軟鏈接,但是目錄只能建立軟鏈接!
當(dāng)我們新建一個(gè)文件時(shí),其默認(rèn)硬鏈接數(shù)為1,而目錄的默認(rèn)硬鏈接數(shù)為2
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
為什么新目錄的硬鏈接數(shù)為2? 因?yàn)樾履夸浥c父級(jí)目錄建立了硬鏈接
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
在Linux系統(tǒng)中, . 表示本目錄,**. .**表示上級(jí)目錄!

所以在父級(jí)目錄下,每創(chuàng)建一個(gè)新目錄,其硬鏈接數(shù)就會(huì)+1,因?yàn)樾履夸浥c父級(jí)目錄構(gòu)建的新的硬鏈接關(guān)系,但是Linux系統(tǒng)不允許用戶(hù)手動(dòng)為目錄創(chuàng)建硬鏈接,因?yàn)檫@樣會(huì)破壞文件系統(tǒng)的樹(shù)結(jié)構(gòu),嚴(yán)重時(shí)可能會(huì)變成圖,使得文件系統(tǒng)崩潰!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
硬鏈接就像是淺拷貝,只拷貝了inode。


使用


生成軟鏈接文件:

$ ln -s 源文件路徑 軟鏈接文件名

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
注意:可以對(duì)目錄進(jìn)行軟鏈接,其方式與普通文件進(jìn)行軟鏈接方式相同!



生成硬鏈接文件:

$ ln 源文件路徑 軟鏈接文件名

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器

雖然軟硬鏈接在使用上沒(méi)有差別,但是底層差別還是非常大的!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器

取消鏈接:

  • 刪除鏈接文件
$ rm 鏈接文件
  • unlink取消鏈接
$ unlink 鏈接文件

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
注意:普通文件的首個(gè)標(biāo)識(shí)符為 -,軟鏈接文件標(biāo)識(shí)符為 l,而硬鏈接本質(zhì)上是源文件的別名,所以也是普通文件 -!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器


文件時(shí)間


每一個(gè)文件從創(chuàng)建之日起就有三個(gè)時(shí)間(簡(jiǎn)稱(chēng)為 ACM 時(shí)間):

  • 訪問(wèn)時(shí)間 Access :最后一次查看內(nèi)容的時(shí)間,如何判定取決于系統(tǒng)
  • 修改屬性時(shí)間 Change:最后一次修改文件屬性的時(shí)間
  • 修改內(nèi)容時(shí)間 Modify:最后一次修改文件內(nèi)容的時(shí)間

注意: 因?yàn)閙odify是文件屬性,modify修改了change也會(huì)修改;更改文件內(nèi)容與查看文件內(nèi)容不一樣,區(qū)別于access和modify,查看文件改變access,修改文件改變modify,Linux系統(tǒng)并非每次查看都會(huì)改變文件的access時(shí)間(因?yàn)樾薷腶ccess涉及文件屬性的修改需要讀取硬盤(pán)),有一定的策略,這樣可以減少與硬盤(pán)的交涉提高效率。


我們可以通過(guò) stat 命令查看文件屬性和ACM時(shí)間:

$ stat 文件名

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器


動(dòng)靜態(tài)庫(kù)


庫(kù)介紹

原來(lái)在學(xué)習(xí)C語(yǔ)言時(shí),寫(xiě)一下學(xué)校課程設(shè)計(jì)可能會(huì)需要函數(shù)的聲明和定義進(jìn)行分離,這樣可以讓代碼顯得不凌亂!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
其實(shí)圖中的test.cpp就可以充當(dāng)一個(gè)C/C++的函數(shù)庫(kù),但是我們?cè)谑褂脮r(shí)需要結(jié)合頭文件test.h一起使用!


但是在實(shí)際的項(xiàng)目開(kāi)發(fā)過(guò)程中,一個(gè)保密的項(xiàng)目是不能透露庫(kù)中的源代碼的,我們只想留下 頭文件 聲明函數(shù)接口,而具體實(shí)現(xiàn)放在一個(gè)保密的庫(kù)中(別人可以使用,但是無(wú)法獲取函數(shù)實(shí)現(xiàn)),此時(shí)我們就需要引入動(dòng)靜態(tài)庫(kù)了!

說(shuō)明: 一般系統(tǒng)已經(jīng)預(yù)裝了C/C++頭文件和動(dòng)態(tài)庫(kù)文件,頭文件提供方法說(shuō)明,庫(kù)提供方法實(shí)現(xiàn),頭和庫(kù)是有對(duì)應(yīng)關(guān)系的,要組合在一起使用;頭文件是在預(yù)處理階段就引入的,鏈接的本質(zhì)其實(shí)就是鏈接庫(kù);引入庫(kù)文件一方面是為了提高開(kāi)發(fā)效率(代碼復(fù)用性等),另一方面可以保密!


無(wú)論是在Linux系統(tǒng)中還是Windows系統(tǒng)中,都存在庫(kù),分為動(dòng)態(tài)庫(kù)靜態(tài)庫(kù),雖然不同環(huán)境下的后綴有所不同,但其工作原理是一致的!

  • Linux 系統(tǒng)中:.a 后綴為靜態(tài)庫(kù),.so 后綴為動(dòng)態(tài)庫(kù)
  • Windows 系統(tǒng)中:.lib 后綴為靜態(tài)庫(kù),.dll 后綴為動(dòng)態(tài)庫(kù)

在Linux系統(tǒng)中,庫(kù)命名一般為:libstdc++.so.6,去掉前綴 lib 和后綴 .so.6 ,剩下的就是庫(kù)名 stdc++ 。

我們可以使用命令查看Linux環(huán)境中的庫(kù)文件:

# 查看C庫(kù)
$ find /usr/lib64/libc*
# 查看C++庫(kù)
$ find /usr/lib64/libstdc*
# 查看所有庫(kù)
$ find /usr/lib64/lib

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
該圖只截取了一部分,實(shí)際上有很多庫(kù)!

在我們寫(xiě)C/C++程序時(shí),離不開(kāi)庫(kù)函數(shù),比如我們使用的各種STL容器,庫(kù)中只會(huì)提供給我們頭文件開(kāi)放接口進(jìn)行使用,并不會(huì)讓我們看到具體實(shí)現(xiàn),其具體實(shí)現(xiàn)已經(jīng)打包成庫(kù)(二進(jìn)制文件),在平時(shí)使用時(shí),編譯器默認(rèn)使用動(dòng)態(tài)庫(kù)而非靜態(tài)庫(kù),動(dòng)態(tài)庫(kù)在日常使用具有較大優(yōu)勢(shì)!

如果我們想指定使用靜態(tài)庫(kù)編譯,在gcc/g++下,只需要加上 -static 選項(xiàng)即可,但是前提是Linux環(huán)境中已經(jīng)安裝C/C++靜態(tài)庫(kù),一般服務(wù)器和虛擬機(jī)是沒(méi)有安裝的!

C/C++靜態(tài)庫(kù)的安裝(非root用戶(hù)需要sudo提權(quán)):

# 安裝C靜態(tài)庫(kù)
yum install -y glibc-static
# 安裝C++靜態(tài)庫(kù)
yum install -y libstdc++-static

動(dòng)靜態(tài)庫(kù)比較:

區(qū)別 靜態(tài)庫(kù) 動(dòng)態(tài)庫(kù)
空間大小 占用空間較大 占用空間小
調(diào)用方式 函數(shù)實(shí)現(xiàn)在程序中,直接在程序中執(zhí)行 通過(guò)地址轉(zhuǎn)到動(dòng)態(tài)庫(kù)中執(zhí)行動(dòng)代碼
加載速度 庫(kù)函數(shù)加載到程序中,空間占用大 多個(gè)程序共享一個(gè)已加載的動(dòng)態(tài)庫(kù),空間占用小
依賴(lài)性 直接在程序中運(yùn)行 依賴(lài)于動(dòng)態(tài)庫(kù)

補(bǔ)充: 動(dòng)態(tài)庫(kù)是在函數(shù)調(diào)用出留下地址鏈接,在調(diào)用該函數(shù)時(shí)轉(zhuǎn)到內(nèi)存中的動(dòng)態(tài)庫(kù)在指定的函數(shù)位置執(zhí)行代碼;而靜態(tài)庫(kù)是將函數(shù)實(shí)現(xiàn)直接拷貝到調(diào)用出,運(yùn)行時(shí)直接執(zhí)行!

簡(jiǎn)言之,如果沒(méi)有庫(kù)文件,那么你在開(kāi)發(fā)時(shí),需要自己手動(dòng)將 printf/cout 等高頻函數(shù)編寫(xiě)出來(lái),因此庫(kù)文件可以提高我們的開(kāi)發(fā)效率,比如 Python 中就有很多現(xiàn)成的庫(kù)函數(shù)可以使用,效率很高!

一般庫(kù)分為三種:

  • 第一方庫(kù):語(yǔ)言自帶的庫(kù)
  • 第二方庫(kù):操作系統(tǒng)提供的庫(kù)
  • 第三方庫(kù):我們自己制作的庫(kù)或網(wǎng)上下載的庫(kù)

靜態(tài)庫(kù)


靜態(tài)庫(kù)制作

準(zhǔn)備庫(kù)文件和頭文件

add.hpp

#pragma once

int add(int a,int b);

add.cpp

#include "add.hpp"

int add(int a,int b) { return a+b; }

sub.hpp

#pragma once

int sub(int a,int b);

add.cpp

#include "sub.hpp"

int sub(int a,int b) { return a-b; }

main.cpp

#include <iostream>
#include "add.hpp"
#include "sub.hpp"
using namespace std;

int main()
{
   cout<<add(1,2)<<endl;
   cout<<sub(1,2)<<endl;

   return 0;
}

編譯鏈接形成二進(jìn)制程序:

$ g++ main.cpp add.cpp sub.cpp -o exe -std=c++11

注意:聲明與定義分離的情況下,需要指明鏈接的函數(shù)實(shí)現(xiàn)文件
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器

接下來(lái)開(kāi)始打包成靜態(tài)庫(kù),主要分為兩步:

  • 1.將源文件進(jìn)行 預(yù)處理->編譯->匯編,生成可鏈接的二進(jìn)制 .o 文件
$ g++ -c add.cpp sub.cpp

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
執(zhí)行完畢后生成與文件名相同的 .o 二進(jìn)制鏈接文件

  • 2.通過(guò) ar指令 將 .o 文件打包為靜態(tài)庫(kù)
#格式:ar -rc { lib靜態(tài)庫(kù)名.a } {鏈接文件1.o 鏈接文件2.o ...}
$ ar -rc libmymath.a add.o sub.o
# 也可以簡(jiǎn)寫(xiě)為:ar -rc libmymath.a *.o

注意:實(shí)際的靜態(tài)庫(kù)名為 mymath 但是gcc/g++編譯器會(huì)識(shí)別靜態(tài)庫(kù)自動(dòng)去掉頭(lib)尾(.a),按照規(guī)范我們必須這樣寫(xiě)!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
此時(shí)就成功生成了靜態(tài)庫(kù)文件!


ar指令除了可以打包鏈接文件成為庫(kù)文件,還可以查看庫(kù)文件中的打包內(nèi)容:

$ ar -tv {靜態(tài)庫(kù)文件.o}

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器

靜態(tài)庫(kù)的使用

我們自己指針的庫(kù)是第三方庫(kù),在使用上區(qū)別與第一方和第二方庫(kù)區(qū)別很大!
此時(shí)如果我們直接編譯程序,是無(wú)法編譯的!

我們將上面使用和生成的文件進(jìn)行規(guī)整:
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
將頭文件放在_hpp目錄,庫(kù)文件放在lib,鏈接文件放在_o,實(shí)現(xiàn)文件放在_cpp,留下main.cpp在本目錄下,這樣在本目錄下就既沒(méi)有頭文件也沒(méi)有實(shí)現(xiàn)文件了,此時(shí)我們進(jìn)行靜態(tài)編譯!


1.直接使用靜態(tài)庫(kù)

# 格式:g++ 代碼文件.cpp  -I 頭文件夾路徑 -L 庫(kù)文件夾路徑 -l 靜態(tài)庫(kù)名(去掉頭尾)
$ g++ main.cpp -o static_exe  -I ./_hpp -L ./lib -l mymath -static #靜態(tài)鏈接
$ g++ main.cpp -o exe  -I ./_hpp -L ./lib -l mymath #動(dòng)靜混合
# gcc使用方法與此相同

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
使用第三方庫(kù)與使用標(biāo)準(zhǔn)庫(kù)和系統(tǒng)庫(kù)不同,使用標(biāo)準(zhǔn)庫(kù)和系統(tǒng)庫(kù)都是系統(tǒng)級(jí)的,gcc/g++ 默認(rèn)找的就是 stdc/stdc++ 庫(kù),而第三方庫(kù)則需要我們自己指定!


2.將頭文件和靜態(tài)庫(kù)文件安裝至系統(tǒng)庫(kù)下
Linux系統(tǒng)C/C++頭文件路徑:/usr/include/
Linux系統(tǒng)庫(kù)路徑:/lib64/

# 注意:非root用戶(hù)需要sudo提權(quán)
$ cp ./_hpp/*.hpp /usr/include/
$ cp ./lib/*.a /lib64/

將庫(kù)和頭文件安裝到系統(tǒng)目錄下后,只需要指定庫(kù)名即可完成編譯鏈接!

$ g++ main.cpp -o exe -l mymath #動(dòng)靜混合
$ g++ main.cpp -o static_exe -l mymath -static #靜態(tài)鏈接

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
注意:這里極其不提倡這種私自安裝外部庫(kù)的方式,將自己寫(xiě)的文件安裝到系統(tǒng)目錄下是一件危險(xiǎn)的事(導(dǎo)致系統(tǒng)環(huán)境被污染),如果不得已,用完后記得手動(dòng)刪除!

關(guān)于靜態(tài)鏈接

靜態(tài)鏈接,是在鏈接時(shí)將調(diào)用函數(shù)處的函數(shù)調(diào)用替換為函數(shù)執(zhí)行代碼(二進(jìn)制代碼),可執(zhí)行程序從根本上脫離了庫(kù)的限制,在同系統(tǒng)的機(jī)器上無(wú)論是否有靜態(tài)庫(kù)都可以運(yùn)行,不依賴(lài)任何靜態(tài)庫(kù)!

靜態(tài)庫(kù)所體現(xiàn)的優(yōu)點(diǎn)是運(yùn)行比較快,但靜態(tài)鏈接形成的可執(zhí)行程序本身就有靜態(tài)庫(kù)中對(duì)應(yīng)方法的實(shí)現(xiàn)(將代碼拷貝到可執(zhí)行程序中),靜態(tài)鏈接的程序,非常占用資源,內(nèi)存中會(huì)程序多個(gè)重復(fù)的代碼(可執(zhí)行程序體積變大加載占用內(nèi)存),也占用磁盤(pán)資源,如果是給用戶(hù)用的軟件那么下載周期就會(huì)變長(zhǎng),占用網(wǎng)絡(luò)資源!

注意:如果要使用靜態(tài)鏈接需要加上 -static 否則編譯器將使用靜態(tài)庫(kù)進(jìn)行動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的混合鏈接!


動(dòng)態(tài)庫(kù)


動(dòng)態(tài)庫(kù)制作

我們準(zhǔn)備與靜態(tài)庫(kù)制作相同的五個(gè)文件

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
打包為動(dòng)態(tài)庫(kù)分為兩步:

  • 1.編譯源文件,生成二進(jìn)制可鏈接文件.o同時(shí)形成與位置無(wú)關(guān)碼
# 格式:gcc -c -fPIC {實(shí)現(xiàn)文件.cpp}
$ g++ -c -fPIC add.cpp sub.cpp
# gcc 使用方式與g++相同

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
同樣的,會(huì)形成 .o 鏈接文件!

說(shuō)明:fPIC這個(gè)選項(xiàng)是形成.o文件同時(shí)形成與位置無(wú)關(guān)碼,動(dòng)態(tài)庫(kù)中里面的代碼地址排布與靜態(tài)庫(kù)是有區(qū)別的,動(dòng)態(tài)庫(kù)經(jīng)常使用,所以gcc/g++自帶打包動(dòng)態(tài)庫(kù)功能。

  • 2.打包鏈接文件形成動(dòng)態(tài)庫(kù)
# 格式:g++ -shared { 鏈接文件.o } -o { libmymath.so }
g++ -o libmymath.so *.o -shared
# gcc 使用方式與此相同

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
說(shuō)明:shared表示形成(打包成)動(dòng)態(tài)庫(kù)或共享文件

動(dòng)態(tài)庫(kù)的使用

同樣的,我們先規(guī)整文件到不同的文件夾
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器

我們使用靜態(tài)庫(kù)的方法去編譯可執(zhí)行程序:

$ g++ main.cpp -o exe -I ./_hpp -L ./lib -l mymath

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
之所以會(huì)運(yùn)行失敗,是因?yàn)楫?dāng)前只告訴了編譯器動(dòng)態(tài)庫(kù)的位置,沒(méi)有告訴 OS!

出現(xiàn)這種情況,可以使用 ldd 指令查看程序的鏈接情況:

$ ldd 可執(zhí)行程序

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
動(dòng)態(tài)庫(kù)處,顯示狀態(tài)為沒(méi)有鏈接,未發(fā)現(xiàn)動(dòng)態(tài)庫(kù)!

這也說(shuō)明,我們不能盲目進(jìn)行鏈接,在此之前我們需要讓操作系統(tǒng)知道庫(kù)的位置,有三種方法:

  • 1.修改臨時(shí)環(huán)境變量: 添加動(dòng)態(tài)庫(kù)路徑至 LD_LIBRARY_PATH 環(huán)境變量中;因?yàn)榄h(huán)境變量 LD_LIBRARY_PATH 是程序在進(jìn)行動(dòng)態(tài)庫(kù)查找時(shí)的默認(rèn)搜索路徑。
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/動(dòng)態(tài)庫(kù)目錄詳細(xì)(絕對(duì))路徑/

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
注意: 更改環(huán)境變量只是臨時(shí)方案,重新登錄bash后就失效了,需要重新配置

  • 2.將動(dòng)態(tài)庫(kù)的軟鏈接文件存入系統(tǒng)目錄中

    我們將動(dòng)態(tài)庫(kù)建立軟鏈接放入系統(tǒng)庫(kù)目錄中(普通用戶(hù)需要sudo提權(quán))
# ln -s /動(dòng)態(tài)庫(kù)絕對(duì)路徑/ /lib64/動(dòng)態(tài)庫(kù)名稱(chēng)(與軟鏈接的動(dòng)態(tài)庫(kù)名稱(chēng)相同)
 $ ln -s /home/ARMCSKGT/演示文件夾/lib/libmymath.so /lib64/libmymath.so

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
注意: 創(chuàng)建軟連接文件時(shí),需要使用絕對(duì)路徑;這種方式的修改是永久有效的,但是我們不建議使用,如果非必要建議用后刪除,避免沖突和污染系統(tǒng)環(huán)境。

  • 3.更改配置文件中的信息
    系統(tǒng)的第三個(gè)動(dòng)態(tài)庫(kù)查找路徑就是前往動(dòng)態(tài)庫(kù)配置目錄的各配置文件提供的路徑中查找,我們可以寫(xiě)一個(gè)自己配置文件,里面寫(xiě)入動(dòng)態(tài)庫(kù)的路徑,放入該目錄中!
$ touch mylib.conf  #創(chuàng)建一個(gè)配置文件
$ echo /home/ARMCSKGT/演示文件夾/lib/ > mylib.conf #將動(dòng)態(tài)庫(kù)絕對(duì)路徑寫(xiě)入配置文件
$ mv mylib.conf /etc/ld.so.conf.d/ #將配置文件放入系統(tǒng)目錄/etc/ld.so.conf.d/中
$ ldconfig #重新加載系統(tǒng)配置文件

說(shuō)明: mv和ldconfig操作在普通用戶(hù)操作下需要sudo提權(quán)
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
注意: 這種方式的修改也是永久有效的,如果非必要建議用后刪除,避免沖突和污染系統(tǒng)環(huán)境。

關(guān)于動(dòng)態(tài)鏈接

動(dòng)態(tài)庫(kù)的鏈接:將可執(zhí)行程序中的外部符號(hào)替換為庫(kù)中的具體地址,在程序執(zhí)行時(shí)直接將庫(kù)地址加載到內(nèi)存中,只要我們把庫(kù)加載到內(nèi)存,映射到進(jìn)程的地址空間中后,我們的代碼執(zhí)行庫(kù)中的方法,就依舊還是在自己的地址空間內(nèi)進(jìn)行函數(shù)跳轉(zhuǎn),當(dāng)庫(kù)因?yàn)槌绦蛘{(diào)用已經(jīng)在內(nèi)存中,另一個(gè)程序使用時(shí)就直接在頁(yè)表中映射然后在共享空間中調(diào)用即可!

動(dòng)態(tài)庫(kù)的方法只需要在內(nèi)存中存在一份就可以被所有進(jìn)程使用了,庫(kù)的加載也不一定是全部加載到內(nèi)存,使用什么加載什么就行,具體根據(jù)操作系統(tǒng)的策略就行操作。

程序在鏈接動(dòng)態(tài)庫(kù)函數(shù)時(shí),是通過(guò) 動(dòng)態(tài)庫(kù)起始地址 + 所鏈接函數(shù)偏移量 的方式進(jìn)行鏈接訪問(wèn)的,而這個(gè)偏移量就是 fPIC 與位置無(wú)關(guān)碼!

地址就兩類(lèi):絕對(duì)編址 and 相對(duì)編制

靜態(tài)鏈接時(shí),將可鏈接的二進(jìn)制文件加載至程序中,直接通過(guò) 絕對(duì)地址 進(jìn)行鏈接,如果函數(shù)被調(diào)用了多次,就會(huì)導(dǎo)致代碼冗余等問(wèn)題。
動(dòng)態(tài)鏈接采用 相對(duì)地址 的方式進(jìn)行鏈接,同一個(gè)函數(shù)的 動(dòng)態(tài)庫(kù)起始地址 + 所鏈接函數(shù)偏移量 值相同,代碼只需要加載一份,并且可以任意位置進(jìn)行函數(shù)調(diào)用(與位置無(wú)關(guān))。

動(dòng)態(tài)庫(kù)必定面臨一個(gè)問(wèn)題:不同的進(jìn)程,運(yùn)行程度不同,需要使用的第三方庫(kù)不同,注定了每一個(gè)進(jìn)程的共享空間中的空閑位置是不確定的

動(dòng)態(tài)庫(kù)中的地址,絕對(duì)不能確定,去使用絕對(duì)編址,動(dòng)態(tài)庫(kù)中的所有地址都是偏移量,默認(rèn)從0地址開(kāi)始,當(dāng)一個(gè)庫(kù)真正被映射到地址空間時(shí),他的起始地址才能真正確定,動(dòng)態(tài)庫(kù)在進(jìn)程的地址空間中隨便加載,與我們加載到地址空間的什么位置毫無(wú)關(guān)系!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器


補(bǔ)充

當(dāng)同時(shí)存在動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)時(shí),編譯器默認(rèn)采用動(dòng)態(tài)庫(kù)!

如果我們想指定生成靜態(tài)庫(kù)程序,只需要加上 -static 選項(xiàng)即可:

$ g++ [代碼文件.cpp] -static #如果是第三方庫(kù)需要指定頭文件,庫(kù)路徑和庫(kù)名稱(chēng)

如果只提供靜態(tài)庫(kù),但編譯時(shí)不加-static,編譯時(shí)會(huì)將靜態(tài)庫(kù)進(jìn)行靜態(tài)鏈接(結(jié)合具體的情況)(將可以動(dòng)態(tài)鏈接的庫(kù)動(dòng)態(tài)鏈接,然后將不能動(dòng)態(tài)鏈接的靜態(tài)庫(kù)中代碼拷貝到文件中),可以動(dòng)態(tài)鏈接的庫(kù)進(jìn)行動(dòng)態(tài)鏈接!

Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器
靜態(tài)鏈接生成的程序比動(dòng)態(tài)鏈接大得多,并且內(nèi)含靜態(tài)庫(kù)的動(dòng)態(tài)鏈接程序,也比純粹的動(dòng)態(tài)鏈接程序大,說(shuō)明程序不是 非靜即動(dòng),可以同時(shí)使用動(dòng)態(tài)庫(kù)與靜態(tài)庫(kù)!


最后

以上就是 【Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù)】 的全部?jī)?nèi)容了,本節(jié)我們結(jié)束了如同快捷方式一樣的軟硬鏈接,讓我們可以對(duì)目標(biāo)建立鏈接快速訪問(wèn),同時(shí)學(xué)習(xí)了程序的運(yùn)行需要庫(kù)的加持,動(dòng)靜態(tài)庫(kù)的區(qū)別,學(xué)習(xí)了制作庫(kù),最后介紹了庫(kù)的鏈接原理,相信本次的介紹可以幫助各位開(kāi)發(fā)者!

本次 <Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù)> 就先介紹到這里啦,希望能夠盡可能幫助到大家。

如果文章中有瑕疵,還請(qǐng)各位大佬細(xì)心點(diǎn)評(píng)和留言,我將立即修補(bǔ)錯(cuò)誤,謝謝!
Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù),Linux知識(shí)與編程,linux,運(yùn)維,服務(wù)器

文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-713192.html

??其他文章閱讀推薦??
Linux<文件系統(tǒng)概述> -CSDN博客
Linux<重定向和緩沖區(qū)理解> -CSDN博客
Linux<文件理解和系統(tǒng)調(diào)用> -CSDN博客
Linux<進(jìn)程控制> -CSDN博客
Linux<進(jìn)程地址空間> -CSDN博客
??歡迎讀者多多瀏覽多多支持!??

到了這里,關(guān)于Linux軟硬鏈接和動(dòng)靜態(tài)庫(kù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Linux】軟硬鏈接與動(dòng)靜態(tài)庫(kù)

    【Linux】軟硬鏈接與動(dòng)靜態(tài)庫(kù)

    相關(guān)文章: 【Linux】動(dòng)靜態(tài)庫(kù)以及動(dòng)靜態(tài)鏈接 【Linux】基礎(chǔ)IO_文件系統(tǒng) 我們知道,每一個(gè)文件都會(huì)有自己的inode編號(hào),我們可以通過(guò)如下指令來(lái)查看: ?我們發(fā)現(xiàn), 每一個(gè)不同文件的inode編號(hào)都不相同,所以inode可以說(shuō)是用來(lái)標(biāo)識(shí)文件的標(biāo)識(shí)符 。接下來(lái),我們通過(guò)下面指令來(lái)

    2024年02月10日
    瀏覽(20)
  • 【看表情包學(xué)Linux】軟硬鏈接 | 軟連接數(shù) | 創(chuàng)建軟硬鏈接 | 動(dòng)靜態(tài)庫(kù) | 生成靜態(tài)庫(kù) | 生成動(dòng)態(tài)庫(kù)

    【看表情包學(xué)Linux】軟硬鏈接 | 軟連接數(shù) | 創(chuàng)建軟硬鏈接 | 動(dòng)靜態(tài)庫(kù) | 生成靜態(tài)庫(kù) | 生成動(dòng)態(tài)庫(kù)

    ?? ??? 爆笑 教程 ????《看表情包學(xué)Linux》?? ? 猛戳訂閱 ? ? ?? ?? 寫(xiě)在前面: 上一章我們講解了 inode,為文件系統(tǒng)收了尾,這幾章我們充分地講解完了文件系統(tǒng)的知識(shí)點(diǎn),現(xiàn)在我們開(kāi)始開(kāi)始學(xué)習(xí)軟硬鏈接了。如果沒(méi)有文件系統(tǒng)的鋪墊,想直接理解軟硬鏈接難免有些困

    2024年02月14日
    瀏覽(40)
  • 【看表情包學(xué)Linux】軟硬鏈接 | 動(dòng)靜態(tài)庫(kù)

    【看表情包學(xué)Linux】軟硬鏈接 | 動(dòng)靜態(tài)庫(kù)

    ?? ??? 爆笑 教程 ????《看表情包學(xué)Linux》?? ? 猛戳訂閱 ? ? ?? ?? 寫(xiě)在前面: 上一章我們講解了 inode,為文件系統(tǒng)收了尾,這幾章我們充分地講解完了文件系統(tǒng)的知識(shí)點(diǎn),現(xiàn)在我們開(kāi)始開(kāi)始學(xué)習(xí)軟硬鏈接了。如果沒(méi)有文件系統(tǒng)的鋪墊,想直接理解軟硬鏈接難免有些困

    2024年02月16日
    瀏覽(21)
  • 【Linux】基礎(chǔ)IO——文件系統(tǒng)|軟硬鏈接|動(dòng)靜態(tài)庫(kù)

    【Linux】基礎(chǔ)IO——文件系統(tǒng)|軟硬鏈接|動(dòng)靜態(tài)庫(kù)

    基于上篇博客所寫(xiě)到的文件各種操作都是基于被打開(kāi)文件所進(jìn)行操作的,那么如果一個(gè)文件沒(méi)有被打開(kāi)它存在哪里呢?這個(gè)答案毫無(wú)疑問(wèn)肯定是存在于磁盤(pán)上的。那么,對(duì)于一個(gè)沒(méi)有打開(kāi)的文件(也就是磁盤(pán)文件)我們應(yīng)該如何理解呢? 這里我們所要講的磁盤(pán)是機(jī)械硬盤(pán)、即

    2024年02月04日
    瀏覽(21)
  • Linux基礎(chǔ)IO【軟硬鏈接與動(dòng)靜態(tài)庫(kù)】

    Linux基礎(chǔ)IO【軟硬鏈接與動(dòng)靜態(tài)庫(kù)】

    ?個(gè)人主頁(yè): 北 海 ??所屬專(zhuān)欄: Linux學(xué)習(xí)之旅 ??操作環(huán)境: CentOS 7.6 阿里云遠(yuǎn)程服務(wù)器 假設(shè)你下載了一款游戲,你是否會(huì)跑到游戲所在目錄中雙擊 .exe 打開(kāi)游戲?答案是不會(huì),大多數(shù)人都會(huì)通過(guò)桌面的快捷方式直接打開(kāi)文件,而這個(gè)快捷方式實(shí)際就是對(duì) .exe 的 軟鏈接 文

    2024年02月02日
    瀏覽(24)
  • 【linux深入剖析】深入理解軟硬鏈接 | 動(dòng)靜態(tài)庫(kù)的制作以及使用

    【linux深入剖析】深入理解軟硬鏈接 | 動(dòng)靜態(tài)庫(kù)的制作以及使用

    ??你好,我是 RO-BERRY ?? 致力于C、C++、數(shù)據(jù)結(jié)構(gòu)、TCP/IP、數(shù)據(jù)庫(kù)等等一系列知識(shí) ??感謝你的陪伴與支持 ,故事既有了開(kāi)頭,就要畫(huà)上一個(gè)完美的句號(hào),讓我們一起加油 軟鏈接和硬鏈接是在Linux系統(tǒng)中常見(jiàn)的文件鏈接方式。 軟鏈接(Symbolic Link): 軟鏈接是一個(gè)指向目標(biāo)文

    2024年04月13日
    瀏覽(25)
  • [Linux]理解文件系統(tǒng)!動(dòng)靜態(tài)庫(kù)詳細(xì)制作使用?。ň彌_區(qū)、inode、軟硬鏈接、動(dòng)靜態(tài)庫(kù))

    [Linux]理解文件系統(tǒng)!動(dòng)靜態(tài)庫(kù)詳細(xì)制作使用?。ň彌_區(qū)、inode、軟硬鏈接、動(dòng)靜態(tài)庫(kù))

    ? ? ? ? hello,大家好,這里是bang___bang_,今天來(lái)談?wù)劦奈募到y(tǒng)知識(shí),包含有緩沖區(qū)、inode、軟硬鏈接、動(dòng)靜態(tài)庫(kù)。本篇旨在分享記錄知識(shí),如有需要,希望能有所幫助。 目錄 1??緩沖區(qū) ??緩沖區(qū)的意義 ??常見(jiàn)緩沖區(qū)刷新策略 ??緩沖區(qū)位置猜想 ??現(xiàn)象猜測(cè) ??現(xiàn)象解

    2024年02月13日
    瀏覽(27)
  • 【探索Linux】—— 強(qiáng)大的命令行工具 P.13(文件系統(tǒng) | 軟硬鏈接 | 動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù))

    【探索Linux】—— 強(qiáng)大的命令行工具 P.13(文件系統(tǒng) | 軟硬鏈接 | 動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù))

    在計(jì)算機(jī)科學(xué)領(lǐng)域中,Linux 系統(tǒng)一直以來(lái)都是備受推崇的操作系統(tǒng)之一。其中,文件系統(tǒng)、軟硬鏈接、動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)是 Linux 系統(tǒng)中非常重要的概念,在實(shí)際應(yīng)用中扮演著不可或缺的角色。 在上一篇文章中,我們了解了 Linux 系統(tǒng)中文件描述符、重定向以及基礎(chǔ) IO 操作的相關(guān)

    2024年02月04日
    瀏覽(21)
  • 【Linux】-- 基礎(chǔ)IO和動(dòng)靜態(tài)庫(kù)

    【Linux】-- 基礎(chǔ)IO和動(dòng)靜態(tài)庫(kù)

    對(duì)于C文件接口,假如想向特定文件寫(xiě)入字符串: cFile.c 執(zhí)行結(jié)果如下,查看log.txt文件: 假如想從特定文件讀字符串,從log.txt中按行讀取,讀取的內(nèi)容放在緩沖區(qū),如果fgets讀取成功,返回讀取的新字符串的地址,如果讀取失敗就返回NULL,feof用來(lái)判斷文件是否正常退出,即

    2024年02月07日
    瀏覽(23)
  • linux之文件系統(tǒng)、inode和動(dòng)靜態(tài)庫(kù)制作和發(fā)布

    linux之文件系統(tǒng)、inode和動(dòng)靜態(tài)庫(kù)制作和發(fā)布

    1.沒(méi)有被打開(kāi)的文件都在磁盤(pán)上? --- 磁盤(pán)級(jí)文件 2.對(duì)磁盤(pán)級(jí)別的文件,我們的側(cè)重點(diǎn) 單個(gè)文件角度 -- 這個(gè)文件在哪里,有多大,其他屬性是什么? 站在系統(tǒng)角度 --? 一共有多少文件?各自屬性在哪里?如何快速找到?可以存儲(chǔ)多少個(gè)文件?如何快速找到指定文件?如何對(duì)此

    2024年04月10日
    瀏覽(21)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包