Linux學習筆記 如何使用共享庫交叉編譯

2021-09-07 01:19:51 字數 4179 閱讀 4107

0.前言

在較為複雜的專案中會利用到交叉編譯得到的共享庫(*.so檔案)。在這樣的情況下便會產生下面疑問,比如:

交叉編譯時的共享庫是否須要放置於目標板中,假設須要放置在哪個資料夾中。

交叉編譯時的共享庫是否須要放置於宿主機中,假設須要放置於哪個資料夾中。

交叉編譯時怎樣指定共享庫

程式執行時怎樣查詢共享庫

等等問題。

博文總結了使用共享庫的一般方法。並通過乙個樣例說明問題。假設已經有了交叉編譯好的共享庫,能夠從開始,步驟僅僅是為了說明問題。捏造乙個簡單的共享庫試圖說明問題。

交叉編譯獲得鏈結庫

交叉編譯原始檔並增加鏈結庫

移動動態鏈結庫

執行

【必要說明】

【宿主機】ubuntu 14.04 amd64

【目標板】樹莓派

【相關博文】

【 例說makefile索引博文】

【 樹莓派學習筆記——交叉編譯工具鏈】

【**倉庫】——

makefile-example

1.交叉編譯獲得動態鏈結庫

本例先製作乙個很easy的共享庫。共享庫包括兩個api——add和sub。

【libtest.h】

指定介面。給出對應宣告

#ifndef __libtest_h

#define __libtest_h

int sub(int a, int b);

int add(int a, int b);

#endif

【test-add.c】

int add(int a, int b)

【test-sub.c】

int sub(int a, int b)

【makefile】

在同資料夾下包括makefile檔案,請替換當中的[tab],並以**倉庫中的makefile檔案為主。

編譯完畢之後。把libtest.so移動到上級lib資料夾中。請注意此時的交叉工具鏈為arm-linux-gnueabihf-gcc

,目標b

# 指令編譯器和選項

cc = arm-linux-gnueabihf-gcc

cflags = -wall -std=gnu99

# 目標檔案

target = libtest.so

# c檔案

srcs = test-add.c test-sub.c

# 目標檔案

objs = $(srcs:.c=.o)

# 鏈結為可執行檔案

$(target):$(objs)

[tab]$(cc) -shared -o $@ $^

[tab]mv $(target) ../lib

clean:

[tab]rm -rf $(target) $(objs)

# 編譯規則 $@代表目標檔案 $< 代表第乙個依賴檔案

%.o:%.c

[tab]$(cc) $(cflags) -o $@ -fpic -c $<

【必要的驗證】

使用file指令檢視libtest.so資訊。

file libtest.so

libtest.so: elf 32-bit lsb  

shared object, arm, eabi5

version 1 (sysv), dynamically linked, buildid[sha1]=e22558b8cf089b92e5534b636c6d501f1cc54581, not stripped

從控制台的輸出資訊能夠看出。libtest.so執行於arm平台,而不是宿主機的amd64平台。

2.交叉編譯原始檔並增加動態鏈結庫

【原始檔】

#include

#include

int main(void)

【makefile檔案】    

# 指定編譯器和選項

# 指定樹莓派交叉編譯器

cc = arm-linux-gnueabihf-gcc

cflags = -wall -std=gnu99

# 目標檔案

target = test

# c檔案

srcs = test.c

# 標頭檔案查詢路徑

inc = -i.

# 庫檔案和庫查詢路徑

dlibs = -ltest

ldflags = -l./lib

# 目標檔案

objs = $(srcs:.c=.o)

# 鏈結為可執行檔案

$(target):$(objs)

[tab]$(cc) -o $@ $^ $(ldflags) $(dlibs)

clean:

[tab]rm -rf $(target) $(objs)

# 編譯規則 $@代表目標檔案 $< 代表第乙個依賴檔案

%.o:%.c

[tab]$(cc) $(cflags) $(inc) -o $@ -c $<

【說明】

交叉工具鏈為arm-linux-gnueabihf-gcc

指定了交叉編譯之後的共享庫和共享庫路徑,鏈結共享庫使用-ltest,共享庫位於lib資料夾下。請注意-ltest相應libtest.so。

make之後可獲得可執行檔案,通過file test檢視資訊。

test: elf 32-bit lsb  

executable, arm, eabi5

version 1 (sysv), dynamically linked (uses shared libs), for gnu/linux 2.6.26, buildid[sha1]=88e4142dceabd295369657b29757141f98a03753, not stripped

從控制台的輸出能夠看出,該可執行檔案執行平台為arm,而不是amd64。

3.移動動態鏈結庫

【移動共享庫至目標板/usr/lib資料夾中】

通過ftp工具把共享庫傳輸至樹莓派中,然後通過cp指令拷貝到/usr/lib中

sudo cp libtest.so /usr/lib

linux系統中預設的搜多路徑為/lib和/usr/lib,libtest.so能夠拷貝到不論什麼資料夾中。

改動libtest.so的執行許可權。

sudo chmod 775 libtest.so

4.執行

【ftp上傳】

通過ftp工具把可執行檔案test拷貝到樹莓派中。然後通過ldd指令檢視共享庫鏈結狀態。

【檢驗】

ldd test

/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6f7f000)

libtest.so => /usr/lib/libtest.so (0xb6f6b000)

libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6e3b000)

/lib/ld-linux-armhf.so.3 (0xb6f8d000)

從控制台的輸出能夠看出,test成功鏈結了位於/usr/lib中的libtest.so

【執行】

./test

a=3

b=2

a+b=5

a-b=1

從執行結果看,前面所做的努力是正確的。

5.總結

回答在前言中的問題。

交叉編譯時的共享庫是否須要放置於目標板中,假設須要放置在哪個資料夾中。

交叉編譯之後的共享庫須要拷貝到目標板中,最好放置於/usr/lib或/lib中。當然也有其它的方法,在這裡不具體說明。

交叉編譯時的共享庫是否須要放置於宿主機中。假設須要放置於哪個資料夾中。

交叉編譯時確切的說鏈結過程中須要指定共享庫的問題,通過-l指定資料夾,通過-l指定共享庫名稱。

可是此時交叉編譯的共享庫最好不要放置於宿主機的/lib或/usr/lib中。以免產生混淆。

綜合和,libtest.so同一時候存在於目標板和宿主機中。

交叉編譯時怎樣指定共享庫

通過-l指定資料夾,通過-l指定共享庫名稱

程式執行時怎樣查詢共享庫

最直觀的方法,拷貝到/usr/lib資料夾中。讓linux系統自己主動查詢。

最後,發現博文寫多了自己感覺好累啊,希望這些總結對大家實用。

Linux學習筆記之共享記憶體

共享記憶體物件 shm 操作框架 key值 申請物件 掛載物件 讀寫物件 解除安裝物件 刪除物件 shmget shmat 記憶體讀寫 shmdt shmctl 1 申請物件 include include int shmget key t key,size t size,int shm 功能 該函...

linux學習筆記17 linux共享記憶體使用

共享記憶體的使用也是ipc的一種方式,這種方式資料拷貝次數較少,效率較高。其原理也是在記憶體中開闢一塊公共訪問的區域,可以讓各個程序連線讀寫。共享記憶體的api函式主要有以下四個 int shmget key t key,size t size,int shm 建立或加入共享記憶體 key t ke...

Linux學習筆記 四 ftp檔案共享

在linux和其他機器之間共享檔案 ftp server vsftpd 穩定,安全 sudo apt get install vsftpd apt get autoremove vsftpd 移除軟體 二.啟動vsftpd 服務 後台程式 service vsftpd start 三.測試ftp是否...