大家好 ,我是谢艺华。
我相信对于刚毕业的新人而言,编译这一块绝对是一个令人头疼的点。特别需要用到一些开源库,开源工具时,我们就不得进行移植流程。很多人可能就会犯怵,遇到编译的报错,就手无足措,不知道该怎么解决。本文就介绍工具移植的流程,希望能够帮助有需要的人。
在我们工作中,经常会遇到一些问题或者需求,需要第三方开源工具进行协助。这就需要我们具有如何使用开源库的能力。本文主要秉着授人以鱼不如授人以渔的思想,不会直接提供编译好的工具,而是介绍移植的流程,以及过程中遇到问题的处理思路。
名词 | 含义 |
---|---|
本地编译 | 即在当前目标平台下,编译出来的程序,也只是放到当前平台下,就可以运行 |
交叉编译 | 在一种平台上编译,编译出来的程序,是放到别的平台上运行即编译的环境,和运行的环境不一样,属于交叉的,此所谓cross |
交叉编译工具链 | 由编译器、连接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils、gcc和glibc三个部分组成。 |
移植开源工具的步骤可以简单分为下载源码、交叉编译、安装验证三步骤。
由于最终需要进行交叉编译,所以必须获取工具源码。下载源码的方式一般可以通过百度搜索(以gdb工具为例):
a) 通过百度检索到工具官网,点击进入;
b) 点击download 栏,选择版本下载。
d) 选择版本。(不建议选择大版本中最新版本,比如截图中,我选择gdb-10.2版本,一般大版本最新版不太稳定)。
e) 点击下载,并放入虚拟机中。
编译主机环境工具的编译流程一般如下:
a) 解压缩。tar -xvf gdb-10.2.tar.gz -C ./
b) 编译选项配置。cd gdb-10.2 && ./configure
该步骤,configure 脚本会根据的虚拟机环境变量设置编译属性,生成对应的Makefile。
c) 编译。make
该操作开始进行编译,耗时较长。主要的困难也是在这其中,我们一般遇到的问题就是在这里,因为不同的编译链对语法的要求不一样,因此会冒出各种问题。需要我们去解决。
交叉编译的流程与主机环境一致。我根据江铃GES项目中T-Box供应商云动提供的交叉编译工具链作为举例。
tar -xvf gdb-10.2.tar.gz -C ./ && cd gdb-10.2
DIR=/home/simcom/crosstool
export CROSSTOOL_PATH=${DIR}
echo ${CROSSTOOL_PATH}
export LIB_PATH=${CROSSTOOL_PATH}/mdm9607-perf
export PATH=${CROSSTOOL_PATH}/x86_64-linux/usr/bin:${CROSSTOOL_PATH}/x86_64-linux/usr/bin/arm-oe-linux-gnueabi:$PATH
export CROSS_BASED_PATH=${CROSSTOOL_PATH}/x86_64-linux/usr/bin/arm-oe-linux-gnueabi/
export CC=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-gcc -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=${LIB_PATH}/"
export CXX=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-g++ -march=armv7-a -mfloat-abi=softfp -mfpu=neon -std=c++11 --sysroot=${LIB_PATH}/"
export CPP=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-gcc -E -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=${LIB_PATH}/"
export AS=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-as "
export LD=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-ld "
export GDB=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-gdb"
export STRIP=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-strip"
export RANLIB=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-ranlib"
export OBJCOPY=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-objcopy"
export OBJDUMP=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-objdump"
export AR=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-ar"
export NM=${CROSS_BASED_PATH}"arm-oe-linux-gnueabi-nm"
export M4=m4
export CXXFLAGS=" -O2 -fexpensive-optimizations -frename-registers -fomit-frame-pointer -fstack-protector-strong -pie -fpie -Wa,--noexecstack -fvisibility-inlines-hidden"
export LDFLAGS="-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-z,relro,-z,now,-z,noexecstack"
export CPPFLAGS=""
export ARCH=arm
export CROSS_COMPILE=arm-oe-linux-gnueabi-
export LIBGCC=${LIB_PATH}/usr/lib/arm-oe-linux-gnueabi/4.9.2/libgcc.a
export CROSSCOMPILE_FLAG=1
其中黑色字体的环境变量需要我们注意。
./configure --host=arm-linux
–host 参数告诉configure 目标平台是什么。arm-linux则会被解析为host=arm,os=linux,即目标平台是arm架构,linux 系统。则会根据这些参数去生成对应的Makefile。
如何判断host 信息:
uname -a
。移植过程中主要的问题一般都是出现在编译。不同的编译工具链遇到的问题可能也有不同。这就需要我们去分析,解决,总结。
makefile生成之后,直接执行make
进行编译即可。
问题分析: 通过报错提示,表示(SYM)前应该是类型。很明显这样的语法是符合我们常用的习惯。
解决方式:
a) 从根因解决。很遗憾我并没有找到相关的解决方式。
b) 想办法避免。通过源文件查看,我发现__attribute__ ((visibility(“default”)))的作用显示的让符号外部可见。我觉得并不影响,所以就将该部分内容屏蔽了。
这个错误就避免了。
如错误提示,我们在编译过程中需要告诉编译器产生与位置无关的代码。即在编译环境变量中添加-fPIC 参数。
修改方式:
在我的环境中只遇到这两个问题,但是遇到问题的处理思路都是差不多的。
如图所示,编译生成的gdb 工具运行平台就是arm 架构unix系统。
在目标平台上运行时,可能还会依赖一些库,同理,可以按照上述的流程,再编译需求的库。
编译是大部分工程师的烦恼,大家普遍喜欢去写业务代码。但我觉得基本的编译流程,我们还是需要掌握的,希望遇到相关问题,不要退缩,尝试去解决。天下文章一大抄,百度能解决我们90%的问题。