yocto-第28篇-应用开发的SDK或toolchain或gcc

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工具的方法。