交叉编译与静态链接问题

问题一:交叉编译生成可执行文件,无法在目标板上运行

一、问题描述

arm-linux-gcc  -o  name.c  

编译程序正常,但可执行文件无法在开发板上运行。提示找不到该文件

二、问题排除

1. gcc编译,可在虚拟机里正常运行,因此不是c文件的问题。

2. 试过绝对路径后,确定不是文件存在的问题,而是这个文件并不能被执行.

 

三、问题分析

通过排除法将问题定位到动态链接库.

在主机上用arm-linux-gcc-static -o 来进行静态编译.然后将新产生的文件传到目标板上.可以发现通过静态编译的文件明显比动态编译的要大.

然后再次执行./hello 可以看到屏幕上出现了久违的Hello,World!

原因:内核文件与可执行程序使用了不同的编译器进行编译,导致动态链接库对应不上。

 

如何彻底解决,而不是每次都使用静态编译?

既然是动态库引起的问题,那么应该和编译器的版本有关. 一般编译应用程序对编译器版本没有限制,而编译Linux内核和 u-boot时,手册上会指定编译器。

实验:目标板上linux内核使用4.3.3编译的,而我们刚才编译hello可执行文件是使用3.4.1编译的。

解决方案:将$PATH中的原来包含3.4.1/bin 的路径改为 4.4.3/bin . 修改的方法网上有很多.(直接export PATH=”想要的路径”)

再次编译hello文件,下载.

目标板上执行,成功显示”Hello,World!”.

可以看到系统中动态库的支持和编译器还是有关的.建议编译内核和编译可执行文件的编译器保持一致。

 

 

问题二: “运行arm-linux-gcc命令,提示No such file or directory”

ubuntu16.04上安装arm的交叉编译器arm-linux-gcc,环境变量配置好以后,运行arm-linux-gcc命令,总提示No such file ordirectory。然后去arm-linux-gcc所在的目录下,发现不缺少任何文件。而且环境变量配置也是正确的(环境变量很easy,只要配置个path路径就行),因为arm-是可以补全的。之后又在网上下载了几个版本,甚至最新版,还是同样的问题。

分析了好久,才发现是ubuntu版本的问题。

本人的ubuntu64位,而下载的这些交叉编译器是32位的。因此需要安装ia32-libs库,如果apt-get 搜不到这个库的话,可以安装lib32ncurses5库,也是一样的。本人安装了后者,解决了该问题。

结论:

简单粗暴的解决方式→用同一个编译器编译内核和可执行程序。程序直接用静态编译即可无压力运行。

 

 

基础知识

 

1. 链接方法

程序的静态链接还是动态链接是根据编译器的链接参数指定的。

静态链接方法:#pragmacomment(lib, "test.lib") ,静态链接的时候,载入代码就会把程序会用到的动态代码或动态代码的地址确定下来。

动态链接方法:LoadLibrary()/GetProcessAddress()和FreeLibrary(),使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这种方式使程序初始化时间较短,但运行期间的性能比不上静态链接的程序。

 

2. 静态链接和动态链接

(1)静态链接:

就是在编译链接时直接将需要的执行代码拷贝到调用处,优点就是在程序发布的时候就不需要的依赖库,也就是不再需要带着库一块发布,程序可以独立执行,但是体积可能会相对大一些。(所谓库就是一些功能代码经过编译连接后的可执行形式。)

(2)动态链接:

就是在编译的时候不直接拷贝可执行代码,而是通过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操作系统,操作系统负责将需要的动态库加载到内存中,然后程序在运行到指定的代码时,去共享执行内存中已经加载的动态库可执行代码,最终达到运行时连接的目的。优点是多个程序可以共享同一段代码,而不需要在磁盘上存储多个拷贝,缺点是由于是运行时加载,可能会影响程序的前期执行性能。

 

3. 静态库和动态库

静态库和应用程序编译在一起,在任何情况下都能运行。而动态库是动态链接,顾名思义就是在应用程序启动的时候才会链接,所以,当用户的系统上没有该动态库时,应用程序就会运行失败。再看它们的特点:

Ø  动态库:

1.共享:多个应用程序可以使用同一个动态库,启动多个应用程序的时候,只需要将动态库加载到内存一次即可;

2.开发模块好:要求设计者对功能划分的比较好。

Ø  静态库:

代码的装载速度快,执行速度也比较快,因为编译时它只会把你需要的那部分链接进去,应用程序相对比较大。但是如果多个应用程序使用的话,会被装载多次,浪费内存。

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值