1 为什么使用SDK
在上一篇文章中讲解了如何添加自定义软件,整个过程还是较麻烦的,那若有一些软件是开源工具呢?比如某个性能测试工具,按上一篇文章添加方式添加太麻烦,并且标准工具也不需要修改,所以不需要将工具源码一起加入项目工程编译,只需使用yocto工程编译环境编译好工具再加入映像中即可。
以下为SDK生成输出工作流。
构建输出的是一组特定形式文件,其中包括SDK自解压安装程序(*.sh)、主机、目标清单文件以及用于SDK测试的文件。SDK详细介绍可参阅 https://www.yoctoproject.org/docs/2.7/sdk-manual/sdk-manual.html。
2 SDK构建及安装
下面介绍sdk构建过程。
2.1 查看并选择机型
~/work/byobmc$ . setup
Target machine must be specified. Use one of:
1u-x91 2u-x201 4u-x201 atx-i1331
还是以4u-x201机型为例,设置环境变量并解析。
export TEMPLATECONF=meta-byosoft/meta-4u-x201/conf
. openbmc-env
这样就选择了4u-x201机型。
2.2 执行命令编译构建SDK
bitbake obmc-phosphor-image -c populate_sdk
将出现下图类似错误:
这是因为源码缺少一些组件包,并且编译过程未连接网络(或下载网址不可访问),后续也会陆陆续续提示缺少其他组件包,这些组件包可从提示的网址中下载(或网络中搜索下载一样的组件),并放至build/downloads/目录下,然后在该目录下创建 组件包名+ .done 的文件即可。
例如:
~/work/byobmc$ ls build/downloads/
Cython-0.29.21.tar.gz
Cython-0.29.21.tar.gz.done
Linux-PAM-1.3.1.tar.xz
Linux-PAM-1.3.1.tar.xz.done
Mako-1.1.4.tar.gz
Mako-1.1.4.tar.gz.done
...
不断尝试,直到所有缺少的组件下载完成后即可编译,编译大概需要1到2小时,具体看编译机器配置。
2.3 查看编译输出
编译输出位于 build/tmp/deploy/sdk 目录:
~/work/byobmc$ ls build/tmp/deploy/sdk/
oecore-x86_64-armv6-toolchain-nodistro.0.host.manifest oecore-x86_64-armv6-toolchain-nodistro.0.target.manifest
oecore-x86_64-armv6-toolchain-nodistro.0.sh oecore-x86_64-armv6-toolchain-nodistro.0.testdata.json
其中 *.sh 文件时SDK自解压程序,执行该文件将在指定目录下安装SDK。
2.4 安装sdk
在build目录下创建mytest/sdk目录并记录其绝对路径,然后执行build/tmp/deploy/sdk目录下sdk安装脚本并指定安装目录为build/mytest/sdk,结果如下:
~/work/byobmc/build$ mkdir -p mytest/sdk
~/work/byobmc/build$ ls
bitbake-cookerdaemon.log cache conf mytest sstate-cache tmp
~/work/byobmc/build$ cd mytest/sdk/
~/work/byobmc/build/mytest/sdk$ pwd
/data1/hostname/work/byobmc/build/mytest/sdk
~/work/byobmc/build/mytest/sdk$ cd ../..
~/work/byobmc/build$ ./tmp/deploy/sdk/oecore-x86_64-armv6-toolchain-nodistro.0.sh
Phosphor OpenBMC (Phosphor OpenBMC Project Reference Distro) SDK installer version nodistro.0
=============================================================================================
Enter target directory for SDK (default: /usr/local/oecore-x86_64): /data1/hostname/work/byobmc/build/mytest/sdk
You are about to install the SDK to "/data1/hostname/work/byobmc/build/mytest/sdk". Proceed [Y/n]? Y
Extracting SDK......................................................................done
Setting it up...done
SDK has been successfully set up and is ready to be used.
Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
$ . /data1/hostname/work/byobmc/build/mytest/sdk/environment-setup-armv6-openbmc-linux-gnueabi
进入build/mytest/sdk目录查看,结果如下:
~/work/byobmc/build/mytest/sdk$ ls
environment-setup-armv6-openbmc-linux-gnueabi sysroots
site-config-armv6-openbmc-linux-gnueabi version-armv6-openbmc-linux-gnueabi
SDK是由一个交叉开发工具链、一组库、头文件以及一个SDK环境设置脚本组成,如上所示sysroots就是最终打包到映像中的文件系统。
3 SDK使用
进入build/mytest/sdk目录下,执行 . environment-setup-armv6-openbmc-linux-gnueabi
命令(注意前面有个 . 号且.号后面有空格),结果如下。
~/work/byobmc/build/mytest/sdk$ . environment-setup-armv6-openbmc-linux-gnueabi
Your environment is misconfigured, you probably need to 'unset LD_LIBRARY_PATH'
but please check why this was set in the first place and that it's safe to unset.
The SDK will not operate correctly in most cases when LD_LIBRARY_PATH is set.
For more references see:
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html#AEN80
http://xahlee.info/UnixResource_dir/_/ldpath.html
提示设置了环境变量保护,执行 unset LD_LIBRARY_PATH
命令解保护,再次执行脚本即可(如果没有提示,则不需要执行解锁命令)。
注意:每次使用SDK都需要执行一次该脚本(或新打开终端)。
执行 $CC -v 命令查看编译器详情:
~/work/byobmc/build/mytest/sdk$ $CC -v
Using built-in specs.
COLLECT_GCC=arm-openbmc-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/data1/hostname/work/byobmc/build/mytest/sdk/sysroots/x86_64-oesdk-linux/usr/libexec/arm-openbmc-linux-gnueabi/gcc/arm-openbmc-linux-gnueabi/8.3.0/lto-wrapper
Target: arm-openbmc-linux-gnueabi
Configured with: ...
...
在build/mytest/sdk目录下新建test目录,并在test目录下新建hello.c文件,填入以下。
#include <stdio.h>
int main (int argc, char *argv[])
{
printf("Hello World!\n");
return 0;
}
在build/mytest/sdk/test目录下执行编译命令 $CC -o hello hello.c
,一定要使用$CC,注意,如果是通过CMAKE方式编译的程序,必须指定host,即执行 ./configure --host=arm-openbmc-linux-gnueabi (通过$CC -v获取编译器名称)。
~/work/byobmc/build/mytest/sdk$ mkdir test
~/work/byobmc/build/mytest/sdk$ cd test/
~/work/byobmc/build/mytest/sdk/test$ vim hello.c
~/work/byobmc/build/mytest/sdk/test$ $CC -o hello hello.c
~/work/byobmc/build/mytest/sdk/test$ ls
hello hello.c
执行 file ./hello 命令,可以看到hello二进制文件,通过file命令查看文件信息,为32位arm,并且是动态链接。
~/work/byobmc/build/mytest/sdk/test$ file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, BuildID[sha1]=a21307be9712a1e4522b888615593960f945ac8b, for GNU/Linux 3.2.0, with debug_info, not stripped
在build/opt/bmcsdk/test目录下,直接执行 qemu-arm ./helloc 命令,提示找不到so库文件。
~/work/byobmc/build/mytest/sdk/test$ qemu-arm ./hello
/lib/ld-linux.so.3: No such file or directory
需要指定映像文件系统中库路径,即SDK安装生成sysroots目录中的库。
最终执行结果如下:
~/work/byobmc/build/mytest/sdk/test$ qemu-arm /data1/hostname/work/byobmc/build/mytest/sdk/sysroots/armv6-openbmc-linux-gnueabi/lib/ld-linux.so.3 --library-path /data1/hostname/work/byobmc/build/mytest/sdk/sysroots/armv6-openbmc-linux-gnueabi/lib ./hello
Hello World!
这样一来,编译生成的hello程序可直接加入映像打包,加入过程参考上一篇文章脚本添加方式。
提醒一下:在使用SDK编译程序前,一定要先执行环境变量插入脚本,并且每次新打开的终端都需要插入环境变量
4 固件中添加工具链
有时我们想要在目标设备上编译调试程序怎么办?
临时方法:在build/conf/local.conf添加
EXTRA_IMAGE_FEATURES += "tools-sdk"
这种方式随着build目录下配置文件改变就丢失了,另一种是在机型的配置文件中添加,不需要的时候再去掉(不建议使用这种方式),比如在meta-byosoft/meta-4u-x201/conf/local.conf.sample文件中添加。