Developing with the Yocto Project
在本书中,我们一直将 Poky 用作构建工具。换句话说,我们将其用作设计和生成镜像的工具,将镜像交付到产品。
So far in this book, we have used Poky as a build tool. In other words, we have used it as a tool to design and generate the image delivered to products.
在本章中,我们将了解如何在目标机内部设置开发环境,以及如何使用标准 SDK 和可扩展 SDK 工具,这些工具可以帮助我们在目标机之外开发应用程序。例如,它们允许我们交叉编译应用程序、配方和图像。
In this chapter, we will see how to set up a development environment for use inside the target and meet the Standard SDK and Extensible SDK tools, which can help us develop applications outside the target. For example, they allow us to cross-compile applications, recipes, and images.
1, What is a software development kit?
在嵌入式开发中,工具链通常由跨平台工具或在一种体系结构上执行的工具组成,然后生成二进制文件供另一种体系结构使用--例如,在 x86-64 兼容机器上运行的 GCC 工具为 ARM 机器生成的二进制文件就是一个交叉编译器。当工具和生成的二进制文件依赖于运行工具的同一主机时,通常称为本地构建。构建和目标架构可能相同,但如果目标二进制文件使用单独保存的根文件系统查找其依赖项,则属于交叉编译。
In embedded development, the toolchain is often composed of cross-platform tools or tools executed on one architecture, which then produces a binary for use in another architecture – for example, a GCC tool that runs on an x86-64-compatible machine and generates binaries for an ARM machine is a cross-compiler. When a tool and the resulting binaries rely on dependencies from the same host on which the tool runs, this is commonly called a native build. Build and target architectures may be the same, but it is cross-compilation if the target binary uses a staged root filesystem to find its dependencies.
软件开发工具包(SDK)是一套用于开发和调试程序的工具和文件。这些工具包括编译器、链接器、调试器、外部库、头文件和二进制文件,也称为工具链。它还可能包括额外的实用程序和应用程序。我们可以使用两种 SDK:
A software development kit (SDK) is a set of tools and files to develop and debug applications. These tools include compilers, linkers, debuggers, external libraries, headers, and binaries, also called a toolchain. It may also include extra utilities and applications. We can have two types of SDK:
* 交叉开发SDK: 其目标是在开发主机中使用,为目标生成二进制文件。
* 本地SDK: 目标是在目标设备上运行
* Cross-development SDKs: These have the goal of being used in the development host to generate binaries for the target
* Native SDKs: These aim to run on the target device
2,
Generating a native SDK for on-device development
有些嵌入式设备功能强大,足以用作开发环境。但是,不同的库或应用程序构建所需的资源差别很大,因此使用目标设备作为构建环境并不总是可行的。开发映像需要以下资源:
Some embedded devices are powerful enough to be used as a development environment. However, the resources needed for the build vary significantly from one library or application to another, so using the target as the building environment may not always be viable. The development image needs the following:
* The header files and libraries
* The toolchain
下面一行将这些属性添加到图像中:
The following line adds these properties to an image:
[ Figure 9.1 – How to configure an image to include development artifacts
]
上例中的 IMAGE_FEATURES 对镜像功能进行了如下扩展:
IMAGE_FEATURES in the preceding example extends the image functionality as follows:
* dev-pkgs: 为指定镜像中安装的所有软件包安装开发包(头文件和额外的库链接)
* tools-sdk: 安装在设备上运行的工具链
* dev-pkgs: Installs development packages (headers and extra library links) for all packages installed in a given image
* tools-sdk: Installs the toolchain that runs on the device
有关 IMAGE_FEATURES 变量的详细介绍,请参阅第 12 章 创建自定义图层。
The
IMAGE_FEATURES variable is described in more detail in Chapter 12, Creating Custom Layers.
Tip
如果我们只想修改 build/conf/local.conf,则应使用 EXTRA_IMAGE_FEATURES 变量。
If we want to modify only
build/conf/local.conf, the variable we should use is
EXTRA_IMAGE_FEATURES.
目标机器可以在应用程序开发周期中使用该镜像,并在为同一项目工作的所有开发人员之间共享该镜像。每个开发人员都将拥有一份副本,开发团队将始终使用相同的开发环境。
The target can use this image during the application development cycle and share the image among all developers working on the same project. Each developer will have a copy, and the development team will use the same development environment consistently.
3, Understanding the types of cross-development SDKs
Yocto 项目可以生成两种类型的交叉开发SDK,以满足不同的需求。它们的定义如下:
The Yocto Project can generate two types of cross-development SDKs that aim to cover different needs. They are defined as follows:
* 标准 SDK: 标准 SDK:提供应用程序开发所需的工件,无论是引导加载程序、Linux 内核开发,还是其他用户空间软件。
* 可扩展 SDK: 它允许在 SDK 的 sysroot 目录中安装额外的软件包,以及在 Yocto 项目控制的环境中集成配方和应用程序。
* Standard SDK: This provides the artifacts for application development, be it for bootloader or Linux kernel development, or some other user space software
* Extensible SDK: This allows the installation of extra packages inside the SDK’s
sysroot directory, as well as recipe and application integration inside a Yocto Project-controlled environment
标准 SDK 包括工具链和调试程序。其目标是让用户生成二进制文件,供目标机使用。可扩展 SDK 功能更强大,可以生成映像和配方。这两种 SDK 的一个显著区别是可扩展 SDK 中的 devtool。
The Standard SDK includes a toolchain and debugging applications. Its goal is to allow users to generate binaries for use in the target. The Extensible SDK is more powerful and can build images and recipes. A notable difference between the two types of SDK is the presence of
devtool in the Extensible SDK.
devtool 负责提供可扩展 SDK 的附加功能。它是使用 BitBake 和 recipetool 功能的接口。devtool 和 recipetool 命令同样适用于传统的 Yocto Project 环境。
devtool is responsible for providing the additional features of the Extensible SDK. It is an interface for using BitBake and
recipetool’s power. The
devtool and
recipetool commands are also available in the traditional Yocto Project environment.
4, Using the Standard SDK
通常情况下,SDK 有一套必须提供的库和应用程序,这些库和应用程序定义在专为产品定制的映像中。这些被称为基于映像的 SDK。例如,我们可以使用以下命令为
core-image-full-cmdline 生成标准 SDK:
Usually, an SDK has a set of libraries and applications it must provide, which is defined in an image tailored to the product. These are called image-based SDKs. For example, we can generate the Standard SDK for core-image-full-cmdline with the following command:
[ Figure 9.2 – How to generate the Standard SDK for core-image-full-cmdline ]
另一种方法是创建一个包含工具链和调试工具的通用 SDK。这种通用 SDK 称为元工具链,主要用于 Linux 内核和引导加载程序的开发及其调试过程。它可能不足以构建具有复杂依赖关系的应用程序。要创建元工具链,请使用以下命令:
Another option is to create a generic SDK with the toolchain and debugging tools. This generic SDK is called
meta-toolchain and is used mainly for Linux kernel and bootloader development and their debugging processes. It may not be sufficient to build applications with complex dependencies. To create
meta-toolchain, use the following command:
[ Figure 9.3 – How to generate a generic SDK ]
在这两种情况下,生成的 SDK 自安装文件都位于 build/tmp/deploy/sdk/。考虑到我们为 core-image-full-cmdline 使用的是标准 SDK,我们可以看到以下结果文件集:
In both cases, the resulting SDK self-installer files are at
build/tmp/deploy/sdk/. Considering we used the Standard SDK for
core-image-full-cmdline, we can see the following resulting set of files:
[ Figure 9.4 – The resultant files after running bitbake core-image-full-cmdline -c populate_sdk ]
创建标准 SDK 后的下一步是安装,因为标准 SDK 封装在一个安装脚本中,可以像其他脚本一样执行。下面的序列显示了使用标准目标目录安装标准 SDK 的过程:
The next step after creating the Standard SDK is to install it, as the Standard SDK is wrapped in an installation script that can be executed in the same manner as any other script. The following sequence shows the Standard SDK installation process using the standard target directory:
[ Figure 9.5 – The Standard SDK installation process ]
前面的标准 SDK 演示了我们如何生成和安装标准 SDK。不过,使用不符合当前需求的标准映像并不理想。因此,强烈建议创建一个符合我们应用需求的自定义映像。我们还建议将标准 SDK 建立在自定义映像的基础上。
The preceding Standard SDK illustrates how we can generate and install a Standard SDK. Still, it is not ideal to use a standard image that is not tailored to your current needs. Therefore, creating a custom image that fits our application needs is highly recommended. It is also recommended to base the Standard SDK on this custom image.
标准 SDK 是根据我们使用 MACHINE 变量设置的机器架构生成的。要使用标准 SDK 构建自定义应用程序(例如 hello-world.c),我们可以使用以下针对 x86-64 架构的代码行:
The Standard SDK is generated to match the machine architecture we set using the
MACHINE variable. To use the Standard SDK to build a custom application, for example,
hello-world.c, we can use the following lines, targeting the x86-64 architecture:
[ Figure 9.6 – The steps to build a C application using the Standard SDK ]
另一个非常常用的项目是 Linux 内核。当我们要构建 Linux 内核源代码时,可以使用以下命令序列:
Another very commonly used project is the Linux kernel. When we want to build the Linux kernel source code, we can use the following sequence of commands:
[ Figure 9.7 – The steps to build the Linux kernel using the Standard SDK
]
需要使用 unset LDFLAGS 来避免使用 GCC 进行链接,这是基于 Yocto Project 的标准 SDK 的默认设置。
unset LDFLAGS is required to avoid using GCC for linking, which is the Yocto Project-based Standard SDK’s default.
5, Using the Extensible SDK
可扩展 SDK 扩展了标准 SDK 的功能。其中包括以下一些重要功能:
The Extensible SDK expands the functionalities of the Standard SDK. Some of the significant capabilities included are as follows:
* 生成配方
* 构建配方
* 生成映像
* 在内部工具链中安装软件包
* 将软件包部署到目标
* Generate recipes
* Build recipes
* Build images
* Install packages in the internal toolchain
* Deploy packages to the target
这些附加功能由 devtool 工具提供,标准的 Yocto Project 环境中也有该工具。
Those additional features are provided by the
devtool utility, which is also available in the standard Yocto Project environment.
要生成可扩展 SDK,请使用以下命令:
To generate the Extensible SDK, use the following command:
[ Figure 9.8 – Command to generate the Extensible SDK ]
生成的文件位于
build/tmp/deploy/sdk/。考虑到我们为 core-image-full-cmdline 使用了可扩展 SDK,我们可以看到以下文件集:
The resulting files are in
build/tmp/deploy/sdk/. Considering we used the Extensible SDK for
core-image-full-cmdline, we see the following set of files:
[ Figure 9.9 – The resultant files after running bitbake core-image-full-cmdline -c populate_sdk_ext ]
创建可扩展 SDK 后的下一步是安装。要安装它,我们可以执行生成的脚本。以下序列显示了使用标准目标目录安装 Extensible SDK 的过程:
The next step after creating the Extensible SDK is to install it. To install it, we can execute the generated script. The following sequence shows the Extensible SDK installation process using the standard target directory:
[ Figure 9.10 – The Extensible SDK installation process ]
前面的截图说明了我们如何生成和安装可扩展 SDK。不过,使用不符合当前需求的标准映像并不理想。因此,我们强烈建议创建一个适合你的应用需求的自定义镜像,就像将可扩展 SDK 建立在一个镜像上一样。不过,我们可以使用可扩展 SDK 将任何额外的依赖项构建并安装到 SDK 中。
The preceding screenshot illustrates how we can generate and install an Extensible SDK. Still, it is not ideal to use a standard image that is not tailored to your current needs. Therefore, creating a custom image that fits your application needs is highly recommended, as is basing the Extensible SDK on one. However, we can build and install any extra dependencies into the SDK using the Extensible SDK.
在我们的例子中,我们将 Extensible SDK 安装在 /home/user/poky_sdk。安装完成后,下一步是使用提供的脚本导出所需的环境变量,这样就可以使用 Extensible SDK 了:
In our case, we installed the Extensible SDK in
/home/user/poky_sdk. After the installation has been completed, the next step is to use the provided script to export the required environment variables, which enables the Extensible SDK’s use, with the following command:
[ Figure 9.11 – Exporting the environment variables to allow the Extensible SDK to be used ]
在下面的章节中,我们将介绍一些使用 devtool 的案例。所有命令都在终端内执行,并导出可扩展 SDK 变量。
In the following sections, we will cover some use cases using devtool. All commands are executed inside a terminal with the Extensible SDK variables exported.
可扩展 SDK 是提供相同 Yocto 项目工具和元数据的另一种方式。它整合了以下内容:
The Extensible SDK is a different way to deliver the same Yocto Project tools and metadata. It wraps together the following:
* 用于执行 Yocto 项目环境的基本二进制文件集
* 用于开发的标准 SDK
* 减少本地构建的共享状态缓存
* Yocto 项目元数据和配置快照
* A basic set of binaries for the Yocto Project environment execution
* A Standard SDK for development
* A shared state cache to reduce local builds
* A snapshot of the Yocto Project metadata and configuration
从本质上讲,可扩展 SDK 是创建环境的快照。因此,所有 devtool 命令,包括我们将在下文中使用的命令,都可以在 Yocto Project 环境中使用。
Essentially, the Extensible SDK is a snapshot of the environment used to create it. Therefore, all devtool commands, including those we will use in the following sections, are available inside the Yocto Project environment.
6, Building an image using devtool
让我们从创建图像开始。可扩展 SDK 能够创建任何受支持的图像。例如,创建 core-image-full-cmdline 时,我们可以使用以下命令行:
Let’s start by creating an image. The Extensible SDK is capable of creating any supported image. For example, to create core-image-full-cmdline, we can use the following command line:
[ Figure 9.12 – Building core-image-full-cmdline with devtool ]
After running the
devtool command, the generated files can be found in
/home/user/poky_sdk/tmp/deploy/images/qemux86-64.
7, Running an image on QEMU
我们可以通过 QEMU 使用先前构建的映像 core-image-full-cmdline,并使用以下命令模拟目标硬件:
We can emulate the target hardware with QEMU using the previously built image,
core-image-full-cmdline, with the following command:
[ Figure 9.13 – Emulating with devtool and QEMU ]
它将启动 QEMU 的执行并生成启动画面,如下图所示:
It starts the QEMU execution and generates the boot splash, as is shown in the following screenshot:
[ Figure 9.14 – The QEMU boot splash ]
Creating a recipe from an external Git repository
devtool 还能从外部 Git 仓库生成配方。这里,我们将使用
GitHub - OSSystems/bbexample: OpenEmbedded/Yocto Project example recipe application:
devtool is also capable of producing a recipe from an external Git repository. Here, we are going to use
https://github.com/OSSystems/bbexample:
[ Figure 9.15 – Creating the recipe using devtool ]
devtool 会为给定的软件源创建一个基本配方文件。它会创建一个包含软件包源代码和所需元数据的工作区。运行 devtool add
GitHub - OSSystems/bbexample: OpenEmbedded/Yocto Project example recipe application 命令后,devtool 使用的文件结构如下:
devtool creates a basic recipe file for the given repository. It creates a workspace with the package source code and the needed metadata. The file structure used by devtool, after the
devtool add https://github.com/OSSystems/bbexample command is run, is as follows:
[ Figure 9.16 – The file structure created by devtool when creating a recipe ]
目前,devtool 会根据以下内容为项目生成暂定配方:
Currently,
devtool generates a tentative recipe for projects based on the following:
* Autotools (autoconf and automake)
* CMake
* Scons
* qmake
* A plain Makefile
* The Node.js module
* Python modules that use setuptools or distutils
Building a recipe using devtool
现在配方已在工作区目录下创建,我们可以使用以下命令构建它:
Now that the recipe has been created under the workspace directory, we can build it with the following command:
[ Figure 9.17 – Building a recipe with devtool ]
Deploying to the target using devtool
使用 devtool 构建软件包后,我们就可以将其部署到目标上。在我们的例子中,目标是正在运行的 QEMU。要访问它,请使用 QEMU 的默认 IP 地址 192.168.7.2,如以下命令所示:
After building the package with
devtool, we can deploy it to the target. In our example, the target is the running QEMU. To access it, use the default QEMU IP address,
192.168.7.2, as shown in the following command:
[ Figure 9.18 – Deploying to the target using devtool ]
应用程序已安装在目标机中。我们可以看到 bbexample 正在 QEMU 目标机中执行,如下图所示:
The application is installed in the target. We can see bbexample being executed in the QEMU target, as shown in the following screenshot:
[ Figure 9.19 – bbexample executing on the target ]
Extending the SDK
可扩展 SDK 的目标之一是允许我们在 SDK 环境中安装不同的配方。例如,要想获得 libusb1,我们可以运行以下命令:
One of the goals of the Extensible SDK is to allow us to install different recipes in the SDK environment. For example, to have libusb1 available, we can run the following command:
[ Figure 9.20 – The installation of a new recipe in the Extensible SDK ]
Tip
Yocto Project 可扩展 SDK 允许分布式开发,因为开发者可以在项目生命周期内更新和扩展现有的 SDK 环境。要正确使用可扩展 SDK 作为 sstate-cache 镜像和可扩展 SDK 服务器,需要进行一些基础设置,其复杂程度超出了本书的范围。更多详情,请参阅《Yocto 项目应用程序开发和可扩展软件开发工具包 (eSDK)》(
6 Customizing the Extensible SDK — The Yocto Project ® 4.0.4 documentation)中的 “安装后为可扩展 SDK 提供更新 ”部分。
The Yocto Project Extensible SDK allows for distributed development, as developers can update and extend the existing SDK environment during a project’s lifetime. There is some infrastructure setup required for the proper use of the Extensible SDK as a sstate-cache mirror and Extensible SDK server, which requires a complex configuration beyond the scope of this book. For more details, please refer to the Providing Updates to the Extensible SDK After Installation section of Yocto Project Application Development and the Extensible Software Development Kit (eSDK) (https://docs.yoctoproject.org/4.0.4/sdk-manual/appendix-customizing.html#providing-updates-to-the-extensible-sdk-after-installation).
8, Summary
在本章中,我们了解到 Yocto 项目可用于开发和镜像创建。我们学习了如何创建不同类型的工具链,以及如何使用它们。
In this chapter, we learned that the Yocto Project can be used for development and image creation. We learned how to create different types of toolchains and also how to use them.
在下一章中,我们将了解如何配置 Poky 以帮助我们完成调试过程,如何配置系统以提供使用 GDB 进行远程调试所需的工具,以及如何使用 buildhistory 跟踪更改。
In the next chapter, we will look at how we can configure Poky to help us in the debugging process, how we can configure our system to provide the required tools for remote debugging using GDB, and how we can track our changes using buildhistory.