1. 程式人生 > >Linux學習筆記——如何在交叉編譯時使用共享庫

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

1.交叉編譯獲得動態連結庫
    本例先製作一個非常簡單的共享庫,共享庫包含兩個API——add和sub。    【libtest.h】    指定介面,給出相應宣告#ifndef __LIBTEST_H#define __LIBTEST_Hint sub(int a, int b);int add(int a, int b);#endif    【test-add.c】int add(int a, int b){    return a+b;}    【test-sub.c】int sub(int a, int b){    return a-b;}    【makefile】    在同目錄下包含makefile檔案,請替換其中的[tab],並以程式碼倉庫中的makefile檔案為主。編譯完成之後,把libtest.so移動到上級lib目錄中。請注意此時的交叉工具鏈為arm-linux-gnueabihf-gcc ,目標b
# 指令編譯器和選項CC = arm-linux-gnueabihf-gccCFLAGS = -Wall -std=gnu99# 目標檔案TARGET = libtest.so# C檔案SRCS = test-add.c test-sub.c# 目標檔案OBJS = $(SRCS:.c=.o)# 連結為可執行檔案$(TARGET):$(OBJS)[tab]$(CC) -shared -o
[email protected]
$^[tab]mv $(TARGET) ../libclean:[tab]rm -rf $(TARGET) $(OBJS)# 編譯規則 [email protected]代表目標檔案 $< 代表第一個依賴檔案%.o:%.c[tab]$(CC) $(CFLAGS) -o [email protected] -fPIC -c $<    【必要的驗證】    使用file指令檢視libtest.so資訊。    file libtest.solibtest.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 <stdio.h>#include <libtest.h>int main(void){    int a = 3;    int b = 2;    printf("a=%d\n", a);    printf("b=%d\n", b);    printf("a+b=%d\n", add(a, b));    printf("a-b=%d\n", sub(a, b));    return 0;}    【makefile檔案】    # 指定編譯器和選項# 指定樹莓派交叉編譯器CC = arm-linux-gnueabihf-gccCFLAGS = -Wall -std=gnu99# 目標檔案TARGET = test# C檔案SRCS = test.c# 標頭檔案查詢路徑INC = -I.# 庫檔案和庫查詢路徑DLIBS = -ltestLDFLAGS = -L./lib# 目標檔案OBJS = $(SRCS:.c=.o)# 連結為可執行檔案$(TARGET):$(OBJS)[tab]$(CC) -o
[email protected]
$^ $(LDFLAGS) $(DLIBS)clean:[tab]rm -rf $(TARGET) $(OBJS)# 編譯規則 [email protected]代表目標檔案 $< 代表第一個依賴檔案%.o:%.c[tab]$(CC) $(CFLAGS) $(INC) -o [email protected] -c $<    【說明】    【1】交叉工具鏈為arm-linux-gnueabihf-gcc    【2】指定了交叉編譯之後的共享庫和共享庫路徑,連結共享庫使用-ltest,共享庫位於lib目錄下。請注意-ltest對應libtest.so。    【3】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.so4.執行    【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.總結    回答在前言中的問題。    【1】交叉編譯時的共享庫是否需要放置於目標板中,如果需要放置在哪個目錄中。    交叉編譯之後的共享庫需要複製到目標板中,最好放置於/usr/lib或/lib中,當然也有其他的方法,在這裡不詳細說明。    【2】交叉編譯時的共享庫是否需要放置於宿主機中,如果需要放置於哪個目錄中。    交叉編譯時確切的說連結過程中需要指定共享庫的問題,通過-L指定目錄,通過-l指定共享庫名稱。但是此時交叉編譯的共享庫最好不要放置於宿主機的/lib或/usr/lib中,以免產生混淆。    綜合【1】和【2】,libtest.so同時存在於目標板和宿主機中。    【3】交叉編譯時如何指定共享庫    通過-L指定目錄,通過-l指定共享庫名稱    【4】程式執行時如何查詢共享庫    最直觀的方法,複製到/usr/lib目錄中,讓linux系統自動查詢。    最後,發現博文寫多了自己感覺好累啊,希望這些總結對大家有用。