0.前言
在較為復雜的項目中會利用到交叉編譯得到的共享庫(*.so文件)。在這種情況下便會產(chǎn)生以下疑問,例如:
【1】交叉編譯時的共享庫是否需要放置于目標板中,如果需要放置在哪個目錄中。
【2】交叉編譯時的共享庫是否需要放置于宿主機中,如果需要放置于哪個目錄中。
【3】交叉編譯時如何指定共享庫
【4】程序運行時如何查找共享庫
等等問題。
博文總結了使用共享庫的一般方法,并通過一個例子說明問題。如果已經(jīng)有了交叉編譯好的共享庫,可以從【2】開始,步驟【1】只是為了說明問題,捏造一個簡單的共享庫試圖說明問題。
【1】交叉編譯獲得鏈接庫
【2】交叉編譯源文件并加入鏈接庫
【3】移動動態(tài)鏈接庫
【4】執(zhí)行
【必要說明】
【宿主機】Ubuntu 14.04 AMD64
【目標板】樹莓派
【相關博文】
【例說makefile索引博文】
【樹莓派學習筆記——交叉編譯工具鏈】
【代碼倉庫】——makefile-example
代碼倉庫位于bitbucket,可借助TortoiseHg(GUI工具)克隆代碼或者在網(wǎng)頁中直接下載zip包。
1.交叉編譯獲得動態(tài)鏈接庫
本例先制作一個非常簡單的共享庫,共享庫包含兩個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)
{
return a+b;
}
【test-sub.c】
int sub(int a, int b)
{
return a-b;
}
【makefile】
在同目錄下包含makefile文件,請?zhí)鎿Q其中的[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)
# 鏈接為可執(zhí)行文件
$(TARGET):$(OBJS)
[tab]$(CC) -shared -o $@ $^
[tab]mv $(TARGET) ../lib
clean:
[tab]rm -rf $(TARGET) $(OBJS)
# 編譯規(guī)則 [email protected] $< 代表第一個依賴文件
%.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.交叉編譯源文件并加入動態(tài)鏈接庫
【源文件】
#include
#include
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-gcc
CFLAGS = -Wall -std=gnu99
# 目標文件
TARGET = test
# C文件
SRCS = test.c
# 頭文件查找路徑
INC = -I.
# 庫文件和庫查找路徑
DLIBS = -ltest
LDFLAGS = -L./lib
# 目標文件
OBJS = $(SRCS:.c=.o)
# 鏈接為可執(zhí)行文件
$(TARGET):$(OBJS)
[tab]$(CC) -o $@ $^ $(LDFLAGS) $(DLIBS)
clean:
[tab]rm -rf $(TARGET) $(OBJS)
# 編譯規(guī)則 [email protected] $< 代表第一個依賴文件
%.o:%.c
[tab]$(CC) $(CFLAGS) $(INC) -o $@ -c $<
【說明】
【1】交叉工具鏈為arm-linux-gnueabihf-gcc
【2】指定了交叉編譯之后的共享庫和共享庫路徑,鏈接共享庫使用-ltest,共享庫位于lib目錄下。請注意-ltest對應libtest.so。
【3】make之后可獲得可執(zhí)行文件,通過file test查看信息。