日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

大家好,我是阿木實(shí)驗(yàn)室的松溪,今天給大家介紹一下,linux系統(tǒng)中,庫(kù)的概念。

一、庫(kù)的簡(jiǎn)介

什么是庫(kù),庫(kù)簡(jiǎn)單地說,就是模塊。用于提供不同功能的模塊,比如我們經(jīng)常會(huì)用的ceres庫(kù),eigen庫(kù),pcl庫(kù)等等。庫(kù)從本質(zhì)上來說,是一種可以執(zhí)行代碼的二進(jìn)制形式,可以被載入到內(nèi)存中使用,在Liunx系統(tǒng)中,庫(kù)以文件的形式存在,并且可以分為動(dòng)態(tài)鏈接庫(kù)靜態(tài)鏈接庫(kù)兩種,簡(jiǎn)稱為動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)。其中,靜態(tài)庫(kù)文件的后綴為.a,動(dòng)態(tài)庫(kù)文件的后綴為.so。無論是動(dòng)態(tài)庫(kù)還是靜態(tài)庫(kù),它們無非是向調(diào)用的人提供變量、函數(shù)或者類。

二、庫(kù)的區(qū)別

靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別在于:二者代碼被載入的時(shí)刻不同。靜態(tài)庫(kù)在程序編譯的時(shí)候會(huì)被鏈接到目標(biāo)代碼中,目標(biāo)程序運(yùn)行的時(shí)候?qū)⒉辉傩枰搸?kù),移植方便,但是體積會(huì)變大,浪費(fèi)空間和資源,因?yàn)榕c之相關(guān)的所有文件都會(huì)鏈接合成一個(gè)可執(zhí)行文件,導(dǎo)致可執(zhí)行文件的體積變大。動(dòng)態(tài)庫(kù)在程序編譯的時(shí)候并不會(huì)被鏈接到目標(biāo)代碼中,而是在程序運(yùn)行的時(shí)候才被載入,因此可執(zhí)行文件體積較小。

基本上,大部分的庫(kù)都是動(dòng)態(tài)庫(kù),比如:eigen,ceres等,這就是我們通常所說的依賴項(xiàng),如果你的程序中有需要某個(gè)庫(kù),而你的環(huán)境中沒有這樣的庫(kù),那么在編譯的時(shí)候就會(huì)出現(xiàn)這樣的錯(cuò)誤:xxxx.h文件未找到。這就是典型的缺少動(dòng)態(tài)庫(kù)的bug。對(duì)此,只需要安裝對(duì)應(yīng)的動(dòng)態(tài)庫(kù)即可解決。這個(gè)問題經(jīng)常出現(xiàn)在當(dāng)你clone某一個(gè)代碼下來,但是卻沒有這個(gè)代碼的運(yùn)行環(huán)境,當(dāng)你編譯的時(shí)候,就會(huì)出現(xiàn)上面的報(bào)錯(cuò)。是不是又get到了一個(gè)小技巧呢?

三、靜態(tài)庫(kù)的創(chuàng)建和使用

在Linux系統(tǒng)中創(chuàng)建靜態(tài)庫(kù)的過程如下:

1. 編輯源文件(.c或.cpp文件)

2. 通過 gcc -c xxx.c 或 g++ -c xxx.cpp 生成目標(biāo)文件(.o文件)

3. 使用 ar 命令歸檔目標(biāo)文件,生成靜態(tài)庫(kù)

4. 配合靜態(tài)庫(kù)寫一個(gè)頭文件,文件里的內(nèi)容就是提供給調(diào)用者使用的函數(shù)、變量或者類的聲明。

在實(shí)際創(chuàng)建之前,有必要了解一下,ar命令的使用。ar命令不但可以創(chuàng)建靜態(tài)庫(kù),也可以修改或提取已有靜態(tài)庫(kù)中的信息,其基本用法如下:

ar [option] libxxx.a xx1.o xx2.o xx3.o

其中,libxxx.a是生成靜態(tài)庫(kù)的文件名字,xxx是自己設(shè)定的名稱,lib表示該文件是一個(gè)庫(kù),所有在Linux下的庫(kù),都遵守這種命名。即libxxx.a或者libxxx.so。xx1.o xx2.o為靜態(tài)庫(kù)的目標(biāo)代碼文件,可以有多個(gè)。option常見的選項(xiàng)如下:

-c:創(chuàng)建一個(gè)庫(kù),無論庫(kù)是否存在,都會(huì)創(chuàng)建

-s:創(chuàng)建目標(biāo)文件索引

-r:在庫(kù)中插入模塊,如插入的模塊名已經(jīng)在庫(kù)中存在,則將會(huì)替換。如果有一個(gè)模塊不存在,將會(huì)保存,并不會(huì)替換其他同名模塊

-t:顯示庫(kù)文件中有哪些目標(biāo)文件。僅僅顯示

-tv:顯示庫(kù)文件有哪些目標(biāo)文件。包括文件名、時(shí)間、大小等

-s:顯示靜態(tài)庫(kù)文件中的索引表

下面將講解如何創(chuàng)建和使用一個(gè)靜態(tài)庫(kù)

新建一個(gè)源文件,test.cpp,復(fù)制以下代碼:

#include <IOStream>

void show_age(int age) {
 std::cout << "Your age is: " << age << std::endl;
 }

然后輸入命令

g++ -c test.cpp
ar rcs libshowage.a test.o

這樣就生成了一個(gè)靜態(tài)庫(kù),要想使用,需要編寫另一個(gè)源文件,demo.cpp。復(fù)制以下代碼

#include <iostream>

extern void show_age(int age);  //聲明要使用的函數(shù)

int main(int argc, char** argv) {
  show_age(18);
  std::cout << "Hi" << std::endl;
}

CMakeLists.txt文件

cmake_minimum_required(VERSION 3.0)
project(demo)

add_executable(demo demo.cpp)
target_link_libraries(demo -L.. -lshowage)

其中,-L參數(shù)表示從什么地方找這個(gè)庫(kù),(..)表示上一級(jí)目錄。-l指定具體的庫(kù),其中l(wèi)ib和.a不需要顯示寫出,編譯器會(huì)自動(dòng)去尋找libshowage.a這個(gè)文件。這也就是為什么庫(kù)命名的時(shí)候要以lib開頭。

四、動(dòng)態(tài)庫(kù)的創(chuàng)建和使用

在Linux系統(tǒng)中,存放動(dòng)態(tài)庫(kù)的路徑一般為/usr/lib。在Linux系統(tǒng)下進(jìn)行的鏈接,默認(rèn)是先鏈接動(dòng)態(tài)庫(kù),如果同時(shí)存在靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù),如果不特別指出,將與動(dòng)態(tài)庫(kù)鏈接。這樣有助于節(jié)省空間。

同理,我們創(chuàng)建一個(gè)動(dòng)態(tài)庫(kù),test.cpp。代碼同上,不做改變。只需要修改生成動(dòng)態(tài)庫(kù)的命令。該命令如下:

g++ test.cpp -fPIC -shared -o libshowage.so

-shared 表示生成共享庫(kù)

-fPIC表明使用地址無關(guān)代碼。PIC全稱是Position Independent Code。在Linux系統(tǒng)下編譯共享庫(kù)時(shí),必須加上這個(gè)參數(shù),否則在鏈接的時(shí)候?qū)?huì)報(bào)錯(cuò)。因?yàn)楣蚕韼?kù)文件可能會(huì)被不同的進(jìn)程加載到不同的位置上,如果共享對(duì)象中的指令使用了絕對(duì)地址、外部模塊地址等,那么該庫(kù)在被加載的時(shí)候,就需要修改地址,這樣就不能實(shí)現(xiàn)多進(jìn)程共享一份物理內(nèi)存。

編寫一個(gè)調(diào)用該庫(kù)的函數(shù),demo.cpp。內(nèi)容還是不變。CMakeLists.txt也不變。

五、多個(gè)文件生成一個(gè)動(dòng)態(tài)庫(kù)

創(chuàng)建test1.cpp文件,復(fù)制以下代碼

#include <iostream>

void show_age_1(int age) {
 std::cout << "This is lib_1: " << age << std::endl;
 }

創(chuàng)建test2.cpp文件,復(fù)制以下代碼

#include <iostream>

void show_age_2(int age) {
 std::cout << "This is lib_2: " << age << std::endl;
 }

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

g++ test1.cpp test2.cpp -fPIC -shared -o libshowage.so

需要說明的是,多個(gè)文件創(chuàng)建動(dòng)態(tài)庫(kù)的時(shí)候,不能有同名的函數(shù)、類、變量的聲明,否則將無法創(chuàng)建,因?yàn)榫退銊?chuàng)建成功以后,當(dāng)調(diào)用的時(shí)候,編譯器并不知道該去調(diào)用哪一個(gè)源文件里面的聲明。

創(chuàng)建 main.cpp 文件,使用這個(gè)庫(kù),復(fù)制以下代碼

#include <iostream>

//聲明要使用的函數(shù)
extern void show_age_1(int age);
extern void show_age_2(int age);

int main(int argc, char** argv) {
  show_age_1(18);
  show_age_2(36);
}

CMakeLists.txt文件如下

cmake_minimum_required(VERSION 3.0)
project(demo)

add_executable(main main.cpp)
target_link_libraries(main -L.. -lshowage)

當(dāng)我們運(yùn)行的時(shí)候,會(huì)發(fā)現(xiàn)這樣的錯(cuò)誤

./main: error while loading shared libraries: libshowage.so: cannot open shared object file: No such file or directory

在編譯的時(shí)候,我們告訴了編譯器,在什么地方去尋找該庫(kù),但是在運(yùn)行的時(shí)候,由于該庫(kù)是動(dòng)態(tài)庫(kù),其代碼沒有被鏈接到目標(biāo)代碼中,因此,在運(yùn)行的時(shí)候,會(huì)提示找不到該庫(kù)。

因此,只需要將動(dòng)態(tài)庫(kù)放到默認(rèn)的路徑上或者告訴其指定路徑即可。

在Linux系統(tǒng)中,一般將庫(kù)放在以下三個(gè)地方。其中,/lib用于放置系統(tǒng)級(jí)別(或者說內(nèi)核級(jí)別)的庫(kù)文件,/usr/lib 用于放置程序級(jí)別的庫(kù)文件,/usr/local/lib 為用戶級(jí)別,一般用戶編譯的都放在這里,以及源碼編譯安裝,例如:opencv的源碼編譯。

因此,我們要將自己的庫(kù)放在 /usr/local/lib 下,輸入以下命令

sudo cp ~/C++/demo/libshowage.so /usr/local/lib

當(dāng)我們移動(dòng)以后,需要輸入以下命令(必須),更新

sudo ldconfig

這樣,當(dāng)我們?cè)俅芜\(yùn)行的時(shí)候,就不會(huì)報(bào)錯(cuò)了。切記,每次有動(dòng)態(tài)庫(kù)在上述目錄中發(fā)生變動(dòng),都需要輸入這個(gè)命令更新,否則還是無法識(shí)別。

六、通過apt安裝缺少的動(dòng)態(tài)庫(kù)

當(dāng)我們從github上clone代碼的時(shí)候,在編譯的時(shí)候,經(jīng)常出現(xiàn)xxx.h文件不存在,或者No such file or directory。其本質(zhì)上就是你的環(huán)境和別人的環(huán)境不一致,缺少相應(yīng)的庫(kù)。一般的解決方式是,將該缺少的頭文件復(fù)制到百度,查一查這個(gè)頭文件是來自哪一個(gè)庫(kù)。然后打開終端,輸入命令

sudo apt install libxxx-dev

即可

如果是自定義的動(dòng)態(tài)庫(kù),一般在readme文檔中有說明。

同理,當(dāng)你向開源社區(qū)貢獻(xiàn)開源代碼的同時(shí),也請(qǐng)務(wù)必告知運(yùn)行的環(huán)境以及所需要的庫(kù)。

七、總結(jié)

相信通過本文的介紹,讀者對(duì)庫(kù)有了一個(gè)簡(jiǎn)單的認(rèn)識(shí),在以后的工作和學(xué)習(xí)過程中,遇到類似的問題,也有了解決問題的思路和方法。

 

阿木實(shí)驗(yàn)室致力于為機(jī)器人研發(fā)提供開源軟硬件工具和課程服務(wù),讓研發(fā)更高效!

- End -

技術(shù)發(fā)展的日新月異,阿木實(shí)驗(yàn)室將緊跟技術(shù)的腳步,不斷把機(jī)器人行業(yè)最新的技術(shù)和硬件推薦給大家。看到經(jīng)過我們培訓(xùn)的學(xué)員在技術(shù)上突飛猛進(jìn),是我們培訓(xùn)最大的價(jià)值。如果你在機(jī)器人行業(yè),就請(qǐng)關(guān)注我們的公眾號(hào),我們將持續(xù)發(fā)布機(jī)器人行業(yè)最有價(jià)值的信息和技術(shù)。

分享到:
標(biāo)簽:Linux
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定