• 转载: buildroot编译环境


    buildroot编译环境
    它其实就是一个脚本和补丁的集合,它是一个针对uClibc的交叉编译环境,里面集成了gtk,directFB,Qt embedded,jpeg库等 ,对于每个包,包括Config.in和 .mk文件。
    对于每一个包,Makefile的流程是下载 ,解压 ,patch ,configure , make , install 。
    这里面最主要的是patch和Config.in,patch解决了source在交叉编译环境下所需要的修改,Congin.in解决了依赖关系。
    Buildroot的目录结构如下:
     package : 各个user space包的目录,每个包里面包括makefile  patch,每个目录下必须有下面2个文件 :
                .mk   : makefile 包括下载,,解压,patch ,configure ,编译,安装 
                Config.in : 描述文件,包括包的依赖关系等,一选上就会相应选择其他的包等等信息
     toolchain : 交叉工具链gcc .binutils,uclibc 等的makefile patch 
     docs :      help file
     target      :产生rootfs 的工具的makefile patch , 包括ext2 jffs2 cramfs等制作工具
     project :    编译多个rootfs在一个buildroot tree下的一些makefile 等
     script :     一些脚本
    Buildroot为编译产生的目录 :
     dl : 下载的包存放的目录,这样不用每次都去下载
     build_ARCH : 不可配置的user space tools 编译目录 ,这样的话 ,如果对于相同的ARCH ,则共享这部分,不用再编译
     project_build_ARCH : configurable user space tools 编译目录, 比如busybox , 对于相同的ARCH,也可能配置不一样
     toolchain_build_ARCH :  toolchain编译目录
     binary /$(project) : rootfs ,kernel image ,boot loader在存放目录,可用来下载到产品中
     build_ARCH/staging_dir : 交叉工具链 安装的地方
     project_buid_ARCH/root : rootfs , 不是打包成.jffs2的那种方式,适合NFS调试 
     .config 配置文件

    Buildroot利用和Linux kernel config一样的原理,直接运行make menuconfig ,图形化选择包,应此比较易用。
    Buildroot的编译过程 如下:
    a)toolchian的制作,如果选择external toolchain,跳过这一步,否则
    1 下载内核代码,通过内核代码 生产内核头文件
    2 下载uClibc 库  
    3  编译binutils (pass 1)
    4  编译gcc (pass 1)
    5 编译uClibc 
    6  编译gcc (pass 2)

    b) 其他包的编译
      1 编译busybox
      2 根据选择的包,编译其他的包 
      3  制作成jffs2 或者ext2 等根文件系统
    对于每一个包,都是下载,解压,patch,configure ,make ,install,所以最终对这些文件的修改,比如mplayer,qtopia等,
    最好也做成patch的方式。这样也便于管理,以及知道我们对源码的修改有那些。

    Buildroot的优点: 1) 易用,直接 make menuconfig ,选择上所需要的包 ,  然后 make 
         2) 支持uClibc,对于很多嵌入式设备,因空间小,需要选择uClibc时,那编译环境最好选择Buildroot了,它
           就是针对uClibc的编译
    缺点: 1)不能制作glibc的toolchain ,如果用glibc 则用external  toolchain 
         2)还有一些变态的功能,比如为多个平台编译阿 支持不好,不过这些我也不需要
        3)修改了代码后,不会重新编译 (这个很麻烦的,一般都是开始的时候全部编译,然后在修改代码,不能直接编译,太麻烦了 )
    这个是package中的问题 ,比如 busybox ,修改其中的代码,发现不会重新编译。
    如果直接修改了其中的代码,需要删除busybox,然后再编译,这点对于在开发过程中比较麻烦,
    如果这样修改busybox.mk 
    --- $(BUSYBOX_DIR)/busybox: $(BUSYBOX_DIR)/.config
    +++ $(BUSYBOX_DIR)/busyboxfake: $(BUSYBOX_DIR)/.config


    --- $(TARGET_DIR)/bin/busybox: $(BUSYBOX_DIR)/busybox
    +++ $(TARGET_DIR)/bin/busybox: $(BUSYBOX_DIR)/busyboxfake

    这样每次修改文件都会重新编译 
    因为busyboxfake永远不存在,所以他永远会去执行make ,make会去检查是否有文件修改
    而buildroot本来的方式 当存在busybox后,它不执行make了 
    依据同样原理去修改其他的.mk 
    但是 后果是 即使没有文件修改了,也会执行install动作 。
    更好的方法一直没想到。
      

    Buildroot使用
    1) 用uClibc工具链,
    a) 工具链编译 ,本机环境 ubuntu 9.04 Gcc 4.3 
     a.1)选择uclibc 以及gcc 版本,然后make
     a.2)下载linux-2.6.30.5.tar.bz2,主要是得到linux 头文件 ,uclibc/glibc编译都需要linux
         kernel header ,以了解kernel所具备的能力
     a.3) 下载uClibc-0.9.30.1.tar.bz2
     a.4) 下载 gmp-4.2.4.tar.bz2 (arbitrary precision arithmetic lib on signed number)
     a.5) download  mpfr (arbitrary precision arithmetic on floating-point numbers)
     a.6) 编译出库文件 .a
     a.7) 下载 binutils-2.19.1.tar.bz2
     a.8) binutils 第一遍编译,
         在build_arm/staging_dir/usr/bin生成了很多工具 如 ar ,ld ,此时的工具host为本机
          target为arm
     a.9) 下载 gcc-4.3.3/gcc-4.3.3.tar.bz2
     a.10) gcc 第一遍编译
           第一次生成的gcc是不完全的, 只能交叉编译uClibc,不能交叉编译其他的,因为一个关键的工具链组件还不存在:启动代码crt?.o。这些代码其实包括了程序初始化进入main函数之前和退出main函数之后结束所需的步骤。用第一遍的gcc 编译
    echo "main(){}" > dummy,c && gcc dummy.c
    这是会出错的。
           参见  http://www.linuxsir.org/bbs/thread267672-4.html
     a.11) 编译uClibc
     a.12) gcc 第二遍编译
           在build_arm/staging_dir/usr/bin生成了gcc 
           这次c++也支持了(而c++支持必须要有glibc/uClibc库的支持,所以a.11编译出了uClibc)
           参见  http://www.linuxsir.org/bbs/thread267672-4.html
      a.13) 编译atk,freetype等,
         在build_arm/staging_dir/usr/include 产生出很多头文件
         在build_arm/staging_dir/usr/lib 产生出库
         这些都是其他user space (比如GTK ,X)的基本库,在make menuconfig的时候,可以看到选择了那些package

     a.14) 在看binutils的 makefile的时候,还有 binutils 第2遍编译
           此时的工具host为arm
          target为arm
         也就是此次生产的这些工具,将在arm平台上跑,编译出arm的代码.
         如此的话,那gcc 有第3次编译了(此时的gcc run on arm ,编译出arm的代码)
         不过我没看到binutils 的第2次编译和gcc的第3次编译,一般都是在pc上编译arm的代码阿,谁还在
        arm机器上跑gcc来编译呢?
     
      
     可能出现的问题 :
     1)  安装Texinfo ,出现问题1
       版本是4.11 ,需要修改,
    将正则表达式改为'texinfo[^0-9]*([1-3] [0-9]|4.[4-9]|4.[1-9][0-9]*|[5-9])' 
    参见
    http://www.lupaworld.com/home/space-32446-do-blog-id-121384.html
     2) 出现问题2 
     /home/lawrencekang/xpndr-infotainment_center_2.0.3/buildroot/toolchain_build_arm_nofpu/gcc-4.2.1-initial/./gcc/as: line 2: exec: -m: 无效的选项
    修改 : ./gcc/as文件
     exec -c /home/lawrencekang/xpndr-infotainment_center_2.0.3/buildroot/build_arm_nofpu/staging_dir/bin/arm-linux-uclibcgnueabi-as "$@"


    b) 编译gtk2 ,用上次生成的toolchain编译
      选择了gtk2 /x ,然后make ,结果出现错误,在编译X server的时候 出现 MB_CUR_MAX 没定义的错误
    在buildroot ->toolchain中 选择 Enable toolchain locale/i18n support? 
                                 Enable WCHAR support
    另外,由于我的目标机器没有 hardware floating 
                       我选择 Use software floating point by default
    Thread library implementation -》选择NPTL
    然后make clean 
    问题 ? 怎么不重新编译 compiler呢?
    solution : 删除 编译的包 重新编译
     发现uClibc还不能Enable toolchain locale/i18n support?  这也说明uClibc小但是功能弱
     去掉,删除toolchain_build_arm 
     重新编译
    ./../gdk/x11/gdkwindow-x11.h:33:36: X11/extensions/Xdamage.h: 没有该文件或目录
    但实际上 这个文件是存在的 目录是 build_arm/staging_dir/usr/include/X11/extensions
    这是因为编译gtk host时,需要libxdamage-dev 
    sudo apt-get install libxdamage-dev
    [Question] 不明白它为什么要编译host Gtk ?

    2) 用外部的external toolchain  编译arm平台 用glibc 
     a) 选择arm-2006q3
     b) 按照buildroot说明文档 ,配置好external tool chains 
      出现错误 :  Incorrect selection of the C library
    原因:
      在目录toolchain/external-toolchain 里面 ,有个ext-tool.mk,check_glibc
      发现他怎么去找  /opt/codesourcery/arm-none-linux-gnueabi/libc 下面的  
    The programs ld.so and ld-linux.so* find and load the shared libraries needed by a program,
    arm-2006q3/libexec/gcc/arm-none-linux-gnueabi/4.1.1/install-tools/mkheaders 
    里面的prefix = /opt/codesourcery     
    解决方法:
      将./external_toolchain/arm-2006q3 下面的文件全部copy 到 /opt/codesourcery下面
     c)编译 fltk OK
     d)编译Qtembedded 4.5  OK

    3) 用外部的external toolchain  自己添加包 
         添加qtopia 4.2.1 
       发现出了一些问题 ,以前用ubuntu 7编译的时候 没出错阿 ,而现在用的是ubuntu 9.04 (linux 2.6.28-15 )
    也许buildroot要向poky一样,先编译出一个host环境,而不依赖于本机的环境

    a) 在packgage 里 添加 一个包 qtopia 
      然后 写上 Config.in , .mk
      Config.in 主要是写上依赖关系 ,选项
       .mk 包括了 解压代码,patch ,然后.configure , make 
    在package/Config.in 中 加上 source ./qtopia/Config.in 
    b) 选上,然后 make 
      b.1) 出现问题 1 
    The system byte order could not be detected!
    Turn on verbose messaging (-v) to see the final report.
    solution :
     修改 qtopiacore/qt/configure
     指定它little-endian
    ---
    +++
    if [ "$F" -eq 0 ]; then
                CFG_ENDIAN="Q_LITTLE_ENDIAN"
            elif [ "$F" -eq 1 ]; then
                CFG_ENDIAN="Q_BIG_ENDIAN"
            else
     +++           CFG_ENDIAN="Q_LITTLE_ENDIAN"
     +++         #  echo
     +++         #  echo "The system byte order could not be detected!"
     +++         #  echo "Turn on verbose messaging (-v) to see the final report."
     +++         #  echo "You can use the -little-endian or -big-endian switch to"
     +++         #  echo "$0 to continue."
     +++         #  exit 101
     ---         echo
     ---          echo "The system byte order could not be detected!"
     ---           echo "Turn on verbose messaging (-v) to see the final report."
     ---           echo "You can use the -little-endian or -big-endian switch to"
     ---           echo "$0 to continue."
     ---           exit 101


      b.2) 出现问题2 
    asm/page.h找不到 
    原因 :目前的kernel是 ubuntu 9.04 (linux 2.6.28-15 ),没有asm/page.h这个文件了。
          而qtopia 4.2.1 那时候 肯定是基于老版本的kernel ,那时候有这个文件
    solution :
      从 linux 2.6.21.5中 在 asm-i386里找了一个page.h copy 到usr/inculde/asm/page.h中

      b.3) 出现问题3
    /usr/include/bits/fcntl2.h:51: 错误: 调用‘__open_missing_mode’,声明有错误属性:open with O_CREAT in second argument needs 3 arguments
    原因 :
    使用open函数的时候,如果在第二个参数中使用了 O_CREAT,就必须添加第三个参数:创建文件时赋予的初始权限,而gcc-4.3对语法错误的检查严格是出了名的(4.1就不会因此错误退出),所以就退出了。
    以前用的gcc版本低

    solution :
    修改 qtopia-phone-4.2.1/src/libraries/qtopiabase/qmemoryfile_unix.cpp
           f = ::open(tmpFile.toLatin1(), O_CREAT | O_WRONLY);
    改为 
          f = ::open(tmpFile.toLatin1(), O_CREAT | O_WRONLY,S_IRWXU|S_IRWXG|S_IRWXO);

      b.4) 出现问题4
     xargs: /media/H/xpndr-multimedia_base_1.1.1_giant/buildroot/build_arm_nofpu/qtopia-phone-4.2.1/bin/qdawggen: 没有该文件或目录
    真奇怪阿 !! 为什么qdawggen没被编译呢?
    solution :
    在device/XXX/custom.pri 里面 

    PROJECTS+=tools/content_installer
              tools/qdawggen
    然后删除 .configured 
    make 
    此时将重新编译整个qtopia 

        b.5) 出现问题5
     media/H/buildroot-2009.08/build_arm/qtopia-phone-4.2.1/bin/content_installer /media/H/buildroot-2009.08/project_build_arm/lawrence/root/opt/Qtopia-4.2.1-release/qtopia_db.sqlite /opt/Qtopia-4.2.1-release /apps/Settings /media/H/buildroot-2009.08/build_arm/qtopia-phone-4.2.1/apps/Settings/TaskManager.desktop
    make[6]: *** [install_docapi_taskmanagerdesktop] 段错误
    原因: 未知,没空去理会
    solution :
    修改 src/tools/content_installer/main.cpp 直接return 0 ; 什么都不做

    c) 然后 OK 

  • 相关阅读:
    重构手法之简化函数调用【5】
    netstat命令
    Python使用wxpy模块实现微信两两群组消息同步
    format函数格式化显示的方法
    scrapy介绍及使用
    Linux常用命令复习
    Django实现博客项目
    Django中CKEditor富文本编译器的使用
    Django-admin站点管理的详细使用
    电脑修改密码后,git push 报错unable to access
  • 原文地址:https://www.cnblogs.com/sstudy-linux/p/4920269.html
Copyright © 2020-2023  润新知