我这个心情本来还行,就是现在不是个滋味...事情是这样的.我今天早上和往常一样打开一本书在看.书很不错
就是这本,讲的可以说是非常好了.我推荐
然后他自己说,开了一个网站,供人下载.
代码语言: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 两种模式互不兼容):
- soft:不用fpu进行浮点计算,即使有fpu浮点运算单元也不用,而是使用软件模式。
- softfp:armel架构(对应的编译器为 arm-linux-gnueabi-gcc )采用的默认值,用fpu计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。
- 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 = %fn”, 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硬件浮点模式。
- 使用 arm-linux-gnueabi-gcc 编译:
- # 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-64mingw64bingcc.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:UsersyunswjAppDataLocalTempccA88Ioz.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:UsersyunswjDesktopCHello> gcc -o static hello_static .hello.o
gcc.exe: error: hello_static: No such file or directory
PS C:UsersyunswjDesktopCHello> gcc -static -o hello_static .hello.o
PS C:UsersyunswjDesktopCHello> ls
开树莓派折腾,我树莓派ssh连不上了...
查看静态链接和静态链接是否需要动态库?
使用 ldd 命令查看
写到这里先,明天补剩下的~