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是否...