0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux中的靜態(tài)庫和共享庫

嵌入式攻城獅 ? 來源:嵌入式攻城獅 ? 2023-05-10 09:34 ? 次閱讀

一. 什么是庫

庫是一個二進制文件,包含的代碼可被程序調用。例如標準C庫、數學庫、線程庫等等。庫有源碼,可下載后編譯,也可以直接安裝二進制包。 庫是事先編譯好的,可以復用的代碼,在OS上運行的程序基本上都要使用庫。使用庫可以提高開發(fā)效率。Windows和Linux下庫文件的格式不兼容。Linux下包含靜態(tài)庫和共享庫。

二. 靜態(tài)庫

靜態(tài)庫有如下特點

編譯(鏈接)時把靜態(tài)庫中相關代碼復制到可執(zhí)行文件中

程序中包含代碼,運行時不再需要靜態(tài)庫

程序運行時無需加載庫,運行速度更快

占用更多磁盤和空間

靜態(tài)庫升級后,程序需要重新編譯鏈接

靜態(tài)庫的創(chuàng)建與鏈接參考如下步驟: 第一步:確定庫中函數的功能、接口

第二步:編寫庫源碼

/****hello.c****/
#include
#include"hello.h"

voidhello(void){
   printf("helloAndyxi
");
}
/****hello.h****/
#ifndef_HELLO_H_
#define_HELLO_H_

voidhello(void);

#endif

第三步:編譯生成目標文件

linux@linux:~/andy/lib$ls
hello.chello.h
linux@linux:~/andy/lib$gcc-chello.c-Wall
linux@linux:~/andy/lib$ls
hello.chello.hhello.o

第四步:創(chuàng)建靜態(tài)庫

linux@linux:~/andy/lib$ls
hello.chello.hhello.o
linux@linux:~/andy/lib$arcrslibhello.ahello.o//使用arcrs命令創(chuàng)建靜態(tài)庫
linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.a   //注意libhello.a是庫文件名,hello是庫名
linux@linux:~/andy/lib$nmlibhello.a   //使用nm命令可查看庫中符號信息

hello.o:
00000000Thello
Uputs

第五步:編寫應用程序

/****test.c****/
#include
#include"hello.h"

intmain(intargc,constchar*argv[]){
   hello();
return0;
}

第六步:編譯應用程序并鏈接靜態(tài)庫

linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.atest.c
linux@linux:~/andy/lib$gcc-otesttest.c-L.-l hello //使用-L.-l+庫名鏈接靜態(tài)庫
linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.atesttest.c
linux@linux:~/andy/lib$./test
helloAndyxi

由于使用的是靜態(tài)庫,編譯后相關代碼已經復制到可執(zhí)行文件中。刪除靜態(tài)庫,不影響程序執(zhí)行

linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.atesttest.c
linux@linux:~/andy/lib$rmlibhello.a
linux@linux:~/andy/lib$ls
hello.chello.hhello.otesttest.c
linux@linux:~/andy/lib$./test
helloAndyxi

三. 共享庫

共享庫有如下特點:

編譯(鏈接)時僅記錄用到哪個共享庫中的哪個符號,不復制共享庫中相關代碼

程序不包含庫中代碼,尺寸小

多個程序可共享一個庫

程序運行時需要加載庫

庫升級方便,無需重新編譯程序

使用更加廣泛

共享庫的創(chuàng)建與鏈接參考如下步驟: 第一步:確定庫中函數的功能、接口

第二步:編寫庫源碼

/****hello.c****/
#include

voidhello(void){
   printf("helloworld
");
   return;
}
/****bye.c****/
#include

voidbye(void){
   printf("bye!
");
   return;
}
/****共享庫頭文件common.h****/
#ifndef__COMMON_H__
#define__COMMON_H__

voidhello(void);
voidbye(void);

#endif

第三步:編譯生成目標文件

linux@linux:~/andy/lib/share$ls
bye.ccommon.hhello.c
linux@linux:~/andy/lib/share$gcc-c-fPIC*.c-Wall
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.o

fPIC選項:告訴編譯器生成位置無關代碼

位置無關代碼:生成的".o文件"文件中的代碼可以被加載到任意的地址執(zhí)行。編譯時用到了相對尋址而不是絕對尋址

第四步:創(chuàng)建共享庫common

linux@linux:~/andy/lib/share$gcc-shared-olibcommon.so.1hello.obye.o
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.so.1

shared選項:告訴編譯器生成一個共享庫

生成的共享庫的文件名叫"libcommon.so.1",其中".so"表示這是一個共享庫,".1"表示這個庫的版本是1

符號鏈接文件命名規(guī)則:lib<庫名>.so

第五步:編寫應用程序

/****test.c****/
#include
#include"common.h"

intmain(intargc,constchar*argv[]){
   hello();
   bye();
return0;
}

第六步:編譯應用程序并鏈接共享庫

#****為共享庫文件創(chuàng)建鏈接文件****#
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.so.1test.c
linux@linux:~/andy/lib/share$ln-slibcommon.so.1libcommon.so //ln-s創(chuàng)建符號鏈接
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.solibcommon.so.1test.c

#****編譯應用程序并鏈接共享庫****#
linux@linux:~/andy/lib/share$gcc-otesttest.c-L.-lcommon
linux@linux-:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.solibcommon.so.1testtest.c

gcc -o test test.c -L. -lcommon:可見此處共享庫和靜態(tài)庫用法相同;GCC在鏈接時首先找共享庫,如果共享庫不存在,則鏈接靜態(tài)庫,如果靜態(tài)庫也找不到,則報錯

加"-static"選項后,編譯器會直接去找靜態(tài)庫

共享庫的加載:如果完成上述步驟后就執(zhí)行程序,會報如下錯誤

linux@linux:~/andy/lib/share$./test
./test:errorwhileloadingsharedlibraries:libcommon.so:cannotopensharedobjectfile:Nosuchfileordirectory

出錯原因:因為程序鏈接的是共享庫,并沒有復制共享庫中的代碼,程序在執(zhí)行時會去加載用到的共享庫,加載時會去缺省路徑(比如"/lib","/usr/lib")下尋找共享庫,但是我們創(chuàng)建的庫在當前目錄下,并不在系統(tǒng)庫的搜索路徑里,所以在執(zhí)行時找不到共享庫,因此報錯

創(chuàng)建好共享庫后還需要添加共享庫加載路徑

第七步:加載共享庫并執(zhí)行程序

linux@linux:~/andy/lib/share$exportLD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
linux@linux:~/andy/lib/share$./test
helloworld
bye!

export 用于將原來的環(huán)境變量導出

":"前面的"$LD_LIBRARY_PATH"是引用原先的值;":"后面的"."是追加了當前目錄;還可追加其余共享庫的路徑,要用":"隔開

此方法是臨時的,只對當前終端有效。當重新打開一個終端再執(zhí)行改程序時又會報錯

為了讓系統(tǒng)能找到要加載的共享庫,通常由三種方法:

把庫拷貝到/usr/lib和/lib目錄下

在LD_LIBRARY_PATH環(huán)境變量中添加庫所在路徑

添加/etc/ld.so.conf.d/*.conf文件,執(zhí)行 ldconfig刷新

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11123

    瀏覽量

    207888
  • 函數
    +關注

    關注

    3

    文章

    4234

    瀏覽量

    61961
  • 靜態(tài)庫
    +關注

    關注

    0

    文章

    21

    瀏覽量

    7407
  • 編譯
    +關注

    關注

    0

    文章

    646

    瀏覽量

    32664
  • 共享庫
    +關注

    關注

    0

    文章

    4

    瀏覽量

    5605

原文標題:Linux 中的靜態(tài)庫和共享庫

文章出處:【微信號:嵌入式攻城獅,微信公眾號:嵌入式攻城獅】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    動態(tài)靜態(tài)的區(qū)別

    一、什么是本質上來說庫是一種可執(zhí)行代碼的二進制形式,可以***作系統(tǒng)載入內存執(zhí)行。二、的種類linux下的有兩種:靜態(tài)
    發(fā)表于 05-26 17:22

    Linux下動態(tài)靜態(tài)的制作及使用

    可執(zhí)行代碼的二進制格式,可以被載入內存執(zhí)行。根據鏈接時期的不同,又有:靜態(tài)共享(動態(tài)
    發(fā)表于 11-18 17:05

    Linux靜態(tài)和動態(tài)的制作與使用

    什么是靜態(tài)函數庫?動態(tài)函數又是什么?linux靜態(tài)函數庫是怎樣創(chuàng)建并使用的?動態(tài)函數是怎樣創(chuàng)建并使用的?
    發(fā)表于 04-26 06:45

    Linux系統(tǒng)共享編程

    一、說明 類似Windows系統(tǒng)的動態(tài)鏈接Linux也有相應的共享用以支持代碼的復用
    發(fā)表于 09-13 16:49 ?24次下載

    Linux靜態(tài)和動態(tài)共享)的制作與使用

    Linux靜態(tài)和動態(tài)共享)的制作與使用Linux
    發(fā)表于 07-09 14:39 ?1114次閱讀

    linux靜態(tài)和動態(tài)分析

    的二進制是不兼容的。 本文僅限于介紹linux下的。 2.的種類 linux下的有兩種:靜態(tài)
    發(fā)表于 11-02 10:12 ?1次下載

    Linux靜態(tài)元件資料合集免費下載

    本文檔的主要內容詳細介紹的是Linux靜態(tài)元件資料合集免費下載
    發(fā)表于 12-28 17:04 ?6次下載

    你知道linux 靜態(tài)共享

    靜態(tài)鏈接和動態(tài)鏈接的區(qū)別在于,主程序在運行前,靜態(tài)鏈接的鏈接固定寫入在程序,而動態(tài)鏈接
    發(fā)表于 04-26 16:46 ?2828次閱讀

    講解Linux虛擬機之使用動態(tài)靜態(tài)

    了解 Linux 如何使用,包括靜態(tài)和動態(tài)的差別,有助于你解決依賴問題。
    發(fā)表于 05-06 17:05 ?2069次閱讀
    講解<b class='flag-5'>Linux</b>虛擬機之使用動態(tài)<b class='flag-5'>庫</b>和<b class='flag-5'>靜態(tài)</b><b class='flag-5'>庫</b>

    C++基礎語法知識之鏈接裝載Linux共享

    Linux共享(Shared Library) Linux 下的共享就是普通的 ELF
    的頭像 發(fā)表于 11-01 10:15 ?2810次閱讀

    嵌入式Linux下動態(tài)靜態(tài)使用

    以下主要介紹Linux 下動態(tài)、靜態(tài)、如何使用已有的動態(tài), 以及如何制作一個動態(tài)。
    發(fā)表于 11-01 16:57 ?1次下載
    嵌入式<b class='flag-5'>Linux</b>下動態(tài)<b class='flag-5'>庫</b>和<b class='flag-5'>靜態(tài)</b><b class='flag-5'>庫</b>使用

    Linux下動態(tài)靜態(tài)制作與調用

    靜態(tài)是指在應用,有一些公共代碼需要反復使用,就把這些代碼編譯為“”文件;在鏈接步驟,連接器將從
    的頭像 發(fā)表于 08-24 15:03 ?3559次閱讀
    <b class='flag-5'>Linux</b>下動態(tài)<b class='flag-5'>庫</b>和<b class='flag-5'>靜態(tài)</b><b class='flag-5'>庫</b>制作與調用

    Linux開發(fā)_動態(tài)靜態(tài)創(chuàng)建與Makefile規(guī)則

    介紹Linux靜態(tài)、動態(tài)創(chuàng)建方式、完成靜態(tài)、動態(tài)
    的頭像 發(fā)表于 09-17 15:41 ?1056次閱讀

    動態(tài)靜態(tài)的制作步驟

    是一種可執(zhí)行的二進制文件,是編譯好的代碼。使用可以提高開發(fā)效率。在 Linux 下有靜態(tài)和動態(tài)
    的頭像 發(fā)表于 07-27 11:00 ?697次閱讀

    如何查看linux程序共享呢?

    linux系統(tǒng),程序通常需要依賴于外部來正常工作。這些可以直接編譯到程序,也可以從共享
    的頭像 發(fā)表于 08-28 09:11 ?1358次閱讀
    如何查看<b class='flag-5'>linux</b>程序<b class='flag-5'>共享</b><b class='flag-5'>庫</b>呢?