Yocto编译流程详细攻略及bitbake实用方法

本文yocto部分转自https://www.kancloud.cn/digest/yocto,整理一下,方便翻阅,比yocto官方文档要简单明了的多,也省去了不少翻译的痛苦。

文章目录

  • 一、yocto
    • (1): Yocto 编译后文件放在了哪里 输出文件位置
    • (2): Yocto Linux内核编译目录在哪?
    • (3): Yocto 如何重新编译Linux内核与dtb,并放到deploy目录?
    • (4): Yocto 如何确定(找到)一个包的名字
    • (5): Yocto如何更改source code的下载与git clone地址
    • (6): Yocto中如何共享已经下载的文件
    • (7): Yocto Bitbake的clean与cleanall以及cleansstate的区别
    • (8): Yocto 如何加快软件包的下载 如何只下载所有需要的软件包而不编译
    • (9): Yocto 软件包的下载地址在哪
    • (10): Yocto hellworld 添加一个软件包
    • (11): Yocto如何往最终的rootfs中添加软件
    • (12): 使用Yocto帮组我们寻找难找的固件与固件放置路径
    • (13): Yocto 查看软件包的依赖关系
    • (14): Yocto中编译链的配置变更(tuning)
    • (15): Yocto中的包管理器
    • (16): Yocto 制作SDK分发Toolchain 脱离Yocto环境开发
    • (17): Yocto License问题:restricted license not whitelisted in LICENSE_FLAGS_WHITELIST
    • (18): Yocto SDK Toolchian中静态库的添加
    • (19): Yocto SDK Toolchian的使用
  • 二、bitbake
    • 简介
    • 下载地址
    • yocto中的目录
    • 功能列表

一、yocto

(1): Yocto 编译后文件放在了哪里 输出文件位置

编译完成后内核以及rootfs,内核,uboot以及dtb会放在相对于build目录的tmp/deploy/images/MACHINE/下面,这里MACHINE需要可能为空(对于老版本的poky/yocto),也可能是你的板子名字,例如sabresd。

对于toolchain,那么放在mp/deploy/sdk/MACHINE/下。
编译完成后内核以及rootfs以及dtb会放在相对于build目录的tmp/deploy/images/imx6qsabresd/下面
Yocto编译流程详细攻略及bitbake实用方法_第1张图片
各个文件都有一个软连接来指向最新编译产生的文件,因此如果需要看到最新的文件,可以直接使用软链接即可:
Yocto编译流程详细攻略及bitbake实用方法_第2张图片

(2): Yocto Linux内核编译目录在哪?

内核放在了哪里? 这个是放在了如下位置,我们可以用下面命令来确定:

bitbake -e linux-imx  | grep ^S=

图示:在这里插入图片描述

(3): Yocto 如何重新编译Linux内核与dtb,并放到deploy目录?

编译内核,并生成uImage+dtb,编译的命令如下:

bitbake linux-imx -C compile

注意这里的-C的C是大写,和小写的c是有区别的。
注意这里的linux-imx是针对imx的内核,你的内核名字可能不一样。

(4): Yocto 如何确定(找到)一个包的名字

使用下面命令来却确定:

bitbake -s | grep XXX

其中XXX为包的关键字,例如linux或者uboot,这样就可以看到所有带有关键字的包了,如下图,就是为了找到内核:
Yocto编译流程详细攻略及bitbake实用方法_第3张图片

(5): Yocto如何更改source code的下载与git clone地址

现象
Yocto中在fetch一些软件包的时候经常出现一天也下载不下来,这种情况极大浪费了我们的时间。
例如,下面有三个Package下载了一天也没有完成:在这里插入图片描述
解决方法
确定下载的地址,手动下载
先确定软件包的下载地址,例如对于opencv与opencv-samples软件包:在这里插入图片描述
可以看到他们的git地址都是一样的,因此,我们可以手动来git clone:
Yocto编译流程详细攻略及bitbake实用方法_第4张图片
可以看到我们只使用了几十分钟而已。clone下来以后,我们就可以让软件包使用我们本地的这个repo了,而不需要忙忙的去远程repo去clone。
让package克隆时使用本地的git
找到软件包对应的bb文件
我们可以使用find命令来查找
在这里插入图片描述
更改bb文件
Yocto编译流程详细攻略及bitbake实用方法_第5张图片
注意里面添加了一个protocol指定。
再一次获取

bitbake opencv -c fetch

结果如下:
在这里插入图片描述
提示找不到branch,于是我们到我们本地的repo中将此branch切出来,也可以将其制作成bare repo:Yocto编译流程详细攻略及bitbake实用方法_第6张图片
然后再一次进行fetch就可以了:Yocto编译流程详细攻略及bitbake实用方法_第7张图片
对于其他软件也是类似的。

(6): Yocto中如何共享已经下载的文件

Yocto的下载耗时可能会超过编译的时间,因此大家都希望下载一次后大家都用共用下载好了的文件,而不要再去下载。

Yocto中所有下载了的以及git clone的文件都放在环境变量DL_DIR指示的目录下,这个目录默认在machine build directory下面。

因此要共享下载文件只需要指定此变量到下载好了的目录即可,可以在local.conf中指定即可:
Yocto编译流程详细攻略及bitbake实用方法_第8张图片

(7): Yocto Bitbake的clean与cleanall以及cleansstate的区别

Yocto中对于不同的Package,有不同的task,即可以执行不同的操作,有一些是所有包共通的,例如clean,build等。
我们可以使用下面命令来查看一个包都有哪些可执行的task:

bitbake Package -c listtasks

图示:Yocto编译流程详细攻略及bitbake实用方法_第9张图片
我们可以从里面看到clean与cleanall以及cleansstate的区别。

(8): Yocto 如何加快软件包的下载 如何只下载所有需要的软件包而不编译

加快下载
Yocto中下载是最耗时的,因此我们可以尽可能的开启最多的并行数量。

对此,我们可以在local.conf中将并行数目调大,例如我的CPU 是E3-1230 v2, 8核,所以我可以开启16个线程来下载,因为我们的网速慢,所以其实这些下载操作并非CPU密集型任务,很多包也很小,所以同时IO也不密集,因此可以适当调大:Yocto编译流程详细攻略及bitbake实用方法_第10张图片
效果如下:Yocto编译流程详细攻略及bitbake实用方法_第11张图片
下载所有需要的软件包而不编译
有的时候我们可能需要先将所有需要的软件包下载下来,等离线回家或者其他时机再编译,对此我们可以使用如下命令来完成:

bitbake fsl-image-qt5 -c fetchall

对于不同的目标,需要替换fsl-image-qt5为其他的,例如可能是core-image-minimal,我们可以看到fetchall的意义:

do_fetchall 				Fetches all remote sources required to build a target

(9): Yocto 软件包的下载地址在哪

一般而言,可以使用Yocto tips (5): Yocto如何更改source code的下载与git clone地址中提到的方法,但是有的时候一些地址是在bb文件include的文件中,而inc文件又可能层层包含,查找比较繁琐,因此直接到env中查找比较快。

例如要找到imx kenrel的fetch地址可以使用下面命令:

bitbake -e linux-imx | grep ^SRC_URI=

效果如下:在这里插入图片描述

(10): Yocto hellworld 添加一个软件包

Yocto中一个软件包是放在bb文件中的,然后很多的bb文件集成一个recipe(配方),然后许多的recipe又组成一个meta layer,因此,要添加一个包其实就是在recipe下面添加一个bb(bitbake配置文件)。下面使用helloworld作为一个例子。

clone bb文件
首先是进入到一个recipe目录下,例如下面就是到了recipes-graphics:

$ pwd
/media/work/iMX6/Yocto/sources/meta-fsl-arm/recipes-graphics

然后clone Package配置与source目录的repo:

git clone https://github.com/tonyho/helloYocto.git

查看软件包是否已经在Yocto中

$ bitbake -s | grep hello
hello                                                   :3-r0

确认在了以后,就可以执行编译等task了,如果有需要也可以deploy到rootfs中,这些操作可以参考我以前的一些博客。

一个软件包的结构
使用tree可以看到,其有一个bb文件,然后其中还有一个目录放着Makefile与source code:Yocto编译流程详细攻略及bitbake实用方法_第12张图片
其中的bb文件内容如下:

DESCRIPTION = "Hello World and Zlib test"
DEPENDS = "zlib"
SECTION = "libs"
LICENSE = "MIT"
PV = "3"
PR = "r0"

SRC_URI = " \
          file://helloYocto.c \
          file://zlibtest.c \
          file://makefile \
          "

LIC_FILES_CHKSUM = "file://helloYocto.c;md5=2dac018fa193620dc085aa1402e0b346"
S = "${WORKDIR}"
do_compile () {
    make
}

do_install () {
	install -d ${D}${bindir}/
	install -m 0755 ${S}/helloYocto ${D}${bindir}/
	install -m 0755 ${S}/zlibtest ${D}${bindir}/
}

FILES_${PN} = "${bindir}/helloYocto \
               ${bindir}/zlibtest "

可以看到,bb文件中指定了下面几个变量的值:

SRC_URI
LIC_FILES_CHKSUM:这个是checksum,如果是基于版本管理的source,那么不需要,例如git与svn
FILES_$(PN):PN是Package number,指代软件版本使用的PV与PR结合表示,即前面bitbake -s中看到的3-r0
还有两个方法,这2个方法重载了bitbake中默认方法:

do_compile
do_install

这两个方法,对应了Package中的compile与install task。

(11): Yocto如何往最终的rootfs中添加软件

在Yocto中如果我们期望在rootfs中添加一些软件,例如可能是bash,可能是lsusb等,那么,我们可以有两种方法:

1、手动添加,一个个文件的拷贝
在bb文件中添加安装项目,让Yocto自动帮助我们添加
第一种方法需要手动将软件包的所有文件以及依赖都一个个添加进去,耗时耗力且易错,因此使用第二中方法比较合适。

2、Yocto中Rootfs中添加软件包的步骤
找到打包rootfs的最终bb
如果我们使用的是下面命令:

bitbake fsl-image-qt5

那么,我们可以按照如下来搜索fsl-image-qt5这个软件包(任务),使用的是哪个bb文件:在这里插入图片描述
添加需要安装到rootfs的软件包
然后打开,并添加需要添加的包即可,例如下面添加的是linux-firmware:Yocto编译流程详细攻略及bitbake实用方法_第13张图片
保存,然后我们再一次使用bitbake构建系统,然后就可以看到rootfs中有对应的文件了:在这里插入图片描述

(12): 使用Yocto帮组我们寻找难找的固件与固件放置路径

有很多的硬件需要firmware才能工作,而这些firmware需要不仅仅需要找到,还需要放置到正确的位置,一般这个位置是/lib/firmware下面,但是很多也不尽然。

手动去查找这些固件,容易出现遗漏或者混淆,也有可能是年久不匹配了的固件,例如在我前面的博客中:Yocto i.MX6 (TQIMX6) (02) : USB Wifi (TP-Link WN821N等设备)AR9170的Linux内核支持与固件使用,就出现了自己按照wiki与help去查找firmware,结果却花了大量时间也没有解决,而使用yocto中的linux-firmware软件包,非法快速的解决了这个问题。

对于firmware放置的path也是类似,例如有些驱动放置的path为非标准的path,例如下面这些都是放在各自的目录中的:
Yocto编译流程详细攻略及bitbake实用方法_第14张图片
因此,直接将linux-firmware添加到打包rootfs,或者直接查看linux-firmware中的image文件夹就可以知道path了,例如前面的ar9170:在这里插入图片描述

(13): Yocto 查看软件包的依赖关系

查看一个文件包的依赖,我们可以使用图形化来查看,下面是一些官方说明:Yocto编译流程详细攻略及bitbake实用方法_第15张图片
例如我们要查看weston的依赖:

bitbake --ui=depexp -g weston或者 bitbake -g  -u depexp  weston

这个会列出不同的依赖,例如中间的是编译时候需要依赖的东西,结果如下:Yocto编译流程详细攻略及bitbake实用方法_第16张图片

(14): Yocto中编译链的配置变更(tuning)

这个在我们自己编译toolchain以及针对不同的硬件自己调整toolchain的时候用得多。变更方法也很简单,只需要在poky对应的配置查找一个合适的即可。

例如针对armv7而言,我们可以到下面文件查找一个合适的来使用:在这里插入图片描述
将自己选择好的写入到local.conf中:在这里插入图片描述

(15): Yocto中的包管理器

使用包管理器

在local.conf中使能即可:Yocto编译流程详细攻略及bitbake实用方法_第17张图片
然后编译后就会有rpm包了:在这里插入图片描述
配置文件服务器
可以使用ngix和apache,但是我们也可以只用使用python:

python -m SimpleHTTPServer

在这里插入图片描述
打开浏览器可以看到:
Yocto编译流程详细攻略及bitbake实用方法_第18张图片
在机器上面查看包的status

smart status

Yocto编译流程详细攻略及bitbake实用方法_第19张图片
在机器上面配置channel
对于rpm使用的smart工具,添加channel:

smart channel --add all type=rpm-md baseurl=http://192.168.2.100:8000/all
smart channel --add  cortexa9hf_vfp_neon  type=rpm-md baseurl=http://192.168.2.100:8000/cortexa9hf_vfp_neon 
smart channel --add cortexa9hf_vfp_neon_mx6qdl type=rpm-md baseurl=http://192.168.2.100:8000/cortexa9hf_vfp_neon_mx6qdl
smart channel --add imx6qsabresd type=rpm-md baseurl=http://192.168.2.100:8000/imx6qsabresd

添加参数之后,就可以update了:

smart update

正确的是下面命令的情形:Yocto编译流程详细攻略及bitbake实用方法_第20张图片
如果配置参数不对,那么就会出错,如果出错,那么检查IP与格式是否正确,例如下面的http少了两个//:Yocto编译流程详细攻略及bitbake实用方法_第21张图片
如果弄错了,那么可以先移除掉:

smart channel --remove all cortexa9hf_vfp_neon_mx6qdl imx6qsabresd cortexa9hf_vfp_neon

然后重新添加。
再看包的数量,可以看到变多了:Yocto编译流程详细攻略及bitbake实用方法_第22张图片
如果在PC中使用bitbake新编译了程序,那么需要使用下面命令重建index,否则客服端找不到新的软件包:

bitbake package-index

参考:
链接: link.

(16): Yocto 制作SDK分发Toolchain 脱离Yocto环境开发

Yocto中SDK有两种:

只有Toolchain,或者Toolchain+某类GUI特性
有针对某个Distribution的SDK,即含有Toolchian也含有这个Distrbutition特殊的文件
下面分别说明。

第一类
这类的软件包有如下这些:Yocto编译流程详细攻略及bitbake实用方法_第23张图片
其实就是两类:

meta-toolchain
meta-toolchain-qt/qte/qt5

后者包含了qt相关的东西,qte是面向embed的,如果需要做qt相关的application开发,那么包含qt的是合适的选择,否则仅仅开发普通application,那么使用meta-toolchian即可。

第二类
这类SDK才是推荐使用的,这个在distribution的task中有一个特别的任务,专门用来制作这个SDK,叫做populate_sdk,例如对应要制作一个fsl-image-qt5 目标的Distribution(也叫做image),那么可以这样子:

bitbake fsl-image-qt5 -c populate_sdk

这两类制作完成后,可以在deploy中看到了:在这里插入图片描述
其中xml文件是SDK包含了的文件列表。

SDK的安装
因为SDK文件是sh脚本+压缩的文件内容组成的,所以直接运行即可,例如:在这里插入图片描述
在prompt提示中,输入安装的路径。

(17): Yocto License问题:restricted license not whitelisted in LICENSE_FLAGS_WHITELIST

Yocto中可以配置一个Distrbution的License,然后所有的软件包,都需要符合这个license才可以被shipped到image中,如果我们需要使用违反此license的软件包,那么就需要额外配置。

例如,在bitbake编译vlc的时候出现下面的错误log:

$ bitbake vlc
Parsing recipes: 100% 
|###################################################################################################################################| Time: 00:00:26
Parsing of 2029 .bb files complete (0 cached, 2029 parsed). 2524 targets, 210 skipped, 1 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
ERROR: Nothing PROVIDES 'ffmpeg' (but /media/work/iMX6/Yocto/sources/meta-openembedded/meta-multimedia/recipes-multimedia/vlc/vlc_2.1.4.bb DEPENDS on or otherwise requires it)
ERROR: libav PROVIDES ffmpeg but was skipped: because it has a restricted license not whitelisted in LICENSE_FLAGS_WHITELIST
ERROR: libav PROVIDES ffmpeg but was skipped: because it has a restricted license not whitelisted in LICENSE_FLAGS_WHITELIST
ERROR: Required build target 'vlc' has no buildable providers.
Missing or unbuildable dependency chain was: ['vlc', 'ffmpeg']

那么就是因为vlc依赖libav,但是libav,的license不符合Distribution的License而无法编译。在libav中的bb文件配置中,可以看到其license flag为commercial:Yocto编译流程详细攻略及bitbake实用方法_第24张图片
开启接受所有的commercial license软件包

因此如果我们需要添加一些commercial Lincense的软件包,就需要添加对commercial的支持,只需要在local.conf中添加一行即可:

LICENSE_FLAGS_WHITELIST="commercial"

只接受特定的commercial license软件包

但是如果我们只期望某些特殊的commercial软件包可以被编译放入到rootfs中,那么我们就需要逐个指定,例如指定libav等包可以被编译:
Yocto编译流程详细攻略及bitbake实用方法_第25张图片

(18): Yocto SDK Toolchian中静态库的添加

Toolchian中静态库的添加

没有静态库,是无法静态编译应用程序的,因此,为了方便,还需要在SDK中添加静态库,例如libc。
这个特性在只需要开启即可,在local.conf中添加一行:

SDKIMAGE_FEATURES_append = "staticdev-pkgs"

Yocto编译流程详细攻略及bitbake实用方法_第26张图片
Toolchian中静态库的验证

然后重新build SDK,并安装SDK之后,我们可以验证其是否存在。
首先source env,导入各种bash变量:

source ../qt5_sdk/environment-setup-cortexa9hf-vfp-neon-poky-linux-gnueabi

然后确认libgcc.a是否exist:

$CC -print-file-name=libgcc.a

如果输出的存在,那么就有了,例如:
在这里插入图片描述

(19): Yocto SDK Toolchian的使用

在使用之前需要先source env,导入各种环境变量(注意将路径变更成你自己的):

source ../qt5_sdk/environment-setup-cortexa9hf-vfp-neon-poky-linux-gnueabi

然后我们可以查看一下bash的env了,下面是多出来的一些env,直接在bash中输入export即可看到:

$ export
declare -x AR="arm-poky-linux-gnueabi-ar"
declare -x ARCH="arm"
declare -x AS="arm-poky-linux-gnueabi-as "
declare -x CC="arm-poky-linux-gnueabi-gcc  -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/media/work/iMX6/Yocto/qt5_sdk/sysroots
/cortexa9hf-vfp-neon-poky-linux-gnueabi"
declare -x CFLAGS=" -O2 -pipe -g -feliminate-unused-debug-types"
declare -x CONFIGURE_FLAGS="--target=arm-poky-linux-gnueabi --host=arm-poky-linux-gnueabi --build=x86_64-linux --with-libtool-sysroot=/media/work/iMX6/Yocto/qt5_sdk/sysro
ots/cortexa9hf-vfp-neon-poky-linux-gnueabi"
declare -x CONFIG_SITE="/media/work/iMX6/Yocto/qt5_sdk/site-config-cortexa9hf-vfp-neon-poky-linux-gnueabi"
declare -x CPP="arm-poky-linux-gnueabi-gcc -E  -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/media/work/iMX6/Yocto/qt5_sdk/sysr
oots/cortexa9hf-vfp-neon-poky-linux-gnueabi"
declare -x CPPFLAGS=""
declare -x CROSS_COMPILE="arm-poky-linux-gnueabi-"
declare -x CXX="arm-poky-linux-gnueabi-g++  -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/media/work/iMX6/Yocto/qt5_sdk/sysroot
s/cortexa9hf-vfp-neon-poky-linux-gnueabi"
declare -x CXXFLAGS=" -O2 -pipe -g -feliminate-unused-debug-types"
declare -x M4="m4"
declare -x MANDATORY_PATH="/usr/share/gconf/kde-plasma.mandatory.path"
declare -x NM="arm-poky-linux-gnueabi-nm"
declare -x OBJCOPY="arm-poky-linux-gnueabi-objcopy"
declare -x OBJDUMP="arm-poky-linux-gnueabi-objdump"
declare -x OECORE_ACLOCAL_OPTS="-I /media/work/iMX6/Yocto/qt5_sdk/sysroots/x86_64-pokysdk-linux/usr/share/aclocal"
declare -x OECORE_DISTRO_VERSION="1.7"
declare -x OECORE_NATIVE_SYSROOT="/media/work/iMX6/Yocto/qt5_sdk/sysroots/x86_64-pokysdk-linux"
declare -x OECORE_SDK_VERSION="1.7"
declare -x OECORE_TARGET_SYSROOT="/media/work/iMX6/Yocto/qt5_sdk/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi"
declare -x OLDPWD="/media/work/iMX6/Yocto/video2lcd_arm/test"
declare -x PATH="/media/work/iMX6/Yocto/qt5_sdk/sysroots/x86_64-pokysdk-linux/usr/bin:/media/work/iMX6/Yocto/qt5_sdk/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi:/home/hexiongjun/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/hexiongjun/010editor:/home/hexiongjun/010editor"
declare -x PKG_CONFIG_PATH="/media/work/iMX6/Yocto/qt5_sdk/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi/usr/lib/pkgconfig"
declare -x PKG_CONFIG_SYSROOT_DIR="/media/work/iMX6/Yocto/qt5_sdk/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi"
declare -x PWD="/media/work/iMX6/Yocto/video2lcd_arm"
declare -x PYTHONHOME="/media/work/iMX6/Yocto/qt5_sdk/sysroots/x86_64-pokysdk-linux/usr"
declare -x QMAKESPEC="/home/hexiongjun/github/BBB/SDK/ti-sdk-am335x-evm-05.07.00.00/linux-devkit/arm-arago-linux-gnueabi/usr/share/qtopia/mkspecs/linux-g++"
declare -x QT_IM_MODULE="fcitx"
declare -x QT_PLUGIN_PATH="/home/hexiongjun/.kde/lib/kde4/plugins/:/usr/lib/kde4/plugins/"
declare -x RANLIB="arm-poky-linux-gnueabi-ranlib"
declare -x SDKTARGETSYSROOT="/media/work/iMX6/Yocto/qt5_sdk/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi"
declare -x SESSION_MANAGER="local/hexiongjun-pc:@/tmp/.ICE-unix/3595,unix/hexiongjun-pc:/tmp/.ICE-unix/3595"

注意点
其中我们重点需要关注的是与编译相关的变量:

CC/LD等编译相关
ARCH/CROSS_COMPILE等croos编译相关
可以看到CC已经被重定义为cross toolchain了,而ARCH和CROSS_COMPILE也悉心的帮我们配置成了对应的。
因此,其实如果我们需要交叉编译一个app,那么很多变量将不再需要自己手动设定了。
同时因为各种tuning的指定,我们必须注意和硬件的匹配。例如这里指定了为cortex-a9而优化。

如何使用
最好的方法就是使用变量来使用Toolchian,例如使用$CC而不是使用arm-poky-XXX-gcc,因为我们可以看到CC其实是对arm-xxx-gcc添加了一些配置:

CC="arm-poky-linux-gnueabi-gcc  -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/media/work/iMX6/Yocto/qt5_sdk/sysroots
/cortexa9hf-vfp-neon-poky-linux-gnueabi"

其中最为核心的是sysroot这个选项,这个选项将告诉toolchian去哪里查找库与头文件,而如果不指定这个,那么就会出现问题,例如,我们直接使用arm-poky-gnueabi-gcc来编译:

$ make
make -C ./ -f /media/work/iMX6/Yocto/video2lcd_arm/Makefile.build
make[1]: Entering directory `/media/work/iMX6/Yocto/video2lcd_arm'
make -C convert -f /media/work/iMX6/Yocto/video2lcd_arm/Makefile.build
make[2]: Entering directory `/media/work/iMX6/Yocto/video2lcd_arm/convert'
arm-poky-linux-gnueabi-gcc -Wall -Werror -O2 -g -I /media/work/iMX6/Yocto/video2lcd_arm/include -I /media/work/iMX6/Yocto/imx6qsabresd_build/tmp/work/imx6qsabresd-poky-linux-gnueabi/fsl-image-qt5/1.0-r0/rootfs/usr/include/ -Wp,-MD,.convert_manager.o.d -c -o convert_manager.o convert_manager.c
In file included from /media/work/iMX6/Yocto/imx6qsabresd_build/tmp/work/imx6qsabresd-poky-linux-gnueabi/fsl-image-qt5/1.0-r0/rootfs/usr/include/features.h:389:0,
                 from /media/work/iMX6/Yocto/imx6qsabresd_build/tmp/work/imx6qsabresd-poky-linux-gnueabi/fsl-image-qt5/1.0-r0/rootfs/usr/include/stdio.h:27,
                 from /media/work/iMX6/Yocto/video2lcd_arm/include/config.h:5,
                 from convert_manager.c:2:
/media/work/iMX6/Yocto/imx6qsabresd_build/tmp/work/imx6qsabresd-poky-linux-gnueabi/fsl-image-qt5/1.0-r0/rootfs/usr/include/gnu/stubs.h:7:29: fatal error: gnu/stubs-soft.h: No such file or directory
 # include 
                             ^
compilation terminated.
make[2]: *** [convert_manager.o] Error 1
make[2]: Leaving directory `/media/work/iMX6/Yocto/video2lcd_arm/convert'
make[1]: *** [convert] Error 2
make[1]: Leaving directory `/media/work/iMX6/Yocto/video2lcd_arm'
make: *** [all] Error 2

可以看到提示说找不到一些标准的头文件,其实这个是因为我们没有添加一些指定的选择来告诉其使用stubs-hard.h,所以默认的去查找stubs-soft.h。

例如我们编译一个helloworld,那么可以按照如下编译:

$CC hello.c -o hello

这样将省去了诸多选项的手动指定,也不会出问题。

二、bitbake

简介

bitbake配合yocto一起食用效果更佳:
基于bitbake,yocto可以实现以下功能:

  1. 解决交叉编译
  2. 解决包之间的依赖关系
  3. 包的管理(tar,rpm,ipk)
  4. 将包作成镜像
  5. 支持高度的可定制性,以满足不同的机器,主机发行版和架构需求
  6. 较容易的实现编写元数据,并且可重用性要好

下载地址

git clone git://git.openembedded.org/bitbake

yocto中的目录

放工具的bitbake目录、放元数据的目录、和执行构建的build目录这三个目录比较重要

  • bitbake目录: 烹饪工具:bitbake。

  • 元数据目录: 在poky中元数据目录是meta。在元数据目录中,有3个目录里是真正的元数据:classes、conf、packages。

  1. packages目录:所有的配方(recipes)文件(以.bb为后缀名)都放在package目录。每个相对独立的软件包或构建任务在package目录下都有自己的子目录。在一个子目录中可以有多个配方(recipes)文件。它们可能是同一个软件包的不同版本。也可能描述了基于同一个软件包的不同构建目标。
    有的配方(recipes)简单,有的配方(recipes)复杂。简单的配方(recipes)仅描述一个软件包的构建。最复杂的配方(recipes)就是要求构建文件系统的配方(recipes),这个配方(recipes)文件本身并不长,甚至还很短,但它通过依赖关系将几百个甚至几千个其它配方(recipes)件卷入了构建过程。 packages目录的images子目录下就是这些要求构建文件系统的配方(recipes)。

  2. classes目录: 这个目录放的是配方(recipes)的类文件(以.bbclass为后缀名)。类文件包含了一些bitbake任务的定义,例如怎么配置、怎么安装。配方(recipes)文件继承类文件,就继承了这些任务的定义。例如:我们如果增加一个使用autotool的软件包,只要在配方(recipes)文件中继承autotools.bbclass:

    inherit autotools
    

    bitbake就知道怎样使用autotool工具配置、编译、安装了。所有的配方(recipes)文件都自动继承了base.bbclass。 base.bbclass提供了大部分bitbake任务的默认实现。
    一个配方(recipes)文件可以继承多个类文件。以后的文章会介绍bitbake的任务,届时会更详细地讨论bitbake的继承。目前,我们只要知道继承类文件是一种构建过程的复用方式就可以了。

  3. conf目录: conf目录包含编译系统的配置文件(以.conf为后缀名)。bitbake在启动时会执行bitbake.conf, bitbake.conf会装载用户提供的local.conf。然后根据用户在local.conf中定义的硬件平台(MACHINE)和发布目标(DISTRO)装载machine子目录和distro子目录的配置文件。machine子目录里是硬件平台相关的配置文件。distro子目录里是与发布目标相关的配置文件。配置文件负责设置bitbake内部使用的环境变量。这些变量会影响整个构建过程。

  • build目录: build是我们烹饪嵌入式系统的大厨房。整个构建过程就是在build目录的tmp子目录完成的。 build目录的conf子目录里是用户的配置文件local.conf。
    tmp目录有7个子目录:cache、cross、rootfs、staging、work、deploy和stamps目录。
  1. cache是bitbake内部使用的缓存目录。

  2. cross是构建过程中产生的交互编译器。所谓交互编译器就是在主机平台运行,用于编译目标平台代码的编译器。

  3. rootfs是制作文件系统映像前临时建立的根文件系统。

    我们在工作中通常不需要访问这3个目录。我们访问比较多的是其它4个目录:staging、work、deploy和stamps目录。

  4. staging目录: 软件包B在构建时可能依赖软件包A提供的头文件、库文件,也可能要使用软件包C生成的工具。staging目录就是放这些输出文件的地方。我们必须在配方(recipes)文件中用“DEPENDS”变量声明构建时的依赖关系。bitbake就会在构建软件包B前先构建软件包A和软件包C,并将软件包B需要的头文件、库文件、和工具放在staging目录。这样,在构建软件包, 时就可以从staging目录得到需要的头文件、库文件、和工具。

  5. work目录: 所有软件包的解包、打补丁、配置、编译、安装等工作都是在work目录进行的。所以work目录包含了整个嵌入式系统的完整源代码。work目录下按照硬件平台、发行人、目标平台的不同又分了几个子目录。所有软件包都被放在对应子目录中。每个软件包都有一个独立的目录。因为软件包总是 根据一个配方(recipes)文件构建的,所以软件包所在的目录就是对应配方(recipes)文件的工作目录。在讨论bitbake和配方(recipes)文件时我们还会回来,更仔细地观察配方(recipes)文件的工作。

  6. deploy目录: 这是保存输出成果的目录。其中images目录保存构建成功后产生的文件系统映像、内核映像。 ipk目录保存每个软件包的安装包。我们在修改、构建软件包后,可以在目标平台手工安装ipk目录下的对应安装包。确认没有问题后,再制作文件系统映像。

  7. stamps目录: 和work目录类似,stamps目录也按照硬件平台、发行人、目标平台的不同又分了几个子目录。软件包在完成每个bitbake任务后都会在对应子目录里touch一个对应任务的时间戳。有时我们会手工删除某个软件包的时间戳,强制bitbake重新构建这个软件包。

  • sources目录: OE环境的sources目录是一个储藏间,用来放从网上下载的源代码包。 fetch任务负责下载代码,放到sources目录。

功能列表

bitbake帮助选项可以看到不同参数的功能。

    $ bitbake -h

    Usage: bitbake [options] [recipename/target ...]

    Options:

      --version            show program's version number and exit

      -h, --help           show this help message and exit

      -b BUILDFILE, --buildfile=BUILDFILE

                            Execute tasks from a specific .bb recipe directly.

                            WARNING: Does not handle any dependencies from other

                            recipes.

      -k, --continue       Continue as much as possible after an error. While the

                            target that failed and anything depending on it cannot

                            be built, as much as possible will be built before

                            stopping.

      -a, --tryaltconfigs   Continue with builds by trying to use alternative

                            providers where possible.

      -f, --force          Force the specified targets/task to run (invalidating

                            any existing stamp file).

      -c CMD, --cmd=CMD    Specify the task to execute. The exact options

                            available depend on the metadata. Some examples might

                            be 'compile' or 'populate_sysroot' or 'listtasks' may

                            give a list of the tasks available.

      -C INVALIDATE_STAMP, --clear-stamp=INVALIDATE_STAMP

                            Invalidate the stamp for the specified task such as

                            'compile' and then run the default task for the

                            specified target(s).

      -r PREFILE, --read=PREFILE

                            Read the specified file before bitbake.conf.

      -R POSTFILE, --postread=POSTFILE

                            Read the specified file after bitbake.conf.

      -v, --verbose        Output more log message data to the terminal.

      -D, --debug          Increase the debug level. You can specify this more

                            than once.

      -n, --dry-run        Don't execute, just go through the motions.

      -S SIGNATURE_HANDLER, --dump-signatures=SIGNATURE_HANDLER

                            Dump out the signature construction information, with

                            no task execution. The SIGNATURE_HANDLER parameter is

                            passed to the handler. Two common values are none and

                            printdiff but the handler may define more/less. none

                            means only dump the signature, printdiff means compare

                            the dumped signature with the cached one.

      -p, --parse-only     Quit after parsing the BB recipes.

      -s, --show-versions   Show current and preferred versions of all recipes.

      -e, --environment    Show the global or per-recipe environment complete

                            with information about where variables were

                            set/changed.

      -g, --graphviz       Save dependency tree information for the specified

                            targets in the dot syntax.

      -I EXTRA_ASSUME_PROVIDED, --ignore-deps=EXTRA_ASSUME_PROVIDED

                            Assume these dependencies don't exist and are already

                            provided (equivalent to ASSUME_PROVIDED). Useful to

                            make dependency graphs more appealing

      -l DEBUG_DOMAINS, --log-domains=DEBUG_DOMAINS

                            Show debug logging for the specified logging domains

      -P, --profile        Profile the command and save reports.

      -u UI, --ui=UI       The user interface to use (e.g. knotty, hob, depexp).

      -t SERVERTYPE, --servertype=SERVERTYPE

                            Choose which server to use, process or xmlrpc.

      --token=XMLRPCTOKEN   Specify the connection token to be used when

                            connecting to a remote server.

      --revisions-changed   Set the exit code depending on whether upstream

                            floating revisions have changed or not.

      --server-only        Run bitbake without a UI, only starting a server

                            (cooker) process.

      -B BIND, --bind=BIND  The name/address for the bitbake server to bind to.

      --no-setscene        Do not run any setscene tasks. sstate will be ignored

                            and everything needed, built.

      --remote-server=REMOTE_SERVER

                            Connect to the specified server.

      -m, --kill-server     Terminate the remote server.

      --observe-only       Connect to a server as an observing-only client.

      --status-only        Check the status of the remote bitbake server.

你可能感兴趣的:(yocto)