• 嵌入式linux开发交叉编译的一些tips


    嵌入式linux开发-交叉编译的一些tips

    时间:20201013,版本:V0.1

    1.交叉编译工具链的组成

    交叉编译工具链是一个由编译器、连接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils、gcc和glibc三个部分组成。有时出于减小 libc 库大小的考虑,也可以用别的 c 库来代替 glibc,例如 uClibc和 newlib。

    2.交叉编译工具的获取

    (1)可以去下别人厂商提供的或者别人制作好的。

    (2)交叉编译工具的制作可以参考这个文章:How to Build a GCC Cross-Compiler

    https://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/

    以及《嵌入式linux系统开发教程 第二版》(图6-1),过程说的很清楚。制作过程比较繁琐,主要是因为为了生成完整版的gcc,需要先编译一个辅助版的不依赖glibc的编译器,再用辅助gcc编译libc,再生成完整的gcc。

    (3)从头做一个太麻烦,可以使用工具。我们这里采用buildroot生成的。Buildroot使用见本站其文章。

    3.交叉编译链工具的命名规则

    交叉编译知识解析(二) —— 交叉编译器的名字的命名规则

    https://blog.csdn.net/zqixiao_09/article/details/51823165

    https://www.crifan.com/files/doc/docbook/cross_compile/release/html/cross_compile.html#crosscompiler_naming_rule

    4.交叉编译器引用头文件的位置

    交叉编译器默认引用的.h文件和lib文件的位置,可以使用如下的命令查看:

    (这里的mipsel-linux-gcc是使用buildroot生成的。)

    ./mipsel-linux-gcc -print-search-dirs

    打印出搜索路径。一堆挤在一起的路径,很难看。

    网上大家貌似更喜欢另一个命令:

    $  echo 'main(){}' | ./mipsel-linux-gcc -E -v -x c -

    参数-E:

    只进行预处理步骤,这个不生成文件, 需要把它重定向到一个输出文件里面。

    参数-v:

    使用 gcc -v 可以查看默认开启的选项。编译这个工具时所使用的configure 参数配置。

    参数 - (只有一个短线):

    这个参数需要特殊说明一下。短线的意思是 Specify input file as stdin, 在这里就是从管道接收输入了。-x c 的意思是以c语言来编译接收的文件。因为接收的是字符流,没有文件名,所指告知gcc是c语言。Gcc默认也是c。

    命令输出的结果中会包含搜索路径,并说明这些配置是记录在编译器的 built-in specs。

    我的电脑上,路径是:

    #include <...> search starts here:

    /home/jack/worktable/buildroot/output/host/lib/gcc/mipsel-buildroot-linux-uclibc/8.4.0/include

    /home/jack/worktable/buildroot/output/host/lib/gcc/mipsel-buildroot-linux-uclibc/8.4.0/include-fixed

    /home/jack/worktable/buildroot/output/host/mipsel-buildroot-linux-uclibc/sysroot/usr/include

    End of search list.

    可以看到,交叉编译工具的搜索目录一般就在安装目录了。

    5.源码包交叉编译的一般过程(configure的常用参数的含义

    源码包和普通的linux程序的编译差不多,configure、make、make install。

    这里需要注意的是参数和环境变量。

    configure是autotools生成的配置脚本,用于生成makefile。

    ./configure --help 查看相关的参数。

    重要的参数有:

    --prefix

    安装路径前缀,指使用make install 后,是指生成的可执行文件安装在哪个目录,这个目录需要根据实际情况作选择。如果该目录不存在,会自动创建。

    例如:        

    ./configure  --prefix=$home/work/    

    --build

    执行代码编译的主机,正常的话就是你的主机系统。这个参数一般由config.guess来猜就可以。当然自己指定也可以。

    --host

    编译出来的二进制程序所运行于的主机,因为绝大多数是本机编译,本机执行,所以这个值就等于build。只有交叉编译的时候(也就是本机编译,其他系统机器执行)才会build和host不同。用host指定运行平台。

    --target

    被编译的程序生成的程序将运行于的平台。这个选项只有在建立交叉编译环境(制作交叉编译工具)的时候用到,正常编译和交叉编译都不会用到。他用build主机上的编译器,编译一个新的编译工具(binutils, gcc,gdb等),这个新的编译器运行于host,它(新的编译器)编译出来的其他程序将运行在target系统上。

    在前文中生成的mips平台的工具,执行:

    $ mipsel-linux-gcc -v

    输出中就会显示生成此工具时的configure参数:

    Configured with: ./configure  ..--target=mipsel-buildroot-linux-uclibc ..

    举个栗子:

    ./configure --host=arm-unknown-linux-gnueabi --target=arm-unknown-linux-gnueabi --build="i686-pc-linux" --prefix=$DIST/libnet

    问题是,到哪里精确的获取这几个平台值呢?交叉编译的时候我一般用编译工具的名称去掉工具名称。例如工具是mips-robotech-linux-gcc,那么--host就设置成:

    --host=mips-robotech-linux

    这里其实最重要的是--host参数了,configure使用--host参数寻找交叉编译工具。前提是在path环境变量里设置了交叉编译工具的路径。编译器也可以用环境变量CC指定。

    --with-sysroot

    https://answerywj.com/2019/04/26/what-is-sysroot/

    重要的环境变量:

    CC

    指定编译器,默认为gcc、cc或者HOST-gcc

    例如:

    ./configure  CC=/home/path/mips-linux-gcc

    或者使用export指定

    $export CC=/home/path/mips-linux-gcc

    两种写法有什么区别呢?使用export应该是正规的方式,有的configure脚本可能不支持第一种方式。

    所以,指定编译器既可以通过--host去关联也可以通过CC指定,怎样更合适呢?一般./configure --help里会告诉你,环境变量优先级更高,能够覆盖掉./configure脚本自己的推断。

    CFLAGS、 CPPFLAGS

    C compiler flags,最常用是指定(非标准默认的)头文件的路径。以及其他的编译标志。

    例如:

    export CFLAGS="-I$WDIR/arm-unknown-linux-gnueabi/include  -mhard-float  -mfpu=vfpv3-d16"

    LDFLAGS

    linker flags, 例如.指定库文件的路径 -L<lib dir>, if you have libraries in a nonstandard directory <lib dir>。

    例如:

    export LDFLAGS="-L$WDIR/arm-unknown-linux-gnueabi/lib"

    LIBS

    libraries to pass to the linker, e.g. -l<library>。

    -l后面紧接着库名,链接时在搜索目录中寻找库文件,搜索名为libxxx.a 或 libxxx.so

    LDFLAGS告诉链接器从哪里寻找库文件,LIBS告诉链接器要链接哪些库文件。

    参考:

    https://blog.csdn.net/xhoufei2010/article/details/82768995

    https://unix.stackexchange.com/questions/149359/what-is-the-correct-syntax-to-add-cflags-and-ldflags-to-configure

    https://blog.csdn.net/zqixiao_09/article/details/51823165

    https://www.crifan.com/files/doc/docbook/cross_compile/release/html/cross_compile.html#crosscompiler_naming_rule

  • 相关阅读:
    APP手工测试01-app专项测试要点-测试、开发环境-敏捷开发
    APP测试面试题(一)
    软件测试面试题-网站
    APP 抓包-fiddler
    使用模板快速编写测试用例
    随机数据构造-Faker
    [转载]大规模爬虫流程总结,经验总结
    python高级知识点总结
    python sorted,sort,reversed,reverse函数
    python函数式编程
  • 原文地址:https://www.cnblogs.com/robotech/p/16271575.html
Copyright © 2020-2023  润新知