六、Linux |
您所在的位置:网站首页 › 树莓派什么语言 › 六、Linux |
六、Linux——树莓派平台的交叉编译
6.1 交叉编译的概念
交叉编译是一个行为 ,是在一个平台上生成另一个平台上的可执行代码。同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。 编译:是一个平台上生成在该平台上可执行的代码 交叉编译:是在一个平台上生成,在另一个平台上的可执行代码 例如:编写STM32的代码时,用Keil进行编译,编译出的hex文件就是stm32平台上的可执行文件。 6.2 为什么要交叉编译 目的平台上资源匮乏,无法运行我们所需要的编译器。例如IXM6ULL就没有gcc。目的平台还没有建立,连操作系统都没有,根本就谈不上什么编译器。 6.3 交叉编译链编译的具体过程: 四个阶段分别是:预处理,编译,组装,链接 预处理将头文件展开,将宏定义替换,生成符号文件.S编译则包含了词法检查,语法检查,权限检查, 代码优化组装:将编译后的代码组装成机器码, 形成位置无关的目标文件 .o链接将多个位置无关的目标文件合并成可执行文件可见组装才是平台相关的,之前的操作都与平台无关, 换句话说是编译前端和编译后端 注意:严格意义上来说,交叉编译器,只是指交叉编译的gcc,但是实际上为了方便,我们常说的交叉编译器就是交叉工具链。本文对这两个概念不加以区分,都是指编译链 6.4 交叉编译工具链的安装(树莓派3B+)树莓派交叉编译工具链网址:https://github.com/raspberrypi/tools 导入到ubuntu文件夹后,用以下命令进行解压 unzip tools-master.zip解压完成后,执行以下命令 cd arm-bcm2708/ cd gcc-linaro-arm-linux-gnueabihf-raspbian-x64 cd bin/可以看到如下文件 我们要用到的是左下角的 arm-linux-gnueabihf-gcc(它是一个软链接≈快捷方式) 用 ls-l 命令查看一下文件具体信息 这样进行交叉编译必须要先进入到此文件夹,为了更方便的使用交叉编译,我们把这个路径添加到环境变量中 临时有效(只在这个窗口内有效) 先用echo $PATH显示一下当前的环境变量 再用pwd查看一下当前路径 最后用export PATH=之前的环境变量:当前路径 永久有效 打开工作目录下的.bashrc文件,vi /home/CLC/.bashrc 在最后添加上 export PATH=之前的环境变量:当前地址 然后加载配置文件 source /home/CLC/.bashrc 检查下交叉编译工具链版本 arm-linux-gnueabihf-gcc -v注:wiringPi库在ubuntu平台上编译时,运行的./build脚本默认是用gcc的,所以编译出来的库只能运行到x86平台上,所以可以在树莓派上编译过后,再把对应的库拿过来(注意不要拿成软链接) 6.5 软硬链接软链接(symbolic link) : 等同于 Windows 系统下的快捷方式。仅仅包括所含链接文件的路径名字。因此能链接目录,也能跨文件系统链接。但是,当删除原始文件后,链接文件也将失效。 软链接概念总结 软链接文件有类似于Windows的快捷方式在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息它只会在你选定的位置上生成一个文件的镜像,不会占用磁盘空间 如何生成: ln -s libwiringPi.so.2.50 libwiringPi.so 指令 参数 要链接的文件 软链接文件名字硬链接(hard link) : 可以将它理解为一个 “指向原始文件 inode(储存原始文件信息) 的指针”,系统不为它分配独立的 inode 和 文件(会占用磁盘一点很小的空间)。所以,硬链接文件与原始文件其实是同一个文件,只是名字不同。我们每添加一个硬链接,该文件的 innode 连接数就会增加 1 ; 而且只有当该文件的 inode 连接数为 0 时,才算彻底将它删除**(文件名就是一个硬链接,只有当所有的硬链接删除后,文件才会被删除)。**因此即便删除原始文件,依然可以通过硬链接文件来访问。需要注意的是,我们不能跨分区对文件进行链接。可以使用指令:**ln fileName newFileName ** 为原文件fileName 创建硬链接newFileName 如何生成: ln libwiringPi.so.2.50 libwiringPi.so 指令 要链接的文件 软链接文件名字 6.6 静态库与动态库库是什么? 库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容。 库的分类 1、静态函数库,是在程序执行前就加入到目标程序中去了,文件后缀是.a 2、动态函数库同共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.so ,windows上叫动态加载函数库, 文件后缀是.dll) 命名规则 静态函数库 静态函数库, 是在程序执行前(编译)就加入到目标程序中去了;(链接阶段就被复制到程序里) 优点: 快 被打包到应用程序中运行速度快发布程序无需提供静态库,因为已经在app中,移植方便缺点:大 连接时候完整拷贝到可执行文件中,被多次使用就会有多份冗余拷贝,文件大。更新,部署,发布麻烦静态库制作过程 原材料:源代码.c 或者 .cpp 有两步 将.c文件生成.o,gcc a.c b.c -c将.o 打包 ar rcs lib静态库的名字.a 原材料.o ar rcs libtest.a b.o gcc test.c -c ar rcs libtest.a test.o //生成libtest.a文件静态库的使用 给别人使用库时候,就给xxx.a 和 .h 就行。 编译gcc 主函数.c -lxxx -L ./ -o mainProStatic (-L 是为了指定库文件的位置) -lxxx是-l 加上上面生成的libxxx.a 的xxx -ltest ,-l 是指定要用的动态库,库名砍头(lib)去尾(.a) gcc main.c -ltest -L /home/xx/mylib -o main动态函数库 动态库:动态函数库,是在程序执行时动态(临时)由目标程序去调用 优点:小 小,连接时候不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序可以共用,节省内存。程序升级简单,因为app里没有库的源代码,升级后只要库的名字不变,函数名以及参数不变,只是实现做了优化,就能加载成功缺点:慢 运行慢 加载速度比静态库慢发布程序需要提供依赖的动态库动态库制作过程 将源文件生成.o,需要加一个参数fpic 打包,gcc -shared -fpic 功能代码.c -o libxxx.so gcc -shared -fpic test.c -o libtest.so动态库的使用 给别人使用库时候,就给xxx.so 和 .h 就行。 编译 gcc 主程序.c -l库名 -L ./ -o main gcc main.c -ltest -L./ -o main这时候直接运行就不能运行的,动态和静态的区别就体现出来了,动态是在程序执行时动态(临时)由目标程序去调用。运行的时候会去找动态库,但是找不到动态库。静态库不用去找静态库,因为它编译进去程序里了。 可以通过改变环境变量的方式来指定动态库的寻找路径,创建一个shell脚本 vi start.sh在里面加入以下 export LD_LIBRARY_PATH="LD_LIBRARY_PATH=“动态库所在路径" ./main给脚本加上可执行权限 chmod +x start.sh直接运行脚本就可以直接调用程序 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |