前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >arm-gcc各版本区别

arm-gcc各版本区别

作者头像
云深无际
发布2020-08-12 15:00:01
3.1K0
发布2020-08-12 15:00:01
举报
文章被收录于专栏:云深之无迹云深之无迹

我这个心情本来还行,就是现在不是个滋味...事情是这样的.我今天早上和往常一样打开一本书在看.书很不错

就是这本,讲的可以说是非常好了.我推荐

然后他自己说,开了一个网站,供人下载.

代码语言:javascript
复制
http://www.leeos.org/

我上午一直没有开电脑,也就没有没有看这个网站.书看了半本也晚上了,我就打开电脑准备写笔记.想起了这个网站,准备实操一波.

but,but,but,

出来个这???学习汁源???

和我朋友吐槽,得到答复.转行了...也有可以没发展,真的转行了.

网站我查了一下,服务器在国外托管.翻墙流畅.....emmmm暴露了什么,注意身体~~

这个书前面讲到环境的搭建.说到了gcc.后面写程序编译时,我发现命令是arm-gcc这样的.我哪见过这种东西.赶紧查一下.明白了.我平时用是生成的执行文件是x86平台的.arm当然就是arm环境的.还有一种是linux的.

从本质来讲他们都是编译器,而gcc是linux系统下面用来将代码编译成一个可执行程序的手段。编译出来的是适用于linux系统的可执行二进制文件。可执行程序其实就是一堆的0101二进制机器码。这些机器码代表什么含义只有机器本身能理解。所以你用gcc编译出来的可执行程序只有在linux系统下面可以运行。

举个例子

假设你在Linux系统编译生成了可执行文件,我们本意是要系统打开摄像头,但是如果你在window系统上运行可能就是打开相册。同样的可能这个可执行文件在ARM下面可能是关机。不同系统的机器码含义是不一样的。所以你在linux系统下面写的代码要怎样才能在ARM系统上面跑呢。这就需要用到交叉编译。arm-linux-gcc是什么意思?就是告诉你的编译器,我编写的环境是linux,但是我希望生成的可执行程序是在arm上面跑的。这就是交叉编译。编写环境和执行环境分离的一种手段。

主要我是像给树莓派写系统,所以我得有arm-gcc啊,一查.懵逼了

咋这么多gcc,我该下载哪个啊~

arm-linux-gcc、

arm-none-eabi-gcc、

arm-eabi-gcc、

arm-none-linux-gnueabi-gcc区别

arm-none-eabi-gcc

==(ARM architecture,no vendor,not target an operating system,complies with the ARM EABI)==

Arm官方用于编译 ARM 架构的裸机系统(包括 ARM Linux 的 boot、kernel,==不适用编译 Linux应用==),一般适合 ARM7、Cortex-M 和 Cortex-R 内核的芯片使用,所以不支持那些跟操作系统关系密切的函数,比如fork(2),他使用的是 newlib 这个专用于嵌入式系统的C库。

代码语言:javascript
复制
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads

arm-none-linux-gnueabi-gcc

==(ARM architecture, no vendor, creates binaries that run on the Linux operating system, and uses the GNU EABI)==

主要用于基于ARM架构的Linux系统,==可用于编译 ARM 架构的 u-boot、Linux内核、Linux应用等==。arm-none-linux-gnueabi基于GCC,使用Glibc库,经过 Codesourcery 公司优化过推出的编译器。arm-none-linux-gnueabi-xxx 交叉编译工具的浮点运算非常优秀。一般ARM9、ARM11、Cortex-A 内核,带有 Linux 操作系统的会用到。

代码语言:javascript
复制
下载地址https://www.mentor.com/embedded-software/sourcery-tools/support

arm-eabi-gcc

Android ARM 编译器。

armcc

ARM 公司推出的编译工具,功能和 arm-none-eabi 类似,可以编译裸机程序(u-boot、kernel),但是不能编译 Linux 应用程序。armcc一般和ARM一起,Keil MDK、ADS、RVDS和DS-5中的编译器都是armcc,所以 armcc 编译器都是收费的)。

arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc

arm-none-uclinuxeabi 用于uCLinux,使用Glibc。 arm-none-symbianelf 用于symbian。

ABI 和 EABI

ABI

二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture)。在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。

EABI

嵌入式ABI。嵌入式应用二进制接口指定了文件格式、数据类型、使用、堆积组织优化和在一个嵌入式软件中的参数的标准约定。开发者使用自己的汇编语言也可以使用 EABI 作为与兼容的生成的汇编语言的接口。

==两者主要区别是,ABI是计算机上的,EABI是嵌入式平台上(如ARM,MIPS等)。==

arm-linux-gnueabi-gcc 和 arm-linux-gnueabihf-gcc

两个交叉编译器分别适用于 armel 和 armhf 两个不同的架构,armel 和 armhf 这两种架构在对待浮点运算采取了不同的策略(有 fpu 的 arm 才能支持这两种浮点运算策略)。

其实这两个交叉编译器只不过是 gcc 的选项 -mfloat-abi 的默认值不同。gcc 的选项 -mfloat-abi 有三种值:

soft、softfp、hard(其中后两者都要求 arm 里有 fpu 浮点运算单元,soft 与后两者是兼容的,但 softfp 和 hard 两种模式互不兼容):

  1. soft:不用fpu进行浮点计算,即使有fpu浮点运算单元也不用,而是使用软件模式。
  2. softfp:armel架构(对应的编译器为 arm-linux-gnueabi-gcc )采用的默认值,用fpu计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。
  3. hard:armhf架构(对应的 arm-linux-gnueabihf-gcc )采用的默认值,用fpu计算,传参数也用fpu中的浮点传,省去了转换,性能最好,但是中断负荷高。

把以下测试使用的C文件内容保存成 mfloat.c:

代码语言:javascript
复制
#include <stdio.h>
int main(void)
{
    double a,b,c;
    a = 23.543;
    b = 323.234;
    c = b/a;
    printf(“the 13/2 = %f\n”, c);
    printf(“hello world !\n”);
    return 0;
}

使用 arm-linux-gnueabihf-gcc 编译,使用“-v”选项以获取更详细的信息:

代码语言:javascript
复制
# arm-linux-gnueabihf-gcc -v mfloat.c
COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=hard’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’
-mfloat-abi=hard

可看出使用hard硬件浮点模式。

  1. 使用 arm-linux-gnueabi-gcc 编译:
  2. # arm-linux-gnueabi-gcc -v mfloat.c COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=softfp’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’ -mfloat-abi=softfp

gcc和arm-linux-gcc常用选项:

gcc的使用方法:

语法:gcc [选项] 文件名

3.gcc编译过程分析

一个 C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)和连接(linking)等 4 步才能变成可执行文件,如表 所示。在日常交流中通常使用“编译”统称这 4 个步骤.

接着我们安装在这个东西:

国内环境,自己从这里下载

代码语言:javascript
复制
https://www.jb51.net/softs/696088.html

解压中

C盘建立文件夹,放好文件

搜索一下

配置环境变量

看不懂

翻译一下

成功了

接着我们来试试看,可以看到编辑器识别到了头文件

一段标准入门程序,我们不配置vscode,我们用命令行

2.对这个文件进行预处理

使用命令:gcc -E -o hello.i hello.c

i文件

打开看看

3.对hello.i文件进行编译

使用命令:gcc -S -o hello.s hello.i

产生了这个

4.对编译后的文件hello.s进行汇编(第二步输出的汇编代码hello.s翻译成符合一定格式的机器代码)

使用命令:gcc -c -o hello.o hello.s

我此时,想用2进制编辑器看看是四年情况

下载一个

嗯,很专业.看不懂.....看见字符串了

我本来想看看o文件的类型,file命令win不支持,用了type,输出这些

找不到file的代替品了

5.对hello.o文件进行连接(连接就是将上步生成的 OBJ 文件和系统库的 OBJ 文件、库文件连接起来,最终生成了可以在特定平台运行的可执行文件)

使用命令:gcc -o hello hello.o

成功输出

小结:

1).在编译过程中,除非使用了 -E, -S, -c选项,或者编译出错,不然最后步骤都是链接

简化上边的编译过程:

分别使用命令:

gcc -c -o hello.o hello.c

gcc -o hello hello.o

也是可以的

解释:gcc对.c文件默认的进行预处理操作,-c选项时编译汇编的操作,汇编操作得到.o文件,通过gcc -o hello hello.o命令对hello.o文件进行链接,得到可执行文件。

使用gcc的 -v参数查看系统编译的详细过程

连接就是将上步生成的 OBJ 文件和系统库的 OBJ 文件、库文件连接起来,最终生成了可以在特定平台运行的可执行文件

分别使用命令:

gcc -c -o hello.o hello.c

gcc -v -o hello hello.o

代码语言:javascript
复制
Using built-in specs.
COLLECT_GCC=C:\mingw-64\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/mingw-64/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw810/x86_64-810-win32-seh-rt_v6-rev0/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=win32 --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/x86_64-w64-mingw32-static 
--with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-win32-seh-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-win32-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-win32-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/x86_64-810-win32-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/x86_64-810-win32-seh-rt_v6-rev0/mingw64/opt/lib -L/c/mingw810/prerequisites/x86_64-zlib-static/lib -L/c/mingw810/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: win32
gcc version 8.1.0 (x86_64-win32-seh-rev0, Built by MinGW-W64 project)
COMPILER_PATH=C:/mingw-64/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/;
C:/mingw-64/mingw64/bin/../libexec/gcc/;
C:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/
LIBRARY_PATH=C:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/;
C:/mingw-64/mingw64/bin/../lib/gcc/;C:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/;
C:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../lib/;C:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/;
C:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../
COLLECT_GCC_OPTIONS='-v' '-o' 'hello.exe' '-mtune=core2' '-march=nocona'
C:/mingw-64/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/collect2.exe -plugin 
C:/mingw-64/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/liblto_plugin-0.dll -plugin-opt=C:/mingw-64/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\yunswj\AppData\Local\Temp\ccA88Ioz.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-liconv -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt --sysroot=C:/mingw810/x86_64-810-win32-seh-rt_v6-rev0/mingw64 -m i386pep -Bdynamic -o hello.exe 
C:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o C:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/crtbegin.o -LC:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0 -LC:/mingw-64/mingw64/bin/../lib/gcc -LC:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib -LC:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../lib -LC:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib -LC:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../.. hello.o -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32 -liconv -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt C:/mingw-64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/crtend.o
COLLECT_GCC_OPTIONS='-v' '-o' 'hello.exe' '-mtune=core2' '-march=nocona'

以上是编译细节

1)加入系统标准启动文件(OBJ文件)

2)链接库文件(libc)

在hello.c中使用了printf函数,是在libc中实现的

注意:-L 是指明链接的路径,-l指明链接的库文件。而-lc:链接libc库文件(里边有实现printf等函数)

知识点:

①gcc使用 -nostartfiles 参数

表示不连接系统标准启动文件,而标准库文件仍然正常使用

②gcc使用 -nostdlib 参数

表示不连接系统标准启动文件和标准库文件,只是把指定的文件传递给连接器,这个选项常用与编译内核、bootloader等程序,因为他们不需要启动文件和标准库文件。

验证一下:使用-nostdlib 参数,表示不连接系统标准启动文件和标准库文件,看一下会有什么结果,编译是否成功?

分别使用命令:

gcc -c -o hello.o hello.c

gcc -v -nostdlib -o hello hello.o

编译的结果如下,提示错误:

4.静态连接和动态连接

解析:

1)动态链接:使用动态链接库进行链接库进行链接,生成的程序在执行的时候需要加载所需要的动态库才能运行,动态连接生成的程序体积体积较小,但是必须依赖所需的动态库,否则无法运行。

2)静态链接:使用静态库进行链接,生成的程序包含运行所需要的全部库,可以直接运行,不过静态链接生成的程序体积大。

例子:

分别使用动态库链接和静态库链接

额,此时我暴躁了...不是我想要的结果.

代码语言:javascript
复制
PS C:\Users\yunswj\Desktop\C\Hello> gcc -o static hello_static .\hello.o

gcc.exe: error: hello_static: No such file or directory

PS C:\Users\yunswj\Desktop\C\Hello> gcc -static -o hello_static .\hello.o

PS C:\Users\yunswj\Desktop\C\Hello> ls

开树莓派折腾,我树莓派ssh连不上了...

查看静态链接和静态链接是否需要动态库?

使用 ldd 命令查看

写到这里先,明天补剩下的~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深之无迹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 我这个心情本来还行,就是现在不是个滋味...事情是这样的.我今天早上和往常一样打开一本书在看.书很不错
  • 我上午一直没有开电脑,也就没有没有看这个网站.书看了半本也晚上了,我就打开电脑准备写笔记.想起了这个网站,准备实操一波.
  • but,but,but,
  • 网站我查了一下,服务器在国外托管.翻墙流畅.....emmmm暴露了什么,注意身体~~
  • 这个书前面讲到环境的搭建.说到了gcc.后面写程序编译时,我发现命令是arm-gcc这样的.我哪见过这种东西.赶紧查一下.明白了.我平时用是生成的执行文件是x86平台的.arm当然就是arm环境的.还有一种是linux的.
  • arm-linux-gcc、
  • arm-none-eabi-gcc、
  • arm-eabi-gcc、
  • arm-none-linux-gnueabi-gcc区别
    • arm-none-eabi-gcc
      • arm-none-linux-gnueabi-gcc
        • arm-eabi-gcc
          • armcc
            • arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc
            • ABI 和 EABI
            • ABI
              • EABI
              • arm-linux-gnueabi-gcc 和 arm-linux-gnueabihf-gcc
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档