转载: 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 

原文地址:https://www.cnblogs.com/sstudy-linux/p/4920269.html