|
@@ -257,1326 +257,9 @@ the recipe a source tree that is under your control is used in order to
|
|
|
allow you to make changes to the source as desired. By default, new
|
|
|
recipes and the source go into a "workspace" directory under the SDK.
|
|
|
|
|
|
-The remainder of this section presents the ``devtool add``,
|
|
|
-``devtool modify``, and ``devtool upgrade`` workflows.
|
|
|
-
|
|
|
-Use ``devtool add`` to Add an Application
|
|
|
------------------------------------------
|
|
|
-
|
|
|
-The ``devtool add`` command generates a new recipe based on existing
|
|
|
-source code. This command takes advantage of the
|
|
|
-:ref:`devtool-the-workspace-layer-structure`
|
|
|
-layer that many ``devtool`` commands use. The command is flexible enough
|
|
|
-to allow you to extract source code into both the workspace or a
|
|
|
-separate local Git repository and to use existing code that does not
|
|
|
-need to be extracted.
|
|
|
-
|
|
|
-Depending on your particular scenario, the arguments and options you use
|
|
|
-with ``devtool add`` form different combinations. The following diagram
|
|
|
-shows common development flows you would use with the ``devtool add``
|
|
|
-command:
|
|
|
-
|
|
|
-.. image:: figures/sdk-devtool-add-flow.png
|
|
|
- :width: 100%
|
|
|
-
|
|
|
-#. *Generating the New Recipe*: The top part of the flow shows three
|
|
|
- scenarios by which you could use ``devtool add`` to generate a recipe
|
|
|
- based on existing source code.
|
|
|
-
|
|
|
- In a shared development environment, it is typical for other
|
|
|
- developers to be responsible for various areas of source code. As a
|
|
|
- developer, you are probably interested in using that source code as
|
|
|
- part of your development within the Yocto Project. All you need is
|
|
|
- access to the code, a recipe, and a controlled area in which to do
|
|
|
- your work.
|
|
|
-
|
|
|
- Within the diagram, three possible scenarios feed into the
|
|
|
- ``devtool add`` workflow:
|
|
|
-
|
|
|
- - *Left*: The left scenario in the figure represents a common
|
|
|
- situation where the source code does not exist locally and needs
|
|
|
- to be extracted. In this situation, the source code is extracted
|
|
|
- to the default workspace --- you do not want the files in some
|
|
|
- specific location outside of the workspace. Thus, everything you
|
|
|
- need will be located in the workspace::
|
|
|
-
|
|
|
- $ devtool add recipe fetchuri
|
|
|
-
|
|
|
- With this command, ``devtool`` extracts the upstream
|
|
|
- source files into a local Git repository within the ``sources``
|
|
|
- folder. The command then creates a recipe named recipe and a
|
|
|
- corresponding append file in the workspace. If you do not provide
|
|
|
- recipe, the command makes an attempt to determine the recipe name.
|
|
|
-
|
|
|
- - *Middle*: The middle scenario in the figure also represents a
|
|
|
- situation where the source code does not exist locally. In this
|
|
|
- case, the code is again upstream and needs to be extracted to some
|
|
|
- local area --- this time outside of the default workspace.
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- If required, ``devtool`` always creates a Git repository locally
|
|
|
- during the extraction.
|
|
|
-
|
|
|
- Furthermore, the first positional argument ``srctree`` in this case
|
|
|
- identifies where the ``devtool add`` command will locate the
|
|
|
- extracted code outside of the workspace. You need to specify an
|
|
|
- empty directory::
|
|
|
-
|
|
|
- $ devtool add recipe srctree fetchuri
|
|
|
-
|
|
|
- In summary, the source code is pulled from fetchuri and extracted into the
|
|
|
- location defined by ``srctree`` as a local Git repository.
|
|
|
-
|
|
|
- Within workspace, ``devtool`` creates a recipe named recipe along
|
|
|
- with an associated append file.
|
|
|
-
|
|
|
- - *Right*: The right scenario in the figure represents a situation
|
|
|
- where the ``srctree`` has been previously prepared outside of the
|
|
|
- ``devtool`` workspace.
|
|
|
-
|
|
|
- The following command provides a new recipe name and identifies
|
|
|
- the existing source tree location::
|
|
|
-
|
|
|
- $ devtool add recipe srctree
|
|
|
-
|
|
|
- The command examines the source code and creates a recipe named
|
|
|
- recipe for the code and places the recipe into the workspace.
|
|
|
-
|
|
|
- Because the extracted source code already exists, ``devtool`` does
|
|
|
- not try to relocate the source code into the workspace --- only the
|
|
|
- new recipe is placed in the workspace.
|
|
|
-
|
|
|
- Aside from a recipe folder, the command also creates an associated
|
|
|
- append folder and places an initial ``*.bbappend`` file within.
|
|
|
-
|
|
|
-#. *Edit the Recipe*: You can use ``devtool edit-recipe`` to open up the
|
|
|
- editor as defined by the ``$EDITOR`` environment variable and modify
|
|
|
- the file::
|
|
|
-
|
|
|
- $ devtool edit-recipe recipe
|
|
|
-
|
|
|
- From within the editor, you can make modifications to the recipe that
|
|
|
- take effect when you build it later.
|
|
|
-
|
|
|
-#. *Build the Recipe or Rebuild the Image*: The next step you take
|
|
|
- depends on what you are going to do with the new code.
|
|
|
-
|
|
|
- If you need to eventually move the build output to the target
|
|
|
- hardware, use the following ``devtool`` command::
|
|
|
-
|
|
|
- $ devtool build recipe
|
|
|
-
|
|
|
- On the other hand, if you want an image to contain the recipe's
|
|
|
- packages from the workspace for immediate deployment onto a device
|
|
|
- (e.g. for testing purposes), you can use the ``devtool build-image``
|
|
|
- command::
|
|
|
-
|
|
|
- $ devtool build-image image
|
|
|
-
|
|
|
-#. *Deploy the Build Output*: When you use the ``devtool build`` command
|
|
|
- to build out your recipe, you probably want to see if the resulting
|
|
|
- build output works as expected on the target hardware.
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- This step assumes you have a previously built image that is
|
|
|
- already either running in QEMU or is running on actual hardware.
|
|
|
- Also, it is assumed that for deployment of the image to the
|
|
|
- target, SSH is installed in the image and, if the image is running
|
|
|
- on real hardware, you have network access to and from your
|
|
|
- development machine.
|
|
|
-
|
|
|
- You can deploy your build output to that target hardware by using the
|
|
|
- ``devtool deploy-target`` command::
|
|
|
-
|
|
|
- $ devtool deploy-target recipe target
|
|
|
-
|
|
|
- The target is a live target machine running as an SSH server.
|
|
|
-
|
|
|
- You can, of course, also deploy the image you build to actual
|
|
|
- hardware by using the ``devtool build-image`` command. However,
|
|
|
- ``devtool`` does not provide a specific command that allows you to
|
|
|
- deploy the image to actual hardware.
|
|
|
-
|
|
|
-#. *Finish Your Work With the Recipe*: The ``devtool finish`` command
|
|
|
- creates any patches corresponding to commits in the local Git
|
|
|
- repository, moves the new recipe to a more permanent layer, and then
|
|
|
- resets the recipe so that the recipe is built normally rather than
|
|
|
- from the workspace::
|
|
|
-
|
|
|
- $ devtool finish recipe layer
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- Any changes you want to turn into patches must be committed to the
|
|
|
- Git repository in the source tree.
|
|
|
-
|
|
|
- As mentioned, the ``devtool finish`` command moves the final recipe
|
|
|
- to its permanent layer.
|
|
|
-
|
|
|
- As a final process of the ``devtool finish`` command, the state of
|
|
|
- the standard layers and the upstream source is restored so that you
|
|
|
- can build the recipe from those areas rather than the workspace.
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- You can use the ``devtool reset`` command to put things back should you
|
|
|
- decide you do not want to proceed with your work. If you do use this
|
|
|
- command, realize that the source tree is preserved.
|
|
|
-
|
|
|
-Use ``devtool modify`` to Modify the Source of an Existing Component
|
|
|
---------------------------------------------------------------------
|
|
|
-
|
|
|
-The ``devtool modify`` command prepares the way to work on existing code
|
|
|
-that already has a local recipe in place that is used to build the
|
|
|
-software. The command is flexible enough to allow you to extract code
|
|
|
-from an upstream source, specify the existing recipe, and keep track of
|
|
|
-and gather any patch files from other developers that are associated
|
|
|
-with the code.
|
|
|
-
|
|
|
-Depending on your particular scenario, the arguments and options you use
|
|
|
-with ``devtool modify`` form different combinations. The following
|
|
|
-diagram shows common development flows for the ``devtool modify``
|
|
|
-command:
|
|
|
-
|
|
|
-.. image:: figures/sdk-devtool-modify-flow.png
|
|
|
- :width: 100%
|
|
|
-
|
|
|
-#. *Preparing to Modify the Code*: The top part of the flow shows three
|
|
|
- scenarios by which you could use ``devtool modify`` to prepare to
|
|
|
- work on source files. Each scenario assumes the following:
|
|
|
-
|
|
|
- - The recipe exists locally in a layer external to the ``devtool``
|
|
|
- workspace.
|
|
|
-
|
|
|
- - The source files exist either upstream in an un-extracted state or
|
|
|
- locally in a previously extracted state.
|
|
|
-
|
|
|
- The typical situation is where another developer has created a layer
|
|
|
- for use with the Yocto Project and their recipe already resides in
|
|
|
- that layer. Furthermore, their source code is readily available
|
|
|
- either upstream or locally.
|
|
|
-
|
|
|
- - *Left*: The left scenario in the figure represents a common
|
|
|
- situation where the source code does not exist locally and it
|
|
|
- needs to be extracted from an upstream source. In this situation,
|
|
|
- the source is extracted into the default ``devtool`` workspace
|
|
|
- location. The recipe, in this scenario, is in its own layer
|
|
|
- outside the workspace (i.e. ``meta-``\ layername).
|
|
|
-
|
|
|
- The following command identifies the recipe and, by default,
|
|
|
- extracts the source files::
|
|
|
-
|
|
|
- $ devtool modify recipe
|
|
|
-
|
|
|
- Once ``devtool`` locates the recipe, ``devtool`` uses the recipe's
|
|
|
- :term:`SRC_URI` statements to locate the source code and any local
|
|
|
- patch files from other developers.
|
|
|
-
|
|
|
- With this scenario, there is no ``srctree`` argument. Consequently, the
|
|
|
- default behavior of the ``devtool modify`` command is to extract
|
|
|
- the source files pointed to by the :term:`SRC_URI` statements into a
|
|
|
- local Git structure. Furthermore, the location for the extracted
|
|
|
- source is the default area within the ``devtool`` workspace. The
|
|
|
- result is that the command sets up both the source code and an
|
|
|
- append file within the workspace while the recipe remains in its
|
|
|
- original location.
|
|
|
-
|
|
|
- Additionally, if you have any non-patch local files (i.e. files
|
|
|
- referred to with ``file://`` entries in :term:`SRC_URI` statement
|
|
|
- excluding ``*.patch/`` or ``*.diff``), these files are copied to
|
|
|
- an ``oe-local-files`` folder under the newly created source tree.
|
|
|
- Copying the files here gives you a convenient area from which you
|
|
|
- can modify the files. Any changes or additions you make to those
|
|
|
- files are incorporated into the build the next time you build the
|
|
|
- software just as are other changes you might have made to the
|
|
|
- source.
|
|
|
-
|
|
|
- - *Middle*: The middle scenario in the figure represents a situation
|
|
|
- where the source code also does not exist locally. In this case,
|
|
|
- the code is again upstream and needs to be extracted to some local
|
|
|
- area as a Git repository. The recipe, in this scenario, is again
|
|
|
- local and in its own layer outside the workspace.
|
|
|
-
|
|
|
- The following command tells ``devtool`` the recipe with which to
|
|
|
- work and, in this case, identifies a local area for the extracted
|
|
|
- source files that exists outside of the default ``devtool``
|
|
|
- workspace::
|
|
|
-
|
|
|
- $ devtool modify recipe srctree
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- You cannot provide a URL for ``srctree`` using the ``devtool`` command.
|
|
|
-
|
|
|
- As with all extractions, the command uses the recipe's :term:`SRC_URI`
|
|
|
- statements to locate the source files and any associated patch
|
|
|
- files. Non-patch files are copied to an ``oe-local-files`` folder
|
|
|
- under the newly created source tree.
|
|
|
-
|
|
|
- Once the files are located, the command by default extracts them
|
|
|
- into ``srctree``.
|
|
|
-
|
|
|
- Within workspace, ``devtool`` creates an append file for the
|
|
|
- recipe. The recipe remains in its original location but the source
|
|
|
- files are extracted to the location you provide with ``srctree``.
|
|
|
-
|
|
|
- - *Right*: The right scenario in the figure represents a situation
|
|
|
- where the source tree (``srctree``) already exists locally as a
|
|
|
- previously extracted Git structure outside of the ``devtool``
|
|
|
- workspace. In this example, the recipe also exists elsewhere
|
|
|
- locally in its own layer.
|
|
|
-
|
|
|
- The following command tells ``devtool`` the recipe with which to
|
|
|
- work, uses the "-n" option to indicate source does not need to be
|
|
|
- extracted, and uses ``srctree`` to point to the previously extracted
|
|
|
- source files::
|
|
|
-
|
|
|
- $ devtool modify -n recipe srctree
|
|
|
-
|
|
|
- If an ``oe-local-files`` subdirectory happens to exist and it
|
|
|
- contains non-patch files, the files are used. However, if the
|
|
|
- subdirectory does not exist and you run the ``devtool finish``
|
|
|
- command, any non-patch files that might exist next to the recipe
|
|
|
- are removed because it appears to ``devtool`` that you have
|
|
|
- deleted those files.
|
|
|
-
|
|
|
- Once the ``devtool modify`` command finishes, it creates only an
|
|
|
- append file for the recipe in the ``devtool`` workspace. The
|
|
|
- recipe and the source code remain in their original locations.
|
|
|
-
|
|
|
-#. *Edit the Source*: Once you have used the ``devtool modify`` command,
|
|
|
- you are free to make changes to the source files. You can use any
|
|
|
- editor you like to make and save your source code modifications.
|
|
|
-
|
|
|
-#. *Build the Recipe or Rebuild the Image*: The next step you take
|
|
|
- depends on what you are going to do with the new code.
|
|
|
-
|
|
|
- If you need to eventually move the build output to the target
|
|
|
- hardware, use the following ``devtool`` command::
|
|
|
-
|
|
|
- $ devtool build recipe
|
|
|
-
|
|
|
- On the other hand, if you want an image to contain the recipe's
|
|
|
- packages from the workspace for immediate deployment onto a device
|
|
|
- (e.g. for testing purposes), you can use the ``devtool build-image``
|
|
|
- command::
|
|
|
-
|
|
|
- $ devtool build-image image
|
|
|
-
|
|
|
-#. *Deploy the Build Output*: When you use the ``devtool build`` command
|
|
|
- to build out your recipe, you probably want to see if the resulting
|
|
|
- build output works as expected on target hardware.
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- This step assumes you have a previously built image that is
|
|
|
- already either running in QEMU or running on actual hardware.
|
|
|
- Also, it is assumed that for deployment of the image to the
|
|
|
- target, SSH is installed in the image and if the image is running
|
|
|
- on real hardware that you have network access to and from your
|
|
|
- development machine.
|
|
|
-
|
|
|
- You can deploy your build output to that target hardware by using the
|
|
|
- ``devtool deploy-target`` command::
|
|
|
-
|
|
|
- $ devtool deploy-target recipe target
|
|
|
-
|
|
|
- The target is a live target machine running as an SSH server.
|
|
|
-
|
|
|
- You can, of course, use other methods to deploy the image you built
|
|
|
- using the ``devtool build-image`` command to actual hardware.
|
|
|
- ``devtool`` does not provide a specific command to deploy the image
|
|
|
- to actual hardware.
|
|
|
-
|
|
|
-#. *Finish Your Work With the Recipe*: The ``devtool finish`` command
|
|
|
- creates any patches corresponding to commits in the local Git
|
|
|
- repository, updates the recipe to point to them (or creates a
|
|
|
- ``.bbappend`` file to do so, depending on the specified destination
|
|
|
- layer), and then resets the recipe so that the recipe is built
|
|
|
- normally rather than from the workspace::
|
|
|
-
|
|
|
- $ devtool finish recipe layer
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- Any changes you want to turn into patches must be staged and
|
|
|
- committed within the local Git repository before you use the
|
|
|
- ``devtool finish`` command.
|
|
|
-
|
|
|
- Because there is no need to move the recipe, ``devtool finish``
|
|
|
- either updates the original recipe in the original layer or the
|
|
|
- command creates a ``.bbappend`` file in a different layer as provided
|
|
|
- by layer. Any work you did in the ``oe-local-files`` directory is
|
|
|
- preserved in the original files next to the recipe during the
|
|
|
- ``devtool finish`` command.
|
|
|
-
|
|
|
- As a final process of the ``devtool finish`` command, the state of
|
|
|
- the standard layers and the upstream source is restored so that you
|
|
|
- can build the recipe from those areas rather than from the workspace.
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- You can use the ``devtool reset`` command to put things back should you
|
|
|
- decide you do not want to proceed with your work. If you do use this
|
|
|
- command, realize that the source tree is preserved.
|
|
|
-
|
|
|
-``devtool ide-sdk`` configures IDEs and bootstraps SDKs
|
|
|
--------------------------------------------------------
|
|
|
-
|
|
|
-The ``devtool ide-sdk`` command can provide an IDE configuration for IDEs when
|
|
|
-working on the source code of one or more recipes.
|
|
|
-Depending on the programming language, and the build system used by the recipe,
|
|
|
-the tools required for cross-development and remote debugging are different.
|
|
|
-For example:
|
|
|
-
|
|
|
-- A C/C++ project usually uses CMake or Meson.
|
|
|
-
|
|
|
-- A Python project uses setuptools or one of its successors.
|
|
|
-
|
|
|
-- A Rust project uses Cargo.
|
|
|
-
|
|
|
-Also, the IDE plugins needed for the integration of a build system with the
|
|
|
-IDE and the corresponding settings are usually specific to these build-systems.
|
|
|
-To hide all these details from the user, ``devtool ide-sdk`` does two things:
|
|
|
-
|
|
|
-- It generates any kind of SDK needed for cross-development and remote
|
|
|
- debugging of the specified recipes.
|
|
|
-
|
|
|
-- It generates the configuration for the IDE (and the IDE plugins) for using
|
|
|
- the cross-toolchain and remote debugging tools provided by the SDK directly
|
|
|
- from the IDE.
|
|
|
-
|
|
|
-For supported build systems the configurations generated by ``devtool ide-sdk``
|
|
|
-combine the advantages of the ``devtool modify`` based workflow
|
|
|
-(see :ref:`using_devtool`) with the advantages of the simple Environment Setup
|
|
|
-script based workflow (see :ref:`running_the_ext_sdk_env`) provided by Yocto's
|
|
|
-SDK or eSDK:
|
|
|
-
|
|
|
-- The source code of the recipe is in the workspace created by
|
|
|
- ``devtool modify`` or ``devtool add``.
|
|
|
- Using ``devtool build``, ``devtool build-image``,
|
|
|
- ``devtool deploy-target`` or ``bitbake`` is possible.
|
|
|
- Also ``devtool ide-sdk`` can be used to update the SDK and the IDE
|
|
|
- configuration at any time.
|
|
|
-
|
|
|
-- ``devtool ide-sdk`` aims to support multiple programming languages and
|
|
|
- multiple IDEs natively. "Natively" means that the IDE is configured to call
|
|
|
- the build tool (e.g. ``cmake`` or ``meson``) directly. This has several
|
|
|
- advantages.
|
|
|
- First of all, it is usually much faster to call for example ``cmake`` than
|
|
|
- ``devtool build``.
|
|
|
- It also allows to benefit from the very good integration that IDEs like
|
|
|
- VSCode offer for tools like CMake or GDB.
|
|
|
-
|
|
|
- However, supporting many programming languages and multiple
|
|
|
- IDEs is quite an elaborate and constantly evolving thing. Support for IDEs
|
|
|
- is therefore implemented as plugins. Plugins can also be provided by
|
|
|
- optional layers.
|
|
|
-
|
|
|
-So much about the introduction to the default mode of ``devtool sdk-ide`` which
|
|
|
-is called the "modified" mode because it uses the workspace created by
|
|
|
-``devtool modify`` and the per recipe :term:`Sysroots <Sysroot>` of BitBake.
|
|
|
-
|
|
|
-For some recipes and use cases, this default behavior of ``devtool ide-sdk``
|
|
|
-with full ``devtool`` and ``bitbake`` integration might not be suitable.
|
|
|
-To offer full feature parity with the SDK and the eSDK, ``devtool ide-sdk`` has
|
|
|
-a second mode called "shared" mode.
|
|
|
-If ``devtool ide-sdk`` is called with the ``--mode=shared`` option, it
|
|
|
-bootstraps an SDK directly from the BitBake environment, which offers the same
|
|
|
-Environment Setup script as described in :ref:`running_the_ext_sdk_env`.
|
|
|
-In addition to the (e)SDK installer-based setup, the IDE gets configured
|
|
|
-to use the shared :term:`Sysroots <Sysroot>` and the tools from the SDK.
|
|
|
-``devtool ide-sdk --mode=shared`` is basically a wrapper for the setup of the
|
|
|
-extensible SDK as described in :ref:`setting_up_ext_sdk_in_build`.
|
|
|
-
|
|
|
-The use of ``devtool ide-sdk`` is an alternative to using one of the SDK
|
|
|
-installers.
|
|
|
-``devtool ide-sdk`` allows the creation of SDKs that offer all the
|
|
|
-functionality of the SDK and the eSDK installers. Compared to the installers,
|
|
|
-however, the SDK created with ``devtool ide-sdk`` is much more flexible.
|
|
|
-For example, it is very easy to change the :term:`MACHINE` in the
|
|
|
-``local.conf`` file, update the layer meta data and then regenerate the SDK.
|
|
|
-
|
|
|
-Let's take a look at an example of how to use ``devtool ide-sdk`` in each of
|
|
|
-the two modes:
|
|
|
-
|
|
|
-#. *Modified mode*:
|
|
|
-
|
|
|
- In order to use the ``devtool ide-sdk``, a few settings are needed. As a
|
|
|
- starting example, the following lines of code can be added to the
|
|
|
- ``local.conf`` file::
|
|
|
-
|
|
|
- # Build the companion debug file system
|
|
|
- IMAGE_GEN_DEBUGFS = "1"
|
|
|
- # Optimize build time: with devtool ide-sdk the dbg tar is not needed
|
|
|
- IMAGE_FSTYPES_DEBUGFS = ""
|
|
|
- # Without copying the binaries into roofs-dbg, GDB does not find all source files.
|
|
|
- IMAGE_CLASSES += "image-combined-dbg"
|
|
|
-
|
|
|
- # SSH is mandatory, no password simplifies the usage
|
|
|
- EXTRA_IMAGE_FEATURES += "\
|
|
|
- ssh-server-openssh \
|
|
|
- allow-empty-password \
|
|
|
- allow-root-login \
|
|
|
- empty-root-password \
|
|
|
- "
|
|
|
-
|
|
|
- # Remote debugging needs gdbserver on the target device
|
|
|
- IMAGE_INSTALL:append = " gdbserver"
|
|
|
-
|
|
|
- # Add the recipes which should be modified to the image
|
|
|
- # Otherwise some dependencies might be missing.
|
|
|
- IMAGE_INSTALL:append = " my-recipe"
|
|
|
-
|
|
|
- Assuming the BitBake environment is set up correctly and a workspace has
|
|
|
- been created for the recipe using ``devtool modify my-recipe`` or probably
|
|
|
- even better by using ``devtool modify my-recipe --debug-build``, the
|
|
|
- following command can create the SDK and the configuration for VSCode in
|
|
|
- the recipe workspace::
|
|
|
-
|
|
|
- $ devtool ide-sdk my-recipe core-image-minimal --target root@192.168.7.2
|
|
|
-
|
|
|
- The command requires an image recipe (``core-image-minimal`` for this
|
|
|
- example) that is used to create the SDK.
|
|
|
- This firmware image should also be installed on the target device.
|
|
|
- It is possible to pass multiple package recipes::
|
|
|
-
|
|
|
- $ devtool ide-sdk my-recipe-1 my-recipe-2 core-image-minimal --target root@192.168.7.2
|
|
|
-
|
|
|
- ``devtool ide-sdk`` tries to create an IDE configuration for all package
|
|
|
- recipes.
|
|
|
-
|
|
|
- What this command does exactly depends on the recipe, more precisely on the
|
|
|
- build tool used by the recipe. The basic idea is to configure the IDE so
|
|
|
- that it calls the build tool exactly as ``bitbake`` does.
|
|
|
-
|
|
|
- For example, a CMake preset is created for a recipe that inherits
|
|
|
- :ref:`ref-classes-cmake`. In the case of VSCode, CMake presets are supported
|
|
|
- by the CMake Tools plugin. This is an example of how the build configuration
|
|
|
- used by ``bitbake`` is exported to an IDE configuration that gives exactly
|
|
|
- the same build results.
|
|
|
-
|
|
|
- Support for remote debugging with seamless integration into the IDE is
|
|
|
- important for a cross-SDK. ``devtool ide-sdk`` automatically generates the
|
|
|
- necessary helper scripts for deploying the compiled artifacts to the target
|
|
|
- device as well as the necessary configuration for the debugger and the IDE.
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- To ensure that the debug symbols on the build machine match the binaries
|
|
|
- running on the target device, it is essential that the image built by
|
|
|
- ``devtool ide-sdk`` is running on the target device.
|
|
|
-
|
|
|
- The default IDE is VSCode. Some hints about using VSCode:
|
|
|
-
|
|
|
- - VSCode can be used to work on the BitBake recipes or the application
|
|
|
- source code.
|
|
|
- Usually there is one instance of VSCode running in the folder where the
|
|
|
- BitBake recipes are. This instance has the
|
|
|
- `Yocto Project BitBake plugin <https://marketplace.visualstudio.com/items?itemName=yocto-project.yocto-bitbake>`_
|
|
|
- running.
|
|
|
-
|
|
|
- .. warning::
|
|
|
-
|
|
|
- Some VSCode plugins (Python, BitBake and others) need a reasonable
|
|
|
- configuration to work as expected. Otherwise, some plugins try to
|
|
|
- index the build directory of BitBake, which keeps your system quite
|
|
|
- busy until an out of memory exception stops this nonsense.
|
|
|
- Other plugins, such as the BitBake plugin, do not behave as expected.
|
|
|
-
|
|
|
- To work around such issues, the ``oe-init-build-env`` script creates
|
|
|
- an initial ``.vscode/settings.json`` file if ``code`` can be found
|
|
|
- and the ``.vscode`` folder does not yet exist.
|
|
|
- It is best to run ``oe-init-build-env`` once before starting VSCode.
|
|
|
- An alternative approach is to use a build folder outside the layers,
|
|
|
- e.g. ``oe-init-build-env ../build``.
|
|
|
-
|
|
|
- The BitBake plugin also offers to create devtool workspaces and run
|
|
|
- ``devtool ide-sdk`` with a few mouse clicks.
|
|
|
- Of course, issuing commands in the terminal works as well.
|
|
|
-
|
|
|
- - To work on the source code of a recipe another instance of VSCode is
|
|
|
- started in the recipe's workspace. Example::
|
|
|
-
|
|
|
- code build/workspace/sources/my-recipe
|
|
|
-
|
|
|
- This instance of VSCode uses plugins that are useful for the development
|
|
|
- of the application. ``devtool ide-sdk`` generates the necessary
|
|
|
- ``extensions.json``, ``settings.json``, ``tasks.json``and ``launch.json``
|
|
|
- configuration files for all the involved plugins.
|
|
|
-
|
|
|
- When the source code folder present in the workspace folder is opened in
|
|
|
- VSCode for the first time, a pop-up message recommends installing the
|
|
|
- required plugins.
|
|
|
- After accepting the installation of the plugins, working with the source
|
|
|
- code or some debugging tasks should work as usual with VSCode.
|
|
|
-
|
|
|
- Starting the VSCode instances in the recipe workspace folders can also be
|
|
|
- done by a mouse click on the recipe workspaces in the first VSCode
|
|
|
- instance.
|
|
|
-
|
|
|
- - To work with CMake press ``Ctrl + Shift + p``, type ``cmake``. This will
|
|
|
- show some possible commands like selecting a CMake preset, compiling or
|
|
|
- running CTest.
|
|
|
-
|
|
|
- For recipes inheriting :ref:`ref-classes-cmake-qemu` rather than
|
|
|
- :ref:`ref-classes-cmake`, executing cross-compiled unit tests on the host
|
|
|
- can be supported transparently with QEMU user-mode.
|
|
|
-
|
|
|
- - To work with Meson press ``Ctrl + Shift + p``, type ``meson``. This will
|
|
|
- show some possible commands like compiling or executing the unit tests.
|
|
|
-
|
|
|
- A note on running cross-compiled unit tests on the host: Meson enables
|
|
|
- support for QEMU user mode by default. It is expected that the execution
|
|
|
- of the unit tests from the IDE will work without any additional steps,
|
|
|
- given that the code is suitable for the execution on the host machine.
|
|
|
-
|
|
|
- - For the deployment to the target device, just press ``Ctrl + Shift + p``,
|
|
|
- type ``task``. Select ``install && deploy-target``.
|
|
|
-
|
|
|
- - For remote debugging, switch to the debugging view by pressing the "play"
|
|
|
- button with the ``bug icon`` on the left side. This will provide a green
|
|
|
- play button with a drop-down list where a debug configuration can be
|
|
|
- selected. After selecting one of the generated configurations, press the
|
|
|
- "play" button.
|
|
|
-
|
|
|
- Starting a remote debugging session automatically initiates the
|
|
|
- deployment to the target device. If this is not desired, the
|
|
|
- ``"dependsOn": ["install && deploy-target...]`` parameter of the tasks
|
|
|
- with ``"label": "gdbserver start...`` can be removed from the
|
|
|
- ``tasks.json`` file.
|
|
|
-
|
|
|
- VSCode supports GDB with many different setups and configurations for
|
|
|
- many different use cases. However, most of these setups have some
|
|
|
- limitations when it comes to cross-development, support only a few target
|
|
|
- architectures or require a high performance target device. Therefore
|
|
|
- ``devtool ide-sdk`` supports the classic, generic setup with GDB on the
|
|
|
- development host and gdbserver on the target device.
|
|
|
-
|
|
|
- Roughly summarized, this means:
|
|
|
-
|
|
|
- - The binaries are copied via SSH to the remote target device by a
|
|
|
- script referred by ``tasks.json``.
|
|
|
-
|
|
|
- - gdbserver is started on the remote target device via SSH by a script
|
|
|
- referred by ``tasks.json``.
|
|
|
-
|
|
|
- Changing the parameters that are passed to the debugging executable
|
|
|
- requires modifying the generated script. The script is located at
|
|
|
- ``oe-scripts/gdbserver_*``. Defining the parameters in the ``args``
|
|
|
- field in the ``launch.json`` file does not work.
|
|
|
-
|
|
|
- - VSCode connects to gdbserver as documented in
|
|
|
- `Remote debugging or debugging with a local debugger server
|
|
|
- <https://code.visualstudio.com/docs/cpp/launch-json-reference#_remote-debugging-or-debugging-with-a-local-debugger-server>`__.
|
|
|
-
|
|
|
- Additionally ``--ide=none`` is supported. With the ``none`` IDE parameter,
|
|
|
- some generic configuration files like ``gdbinit`` files and some helper
|
|
|
- scripts starting gdbserver remotely on the target device as well as the GDB
|
|
|
- client on the host are generated.
|
|
|
-
|
|
|
- Here is a usage example for the ``cmake-example`` recipe from the
|
|
|
- ``meta-selftest`` layer which inherits :ref:`ref-classes-cmake-qemu`:
|
|
|
-
|
|
|
- .. code-block:: sh
|
|
|
-
|
|
|
- # Create the SDK
|
|
|
- devtool modify cmake-example --debug-build
|
|
|
- devtool ide-sdk cmake-example core-image-minimal -c --ide=none
|
|
|
-
|
|
|
- # Install the firmware on a target device or start QEMU
|
|
|
- runqemu
|
|
|
-
|
|
|
- # From exploring the workspace of cmake-example
|
|
|
- cd build/workspace/sources/cmake-example
|
|
|
-
|
|
|
- # Find cmake-native and save the path into a variable
|
|
|
- # Note: using just cmake instead of $CMAKE_NATIVE would work in many cases
|
|
|
- CMAKE_NATIVE="$(jq -r '.configurePresets[0] | "\(.cmakeExecutable)"' CMakeUserPresets.json)"
|
|
|
-
|
|
|
- # List available CMake presets
|
|
|
- "$CMAKE_NATIVE" --list-presets
|
|
|
- Available configure presets:
|
|
|
-
|
|
|
- "cmake-example-cortexa57" - cmake-example: cortexa57
|
|
|
-
|
|
|
- # Re-compile the already compiled sources
|
|
|
- "$CMAKE_NATIVE" --build --preset cmake-example-cortexa57
|
|
|
- ninja: no work to do.
|
|
|
- # Do a clean re-build
|
|
|
- "$CMAKE_NATIVE" --build --preset cmake-example-cortexa57 --target clean
|
|
|
- [1/1] Cleaning all built files...
|
|
|
- Cleaning... 8 files.
|
|
|
- "$CMAKE_NATIVE" --build --preset cmake-example-cortexa57 --target all
|
|
|
- [7/7] Linking CXX executable cmake-example
|
|
|
-
|
|
|
- # Run the cross-compiled unit tests with QEMU user-mode
|
|
|
- "$CMAKE_NATIVE" --build --preset cmake-example-cortexa57 --target test
|
|
|
- [0/1] Running tests...
|
|
|
- Test project .../build/tmp/work/cortexa57-poky-linux/cmake-example/1.0/cmake-example-1.0
|
|
|
- Start 1: test-cmake-example
|
|
|
- 1/1 Test #1: test-cmake-example ............... Passed 0.03 sec
|
|
|
-
|
|
|
- 100% tests passed, 0 tests failed out of 1
|
|
|
-
|
|
|
- Total Test time (real) = 0.03 sec
|
|
|
-
|
|
|
- # Using CTest directly is possible as well
|
|
|
- CTEST_NATIVE="$(dirname "$CMAKE_NATIVE")/ctest"
|
|
|
-
|
|
|
- # List available CMake presets
|
|
|
- "$CTEST_NATIVE" --list-presets
|
|
|
- Available test presets:
|
|
|
-
|
|
|
- "cmake-example-cortexa57" - cmake-example: cortexa57
|
|
|
-
|
|
|
- # Run the cross-compiled unit tests with QEMU user-mode
|
|
|
- "$CTEST_NATIVE" --preset "cmake-example-cortexa57"
|
|
|
- Test project ...build/tmp/work/cortexa57-poky-linux/cmake-example/1.0/cmake-example-1.0
|
|
|
- Start 1: test-cmake-example
|
|
|
- 1/1 Test #1: test-cmake-example ............... Passed 0.03 sec
|
|
|
-
|
|
|
- 100% tests passed, 0 tests failed out of 1
|
|
|
-
|
|
|
- Total Test time (real) = 0.03 sec
|
|
|
-
|
|
|
- # Deploying the new build to the target device (default is QEUM at 192.168.7.2)
|
|
|
- oe-scripts/install_and_deploy_cmake-example-cortexa57
|
|
|
-
|
|
|
- # Start a remote debugging session with gdbserver on the target and GDB on the host
|
|
|
- oe-scripts/gdbserver_1234_usr-bin-cmake-example_m
|
|
|
- oe-scripts/gdb_1234_usr-bin-cmake-example
|
|
|
- break main
|
|
|
- run
|
|
|
- step
|
|
|
- stepi
|
|
|
- continue
|
|
|
- quit
|
|
|
-
|
|
|
- # Stop gdbserver on the target device
|
|
|
- oe-scripts/gdbserver_1234_usr-bin-cmake-example_m stop
|
|
|
-
|
|
|
-#. *Shared sysroots mode*
|
|
|
-
|
|
|
- Creating an SDK with shared :term:`Sysroots <Sysroot>` that contains all the
|
|
|
- dependencies needed to work with ``my-recipe`` is possible with the following
|
|
|
- example command::
|
|
|
-
|
|
|
- $ devtool ide-sdk --mode=shared my-recipe
|
|
|
-
|
|
|
- For VSCode the cross-toolchain is exposed as a CMake kit. CMake kits are
|
|
|
- defined in ``~/.local/share/CMakeTools/cmake-tools-kits.json``.
|
|
|
- The following example shows how the cross-toolchain can be selected in
|
|
|
- VSCode. First of all we need a folder containing a CMake project.
|
|
|
- For this example, let's create a CMake project and start VSCode::
|
|
|
-
|
|
|
- mkdir kit-test
|
|
|
- echo "project(foo VERSION 1.0)" > kit-test/CMakeLists.txt
|
|
|
- code kit-test
|
|
|
-
|
|
|
- If there is a CMake project in the workspace, cross-compilation is
|
|
|
- supported:
|
|
|
-
|
|
|
- - Press ``Ctrl + Shift + P``, type ``CMake: Scan for Kits``
|
|
|
- - Press ``Ctrl + Shift + P``, type ``CMake: Select a Kit``
|
|
|
-
|
|
|
- Finally most of the features provided by CMake and the IDE should be
|
|
|
- available.
|
|
|
-
|
|
|
- Other IDEs than VSCode are supported as well. However,
|
|
|
- ``devtool ide-sdk --mode=shared --ide=none my-recipe`` is currently
|
|
|
- just a simple wrapper for the setup of the extensible SDK, as described in
|
|
|
- :ref:`setting_up_ext_sdk_in_build`.
|
|
|
-
|
|
|
-Use ``devtool upgrade`` to Create a Version of the Recipe that Supports a Newer Version of the Software
|
|
|
--------------------------------------------------------------------------------------------------------
|
|
|
-
|
|
|
-The ``devtool upgrade`` command upgrades an existing recipe to that of a
|
|
|
-more up-to-date version found upstream. Throughout the life of software,
|
|
|
-recipes continually undergo version upgrades by their upstream
|
|
|
-publishers. You can use the ``devtool upgrade`` workflow to make sure
|
|
|
-your recipes you are using for builds are up-to-date with their upstream
|
|
|
-counterparts.
|
|
|
-
|
|
|
-.. note::
|
|
|
-
|
|
|
- Several methods exist by which you can upgrade recipes ---
|
|
|
- ``devtool upgrade`` happens to be one. You can read about all the methods by
|
|
|
- which you can upgrade recipes in the
|
|
|
- :ref:`dev-manual/upgrading-recipes:upgrading recipes` section of the Yocto
|
|
|
- Project Development Tasks Manual.
|
|
|
-
|
|
|
-The ``devtool upgrade`` command is flexible enough to allow you to specify
|
|
|
-source code revision and versioning schemes, extract code into or out of the
|
|
|
-``devtool`` :ref:`devtool-the-workspace-layer-structure`, and work with any
|
|
|
-source file forms that the
|
|
|
-:ref:`bitbake-user-manual/bitbake-user-manual-fetching:fetchers` support.
|
|
|
-
|
|
|
-The following diagram shows the common development flow used with the
|
|
|
-``devtool upgrade`` command:
|
|
|
-
|
|
|
-.. image:: figures/sdk-devtool-upgrade-flow.png
|
|
|
- :width: 100%
|
|
|
-
|
|
|
-#. *Initiate the Upgrade*: The top part of the flow shows the typical
|
|
|
- scenario by which you use the ``devtool upgrade`` command. The
|
|
|
- following conditions exist:
|
|
|
-
|
|
|
- - The recipe exists in a local layer external to the ``devtool``
|
|
|
- workspace.
|
|
|
-
|
|
|
- - The source files for the new release exist in the same location
|
|
|
- pointed to by :term:`SRC_URI`
|
|
|
- in the recipe (e.g. a tarball with the new version number in the
|
|
|
- name, or as a different revision in the upstream Git repository).
|
|
|
-
|
|
|
- A common situation is where third-party software has undergone a
|
|
|
- revision so that it has been upgraded. The recipe you have access to
|
|
|
- is likely in your own layer. Thus, you need to upgrade the recipe to
|
|
|
- use the newer version of the software::
|
|
|
-
|
|
|
- $ devtool upgrade -V version recipe
|
|
|
-
|
|
|
- By default, the ``devtool upgrade`` command extracts source
|
|
|
- code into the ``sources`` directory in the
|
|
|
- :ref:`devtool-the-workspace-layer-structure`.
|
|
|
- If you want the code extracted to any other location, you need to
|
|
|
- provide the ``srctree`` positional argument with the command as follows::
|
|
|
-
|
|
|
- $ devtool upgrade -V version recipe srctree
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- In this example, the "-V" option specifies the new version. If you
|
|
|
- don't use "-V", the command upgrades the recipe to the latest
|
|
|
- version.
|
|
|
-
|
|
|
- If the source files pointed to by the :term:`SRC_URI` statement in the
|
|
|
- recipe are in a Git repository, you must provide the "-S" option and
|
|
|
- specify a revision for the software.
|
|
|
-
|
|
|
- Once ``devtool`` locates the recipe, it uses the :term:`SRC_URI` variable
|
|
|
- to locate the source code and any local patch files from other
|
|
|
- developers. The result is that the command sets up the source code,
|
|
|
- the new version of the recipe, and an append file all within the
|
|
|
- workspace.
|
|
|
-
|
|
|
- Additionally, if you have any non-patch local files (i.e. files
|
|
|
- referred to with ``file://`` entries in :term:`SRC_URI` statement
|
|
|
- excluding ``*.patch/`` or ``*.diff``), these files are copied to an
|
|
|
- ``oe-local-files`` folder under the newly created source tree.
|
|
|
- Copying the files here gives you a convenient area from which you can
|
|
|
- modify the files. Any changes or additions you make to those files
|
|
|
- are incorporated into the build the next time you build the software
|
|
|
- just as are other changes you might have made to the source.
|
|
|
-
|
|
|
-#. *Resolve any Conflicts created by the Upgrade*: Conflicts could happen
|
|
|
- after upgrading the software to a new version. Conflicts occur
|
|
|
- if your recipe specifies some patch files in :term:`SRC_URI` that
|
|
|
- conflict with changes made in the new version of the software. For
|
|
|
- such cases, you need to resolve the conflicts by editing the source
|
|
|
- and following the normal ``git rebase`` conflict resolution process.
|
|
|
-
|
|
|
- Before moving onto the next step, be sure to resolve any such
|
|
|
- conflicts created through use of a newer or different version of the
|
|
|
- software.
|
|
|
-
|
|
|
-#. *Build the Recipe or Rebuild the Image*: The next step you take
|
|
|
- depends on what you are going to do with the new code.
|
|
|
-
|
|
|
- If you need to eventually move the build output to the target
|
|
|
- hardware, use the following ``devtool`` command::
|
|
|
-
|
|
|
- $ devtool build recipe
|
|
|
-
|
|
|
- On the other hand, if you want an image to contain the recipe's
|
|
|
- packages from the workspace for immediate deployment onto a device
|
|
|
- (e.g. for testing purposes), you can use the ``devtool build-image``
|
|
|
- command::
|
|
|
-
|
|
|
- $ devtool build-image image
|
|
|
-
|
|
|
-#. *Deploy the Build Output*: When you use the ``devtool build`` command
|
|
|
- or ``bitbake`` to build your recipe, you probably want to see if the
|
|
|
- resulting build output works as expected on target hardware.
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- This step assumes you have a previously built image that is
|
|
|
- already either running in QEMU or running on actual hardware.
|
|
|
- Also, it is assumed that for deployment of the image to the
|
|
|
- target, SSH is installed in the image and if the image is running
|
|
|
- on real hardware that you have network access to and from your
|
|
|
- development machine.
|
|
|
-
|
|
|
- You can deploy your build output to that target hardware by using the
|
|
|
- ``devtool deploy-target`` command::
|
|
|
-
|
|
|
- $ devtool deploy-target recipe target
|
|
|
-
|
|
|
- The target is a live target machine running as an SSH server.
|
|
|
-
|
|
|
- You can, of course, also deploy the image you build using the
|
|
|
- ``devtool build-image`` command to actual hardware. However,
|
|
|
- ``devtool`` does not provide a specific command that allows you to do
|
|
|
- this.
|
|
|
-
|
|
|
-#. *Finish Your Work With the Recipe*: The ``devtool finish`` command
|
|
|
- creates any patches corresponding to commits in the local Git
|
|
|
- repository, moves the new recipe to a more permanent layer, and then
|
|
|
- resets the recipe so that the recipe is built normally rather than
|
|
|
- from the workspace.
|
|
|
-
|
|
|
- Any work you did in the ``oe-local-files`` directory is preserved in
|
|
|
- the original files next to the recipe during the ``devtool finish``
|
|
|
- command.
|
|
|
-
|
|
|
- If you specify a destination layer that is the same as the original
|
|
|
- source, then the old version of the recipe and associated files are
|
|
|
- removed prior to adding the new version::
|
|
|
-
|
|
|
- $ devtool finish recipe layer
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- Any changes you want to turn into patches must be committed to the
|
|
|
- Git repository in the source tree.
|
|
|
-
|
|
|
- As a final process of the ``devtool finish`` command, the state of
|
|
|
- the standard layers and the upstream source is restored so that you
|
|
|
- can build the recipe from those areas rather than the workspace.
|
|
|
-
|
|
|
- .. note::
|
|
|
-
|
|
|
- You can use the ``devtool reset`` command to put things back should you
|
|
|
- decide you do not want to proceed with your work. If you do use this
|
|
|
- command, realize that the source tree is preserved.
|
|
|
-
|
|
|
-A Closer Look at ``devtool add``
|
|
|
-================================
|
|
|
-
|
|
|
-The ``devtool add`` command automatically creates a recipe based on the
|
|
|
-source tree you provide with the command. Currently, the command has
|
|
|
-support for the following:
|
|
|
-
|
|
|
-- Autotools (``autoconf`` and ``automake``)
|
|
|
-
|
|
|
-- CMake
|
|
|
-
|
|
|
-- Scons
|
|
|
-
|
|
|
-- ``qmake``
|
|
|
-
|
|
|
-- Plain ``Makefile``
|
|
|
-
|
|
|
-- Out-of-tree kernel module
|
|
|
-
|
|
|
-- Binary package (i.e. "-b" option)
|
|
|
-
|
|
|
-- Node.js module
|
|
|
-
|
|
|
-- Python modules that use ``setuptools`` or ``distutils``
|
|
|
-
|
|
|
-Apart from binary packages, the determination of how a source tree
|
|
|
-should be treated is automatic based on the files present within that
|
|
|
-source tree. For example, if a ``CMakeLists.txt`` file is found, then
|
|
|
-the source tree is assumed to be using CMake and is treated accordingly.
|
|
|
-
|
|
|
-.. note::
|
|
|
-
|
|
|
- In most cases, you need to edit the automatically generated recipe in
|
|
|
- order to make it build properly. Typically, you would go through
|
|
|
- several edit and build cycles until the recipe successfully builds.
|
|
|
- Once the recipe builds, you could use possible further iterations to
|
|
|
- test the recipe on the target device.
|
|
|
-
|
|
|
-The remainder of this section covers specifics regarding how parts of
|
|
|
-the recipe are generated.
|
|
|
-
|
|
|
-Name and Version
|
|
|
-----------------
|
|
|
-
|
|
|
-If you do not specify a name and version on the command line,
|
|
|
-``devtool add`` uses various metadata within the source tree in an
|
|
|
-attempt to determine the name and version of the software being built.
|
|
|
-Based on what the tool determines, ``devtool`` sets the name of the
|
|
|
-created recipe file accordingly.
|
|
|
-
|
|
|
-If ``devtool`` cannot determine the name and version, the command prints
|
|
|
-an error. For such cases, you must re-run the command and provide the
|
|
|
-name and version, just the name, or just the version as part of the
|
|
|
-command line.
|
|
|
-
|
|
|
-Sometimes the name or version determined from the source tree might be
|
|
|
-incorrect. For such a case, you must reset the recipe::
|
|
|
-
|
|
|
- $ devtool reset -n recipename
|
|
|
-
|
|
|
-After running the ``devtool reset`` command, you need to
|
|
|
-run ``devtool add`` again and provide the name or the version.
|
|
|
-
|
|
|
-Dependency Detection and Mapping
|
|
|
---------------------------------
|
|
|
-
|
|
|
-The ``devtool add`` command attempts to detect build-time dependencies and map
|
|
|
-them to other recipes in the system. During this mapping, the command fills in
|
|
|
-the names of those recipes as part of the :term:`DEPENDS` variable within the
|
|
|
-recipe. If a dependency cannot be mapped, ``devtool`` places a comment
|
|
|
-in the recipe indicating such. The inability to map a dependency can
|
|
|
-result from naming not being recognized or because the dependency simply
|
|
|
-is not available. For cases where the dependency is not available, you
|
|
|
-must use the ``devtool add`` command to add an additional recipe that
|
|
|
-satisfies the dependency. Once you add that recipe, you need to update
|
|
|
-the :term:`DEPENDS` variable in the original recipe to include the new
|
|
|
-recipe.
|
|
|
-
|
|
|
-If you need to add runtime dependencies, you can do so by adding the
|
|
|
-following to your recipe::
|
|
|
-
|
|
|
- RDEPENDS:${PN} += "dependency1 dependency2 ..."
|
|
|
-
|
|
|
-.. note::
|
|
|
-
|
|
|
- The ``devtool add`` command often cannot distinguish between mandatory and
|
|
|
- optional dependencies. Consequently, some of the detected dependencies might
|
|
|
- in fact be optional. When in doubt, consult the documentation or the
|
|
|
- configure script for the software the recipe is building for further
|
|
|
- details. In some cases, you might find you can substitute the
|
|
|
- dependency with an option that disables the associated functionality
|
|
|
- passed to the configure script.
|
|
|
-
|
|
|
-License Detection
|
|
|
------------------
|
|
|
-
|
|
|
-The ``devtool add`` command attempts to determine if the software you are
|
|
|
-adding is able to be distributed under a common, open-source license. If
|
|
|
-so, the command sets the :term:`LICENSE` value accordingly.
|
|
|
-You should double-check the value added by the command against the
|
|
|
-documentation or source files for the software you are building and, if
|
|
|
-necessary, update that :term:`LICENSE` value.
|
|
|
-
|
|
|
-The ``devtool add`` command also sets the :term:`LIC_FILES_CHKSUM`
|
|
|
-value to point to all files that appear to be license-related. Realize
|
|
|
-that license statements often appear in comments at the top of source
|
|
|
-files or within the documentation. In such cases, the command does not
|
|
|
-recognize those license statements. Consequently, you might need to
|
|
|
-amend the :term:`LIC_FILES_CHKSUM` variable to point to one or more of those
|
|
|
-comments if present. Setting :term:`LIC_FILES_CHKSUM` is particularly
|
|
|
-important for third-party software. The mechanism attempts to ensure
|
|
|
-correct licensing should you upgrade the recipe to a newer upstream
|
|
|
-version in future. Any change in licensing is detected and you receive
|
|
|
-an error prompting you to check the license text again.
|
|
|
-
|
|
|
-If the ``devtool add`` command cannot determine licensing information,
|
|
|
-``devtool`` sets the :term:`LICENSE` value to "CLOSED" and leaves the
|
|
|
-:term:`LIC_FILES_CHKSUM` value unset. This behavior allows you to continue
|
|
|
-with development even though the settings are unlikely to be correct in
|
|
|
-all cases. You should check the documentation or source files for the
|
|
|
-software you are building to determine the actual license.
|
|
|
-
|
|
|
-Adding Makefile-Only Software
|
|
|
------------------------------
|
|
|
-
|
|
|
-The use of Make by itself is very common in both proprietary and
|
|
|
-open-source software. Unfortunately, Makefiles are often not written
|
|
|
-with cross-compilation in mind. Thus, ``devtool add`` often cannot do
|
|
|
-very much to ensure that these Makefiles build correctly. It is very
|
|
|
-common, for example, to explicitly call ``gcc`` instead of using the
|
|
|
-:term:`CC` variable. Usually, in a
|
|
|
-cross-compilation environment, ``gcc`` is the compiler for the build
|
|
|
-host and the cross-compiler is named something similar to
|
|
|
-``arm-poky-linux-gnueabi-gcc`` and might require arguments (e.g. to
|
|
|
-point to the associated sysroot for the target machine).
|
|
|
-
|
|
|
-When writing a recipe for Makefile-only software, keep the following in
|
|
|
-mind:
|
|
|
-
|
|
|
-- You probably need to patch the Makefile to use variables instead of
|
|
|
- hardcoding tools within the toolchain such as ``gcc`` and ``g++``.
|
|
|
-
|
|
|
-- The environment in which Make runs is set up with various standard
|
|
|
- variables for compilation (e.g. :term:`CC`, :term:`CXX`, and so forth) in a
|
|
|
- similar manner to the environment set up by the SDK's environment
|
|
|
- setup script. One easy way to see these variables is to run the
|
|
|
- ``devtool build`` command on the recipe and then look in
|
|
|
- ``oe-logs/run.do_compile``. Towards the top of this file, there is
|
|
|
- a list of environment variables that are set. You can take
|
|
|
- advantage of these variables within the Makefile.
|
|
|
-
|
|
|
-- If the Makefile sets a default for a variable using "=", that default
|
|
|
- overrides the value set in the environment, which is usually not
|
|
|
- desirable. For this case, you can either patch the Makefile so it
|
|
|
- sets the default using the "?=" operator, or you can alternatively
|
|
|
- force the value on the ``make`` command line. To force the value on
|
|
|
- the command line, add the variable setting to
|
|
|
- :term:`EXTRA_OEMAKE` or
|
|
|
- :term:`PACKAGECONFIG_CONFARGS`
|
|
|
- within the recipe. Here is an example using :term:`EXTRA_OEMAKE`::
|
|
|
-
|
|
|
- EXTRA_OEMAKE += "'CC=${CC}' 'CXX=${CXX}'"
|
|
|
-
|
|
|
- In the above example,
|
|
|
- single quotes are used around the variable settings as the values are
|
|
|
- likely to contain spaces because required default options are passed
|
|
|
- to the compiler.
|
|
|
-
|
|
|
-- Hardcoding paths inside Makefiles is often problematic in a
|
|
|
- cross-compilation environment. This is particularly true because
|
|
|
- those hardcoded paths often point to locations on the build host and
|
|
|
- thus will either be read-only or will introduce contamination into
|
|
|
- the cross-compilation because they are specific to the build host
|
|
|
- rather than the target. Patching the Makefile to use prefix variables
|
|
|
- or other path variables is usually the way to handle this situation.
|
|
|
-
|
|
|
-- Sometimes a Makefile runs target-specific commands such as
|
|
|
- ``ldconfig``. For such cases, you might be able to apply patches that
|
|
|
- remove these commands from the Makefile.
|
|
|
-
|
|
|
-Adding Native Tools
|
|
|
--------------------
|
|
|
-
|
|
|
-Often, you need to build additional tools that run on the :term:`Build Host`
|
|
|
-as opposed to the target. You should indicate this requirement by using one of
|
|
|
-the following methods when you run ``devtool add``:
|
|
|
-
|
|
|
-- Specify the name of the recipe such that it ends with "-native".
|
|
|
- Specifying the name like this produces a recipe that only builds for
|
|
|
- the build host.
|
|
|
-
|
|
|
-- Specify the "--also-native" option with the ``devtool add``
|
|
|
- command. Specifying this option creates a recipe file that still
|
|
|
- builds for the target but also creates a variant with a "-native"
|
|
|
- suffix that builds for the build host.
|
|
|
-
|
|
|
-.. note::
|
|
|
-
|
|
|
- If you need to add a tool that is shipped as part of a source tree
|
|
|
- that builds code for the target, you can typically accomplish this by
|
|
|
- building the native and target parts separately rather than within
|
|
|
- the same compilation process. Realize though that with the
|
|
|
- "--also-native" option, you can add the tool using just one
|
|
|
- recipe file.
|
|
|
-
|
|
|
-Adding Node.js Modules
|
|
|
-----------------------
|
|
|
-
|
|
|
-You can use the ``devtool add`` command two different ways to add
|
|
|
-Node.js modules: through ``npm`` or from a repository or local source.
|
|
|
-
|
|
|
-Use the following form to add Node.js modules through ``npm``::
|
|
|
-
|
|
|
- $ devtool add "npm://registry.npmjs.org;name=forever;version=0.15.1"
|
|
|
-
|
|
|
-The name and
|
|
|
-version parameters are mandatory. Lockdown and shrinkwrap files are
|
|
|
-generated and pointed to by the recipe in order to freeze the version
|
|
|
-that is fetched for the dependencies according to the first time. This
|
|
|
-also saves checksums that are verified on future fetches. Together,
|
|
|
-these behaviors ensure the reproducibility and integrity of the build.
|
|
|
-
|
|
|
-.. note::
|
|
|
-
|
|
|
- - You must use quotes around the URL. ``devtool add`` does not
|
|
|
- require the quotes, but the shell considers ";" as a splitter
|
|
|
- between multiple commands. Thus, without the quotes,
|
|
|
- ``devtool add`` does not receive the other parts, which results in
|
|
|
- several "command not found" errors.
|
|
|
-
|
|
|
- - In order to support adding Node.js modules, a ``nodejs`` recipe
|
|
|
- must be part of your SDK.
|
|
|
-
|
|
|
-As mentioned earlier, you can also add Node.js modules directly from a
|
|
|
-repository or local source tree. To add modules this way, use
|
|
|
-``devtool add`` in the following form::
|
|
|
-
|
|
|
- $ devtool add https://github.com/diversario/node-ssdp
|
|
|
-
|
|
|
-In this example, ``devtool`` fetches the specified Git repository, detects the
|
|
|
-code as Node.js code, fetches dependencies using ``npm``, and sets
|
|
|
-:term:`SRC_URI` accordingly.
|
|
|
-
|
|
|
-Working With Recipes
|
|
|
-====================
|
|
|
-
|
|
|
-When building a recipe using the ``devtool build`` command, the typical
|
|
|
-build progresses as follows:
|
|
|
-
|
|
|
-#. Fetch the source
|
|
|
-
|
|
|
-#. Unpack the source
|
|
|
-
|
|
|
-#. Configure the source
|
|
|
-
|
|
|
-#. Compile the source
|
|
|
-
|
|
|
-#. Install the build output
|
|
|
-
|
|
|
-#. Package the installed output
|
|
|
-
|
|
|
-For recipes in the workspace, fetching and unpacking is disabled as the
|
|
|
-source tree has already been prepared and is persistent. Each of these
|
|
|
-build steps is defined as a function (task), usually with a "do\_" prefix
|
|
|
-(e.g. :ref:`ref-tasks-fetch`,
|
|
|
-:ref:`ref-tasks-unpack`, and so
|
|
|
-forth). These functions are typically shell scripts but can instead be
|
|
|
-written in Python.
|
|
|
-
|
|
|
-If you look at the contents of a recipe, you will see that the recipe
|
|
|
-does not include complete instructions for building the software.
|
|
|
-Instead, common functionality is encapsulated in classes inherited with
|
|
|
-the ``inherit`` directive. This technique leaves the recipe to describe
|
|
|
-just the things that are specific to the software being built. There is
|
|
|
-a :ref:`ref-classes-base` class that is implicitly inherited by all recipes
|
|
|
-and provides the functionality that most recipes typically need.
|
|
|
-
|
|
|
-The remainder of this section presents information useful when working
|
|
|
-with recipes.
|
|
|
-
|
|
|
-Finding Logs and Work Files
|
|
|
----------------------------
|
|
|
-
|
|
|
-After the first run of the ``devtool build`` command, recipes that were
|
|
|
-previously created using the ``devtool add`` command or whose sources
|
|
|
-were modified using the ``devtool modify`` command contain symbolic
|
|
|
-links created within the source tree:
|
|
|
-
|
|
|
-- ``oe-logs``: This link points to the directory in which log files and
|
|
|
- run scripts for each build step are created.
|
|
|
-
|
|
|
-- ``oe-workdir``: This link points to the temporary work area for the
|
|
|
- recipe. The following locations under ``oe-workdir`` are particularly
|
|
|
- useful:
|
|
|
-
|
|
|
- - ``image/``: Contains all of the files installed during the
|
|
|
- :ref:`ref-tasks-install` stage.
|
|
|
- Within a recipe, this directory is referred to by the expression
|
|
|
- ``${``\ :term:`D`\ ``}``.
|
|
|
-
|
|
|
- - ``sysroot-destdir/``: Contains a subset of files installed within
|
|
|
- :ref:`ref-tasks-install` that have been put into the shared sysroot. For
|
|
|
- more information, see the
|
|
|
- ":ref:`dev-manual/new-recipe:sharing files between recipes`" section.
|
|
|
-
|
|
|
- - ``packages-split/``: Contains subdirectories for each package
|
|
|
- produced by the recipe. For more information, see the
|
|
|
- ":ref:`sdk-manual/extensible:packaging`" section.
|
|
|
-
|
|
|
-You can use these links to get more information on what is happening at
|
|
|
-each build step.
|
|
|
-
|
|
|
-Setting Configure Arguments
|
|
|
----------------------------
|
|
|
-
|
|
|
-If the software your recipe is building uses GNU autoconf, then a fixed
|
|
|
-set of arguments is passed to it to enable cross-compilation plus any
|
|
|
-extras specified by :term:`EXTRA_OECONF` or :term:`PACKAGECONFIG_CONFARGS`
|
|
|
-set within the recipe. If you wish to pass additional options, add them
|
|
|
-to :term:`EXTRA_OECONF` or :term:`PACKAGECONFIG_CONFARGS`. Other supported build
|
|
|
-tools have similar variables (e.g. :term:`EXTRA_OECMAKE` for CMake,
|
|
|
-:term:`EXTRA_OESCONS` for Scons, and so forth). If you need to pass anything on
|
|
|
-the ``make`` command line, you can use :term:`EXTRA_OEMAKE` or the
|
|
|
-:term:`PACKAGECONFIG_CONFARGS` variables to do so.
|
|
|
-
|
|
|
-You can use the ``devtool configure-help`` command to help you set the
|
|
|
-arguments listed in the previous paragraph. The command determines the
|
|
|
-exact options being passed, and shows them to you along with any custom
|
|
|
-arguments specified through :term:`EXTRA_OECONF` or
|
|
|
-:term:`PACKAGECONFIG_CONFARGS`. If applicable, the command also shows you
|
|
|
-the output of the configure script's "--help" option as a
|
|
|
-reference.
|
|
|
-
|
|
|
-Sharing Files Between Recipes
|
|
|
------------------------------
|
|
|
-
|
|
|
-Recipes often need to use files provided by other recipes on the
|
|
|
-:term:`Build Host`. For example,
|
|
|
-an application linking to a common library needs access to the library
|
|
|
-itself and its associated headers. The way this access is accomplished
|
|
|
-within the extensible SDK is through the sysroot. There is one sysroot per
|
|
|
-"machine" for which the SDK is being built. In practical terms, this
|
|
|
-means there is a sysroot for the target machine, and a sysroot for
|
|
|
-the build host.
|
|
|
-
|
|
|
-Recipes should never write files directly into the sysroot. Instead,
|
|
|
-files should be installed into standard locations during the
|
|
|
-:ref:`ref-tasks-install` task within the ``${``\ :term:`D`\ ``}`` directory. A
|
|
|
-subset of these files automatically goes into the sysroot. The reason
|
|
|
-for this limitation is that almost all files that go into the sysroot
|
|
|
-are cataloged in manifests in order to ensure they can be removed later
|
|
|
-when a recipe is modified or removed. Thus, the sysroot is able to
|
|
|
-remain free from stale files.
|
|
|
-
|
|
|
-Packaging
|
|
|
----------
|
|
|
-
|
|
|
-Packaging is not always particularly relevant within the extensible SDK.
|
|
|
-However, if you examine how build output gets into the final image on
|
|
|
-the target device, it is important to understand packaging because the
|
|
|
-contents of the image are expressed in terms of packages and not
|
|
|
-recipes.
|
|
|
-
|
|
|
-During the :ref:`ref-tasks-package` task, files installed during the
|
|
|
-:ref:`ref-tasks-install` task are split into one main package, which is almost
|
|
|
-always named the same as the recipe, and into several other packages. This
|
|
|
-separation exists because not all of those installed files are useful in every
|
|
|
-image. For example, you probably do not need any of the documentation installed
|
|
|
-in a production image. Consequently, for each recipe the documentation
|
|
|
-files are separated into a ``-doc`` package. Recipes that package
|
|
|
-software containing optional modules or plugins might undergo additional
|
|
|
-package splitting as well.
|
|
|
-
|
|
|
-After building a recipe, you can see where files have gone by looking in
|
|
|
-the ``oe-workdir/packages-split`` directory, which contains a
|
|
|
-subdirectory for each package. Apart from some advanced cases, the
|
|
|
-:term:`PACKAGES` and :term:`FILES` variables controls
|
|
|
-splitting. The :term:`PACKAGES` variable lists all of the packages to be
|
|
|
-produced, while the :term:`FILES` variable specifies which files to include
|
|
|
-in each package by using an override to specify the package. For
|
|
|
-example, ``FILES:${PN}`` specifies the files to go into the main package
|
|
|
-(i.e. the main package has the same name as the recipe and
|
|
|
-``${``\ :term:`PN`\ ``}`` evaluates to the
|
|
|
-recipe name). The order of the :term:`PACKAGES` value is significant. For
|
|
|
-each installed file, the first package whose :term:`FILES` value matches the
|
|
|
-file is the package into which the file goes. Both the :term:`PACKAGES` and
|
|
|
-:term:`FILES` variables have default values. Consequently, you might find
|
|
|
-you do not even need to set these variables in your recipe unless the
|
|
|
-software the recipe is building installs files into non-standard
|
|
|
-locations.
|
|
|
-
|
|
|
-Restoring the Target Device to its Original State
|
|
|
-=================================================
|
|
|
-
|
|
|
-If you use the ``devtool deploy-target`` command to write a recipe's
|
|
|
-build output to the target, and you are working on an existing component
|
|
|
-of the system, then you might find yourself in a situation where you
|
|
|
-need to restore the original files that existed prior to running the
|
|
|
-``devtool deploy-target`` command. Because the ``devtool deploy-target``
|
|
|
-command backs up any files it overwrites, you can use the
|
|
|
-``devtool undeploy-target`` command to restore those files and remove
|
|
|
-any other files the recipe deployed. Consider the following example::
|
|
|
-
|
|
|
- $ devtool undeploy-target lighttpd root@192.168.7.2
|
|
|
-
|
|
|
-If you have deployed
|
|
|
-multiple applications, you can remove them all using the "-a" option
|
|
|
-thus restoring the target device to its original state::
|
|
|
-
|
|
|
- $ devtool undeploy-target -a root@192.168.7.2
|
|
|
-
|
|
|
-Information about files deployed to
|
|
|
-the target as well as any backed up files are stored on the target
|
|
|
-itself. This storage, of course, requires some additional space on the
|
|
|
-target machine.
|
|
|
-
|
|
|
-.. note::
|
|
|
-
|
|
|
- The ``devtool deploy-target`` and ``devtool undeploy-target`` commands do
|
|
|
- not currently interact with any package management system on the target
|
|
|
- device (e.g. RPM or OPKG). Consequently, you should not intermingle
|
|
|
- ``devtool deploy-target`` and package manager operations on the target
|
|
|
- device. Doing so could result in a conflicting set of files.
|
|
|
+To learn how to use ``devtool`` to add, modify, upgrade recipes and more, see
|
|
|
+the :ref:`dev-manual/devtool:Using the \`\`devtool\`\` command-line tool`
|
|
|
+section of the Yocto Project Development Tasks Manual.
|
|
|
|
|
|
Installing Additional Items Into the Extensible SDK
|
|
|
===================================================
|