| .. SPDX-License-Identifier: CC-BY-SA-2.0-UK |
| |
| Using the ``devtool`` command-line tool |
| *************************************** |
| |
| The ``devtool`` command-line tool provides a number of features that |
| help you build, test, and package software. This command is available |
| alongside the ``bitbake`` command. Additionally, the ``devtool`` command |
| is a key part of the :term:`Extensible Software Development Kit (eSDK)`. |
| |
| 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/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/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/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 an :ref:`SDK |
| <overview-manual/concepts:Application Development 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 |
| ---------------------- |
| |
| .. warning:: |
| |
| The NPM fetcher is currently disabled due to security concerns. See |
| :bitbake_rev:`355cd226e0720a9ed7683bb01c8c0a58eee03664` for more information. |
| |
| 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. |
| |
| 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:`dev-manual/devtool: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 |
| is through the :term:`Sysroot`. 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 |
| --------- |
| |
| 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. |