交叉编译工具的使用说明

2020-03-26来源: eefocus关键字:交叉编译工具  使用说明  JZ2440V3

写在前面的话,由于已经学习了JZ2440V3开发板的裸机程序。想检验下学习成果,所以从今天开始把以前学的知识点在tiny4412开发板上面做个检验。裸机部分学习到把uboot移植完成就结束;然后,学习内核的驱动和其他子系统框架。言归正传,现在开始学习交叉编译工具链的使用。


源文件需要经过编译才能生成可执行文件。在Windows下进行开发时,只需要点几个按钮即可编译,集成开发环境(比如 Visual studio)已经将各种编译工具的使用封装好了。


Linux下也有很优秀的集成开发工具,但是更多的时候是直接以命令方式运行编译工具;即使使用集成开发工具,也需要掌握一些编译选项。


PC机上的编译工具链为gcc、 ld、 objcopy、 objdump等,它们编译出来的程序在x86平台上运行。要编译出能在ARM平台上运行的程序,必须使用交叉编译工具arm-linux-gcc、arm-linux-ld等,下面分别介绍。


1.arm-linux-gcc工具介绍


一个 C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)和连接(linking)等4步才能变成可执行文件,如表1.1所示。在日常交流中通常使用"编译"统称这4个步骤,如果不是特指这4个步骤中的某一个,本书也依惯例使用"编译"这个统称。


1.1.预处理


C/C++源文件中,以"#"开头的命令被称为预处理命令,如包含命令"#include"、宏定义命令"#define"、条件编译命令"#if"、"#ifdef"等。预处理就是将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到一个".i"文件中等待进一步处理。预处理将用到arm-linux-cpp工具。


1.2.编译


编译就是把 C/C++代码(比如上述的".i"文件)"翻译"成汇编代码,所用到的工具为cc1(它的名字就是 cc1,不是 arm-linux-cc1)。


1.3.汇编


汇编就是将第二步输出的汇编代码翻译成符合一定格式的机器代码,在Linux系统上一般表现为ELF目标文件(OBJ文件),用到的工具为arm-linux-as。"反汇编"是指将机器代码转换为汇编代码,这在调试程序时常常用到。


1.4.连接


连接就是将上步生成的OBJ文件和系统库的OBJ文件、库文件连接起来,最终生成了可以在特定平台运行的可执行文件,用到的工具为arm-linux-ld。


编译器利用这4个步骤中的一个或多个来处理输入文件,源文件的后缀名表示源文件所用的语言,后缀名控制着编译器的缺省动作,如表1.1。

image.png

其他后缀名的文件被传递给连接器(linker),通常包括:


o:目标文件(Object file,OBJ文件)

a:归档库文件(Archive file)

在编译过程中,除非使用了"-c","-S"或"-E"选项(或者编译错误阻止了完整的过程),否则最后的步骤总是连接。在连接阶段中,所有对应于源程序的.o文件,"-l"选项指定的库文件,无法识别的文件名(包括指定的".o"目标文件和".a"库文件)按命令行中的顺序传递给连接器。


以一个简单的"Hello, world!" C程序为例,它的代码如下,功能为打印"Hello World!"字符串。


/* File: hello.c */

#include

int main(int argc, char *argv[])

{

printf("Hello World!n");

return 0;

}

使用arm-linux-gcc,只需要一个命令就可以生成可执行文件hello,它包含了上述4个步骤:


arm-linux-gcc -o hello hello.c

加上"-v"选项, 即使用"arm-linux-gcc -v -o hello hello.c"命令可以观看编译的细节,下面摘取关键部分:


cc1 hello.c -o /tmp/cctETob7.s

as -o /tmp/ccvv2KbL.o /tmp/cctETob7.s

collect2 -o hello crt1.o crti.o crtbegin.o /tmp/ccvv2KbL.o crtend.o crtn.o

以上3个命令分别对应于编译步骤中的预处理、编译、汇编和连接, ld被collect2调用来连接程序。预处理和编译被放在了一个命令(cc1)中进行的,可以把它再次拆分为以下两步:


cpp -o hello.i hello.c

cc1 hello.i -o /tmp/cctETob7.s

可以通过各种选项来控制arm-linux-gcc的动作,下面介绍一些常用的选项:


总体选项:


-c选项:预处理、编译和汇编源文件,但是不作连接,编译器根据源文件生成OBJ文件。缺省情况下,GCC通过用".o"替换源文件名的后缀".c",".i",".s"等,产生OBJ文件名。可以使用-o选项选择其他名字。GCC忽略-c选项后面任何无法识别的输入文件。


-S选项:编译后即停止,不进行汇编。对于每个输入的非汇编语言文件,输出结果是汇编语言文件。缺省情况下,GCC通过用".s"替换源文件名后缀".c",".i"等等,产生汇编文件名。可以使用-o选项选择其他名字。GCC忽略任何不需要汇编的输入文件。


-E选项:预处理后即停止,不进行编译。预处理后的代码送往标准输出。GCC忽略任何不需要预处理的输入文件。


-o选项:指定输出文件为file。无论是预处理、编译、汇编还是连接,这个选项都可以使用。如果没有使用'-o'选项,默认的输出结果是:可执行文件为'a.out';修改输入文件的名称是'source.suffix',则它的OBJ文件是'source.o',汇编文件是'source.s',而预处理后的C源代码送往标准输出。


-v选项:显示制作GCC工具自身时的配置命令;同时显示编译器驱动程序、预处理器、编译器的版本号。


以一个程序为例,它包含三个文件,下面列出源码:


//File: main.c

#include

#include "sub.h"

 

int main(int argc, char *argv[])

{

int i;

printf("Main fun!n");

sub_fun();

return 0;

}

 

//File: sub.h

void sub_fun(void);

 

//File: sub.c

void sub_fun(void)

{

printf("Sub fun!n");

}

arm-linux-gcc、arm-linux-ld等工具与gcc、ld等工具的使用方法相似,很多选项是一样的。本节使用gcc、ld等工具进行编译、连接,这样可以在PC上直接看到运行结果。使用上面介绍的选项进行编译,命令如下:


$ gcc -c -o main.o main.c

$ gcc -c -o sub.o sub.c

$ gcc -o test main.o sub.o

其中,main.o、sub.o是经过了预处理、编译、汇编后生成的OBJ文件,它们还没有被连接成可执行文件;最后一步将它们连接成可执行文件test,可以直接运行以下命令:


$ ./test

Main fun!

Sub fun!

现在试试其他选项,以下命令生成的main.s是main.c的汇编语言文件:


gcc -S -o main.s main.c

以下命令对main.c进行预处理,并将得到的结果打印出来。里面扩展了所有包含的文件、所有定义的宏。在编写程序时,有时候查找某个宏定义是非常繁琐的事,可以使用'-dM –E'选项来查看。命令如下:


$ gcc -E main.c

警告选项:


-Wall选项:这个选项基本打开了所有需要注意的警告信息,比如没有指定类型的声明、在声明之前就使用的函数、局部变量除了声明就没再使用等。 


上面的main.c文件中,第6行定义的变量i没有被使用,但是使用"gcc –c –o main.o main.c"进行编译时并没有出现提示。

可以加上-Wall选项,例子如下:


$ gcc -Wall -c main.c

执行上述命令后,得到如下警告信息:


main.c: In function `main':

main.c:6: warning: unused variable `i

这个警告虽然对程序没有坏的影响,但是有些警告需要加以关注,比如类型匹配的警告等。


调试选项:


-g选项:以操作系统的本地格式(stabs,COFF,XCOFF,或DWARF)产生调试信息,GDB能够使用这些调试信息。在大多数使用stabs格式的系统上,'-g'选项加入只有GDB才使用的额外调试信息。可以使用下面的选项来生成额外的信息:'-gstabs+','-gstabs','-gxcoff+','-gxcoff','-gdwarf+'或'-gdwarf',具体用法请读者参考GCC手册。


优化选项:


-O或-O1选项:优化:对于大函数,优化编译的过程将占用稍微多的时间和相当大的内存。不使用"-O"或"-O1"选项的目的是减少编译的开销,使编译结果能够调试、语句是独立的;如果在两条语句之间用断点中止程序,可以对任何变量重新赋值,或者在函数体内把程序计数器指到其他语句,以及从源程序中精确地获取你所期待的结果。


-O2选项:多优化一些。除了涉及空间和速度交换的优化选项,执行几乎所有的优化工作。例如不进行循环展开(loop unrolling)和函数内嵌(inlining)。和'-O'或'-O1'选项比较,这个选项既增加了编译时间,也提高了生成代码的运行效果。


-O3选项:优化的更多。除了打开-O2所做的一切,它还打开了-finline-functions选项。 


-O0选项:不优化。


如果指定了多个-O选项,不管带不带数字,生效的是最后一个选项。在一般应用中,经常使用-O2选项,比如对于options程序:


$ gcc -O2 -c -o main.o main.c

$ gcc -O2 -c -o sub.o sub.c

$ gcc -o test main.o sub.o

连接器选项:


下面的选项用于连接OBJ文件,输出可执行文件或库文件。


object-file-name选项:如果某些文件没有特别明确的后缀(a special recognized suffix),GCC就认为他们是OBJ文件或库文件(根据文件内容,连接器能够区分 OBJ 文件和库文件)。如果GCC执行连接操作,这些OBJ文件将成为连接器的输入文件。


比如上面的"gcc -o test main.o sub.o"中,main.o、sub.o就是输入的文件。


-llibrary选项:连接名为library的库文件。连接器在标准搜索目录中寻找这个库文件,库文件的

[1] [2]
关键字:交叉编译工具  使用说明  JZ2440V3 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic492644.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:Exynos4412芯片的时钟管理单元
下一篇:最后一页

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

交叉编译openssl,不用修改Makefile编译工具
利用arm-linux-gnueabihf-gcc交叉编译openssl,生成静态库文件libcrypto.a ,libssl.a以及动态库文件1、从openssl官网下载openssl最新版本,我下载的是openssl-1.0.2e。下载地址:http://www.openssl.org/source/2、安装自己的交叉编译工具链。3、解压openssl源码,进入目录。并配置好交叉编译链的环境变量: export PATH=$PATH:/usr/local/linaro-multilib-2014.06-gcc4.9/bin4.修改环境变量 CC:export CC=arm-linux-gnueabihf-gcc5.创建输出
发表于 2019-10-18
s3c2440的arm-linux交叉编译工具
=$PREFIX  --enable-languages=c,c++ --enable-sharedmake allmake install八、完成工具链的设置cd $TARGET_PREFIX/bin查看文件是否为二进制文件:file as ar gcc ld nm ranlib strip   查看缺省的搜寻路径:arm-linux-gcc -print-search-dirs  九、测试和验证交叉编译工具    下面编写一个简单的C程序,使用建立的工具链。、cd $PRJROOT/programvi hello.c#include <
发表于 2016-12-06
ARM-linux-gcc交叉编译工具提示arm-linux-gcc can not find
;        C: source /etc/profile。       D:查看交叉工具是否生效 :arm-linux-gcc -v      E:编译你的文件,发现工具好用,不会提示错误  总结 :原因是编译文件我们需要超级权限Root,在用户权限下安装的交叉编译工具,超级权限编译文件时是找不到的,相当于只有你是一个军火供应商,你有很多枪,但不好意思,枪支弹药只有警察才有权限适用,普通用户你没得权限适用不了,怎么办呢? 你得通过"使用说明书"告诉警察这些武器是怎样使用的。sudo  -S 切换到ROOT权限
发表于 2016-08-13
嵌入式linux-arm交叉编译工具链的构建
=${SYSROOT} modules_install   注意 :文中的大部分#号是自己当初为了分步编译差错方便而屏蔽掉的部分。自己编译的时候可以去掉。顺便说一下我是在suse环境下建立这个交叉编译环境的,内核是2.6以上的版本,其中—build=i686-pc-linux-gnu。 几个简单的命令: :set nu 显示文本行号。 :1,5s/^/#/g可以在文本的1~5行添加一个#号,也即屏蔽掉这几行。1,5s/^#//g去掉文本1~5行文本开头的#号。   第三步  测试程序Helloworld.c  
发表于 2016-08-13
ubuntu下安装ARM交叉编译工具
1,添加一个源到我们的/etc/apt/sources.list下,这样我么才可以sudo apt-get install gcc-armxxx; 源地址:deb http://www.emdebian.org/debian/ stable main 将上面的地址加到我们的/etc/apt/sources.list下; 手动将 deb http://www.emdebian.org/debian/ stable main添加到 /etc/apt/sources.list 一般用户的权限是不够的,所以需要在你的 编辑器前加上sudo的呢。 2,千万别忘了 sudo apt-get update 3.更新成功后 sudo
发表于 2016-08-06
Debian中AVR交叉编译工具包的安装
1.  查询AVR交叉工具链相关的软件包 debian:~# apt-cache search avr ava - Algebraical Virtual Assembler for Atmel's AVR MCUs avarice - use GDB with Atmel's JTAG ICE for the AVR avr-libc - Standard C library for Atmel AVR development avra - Assembler for Atmel AVR microcontrollers avrdude-doc - documentation for
发表于 2016-07-28
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved