0.前言

    在较为复杂的项目中会利用到交叉编译得到的共享库(*.so文件)。在这样的情况下便会产生下面疑问,比如:
    【1】交叉编译时的共享库是否须要放置于目标板中,假设须要放置在哪个文件夹中。
    【2】交叉编译时的共享库是否须要放置于宿主机中,假设须要放置于哪个文件夹中。
    【3】交叉编译时怎样指定共享库
    【4】程序执行时怎样查找共享库
    等等问题。
    
    博文总结了使用共享库的一般方法,并通过一个样例说明问题。假设已经有了交叉编译好的共享库,能够从【2】開始,步骤【1】仅仅是为了说明问题,捏造一个简单的共享库试图说明问题。
    【1】交叉编译获得链接库
    【2】交叉编译源文件并增加链接库
    【3】移动动态链接库
    【4】运行

    【必要说明】
    【宿主机】Ubuntu 14.04 AMD64
    【目标板】树莓派
    
    【相关博文】

    【代码仓库】——makefile-example
    代码仓库位于bitbucket,可借助TortoiseHg(GUI工具)克隆代码或者在网页中直接下载zip包。    

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)
{
    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-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 <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-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 $<
    【说明】
    【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.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.总结
    回答在前言中的问题。
    【1】交叉编译时的共享库是否须要放置于目标板中,假设须要放置在哪个文件夹中。
    交叉编译之后的共享库须要拷贝到目标板中,最好放置于/usr/lib或/lib中,当然也有其它的方法,在这里不具体说明。

    【2】交叉编译时的共享库是否须要放置于宿主机中,假设须要放置于哪个文件夹中。
    交叉编译时确切的说链接过程中须要指定共享库的问题,通过-L指定文件夹,通过-l指定共享库名称。可是此时交叉编译的共享库最好不要放置于宿主机的/lib或/usr/lib中,以免产生混淆。
    综合【1】和【2】,libtest.so同一时候存在于目标板和宿主机中。

    【3】交叉编译时怎样指定共享库
    通过-L指定文件夹,通过-l指定共享库名称

    【4】程序执行时怎样查找共享库
    最直观的方法,拷贝到/usr/lib文件夹中,让linux系统自己主动查找。

    最后,发现博文写多了自己感觉好累啊,希望这些总结对大家实用。

Linux学习笔记——怎样在交叉编译时使用共享库的更多相关文章

  1. Linux学习笔记(14)-进程通信|共享内存

    在Linux中,共享内存是允许两个不相关的进程访问同一个逻辑内存的进程间通信方法,是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式. 不同进程之间共享的内存通常安排为同一段物理内存.进程可 ...

  2. Linux学习笔记——如何使用共享库交叉编译

    0.前言     在较为复杂的项目中会利用到交叉编译得到的共享库(*.so文件).在这样的情况下便会产生下面疑问,比如:     [1]交叉编译时的共享库是否须要放置于目标板中,假设须要放置在哪个文件 ...

  3. Linux 学习笔记

    Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...

  4. linux学习笔记2-linux的常用命令

    第一篇博客:linux学习笔记1-ubuntu的安装与基本设置 之中,已经介绍了如何安装linux操作系统,以及一些基本的设置修改. 本篇博客主要介绍linux中的一些常用的终端命令 ======== ...

  5. Linux学习笔记-林耐斯Notes-Linux就该这么学

    Linux学习笔记... 参考的优秀Linux网站: http://www.w3cschool.cn/linux/ http://www.linuxeye.com/ http://linux.vbir ...

  6. linux学习笔记2 - linux常用命令

    转载请标注原链接:http://www.cnblogs.com/xczyd/p/5543731.html 第一篇博客:linux学习笔记1-ubuntu的安装与基本设置 之中,已经介绍了如何安装lin ...

  7. Linux 学习笔记之超详细基础linux命令(the end)

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 14---------------- ...

  8. Linux 学习笔记之超详细基础linux命令 Part 14

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 13---------------- ...

  9. Linux 学习笔记之超详细基础linux命令 Part 13

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 12---------------- ...

随机推荐

  1. Windowsport80解决方案被占用

    今天,在一个非常沮丧的实施Server什么时候,一个错误port80占用.因此,找到一种方法来解决各类.最后,我的解决方案列出的问题来,要遇到的人做一些参考同样的问题. 第一步,找出哪些程序正在使用p ...

  2. Visual Studio Team Services使用教程--添加团队成员

  3. linux0.11学习笔记(2)

    makefile文件: makefile 文件是make 实用简介.make 程序是用Makefile最后一次改变的数据文件和代码文件(last-modification time)确定哪些文件需要更 ...

  4. 2g-3g

  5. Display Database Image using MS SQL Server 2008 Reporting Services

    原文 Display Database Image using MS SQL Server 2008 Reporting Services With the new release of MS SQL ...

  6. 一张地图告诉你,只JavaScript不够!

    这将是JavaScript语法,你真的会一JavaScript嘛.看看这个图片!超好用JavaScript一本书的摘录游.熊儿.快去学习! 版权声明:本文博客原创文章.博客,未经同意,不得转载.

  7. Learn Python More

    0, 看了一个python项目开源源码, 才知道现在这点python知识实在是弱爆了.. 尼玛就像学了2500个常用汉字, 然后要去理解"楚辞".. 代码如下, 解释一点一点从网上 ...

  8. SQL Prompt5 破解版+使用说明 [转]

    SQL脚本越写越多,总是觉得编写效率太过于低下,这和打字速度无关.在我个人编写SQL脚本时,至少会把SQL的格式排列成易于阅读的,因为其他人会阅读到你的SQL,无论是在程序中或是脚本文件中,良好的排版 ...

  9. DynamicReports 导出Excel 例子

    import java.awt.Color; import java.io.FileOutputStream; import java.util.ArrayList; import java.util ...

  10. 怎样用OleDbDataAdapter来对数据库进行操作?

      请问怎样用OleDbDataAdapter来对数据库进行删除.改动和加入? OleDbDataAdapter是DataSet和数据源之间建立联系的重要纽带.用它我们能够对数据库进行删除.改动和加入 ...