By: fu linux
E-mail: fulinux@sina.com
Blog: https://blog.csdn.net/fulinus
喜欢的盆友欢迎点赞和订阅!
你的喜欢就是我写作的动力!
应用开发的SDK
在下面的工作流图中,展示了一个SDK生成输出过程。
构建可扩展的SDK(例如bitbake-c populate_SDK_ext imagename)
还是标准SDK(例如bitbake-c populate_SDK imagename),
SDK生成过程会有所不同。本节将详细介绍此输出:
此输出的特定形式是一组文件,其中包括自解压SDK安装程序(*.sh)、主机和目标清单文件,以及用于SDK测试的文件。当SDK安装程序文件运行时,它安装SDK。SDK由一个交叉开发工具链、一组库和头文件以及一个SDK环境设置脚本组成。运行这个安装程序实际上设置了交叉开发环境。您可以将交叉工具链看作是“主机”部分,因为它运行在SDK机器上。您可以将库和头看作“目标”部分,因为它们是为目标硬件构建的。添加了环境设置脚本,以便您可以在使用工具之前初始化环境。
编译标准SDK
poky]$ source oe-init-build-env
build]$ bitbake core-image-sato -c populate_sdk
- 1
- 2
需要一段时间,输出的文件位于如下路径:
build]$ ls tmp/deploy/sdk/
poky-glibc-x86_64-core-image-sato-core2-64-qemux86-64-toolchain-3.1.2.host.manifest
poky-glibc-x86_64-core-image-sato-core2-64-qemux86-64-toolchain-3.1.2.sh
poky-glibc-x86_64-core-image-sato-core2-64-qemux86-64-toolchain-3.1.2.target.manifest
poky-glibc-x86_64-core-image-sato-core2-64-qemux86-64-toolchain-3.1.2.testdata.json
- 1
- 2
- 3
- 4
- 5
安装SDK
下面我们演示如何将其安装到/opt目录(其他目录也可以)下:
build]$ ./tmp/deploy/sdk/poky-glibc-x86_64-core-image-sato-core2-64-qemux86-64-toolchain-3.1.2.sh
Poky (Yocto Project Reference Distro) SDK installer version 3.1.2
=================================================================
Enter target directory for SDK (default: /opt/poky/3.1.2):
You are about to install the SDK to "/opt/poky/3.1.2". Proceed [Y/n]?
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.
$ . /opt/poky/3.1.2/environment-setup-core2-64-poky-linux
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
在安装过程中,如果选择默认的安装路径,可以直接输入回车,否则输入自己需要安装的路径。
$ ls /opt/poky/3.1.2/
environment-setup-core2-64-poky-linux site-config-core2-64-poky-linux sysroots version-core2-64-poky-linux
- 1
- 2
最后安装结束后提示执行:
$ . /opt/poky/3.1.2/environment-setup-core2-64-poky-linux
- 1
在每个需要使用这个SDK的shell环境下都需要执行上面的命令,如下:
demo]$ $CC -v
Using built-in specs.
COLLECT_GCC=x86_64-poky-linux-gcc
COLLECT_LTO_WRAPPER=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/libexec/x86_64-poky-linux/gcc/x86_64-poky-linux/9.3.0/lto-wrapper
Target: x86_64-poky-linux
Configured with: ../../../../../../work-shared/gcc-9.3.0-r0/gcc-9.3.0/configure --build=x86_64-linux --host=x86_64-pokysdk-linux --target=x86_64-poky-linux --prefix=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr --exec_prefix=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr --bindir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/bin/x86_64-poky-linux --sbindir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/bin/x86_64-poky-linux --libexecdir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/libexec/x86_64-poky-linux --datadir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/share --sysconfdir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/etc --sharedstatedir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/com --localstatedir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/var --libdir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/lib/x86_64-poky-linux --includedir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/include --oldincludedir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/include --infodir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/share/info --mandir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/share/man --disable-silent-rules --disable-dependency-tracking --with-libtool-sysroot=/home/peeta/poky/build/tmp/work/x86_64-nativesdk-pokysdk-linux/gcc-cross-canadian-x86-64/9.3.0-r0/recipe-sysroot --with-gnu-ld --enable-shared --enable-languages=c,c++ --enable-threads=posix --enable-multilib --enable-default-pie --enable-c99 --enable-long-long --enable-symvers=gnu --enable-libstdcxx-pch --program-prefix=x86_64-poky-linux- --without-local-prefix --disable-install-libiberty --enable-lto --disable-libssp --enable-libitm --disable-bootstrap --disable-libmudflap --with-system-zlib --with-linker-hash-style=gnu --enable-linker-build-id --with-ppl=no --with-cloog=no --enable-checking=release --enable-cheaders=c_global --without-isl --with-gxx-include-dir=/not/exist/usr/include/c++/9.3.0 --with-build-time-tools=/home/peeta/poky/build/tmp/work/x86_64-nativesdk-pokysdk-linux/gcc-cross-canadian-x86-64/9.3.0-r0/recipe-sysroot-native/usr/x86_64-poky-linux/bin --with-sysroot=/not/exist --with-build-sysroot=/home/peeta/poky/build/tmp/work/x86_64-nativesdk-pokysdk-linux/gcc-cross-canadian-x86-64/9.3.0-r0/recipe-sysroot --enable-poison-system-directories --disable-static --enable-nls --with-glibc-version=2.28 --enable-initfini-array --enable-__cxa_atexit
Thread model: posix
gcc version 9.3.0 (GCC)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
上面我们用来gcc的别名$CC, 因为我并不清楚gcc前缀是什么,否则就会调用到系统的gcc,从上面知道gcc的完整名是:
demo]$ x86_64-poky-linux-gcc -v
Using built-in specs.
COLLECT_GCC=x86_64-poky-linux-gcc
COLLECT_LTO_WRAPPER=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/libexec/x86_64-poky-linux/gcc/x86_64-poky-linux/9.3.0/lto-wrapper
Target: x86_64-poky-linux
Configured with: ../../../../../../work-shared/gcc-9.3.0-r0/gcc-9.3.0/configure --build=x86_64-linux --host=x86_64-pokysdk-linux --target=x86_64-poky-linux --prefix=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr --exec_prefix=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr --bindir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/bin/x86_64-poky-linux --sbindir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/bin/x86_64-poky-linux --libexecdir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/libexec/x86_64-poky-linux --datadir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/share --sysconfdir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/etc --sharedstatedir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/com --localstatedir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/var --libdir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/lib/x86_64-poky-linux --includedir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/include --oldincludedir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/include --infodir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/share/info --mandir=/opt/poky/3.1.2/sysroots/x86_64-pokysdk-linux/usr/share/man --disable-silent-rules --disable-dependency-tracking --with-libtool-sysroot=/home/peeta/poky/build/tmp/work/x86_64-nativesdk-pokysdk-linux/gcc-cross-canadian-x86-64/9.3.0-r0/recipe-sysroot --with-gnu-ld --enable-shared --enable-languages=c,c++ --enable-threads=posix --enable-multilib --enable-default-pie --enable-c99 --enable-long-long --enable-symvers=gnu --enable-libstdcxx-pch --program-prefix=x86_64-poky-linux- --without-local-prefix --disable-install-libiberty --enable-lto --disable-libssp --enable-libitm --disable-bootstrap --disable-libmudflap --with-system-zlib --with-linker-hash-style=gnu --enable-linker-build-id --with-ppl=no --with-cloog=no --enable-checking=release --enable-cheaders=c_global --without-isl --with-gxx-include-dir=/not/exist/usr/include/c++/9.3.0 --with-build-time-tools=/home/peeta/poky/build/tmp/work/x86_64-nativesdk-pokysdk-linux/gcc-cross-canadian-x86-64/9.3.0-r0/recipe-sysroot-native/usr/x86_64-poky-linux/bin --with-sysroot=/not/exist --with-build-sysroot=/home/peeta/poky/build/tmp/work/x86_64-nativesdk-pokysdk-linux/gcc-cross-canadian-x86-64/9.3.0-r0/recipe-sysroot --enable-poison-system-directories --disable-static --enable-nls --with-glibc-version=2.28 --enable-initfini-array --enable-__cxa_atexit
Thread model: posix
gcc version 9.3.0 (GCC)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
当前ubuntu系统内部的gcc如下:
demo]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 6.5.0-2ubuntu1~16.04' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --with-as=/usr/bin/x86_64-linux-gnu-as --with-ld=/usr/bin/x86_64-linux-gnu-ld --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.5.0 20181026 (Ubuntu 6.5.0-2ubuntu1~16.04)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
所以不要搞混淆了。
编译演示
通常, 我推荐大家使用$CC, 因为这个别名在执行编译时,会在sysroot路径下去查找头文件和库文件等,
比如下面我写了一个C程序例子演示他们的区别:
demo]$ vim rand.c
- 1
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
int main(void)
{
int i,j;
srand((int)time(0));
for(i=0;i<10;i++)
{
j=1+(int)(3.0*rand()/(RAND_MAX+1.0));
printf(" %d ",j);
}
printf ("\n");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
编译:
demo]$ x86_64-poky-linux-gcc rand.c -o rand
rand.c:1:9: fatal error: time.h: No such file or directory
1 | #include<time.h>
| ^~~~~~~~
compilation terminated.
- 1
- 2
- 3
- 4
- 5
可见上面编译失败了,下面我们用$CC编译:
demo]$ $CC rand.c -o rand
In file included from /opt/poky/3.1.2/sysroots/core2-64-poky-linux/usr/include/time.h:25,
from rand.c:1:
/opt/poky/3.1.2/sysroots/core2-64-poky-linux/usr/include/features.h:397:4: warning: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Wcpp]
397 | # warning _FORTIFY_SOURCE requires compiling with optimization (-O)
| ^~~~~~~
- 1
- 2
- 3
- 4
- 5
- 6
虽然有警告,但是编译通过了,提示需要用“ -O” 选项,如下:
demo]$ $CC rand.c -O -o rand
- 1
此时我们可以将rand文件拷贝到qemu虚拟机中运行,就不演示了。
上面的过程告诉我们x86_64-poky-linux-gcc命令并不能找到源文件依赖的头文件,$CC可以。参考如下:
demo]$ echo $CC
x86_64-poky-linux-gcc -m64 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/poky/3.1.2/sysroots/core2-64-poky-linux
- 1
- 2
当然我们也可以给x86_64-poky-linux-gcc指定sysroot路径和头文件路径,参考如下
demo]$ x86_64-poky-linux-gcc --sysroot=/opt/poky/3.1.2/sysroots/core2-64-poky-linux -I/opt/poky/3.1.2/sysroots/core2-64-poky-linux/usr/include rand.c -O -o rand
- 1
标准SDK的一些变量
多个变量一起
build]$ bitbake -e core-image-sato | grep "^TOOLCHAIN_HOST_TASK=\|^SDKMACHINE=\|^SDKIMAGE_FEATURES=\|^TOOLCHAIN_TARGET_TASK=\|^SDKPATH=\|^SDK_HOST_MANIFEST=\|^SDK_TARGET_MANIFEST="
SDKIMAGE_FEATURES="dev-pkgs dbg-pkgs src-pkgs "
SDKMACHINE="x86_64"
SDKPATH="/opt/poky/3.1.2"
SDK_HOST_MANIFEST="/home/peeta/poky/build/tmp/work/qemux86_64-poky-linux/core-image-sato/1.0-r0/x86_64-deploy-core-image-sato-populate-sdk/poky-glibc-x86_64-core-image-sato-core2-64-qemux86-64-toolchain-3.1.2.host.manifest"
SDK_TARGET_MANIFEST="/home/peeta/poky/build/tmp/work/qemux86_64-poky-linux/core-image-sato/1.0-r0/x86_64-deploy-core-image-sato-populate-sdk/poky-glibc-x86_64-core-image-sato-core2-64-qemux86-64-toolchain-3.1.2.target.manifest"
TOOLCHAIN_HOST_TASK="nativesdk-packagegroup-sdk-host packagegroup-cross-canadian-qemux86-64 nativesdk-intltool nativesdk-glib-2.0"
TOOLCHAIN_TARGET_TASK="packagegroup-core-standalone-sdk-target target-sdk-provides-dummy packagegroup-core-boot packagegroup-base-extended learnyocto run-postinsts rpm dnf psplash packagegroup-core-ssh-dropbear packagegroup-core-x11-base packagegroup-core-x11-sato"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
DEPLOY_DIR变量
指向deploy目录。参考如下:
build]$ bitbake -e core-image-sato | grep ^DEPLOY_DIR=
DEPLOY_DIR="/home/peeta/poky/build/tmp/deploy"
- 1
- 2
可扩展的SDK一些变量
SDK_EXT_TYPE变量
控制是否将共享状态工件复制到可扩展SDK中。默认情况下,所有必需的共享状态工件都被复制到SDK中。参考如下:
build]$ bitbake -e core-image-sato | grep ^SDK_EXT_TYPE=
SDK_EXT_TYPE="full"
- 1
- 2
SDK_INCLUDE_TOOLCHAIN变量
指定在构建可扩展SDK时是否包含工具链。默认是包含的,参考如下:
build]$ bitbake -e core-image-sato | grep ^SDK_INCLUDE_TOOLCHAIN=
SDK_INCLUDE_TOOLCHAIN="1"
- 1
- 2
core-image-sato-sdk
我在分析
meta/recipes-sato/images/core-image-sato.bb
文件的时候看到了这个core-image-sato-sdk.bb文件,带了一个sdk的关键词,干啥的?。我们看下这个文件大致内容:
poky]$ cat meta/recipes-sato/images/core-image-sato-sdk.bb
require core-image-sato.bb #可以require 一个bb文件哦!
DESCRIPTION = "Image with Sato support that includes everything within \
core-image-sato plus meta-toolchain, development headers and libraries to \
form a standalone SDK."
IMAGE_FEATURES += "dev-pkgs tools-sdk \
tools-debug eclipse-debug tools-profile tools-testapps debug-tweaks ssh-server-openssh"
IMAGE_INSTALL += "kernel-devsrc"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
我们重点他的看下
DESCRIPTION
描述,这个目标镜像包括core-image-sato中的所有内容,并且加上meta-toolchain中的开发的头文件和库:
IMAGE_FEATURES += "... tools-sdk ..."
- 1
我们的
IMAGE_FEATURES
包含了一个
tools-sdk
FEATURE,这个让我想起了上面的:
poky]$ cat meta/recipes-sato/images/core-image-sato.bb
FEATURE_PACKAGES_tools-sdk="packagegroup-core-sdk packagegroup-core-standalone-sdk-target"
- 1
- 2
编译前先清空之前的编译结果,为了能清楚的知道这个目标做了什么:
build]$ bitbake meta-toolchain -c cleansstate
build]$ bitbake core-image-sato -c cleansstate
build]$ ls tmp-qemux86-64/deploy/sdk/
#空的
build]$ ls tmp-qemux86-64/deploy/images/qemux86-64/
bzImage
bzImage--5.8.18+git0+b976de4f41_3c5d210805-r0-qemux86-64-20210502064723.bin
bzImage-qemux86-64.bin
modules--5.8.18+git0+b976de4f41_3c5d210805-r0-qemux86-64-20210502064723.tgz
modules-qemux86-64.tgz
#不包含core-image-sato镜像,ok
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
开始编译下:
build]$ bitbake core-image-sato-sdk
# 开始编译了很多新玩意:
Currently 8 running tasks (5556 of 7367) 75% |################################################ |
0: boost-1.74.0-r0 do_compile - 15m27s (pid 23661)
1: ltp-20200515-r0 do_fetch (pid 13619) 87% |############################################ | 128K/s #LTP(LinuxTest Project)测试工具
2: gdb-9.2-r0 do_compile - 12m8s (pid 10150) #有gdb
3: gcc-10.2.0-r0 do_compile - 10m46s (pid 27487) #有gcc
4: strace-5.8-r0 do_package - 2m36s (pid 21086) #调试工具
5: kernel-devsrc-1.0-r0 do_package - 44s (pid 20319) #内核开发
6: tar-1.32-r0 do_package_write_ipk - 9s (pid 28956)
7: libnewt-0.52.21-r0 do_package_write_ipk - 5s (pid 31150)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
关于LTP参考: LTP(LinuxTest Project)测试工具
可以通过下面的方式看到core-image-sato-sdk生成的文系统中都有哪些内容:
build]$ ls tmp-qemux86-64/work/qemux86_64-poky-linux/core-image-sato-sdk/1.0-r0/rootfs/usr/include/
#有很多头文件:
build]$ ls tmp-qemux86-64/work/qemux86_64-poky-linux/core-image-sato-sdk/1.0-r0/rootfs/usr/bin/
gcc
gdb
...
build]$ ls tmp-qemux86-64/work/qemux86_64-poky-linux/core-image-sato-sdk/1.0-r0/rootfs/opt/ltp/
bin functional runltp scenario_groups testcases ver_linux
conformance IDcheck.sh runtest stress
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
说明,我们可以在目标机器上面直接编译和调试,就行在PC上面一样,而且还带有LTP工具压力测试linux。更多的功能读者盆友可以自行分析。不过也告诉我们一个如何整合gdb工具的方法。