yocto-第7篇-开发工具devtool实操(helloyocto)

By: fu linux
E-mail: fulinux@sina.com
Blog: https://blog.csdn.net/fulinus
喜欢的盆友欢迎点赞和订阅!
你的喜欢就是我写作的动力!

返回总目录 Yocto开发讲解系列 - 总目录

devtool前言

做过 yocto 开发的朋友都有过这种认识,很多开源项目都是从其他网站下载或者git网站下载下来的,并放到了一个编译的中间目录里面,你去里面修改,然后编译搞不好就什么都没有了,白忙活了。自己打补丁又有很多不知道如何做的困扰。今天就给大家简单讲解下 devtool

devtool做什么的

devtool 命令行工具提供了许多功能,可帮助您构建,测试和打包软件,还可以使用该工具选择性地将构建后的文件集成到目标镜像中。该命令与 bitbake 命令一起使用。

devtool 命令使用了许多子命令,允许 add modify upgrade recipes 。使用 devtool add 时,会自动创建一个recipe。使用 devtool modify 时,将指定的现有 recipe 来确定从何处获取源代码以及如何对其进行修补。在这两种情况下,都会设置一个 workspace 目录环境,以便在构建recipe时知道构建的目录在哪里,以便根据需要对源代码进行更改。 devtool upgrade 命令更新现有的 recipe ,以便更新recipe的版本。

获取帮助

devtool 命令行的组织方式感觉与Git相似,因为每个功能都有许多子命令。您可以运行 devtool --help 来查看所有命令:

poky]$ source oe-init-build-env #执行一遍就可以,设计yocto的工具基本上都需要在source后
build]$ devtool -h
NOTE: Starting bitbake server...
usage: devtool [--basepath BASEPATH] [--bbpath BBPATH] [-d] [-q]
               [--color COLOR] [-h]
               <subcommand> ...

OpenEmbedded development tool

options:
  --basepath BASEPATH   Base directory of SDK / build directory
  --bbpath BBPATH       Explicitly specify the BBPATH, rather than getting it
                        from the metadata
  -d, --debug           Enable debug output
  -q, --quiet           Print only errors
  --color COLOR         Colorize output (where COLOR is auto, always, never)
  -h, --help            show this help message and exit

subcommands:
  Beginning work on a recipe:
    add                   Add a new recipe
    modify                Modify the source for an existing recipe
    upgrade               Upgrade an existing recipe
  Getting information:
    status                Show workspace status
    search                Search available recipes
    latest-version        Report the latest version of an existing recipe
    check-upgrade-status  Report upgradability for multiple (or all) recipes
  Working on a recipe in the workspace:
    build                 Build a recipe
    rename                Rename a recipe file in the workspace
    edit-recipe           Edit a recipe file
    find-recipe           Find a recipe file
    configure-help        Get help on configure script options
    update-recipe         Apply changes from external source tree to recipe
    reset                 Remove a recipe from your workspace
    finish                Finish working on a recipe in your workspace
  Testing changes on target:
    deploy-target         Deploy recipe output files to live target machine
    undeploy-target       Undeploy recipe output files in live target machine
    build-image           Build image including workspace recipe packages
  Advanced:
    create-workspace      Set up workspace in an alternative location
    menuconfig            Alter build-time configuration for a recipe
    extract               Extract the source for an existing recipe
    sync                  Synchronize the source tree for an existing recipe
    import                Import exported tar archive into workspace
    export                Export workspace into a tar archive
Use devtool <subcommand> --help to get help on a specific command
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

按照常规帮助输出中的指示,您可以通过提供命令名称并使用 --help 来获得特定命令的更多语法:

build]$ devtool add --help #和git命令很类似
NOTE: Starting bitbake server...
usage: devtool add [-h] [--same-dir | --no-same-dir] [--fetch URI] [--npm-dev]
                   [--version VERSION] [--no-git]
                   [--srcrev SRCREV | --autorev] [--srcbranch SRCBRANCH]
                   [--binary] [--also-native] [--src-subdir SUBDIR]
                   [--mirrors] [--provides PROVIDES]
                   [recipename] [srctree] [fetchuri]

Adds a new recipe to the workspace to build a specified source tree. Can
optionally fetch a remote URI and unpack it to create the source tree.

arguments:
  recipename            Name for new recipe to add (just name - no version,
                        path or extension). If not specified, will attempt to
                        auto-detect it.
  srctree               Path to external source tree. If not specified, a
                        subdirectory of
                        /home/peeta/poky/build/workspace/sources will be used.
  fetchuri              Fetch the specified URI and extract it to create the
                        source tree

options:
  -h, --help            show this help message and exit
  --same-dir, -s        Build in same directory as source
  --no-same-dir         Force build in a separate build directory
  --fetch URI, -f URI   Fetch the specified URI and extract it to create the
                        source tree (deprecated - pass as positional argument
                        instead)
  --npm-dev             For npm, also fetch devDependencies
  --version VERSION, -V VERSION
                        Version to use within recipe (PV)
  --no-git, -g          If fetching source, do not set up source tree as a git
                        repository
  --srcrev SRCREV, -S SRCREV
                        Source revision to fetch if fetching from an SCM such
                        as git (default latest)
  --autorev, -a         When fetching from a git repository, set SRCREV in the
                        recipe to a floating revision instead of fixed
  --srcbranch SRCBRANCH, -B SRCBRANCH
                        Branch in source repository if fetching from an SCM
                        such as git (default master)
  --binary, -b          Treat the source tree as something that should be
                        installed verbatim (no compilation, same directory
                        structure). Useful with binary packages e.g. RPMs.
  --also-native         Also add native variant (i.e. support building recipe
                        for the build host as well as the target machine)
  --src-subdir SUBDIR   Specify subdirectory within source tree to use
  --mirrors             Enable PREMIRRORS and MIRRORS for source tree fetching
                        (disable by default).
  --provides PROVIDES, -p PROVIDES
                        Specify an alias for the item provided by the recipe.
                        E.g. virtual/libgl
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

提一句,有个特殊的参数srctree外部源代码树的路径,如果这个没有特别指定,那么默认会在poky/build/workspace/sources目录下创建

workspace目录结构

devtool 使用一个 workspace 层来完成构建。该层并不特定于任何单个 devtool 命令,而是整个工具使用的公共工作区。
下图显示了工作空间结构:
在这里插入图片描述

 attic - A directory created if devtool believes it must preserve
         anything when you run "devtool reset".  For example, if you
         run "devtool add", make changes to the recipe, and then
         run "devtool reset", devtool takes notice that the file has
         been changed and moves it into the attic should you still
         want the recipe.
         当你运行“devtool reset”时,如果devtool认为它必须保留任何内容,它就会创建一个目录。
         例如,如果你运行“devtool add”,对recipe进行更改,然后运行“devtool reset”,
         devtool会注意到文件已经被更改,并将其移到attic中,如果你仍然想要recipe的话。

 README - Provides information on what is in workspace layer and how to
          manage it.

 .devtool_md5 - A checksum file used by devtool.

 appends - A directory that contains *.bbappend files, which point to
           external source. 一个包含*.bbappend文件的目录,用来给外部的源码打补丁的吧

 conf - A configuration directory that contains the layer.conf file.

 recipes - A directory containing recipes.  This directory contains a
           folder for each directory added whose name matches that of the
           added recipe.  devtool places the recipe.bb file
           within that sub-directory.
           一个包含recipes的目录。此目录包含为每个被添加的子recipe创建的子目录。
           devtool会在每个子目录下放bb文件(一个编译规则的文件)。

 sources - A directory containing a working copy of the source files used
           when building the recipe.  This is the default directory used
           as the location of the source tree when you do not provide a
           source tree path.  This directory contains a folder for each
           set of source files matched to a corresponding recipe.
           一个用来放置源码的目录,这是一个当你没有提供一个源码路径时,默认用来放置源码树的目录。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

新建helloyocto项目

我先在 /home/peeta/code 路径下创建一个 helloyocto 项目实例:

cd /home/peeta/code
mkdir helloyocto
helloyocto]$ vim main.c
  • 1
  • 2
  • 3
#include <stdio.h>

int main (int argc, char **argv)
{
    printf ("Hello Yocto!\n");
	printf ("I am helloyocto project\n");
	
    return 0;
} /* ----- End of main() ----- */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在创建一个 cmake 编译文件:

helloyocto]$ vim CMakeLists.txt
  • 1
project(helloyocto C)
cmake_minimum_required(VERSION 2.6.3)

add_executable (helloyocto main.c)

install(TARGETS helloyocto DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

创建一个build目录,先在这个目录里面手动编译,确保没问题。

helloyocto]$ mkdir build/
helloyocto]$ cd build/
build]$ cmake ..
-- The C compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/peeta/code/helloyocto/build
build]$ make
Scanning dependencies of target helloyocto
[ 50%] Building C object CMakeFiles/helloyocto.dir/main.c.o
[100%] Linking C executable helloyocto
[100%] Built target helloyocto
build]$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  helloyocto  Makefile
[build]$ ./helloyocto
Hello Yocto!
I am helloyocto project
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

验证没有问题后删除上面创建的build目录:

helloyocto]$ rm -rf build/
  • 1

用devtool添加项目

按照上面的说法,使用 devtool add 命令将新recipe添加到workspace工作区层。添加的 recipe 不应该存在,因为 devtool 会创建它。 recipe 使用的源文件应存在于外部区域的目录,比如这里的 /home/peeta/code/helloyocto
下面add一个名为 helloyocto 的新 recipe ,即 recipe 的源代码位于 /home/peeta/code/helloyocto

build]$ devtool add helloyocto /home/peeta/code/helloyocto
NOTE: Starting bitbake server...
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
NOTE: Reconnecting to bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
NOTE: Retrying server connection (#1)...
NOTE: Starting bitbake server...
INFO: Recipe /home/peeta/poky/build/workspace/recipes/helloyocto/helloyocto.bb has been automatically created; further editing may be required to make it fully functional
build]$ ls workspace/
appends  conf  README  recipes  sources
build]$ cat workspace/recipes/helloyocto/helloyocto.bb
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# Unable to find any files that looked like license statements. Check the accompanying
# documentation and source headers and set LICENSE and LIC_FILES_CHKSUM accordingly.
#
# NOTE: LICENSE is being set to "CLOSED" to allow you to at least start building - if
# this is not accurate with respect to the licensing of the software being built (it
# will not be in most cases) you must specify the correct value before using this
# recipe for anything other than initial testing/development!
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""

# No information for SRC_URI yet (only an external source tree was specified)
SRC_URI = ""

inherit cmake  #这里它好像知道我这个是cmake项目

# Specify any options you want to pass to cmake using EXTRA_OECMAKE:
EXTRA_OECMAKE = ""
build]$ cat workspace/appends/helloyocto.bbappend 
inherit externalsrc
EXTERNALSRC = "/home/peeta/code/helloyocto"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

如果在 workspace 不存时添加 recipe ,该命令就会创建workspace(或者layer层 )目录,并且是按照 workspace目录结构 部分中的说明进行创建。
workspace目录 已经存在时运行 devtool add 会添加 recipe append文件 源文件 添加到现有 workspace目录 中。创建 .bbappend 文件以指向外部源代码路径。

注意:如果您的recipe定义了运行时依赖关系,则在尝试运行应用程序之前,必须确保这些软件包已存在于目标硬件上。如果目标程序运行依赖的库在机器上不存在,则您的应用程序在运行时将因为找不到相应的函数而不能正常运行。有关更多信息,请参见“在目标计算机上部署软件(见后续)”一节。

编译新加的recipe

使用 devtool build 命令来构建我们的 recipe (即 helloyocto )。 devtool build 命令类似于 bitbake 命令。
使用 devtool build 命令时,必须使用 recipe 的根名称(这里就是 helloyocto )(即不包含版本,路径或扩展名)。我们可以在构建期间使用“ -s ”或“ --disable-parallel-make” 选项来禁用并行build(编译)。如下我们编译 helloyocto

build]$ devtool build helloyocto
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |#####################################################################################| Time: 0:00:00
Loaded 1321 entries from dependency cache.
Parsing recipes: 100% |###################################################################################| Time: 0:00:00
Parsing of 781 .bb files complete (779 cached, 2 parsed). 1322 targets, 46 skipped, 0 masked, 0 errors.
Removing 1 recipes from the core2-64 sysroot: 100% |######################################################| Time: 0:00:17
Removing 1 recipes from the qemux86_64 sysroot: 100% |####################################################| Time: 0:00:00
Loading cache: 100% |#####################################################################################| Time: 0:00:00
Loaded 1321 entries from dependency cache.
Parsing recipes: 100% |###################################################################################| Time: 0:00:00
Parsing of 781 .bb files complete (779 cached, 2 parsed). 1322 targets, 46 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.46.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "x86_64-poky-linux"
MACHINE              = "qemux86-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1.2"
TUNE_FEATURES        = "m64 core2"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "my-yocto-3.1.2:569b1f5d67c57de957e243997c53ec2f81dc8dfe"
meta-altera          = "master:aa24dfcb39fce3619a87ee6eef6e4296e66d2099"
meta-mylayer         
workspace            = "my-yocto-3.1.2:569b1f5d67c57de957e243997c53ec2f81dc8dfe"

Initialising tasks: 100% |################################################################################| Time: 0:00:00
Sstate summary: Wanted 0 Found 0 Missed 0 Current 132 (0% match, 100% complete)
NOTE: Executing Tasks
NOTE: helloyocto: compiling from external source tree /home/peeta/code/helloyocto
NOTE: Tasks Summary: Attempted 568 tasks of which 559 didn't need to be rerun and all succeeded.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

参考devtool编译后的结果

比起以往的版本,需要深入一个很深的目录才能看到编译的中间文件和最终的执行文件或者库等,但是这个直接在我们的源码目录中创建了两个符号链接,请看下面:

helloyocto]$ ls -l
总用量 20
drwxrwxr-x 3 peeta peeta 4096 1017 19:07 build
-rw-r--r-- 1 peeta peeta  165 1017 19:07 CMakeLists.txt
-rw-rw-r-- 1 peeta peeta  135 1017 16:05 main.c
lrwxrwxrwx 1 peeta peeta   74 1017 19:46 oe-logs -> /home/peeta/poky/build/tmp/work/core2-64-poky-linux/helloyocto/1.0-r0/temp
lrwxrwxrwx 1 peeta peeta   69 1017 19:46 oe-workdir -> /home/peeta/poky/build/tmp/work/core2-64-poky-linux/helloyocto/1.0-r0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

总体上感觉很轻松,没有太多需要手动编辑bb文件的步骤,我想这点对于初学者而言是很轻松的。当然与我们创建的项目比较简单的缘故有关。

倘若,该项目不需要做修改,完成了既定目标,并想将其集成到我们的 meta-mylayer 中去。我试了下这种源码在 poky 目录之外的 非git 项目,不能使用 devtool finish 命令来集成 recipe 。我自能采用手动方式集成了,参考如下过程:

poky]$ cd meta-mylayer/
meta-mylayer]$ mkdir recipes-myapps/ #新建这个目录用来放置自己的一些applications
recipes-myapps]$ mkdir helloyocto/ #新建一个应用的目录,用来放源码和bb文件,这个层级是conf/layer.conf规定的
recipes-myapps]$ cd helloyocto/
helloyocto]$ cp /home/peeta/code/helloyocto . -rf #将源码复制进来
helloyocto]$ cp ../../../build/workspace/recipes/helloyocto/helloyocto.bb . #devtool add生成的bb文件复制到当前目录
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

当前目录的拓扑结构如下:

meta-mylayer]$ tree recipes-myapps/
recipes-myapps/
└── helloyocto
    ├── helloyocto
    │   ├── CMakeLists.txt
    │   └── main.c
    └── helloyocto.bb

2 directories, 3 files
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

修改下bb文件,将源码新的路径加上:

recipes-myapps]$ cat helloyocto.bb                       
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# Unable to find any files that looked like license statements. Check the accompanying
# documentation and source headers and set LICENSE and LIC_FILES_CHKSUM accordingly.
#
# NOTE: LICENSE is being set to "CLOSED" to allow you to at least start building - if
# this is not accurate with respect to the licensing of the software being built (it
# will not be in most cases) you must specify the correct value before using this
# recipe for anything other than initial testing/development!
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""

# No information for SRC_URI yet (only an external source tree was specified)
SRC_URI = ""

inherit externalsrc #添加了这个,来源helloyocto.bbappend,继承源码在外部的类
EXTERNALSRC = "${THISDIR}/helloyocto" #添加了这个,来源helloyocto.bbappend,并做了修改

inherit cmake

# Specify any options you want to pass to cmake using EXTRA_OECMAKE:
EXTRA_OECMAKE = ""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

如何删除workspace目录中的recipe

完成上面这些,我们需要删除 workspace 目录中的 helloyocto ,参考如下:

build]$ devtool reset helloyocto
  • 1

这个 devtool reset 命令可以从 workspace 目录中删除指定的 recipe 。看下workspace目录下:

build]$ ls workspace/recipes/
#空的,已经没有helloyocto.bb文件了
  • 1
  • 2

此时,我们使用 bitbake 命令来验证下:

build]$ bitbake helloyocto
...
Initialising tasks: 100% |########################################################################| Time: 0:00:00
Sstate summary: Wanted 0 Found 0 Missed 0 Current 128 (0% match, 100% complete)
NOTE: Executing Tasks
NOTE: helloyocto: compiling from external source tree /home/peeta/poky/meta-mylayer/recipes-myapps/helloyocto/helloyocto
NOTE: Tasks Summary: Attempted 540 tasks of which 527 didn't need to be rerun and all succeeded.

Summary: There was 1 WARNING message shown.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

后记:
用devtool finish命令不能添加这个源代码在poky目录之外又不是git的recipe,如下:

build]$ devtool finish helloyocto meta-mylayer
NOTE: Starting bitbake server...
WARNING: Layer meta-mybsp should set LAYERSERIES_COMPAT_meta-mybsp in its conf/layer.conf file to list the core layer names it is compatible with.
Traceback (most recent call last):
  File "/home/peeta/poky/scripts/devtool", line 334, in <module>
    ret = main()
  File "/home/peeta/poky/scripts/devtool", line 321, in main
    ret = args.func(args, config, basepath, workspace)
  File "/home/peeta/poky/scripts/lib/devtool/standard.py", line 2035, in finish
    check_git_repo_op(srctree, [corebasedir])
  File "/home/peeta/poky/scripts/lib/devtool/__init__.py", line 371, in check_git_repo_op
    stdout, _ = bb.process.run('git rev-parse --show-toplevel', cwd=srctree)
  File "/home/peeta/poky/bitbake/lib/bb/process.py", line 184, in run
    raise ExecutionError(cmd, pipe.returncode, stdout, stderr)
bb.process.ExecutionError: Execution of 'git rev-parse --show-toplevel' failed with exit code 128:
fatal: Not a git repository (or any of the parent directories): .git
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

希望帮我点个赞加关注,你的喜欢就是我持续更新的动力!