您的位置:首页 > 其它

交叉编译与静态链接问题

2018-01-05 11:22 134 查看
问题一:交叉编译生成可执行文件,无法在目标板上运行
一、问题描述

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版本的问题。
本人的ubuntu是64位,而下载的这些交叉编译器是32位的。因此需要安装ia32-libs库,如果apt-get
搜不到这个库的话,可以安装lib32ncurses5库,也是一样的。本人安装了后者,解决了该问题。
结论:
简单粗暴的解决方式→用同一个编译器编译内核和可执行程序。程序直接用静态编译即可无压力运行。
 

 

基础知识

 

1. 链接方法

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

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

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

 

2. 静态链接和动态链接

(1)静态链接:

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

(2)动态链接:

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

 

3. 静态库和动态库

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

Ø  动态库:

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

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

Ø  静态库:

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

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息