Slides Yocto
Slides Yocto
Slides Yocto
Sergio Prado
https://www.linkedin.com/in/sprado
SOBRE ESTE DOCUMENTO
Slides do treinamento de Yocto Project v1.1.1.
A versão mais atual dos slides está disponível no site da Embedded Labworks.
https://e-labworks.com/training/ypr/slides
https://creativecommons.org/licenses/by-sa/4.0/
SOBRE O INSTRUTOR
Mais de 25 anos de experiência em desenvolvimento de software para sistemas
embarcados, atuando principalmente em projetos com Linux embarcado, Android
embarcado e sistemas operacionais de tempo real.
https://e-labworks.com
https://sergioprado.blog
Programação em C/C++.
AMBIENTE DE LABORATÓRIO
$ tree -L 2 /opt/labs/
/opt/labs/
├── dl
| ...
├── docs
│ ├── agenda.html
│ ├── answers.html
│ ├── install.html
│ ├── labs.html
│ ├── slides.pdf
│ └── version.txt
├── ex
│ ├── downloads
│ └── sstate-cache
└── tools
├── build.conf
├── build.sh
├── layers.conf
├── prepare.cfg
└── prepare.sh
DURANTE O TREINAMENTO
Pergunte...
Troque experiências...
Ajude...
Participe!
YOCTO PROJECT
https://www.mvista.com/products
https://www.linuxfromscratch.org/
SOLUÇÃO 3: SISTEMAS DE BUILD
Um sistema de build permite gerar um sistema Linux completo e customizado para a
plataforma alvo.
https://www.buildroot.org
https://www.ptxdist.org
https://openwrt.org
https://www.openembedded.org
O QUE É O YOCTO PROJECT?
Projeto colaborativo que provê um conjunto de ferramentas para auxiliar na criação
de distribuições Linux customizadas para dispositivos embarcados.
https://www.yoctoproject.org
BitBake
Poky
Matchbox
AutoBuilder
Toaster
https://www.yoctoproject.org/software-overview/project-components/
O QUE O YOCTO PROJECT NÃO É?
O Yocto Project não é uma ferramenta ou um sistema de build.
É um projeto "guarda-chuva" que engloba diversas ferramentas e projetos open-
source com o objetivo de construir distribuições Linux para dispositivos
embarcados.
https://wiki.yoctoproject.org/wiki/Planning#Yocto
Espera-se que um novo release do Yocto Project seja liberado a cada 6 meses
(normalmente em abril e outubro).
https://wiki.yoctoproject.org/wiki/Releases
Patches para corrigir bug críticos e falhas de segurança são aplicados também em
uma versão anterior e em versões LTS.
https://git.yoctoproject.org/poky
https://docs.yoctoproject.org/
https://docs.yoctoproject.org/overview-manual/index.html
https://docs.yoctoproject.org/brief-yoctoprojectqs/index.html
Manual de referência:
https://docs.yoctoproject.org/ref-manual/index.html
DOCUMENTAÇÃO (CONT.)
Manual de desenvolvimento do Yocto Project:
https://docs.yoctoproject.org/dev-manual/index.html
https://docs.yoctoproject.org/bsp-guide/index.html
https://docs.yoctoproject.org/kernel-dev/index.html
DOCUMENTAÇÃO (CONT.)
Manual de desenvolvimento de aplicações (SDK):
https://docs.yoctoproject.org/sdk-manual/index.html
Documentação do BitBake:
https://docs.yoctoproject.org/bitbake.html
INTRODUÇÃO AO POKY
POKY
A comunidade do Yocto Project é responsável por manter diversos projetos, dentre
eles o Poky.
Nesta seção do treinamento, teremos uma breve introdução sobre como utilizar o
Poky para construir uma distribuição Linux customizada.
PREPARANDO A MÁQUINA DE BUILD
É recomendado o uso de uma máquina GNU/Linux com uma das seguintes
distribuições: Fedora, openSUSE, CentOS, Debian ou Ubuntu.
É necessário uma máquina com boa capacidade de processamento (ex: Intel Core i7),
com bastante memória (16Gb+) e espaço em disco (100Gb+).
Alguns pré-requisitos de software: gcc 5.0+, git 1.8.3.1+, python 3.6+, tar 1.28+, make.
https://docs.yoctoproject.org/dev-manual/start.html#preparing-the-build-host
BAIXANDO O POKY
O repositório do Poky é versionado com o Git e pode ser clonado conforme abaixo:
$ git clone git://git.yoctoproject.org/poky.git
Este comando irá clonar o branch master do Poky, não recomendado por ser um
branch de desenvolvimento do projeto.
Este script irá configurar o ambiente de compilação no terminal atual, criando por
padrão um diretório chamado build com os arquivos de configuração necessários
para realizar a compilação.
build/
└── conf
├── bblayers.conf
├── local.conf
└── templateconf.cfg
O DIRETÓRIO DE BUILD (CONT.)
Por padrão, todo o processo de compilação irá acontecer dentro do diretório de
build.
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/opt/labs/ex/layers/poky/meta \
/opt/labs/ex/layers/poky/meta-poky \
/opt/labs/ex/layers/poky/meta-yocto-bsp \
"
LOCAL.CONF
# Machine Selection
DL_DIR ?= "${TOPDIR}/downloads"
SSTATE_DIR ?= "${TOPDIR}/sstate-cache"
TMPDIR = "${TOPDIR}/tmp"
DISTRO ?= "poky"
PACKAGE_CLASSES ?= "package_rpm"
...
VARIÁVEIS NO LOCAL.CONF
Variável Descrição
MACHINE Nome da plataforma alvo
DISTRO Nome da distribuição
DL_DIR Diretório de downloads
SSTATE_DIR Diretório para armazenar os caches de compilação
TMPDIR Diretório de compilação
PACKAGE_CLASSES Formato de empacotamento (rpm, deb, ipk)
CORE_IMAGE_EXTRA_INSTALL Pacotes adicionais para instalar na imagem
EXTRA_IMAGE_FEATURES Funcionalidades de imagem que deseja-se habilitar
COMPILANDO A IMAGEM
Com os arquivos bblayers.conf e local.conf configurados, é só iniciar o processo de
compilação:
$ bitbake core-image-minimal
build-appliance-image core-image-minimal-initramfs.bb
build-appliance-image_15.0.0.bb core-image-minimal-mtdutils.bb
core-image-base.bb core-image-ptest-all.bb
core-image-minimal.bb core-image-ptest-fast.bb
core-image-minimal-dev.bb core-image-tiny-initramfs.bb
DIRETÓRIO DE SAÍDA
Todo o processo de build acontecerá no diretório apontado pela variável TMPDIR
(por padrão tmp):
$ tree -L 1 tmp/
tmp/
├── abi_version
├── buildstats
├── cache
├── deploy
├── hosttools
├── log
├── pkgdata
├── saved_tmpdir
├── sstate-control
├── stamps
├── sysroots-components
├── sysroots-uninative
├── work
└── work-shared
IMAGENS GERADAS
As imagens geradas estarão disponíveis em tmp/deploy/images/<machine>/:
$ ls tmp/deploy/images/qemuarm/
core-image-minimal-qemuarm-20220627125439.qemuboot.conf
core-image-minimal-qemuarm-20220627125439.rootfs.ext4
core-image-minimal-qemuarm-20220627125439.rootfs.manifest
core-image-minimal-qemuarm-20220627125439.rootfs.tar.bz2
core-image-minimal-qemuarm-20220627125439.testdata.json
core-image-minimal-qemuarm.ext4
core-image-minimal-qemuarm.manifest
core-image-minimal-qemuarm.qemuboot.conf
core-image-minimal-qemuarm.tar.bz2
core-image-minimal-qemuarm.testdata.json
modules--5.15.44+git0+947149960e_1585df4dbb-r0-qemuarm-20220627103615.tgz
modules-qemuarm.tgz
zImage
zImage--5.15.44+git0+947149960e_1585df4dbb-r0-qemuarm-20220627103615.bin
zImage-qemuarm.bin
QEMU
O QEMU é um emulador e visualizador de hardware open source que suporta
diversas arquiteturas, incluindo x86, ARM, MIPS e PowerPC.
https://www.qemu.org/
Classes (.bbclass).
Possuem este nome por que contém a "receita" para processar determinado
componente de software.
Uma lista das principais variáveis que podem ser utilizadas para descrever uma
receita está disponível no guia de referência do Yocto Project.
https://docs.yoctoproject.org/ref-manual/varlocality.html#recipes
ARQUIVOS DE APPEND
Arquivos do tipo append possuem a extensão .bbappend e possibilitam modificar o
comportamento de uma receita sem alterar sua implementação.
Para cada arquivo do tipo append deve-se ter uma receita correspondente.
Veja o guia de referência do Yocto Project para uma lista das classes existentes.
https://docs.yoctoproject.org/ref-manual/classes.html
ARQUIVOS DE CONFIGURAÇÃO
Arquivos de configuração possuem a extensão .conf e contém a definição de variáveis
que parametrizam o sistema de build.
https://docs.yoctoproject.org/ref-manual/varlocality.html#configuration
CAMADAS
Os metadados (receitas, classes e arquivos de configuração) são organizados em
camadas (layers) no sistema de build.
poky/
├── bitbake
├── contrib
├── documentation
├── LICENSE
├── LICENSE.GPL-2.0-only
├── LICENSE.MIT
├── MAINTAINERS.md
├── Makefile
├── MEMORIAM
├── meta
├── meta-poky
├── meta-selftest
├── meta-skeleton
├── meta-yocto-bsp
├── oe-init-build-env
├── README.OE-Core.md
├── README.qemu.md
└── scripts
TIPOS DE CAMADAS
Podemos classificar as camadas em três tipos, que podem ser combinadas para
gerar a imagem de um sistema Linux:
Camada de BSP (Board Support Package).
https://docs.yoctoproject.org/bsp-guide/bsp.html
META-YOCTO-BSP
$ tree meta-yocto-bsp/
meta-yocto-bsp/
├── conf
│ ├── layer.conf
│ └── machine
│ ├── beaglebone-yocto.conf
│ ├── edgerouter.conf
│ ├── genericx86-64.conf
│ ├── genericx86.conf
│ └── include
...
├── recipes-bsp
│ ├── formfactor
│ └── gma500-gfx-check
├── recipes-graphics
│ └── xorg-xserver
├── recipes-kernel
│ └── linux
└── wic
├── beaglebone-yocto.wks
├── edgerouter.wks
└── genericx86.wks.in
META-RASPBERRYPI
$ tree meta-raspberrypi/
meta-raspberrypi/
├── classes
├── conf
│ ├── layer.conf
│ └── machine
│ ...
│ ├── raspberrypi3-64.conf
│ ├── raspberrypi3.conf
│ ├── raspberrypi4-64.conf
│ ├── raspberrypi4.conf
│ ├── raspberrypi-cm3.conf
│ ├── raspberrypi-cm.conf
│ └── raspberrypi.conf
...
├── recipes-connectivity
├── recipes-core
├── recipes-devtools
├── recipes-graphics
├── recipes-kernel
├── recipes-multimedia
├── recipes-sato
└── wic
CAMADA DE DISTRO
A camada de distribuição define algumas regras para a geração da imagem do
sistema operacional, incluindo:
Toolchain para compilar a distribuição.
https://docs.yoctoproject.org/ref-manual/varlocality.html#distribution-distro
META-POKY
$ tree meta-poky/
meta-poky/
├── classes
├── conf
├── README.poky.md
└── recipes-core
├── busybox
...
META-LUNEOS
$ tree meta-luneos/
meta-luneos/
├── classes
├── conf
│ ├── distro
│ │ ├── include
│ │ └── luneos.conf
│ └── layer.conf
├── COPYING.MIT
├── lib
├── licenses
├── README
├── recipes-android
├── recipes-benchmark
├── recipes-connectivity
├── recipes-containers
├── recipes-core
├── recipes-devtools
├── recipes-extended
├── recipes-graphics
├── recipes-kernel
├── recipes-luneos
...
CAMADA DE SOFTWARE
As camadas de software fornecem receitas adicionais para compor a imagem que
será gerada.
meta
├── classes
├── conf
├── COPYING.MIT
├── files
├── lib
├── recipes-bsp
├── recipes-connectivity
├── recipes-core
├── recipes-devtools
├── recipes-example
├── recipes-extended
├── recipes-gnome
├── recipes-graphics
├── recipes-kernel
├── recipes-multimedia
├── recipes-rt
├── recipes-sato
├── recipes-support
├── recipes.txt
└── site
META-QT5
$ tree -L 2 meta-qt5/
meta-qt5/
├── classes
├── conf
...
└── recipes-qt
├── demo-extrafiles
├── examples
├── maliit
├── meta
├── packagegroups
├── qmllive
├── qsiv
├── qt5
├── qtchooser
...
BANCO DE DADOS DE CAMADAS
O Yocto Project mantém uma lista seleta de camadas suportadas oficialmente pelo
projeto.
https://www.yoctoproject.org/software-overview/layers/
https://layers.openembedded.org/layerindex/branch/master/layers/
Quando a tarefa não é indicada no comando, o BitBake executa a tarefa build, que
depende de todas as outras tarefas "normais" necessárias para processar a receita.
$ bitbake -c build busybox
EXECUTANDO TAREFAS
Para executar apenas uma tarefa de uma receita, use a opção -c:
$ bitbake -c fetch busybox
A opção -k faz com que o bitbake continue executando as tarefas, mesmo em caso de
erro, até onde puder executar.
$ bitbake -k busybox
Qual então o procedimento utilizado pelo BitBake para ler os metadados definidos
nas camadas, transformá-los em tarefas e executá-las, até que as imagens do sistema
operacional sejam geradas?
Todo o processo de leitura dos metadados pode ser visualizado com o parâmetro -e
do BitBake.
INCLUDE HISTORY
$ bitbake -e
# INCLUDE HISTORY:
# /opt/labs/ex/build-qemu/conf/bblayers.conf
# /opt/labs/ex/layers/poky/meta/conf/layer.conf
# /opt/labs/ex/layers/poky/meta-poky/conf/layer.conf
# /opt/labs/ex/layers/poky/meta-yocto-bsp/conf/layer.conf
# conf/bitbake.conf includes:
# /opt/labs/ex/layers/poky/meta/conf/abi_version.conf
# conf/site.conf
# conf/auto.conf
# /opt/labs/ex/build-qemu/conf/local.conf
# /opt/labs/ex/layers/poky/meta/conf/multiconfig/default.conf
# /opt/labs/ex/layers/poky/meta/conf/machine/qemuarm.conf includes:
# /opt/labs/ex/layers/poky/meta/conf/machine/include/arm/armv7a/tune-cortexa15.inc includes:
# /opt/labs/ex/layers/poky/meta/conf/machine/include/arm/arch-armv7ve.inc includes:
# /opt/labs/ex/layers/poky/meta/conf/machine/include/arm/arch-armv7a.inc includes:
# /opt/labs/ex/layers/poky/meta/conf/machine/include/arm/arch-armv6.inc includes:
# /opt/labs/ex/layers/poky/meta/conf/machine/include/arm/arch-armv5-dsp.inc includes:
# /opt/labs/ex/layers/poky/meta/conf/machine/include/arm/arch-armv5.inc includes:
# /opt/labs/ex/layers/poky/meta/conf/machine/include/arm/arch-armv4.inc includes:
...
PROCESSANDO A RECEITA
Durante a leitura dos arquivos de configuração, a variável BBFILES será populada
com as receitas e arquivos de append existentes nas camadas habilitadas.
As receitas e arquivos de append serão lidos, um a um, e uma lista de tarefas será
definida para cada receita, incluindo as dependências entre elas.
https://docs.yoctoproject.org/bitbake/index.html
GRÁFICO DE DEPENDÊNCIAS
O BitBake é capaz de gerar um gráfico de dependências no formato dot com o
parâmetro -g.
$ bitbake -g core-image-minimal
$ ls *.dot
task-depends.dot
O arquivo gerado pode ser convertido em uma imagem ou aberto diretamente com
um leitor de arquivos dot:
$ dot -Tps task-depends.dot -o task-depends.ps
$ xdot task-depends.dot
CAMADAS
CAMADAS
O OpenEmbedded/Yocto Project suporta a organização dos metadados em camadas
(layers).
https://layers.openembedded.org/layerindex/branch/master/layers/
ORGANIZAÇÃO DAS CAMADAS
As camadas são organizadas em diretórios no sistema de build.
O diretório da camada pode ter qualquer nome, porém o padrão adotado é iniciar
com meta.
Uma distribuição construída com o Yocto Project irá utilizar as camadas do Poky,
além de outras camadas providas pela comunidade e camadas específicas do
projeto.
CRIANDO UMA CAMADA
Primeiro crie um diretório para a camada:
$ mkdir meta-labworks
$ mkdir conf
$ vim conf/layer.conf
BBFILES += " \
${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend \
"
BBFILE_COLLECTIONS += "meta-labworks"
BBFILE_PATTERN_meta-labworks = "^${LAYERDIR}/"
BBFILE_PRIORITY_meta-labworks = "6"
LAYERVERSION_meta-labworks = "1"
LAYERDEPENDS_meta-labworks = "core"
LAYERSERIES_COMPAT_meta-labworks = "kirkstone"
EXPLICANDO O LAYER.CONF
A variável BBPATH deve ser definida para que o BitBake possa encontrar arquivos na
camada (arquivos de configuração, classes, outros arquivos incluídos com as
diretivas include e require, etc).
BBPATH .= ":${LAYERDIR}"
${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend \
"
meta-labworks/
├── conf
│ └── layer.conf
├── COPYING.MIT
└── README
HABILITANDO A CAMADA
Para habilitar a camada, basta adicioná-la à variável BBLAYERS no arquivo
conf/bblayers.conf:
BBLAYERS ?= " \
/home/sprado/yocto/poky/meta \
/home/sprado/yocto/poky/meta-yocto \
/home/sprado/yocto/poky/meta-yocto-bsp \
/home/sprado/yocto/poky/meta-labworks \
"
BITBAKE-LAYERS
$ bitbake-layers -h
usage: bitbake-layers [-d] [-q] [-F] [--color COLOR] [-h] <subcommand> ...
...
subcommands:
<subcommand>
show-overlayed list overlayed recipes (where the same recipe exists in another layer)
show-recipes list available recipes, showing the layer they are provided by
layerindex-fetch Fetches a layer from a layer index along with its dependent layers
layerindex-show-depends
==========================================================================
meta /opt/labs/ex/layers/poky/meta 5
meta-poky /opt/labs/ex/layers/poky/meta-poky 5
meta-yocto-bsp /opt/labs/ex/layers/poky/meta-yocto-bsp 5
BITBAKE-LAYERS: CRIANDO CAMADAS
$ bitbake-layers create-layer --priority 10 ../layers/meta-labworks
$ tree ../layers/meta-labworks/
../layers/meta-labworks/
├── conf
│ └── layer.conf
├── COPYING.MIT
├── README
└── recipes-example
└── example
└── example_0.1.bb
$ bitbake-layers show-layers
==========================================================================
meta /opt/labs/ex/layers/poky/meta 5
meta-poky /opt/labs/ex/layers/poky/meta-poky 5
meta-yocto-bsp /opt/labs/ex/layers/poky/meta-yocto-bsp 5
meta-labworks /opt/labs/ex/layers/meta-labworks 10
DYNAMIC LAYERS
Para utilizar uma camada com metadados que dependem de outra camada
(arquivos de configuração, receitas de append, etc), é necessário baixar todas as
dependências para a camada funcionar.
Por exemplo, o usuário de uma camada de BSP que contém receitas de append
de aplicações gráficas precisará baixar a camada que contém as receitas de
aplicações gráficas, mesmo que sua distribuição não utilize estas aplicações.
Neste caso, a funcionalidade de dynamic layers pode ser utilizada para habilitar o
processamento condicional de metadados.
meta-oe/dynamic-layers/meta-python/recipes-core
└── packagegroups
└── packagegroup-meta-oe.bbappend
$ tree -L 2 meta-oe/dynamic-layers/perl-layer/recipes-core/
meta-oe/dynamic-layers/perl-layer/recipes-core/
└── packagegroups
└── packagegroup-meta-oe.bbappend
# meta-oe/conf/layer.conf
...
BBFILES_DYNAMIC += " \
meta-python:${LAYERDIR}/dynamic-layers/meta-python/recipes-*/*/*.bb \
perl-layer:${LAYERDIR}/dynamic-layers/perl-layer/recipes-*/*/*.bb \
"
...
PROGRAMA DE COMPATIBILIDADE
Ao criar uma camada para ser utilizada com o Yocto Project, é vantajoso garantir que
esta camada seja compatível com os padrões do projeto:
Garante uma qualidade mínima aceitável pela comunidade, incluindo
interoperabilidade com outras camadas.
Mais informações sobre este processo no site do projeto em Making Sure Your Layer
is Compatible With Yocto Project.
YOCTO-CHECK-LAYER
$ yocto-check-layer --without-software-layer-signature-check meta-labworks/
INFO:
INFO: ----------------------------------------------------------------------
INFO: ... ok
INFO: ... ok
...
INFO: OK
INFO: (skipped=3)
INFO:
INFO:
CRIANDO CAMADAS
YOCTO PROJECT
INTRODUÇÃO ÀS RECEITAS
RECEITAS
Receitas (recipes) são arquivos com extensão .bb, processados pela ferramenta
BitBake para gerar os diversos componentes de software do sistema.
libpng_1.6.37.bb
mmc-utils_git.bb
Para processar uma receita, basta usar a primeira parte do seu nome:
$ bitbake libdrm
PACOTES
O resultado do processamento de uma receita são pacotes (packages).
O Yocto Project suporta três tipos de empacotamento: ipk, deb e rpm.
https://layers.openembedded.org/layerindex/branch/kirkstone/recipes/
busybox:
meta 1.35.0
Caso precise criar uma nova receita, outras receitas podem ser utilizadas como
ponto de partida.
DESCRIPTION = "setserial is a program designed to set and/or report the configuration information ass
HOMEPAGE = "http://setserial.sourceforge.net"
SECTION = "console/utils"
LICENSE = "GPLv2.0"
LIC_FILES_CHKSUM = "file://version.h;beginline=1;endline=6;md5=2e7c59cb9e57e356ae81f50f4e4dfd99"
PR = "r3"
DEPENDS += "groff-native"
inherit autotools-brokensep
SRC_URI = "${SOURCEFORGE_MIRROR}/setserial/${BPN}-${PV}.tar.gz \
file://add_stdlib.patch \
file://ldflags.patch \
"
SRC_URI[md5sum] = "c4867d72c41564318e0107745eb7a0f2"
SRC_URI[sha256sum] = "7e4487d320ac31558563424189435d396ddf77953bb23111a17a3d1487b5794a"
do_install() {
install -d ${D}${bindir}
TAREFAS
Tarefa (task) é uma etapa no processamento de uma receita (baixar o código-fonte,
aplicar patches, configurar, compilar, etc).
As tarefas podem ser definidas dentro do arquivo da receita e/ou herdadas através
de uma classe.
Por padrão, todas as receitas herdam automaticamente algumas classes durante seu
processamento, incluindo a classe base.bbclass.
LICENSE = "CLOSED"
...
do_build Default task for a recipe - depends on all other normal tasks
do_checkuri Validates the SRC_URI value
do_cleanall Removes all output files, shared state cache, and downloaded so
do_cleansstate Removes all output files and shared state cache for a target
do_package Analyzes the content of the holding area and splits it into sub
do_package_qa Runs QA checks on packaged files
do_package_setscene Analyzes the content of the holding area and splits it into sub
do_package_write_rpm Creates the actual RPM packages and places them in the Package
do package write rpm setscene Creates the actual RPM packages and places them in the Package
HERDANDO CLASSES
As tarefas de uma receita podem ser alteradas, substituídas ou extendidas através de
classes (arquivos com extensão .bbclass).
As classes definem tarefas comuns que podem ser reutilizadas por receitas.
Uma classe pode ser utilizada em uma receita através da palavra-chave inherit.
inherit autotools
Uma lista das principais classes existentes está disponível no manual de referência
do Yocto Project.
https://docs.yoctoproject.org/ref-manual/classes.html
IMPLEMENTANDO TAREFAS
Uma receita pode alterar tarefas existentes ou mesmo implementar suas próprias
tarefas.
Antes de implementar uma tarefa, verifique se já não existe uma classe com a lógica
necessária para o processamento da receita.
SHELL SCRIPT VS PYTHON
As tarefas são normalmente implementadas em Shell Script:
do_install() {
install -d ${D}${bindir}
import time
}
ALTERANDO TAREFAS
É possível redefinir uma tarefa existente:
do_compile() {
do_install:append() {
}
ADICIONANDO TAREFAS
Tarefas podem ser adicionadas a uma receita com a palavra-chave addtask:
do_mkimage() {
addtask mkimage
Novas tarefas não são executadas automaticamente por padrão, mas podem ser
executadas manualmente com o parâmetro -c:
$ bitbake myrecipe -c mkimage
Algumas variáveis são geradas automaticamente pelo BitBake quando uma receita é
processada.
VARIÁVEIS GERADAS AUTOMATICAMENTE
Variável Descrição
PN Package name - nome da receita/pacote
PV Package version - versão da receita
PR Package revision - revisão da receita
WORKDIR Diretório de processamento da receita
S Diretório onde o código-fonte é descompactado
B Diretório onde o código-fonte é compilado
D Diretório de instalação dos arquivos gerados na compilação
VARIÁVEIS GERADAS AUTOMATICAMENTE (CONT.)
$ cat ../layers/meta-labworks/recipes-test/empty-recipe/empty-recipe_1.0.bb
LICENSE = "CLOSED"
PN="empty-recipe"
PV="1.0"
PR="r0"
WORKDIR="/opt/labs/ex/build/tmp/work/core2-64-poky-linux/empty-recipe/1.0-r0"
S="/opt/labs/ex/build/tmp/work/core2-64-poky-linux/empty-recipe/1.0-r0/empty-recipe-1.0"
B="/opt/labs/ex/build/tmp/work/core2-64-poky-linux/empty-recipe/1.0-r0/empty-recipe-1.0"
D="/opt/labs/ex/build/tmp/work/core2-64-poky-linux/empty-recipe/1.0-r0/image"
PROCESSAMENTO DE UMA RECEITA
DO_FETCH
A variável SRC_URI é utilizada para definir a localização do código-fonte.
SRC_URI = "https://www.mpfr.org/mpfr-${PV}/mpfr-${PV}.tar.xz"
O código-fonte pode ser obtido de diversas origens, incluindo HTTP, FTP, repositórios
GIT e diretórios locais (veja a documentação do BitBake para uma lista completa de
protocolos suportados).
SRC_URI[sha256sum] = "65be9ff6004034b5b2ce9927b5a4db1814930f169c4b2dae0a1e4697075f287b"
SRCREV = "7ad885912efb2131e80914e964d5e635b0d07b40"
PV = "0.3+git${SRCPV}"
DO_UNPACK
O código-fonte será descompactado no diretório definido pela variável S.
S = "${WORKDIR}/git"
Uma receita pode ter arquivos locais (ex: patches), providos na variável SCR_URI
através do protocolo file.
SRC_URI = "http://www.mirrorservice.org/sites/lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_${PV}.
file://lsof-remove-host-information.patch"
DO_UNPACK (CONT.)
Estes arquivos são armazenados junto com os metadados, no diretório da receita, e o
BitBake utiliza a variável FILESPATH para encontrá-los.
$ tree poky/meta/recipes-extended/lsof/
poky/meta/recipes-extended/lsof/
├── files
│ └── lsof-remove-host-information.patch
└── lsof_4.91.bb
Por padrão, será utilizada a opção -p1 para aplicar os patches (este comportamento
pode ser alterado com a opção striplevel).
SRC_URI += "file://0002-llvm-allow-env-override-of-exe-path.patch;striplevel=2"
A receita deve conter também a variável LIC_FILES_CHKSUM para garantir que não
houve mudanças no arquivo da licença.
LIC_FILES_CHKSUM = "file://LICENSE;md5=44bc22578be94b6536c8bdc3a01e5db9"
DO_CONFIGURE
É comum as aplicações possuirem um mecanismo de configuração do software antes
de iniciar a compilação (autotools, cmake, etc).
install -d ${D}/${libdir}/pkgconfig
libpcap
libpcap-dbg
libpcap-dev
libpcap-doc
libpcap-locale
libpcap-src
libpcap-staticdev
DO_PACKAGE (CONT.)
A variável FILES é utilizada para o BitBake saber em qual pacote colocar cada arquivo
gerado:
$ bitbake libpng -e | grep ^FILES\:
FILES:libpng-src=""
libpcap1-1.10.1-r0.cortexa9t2hf_neon.rpm libpcap-dev-1.10.1-r0.cortexa9t2hf_neon.rpm
libpcap-src-1.10.1-r0.cortexa9t2hf_neon.rpm libpcap-dbg-1.10.1-r0.cortexa9t2hf_neon.rpm
libpcap-doc-1.10.1-r0.cortexa9t2hf_neon.rpm libpcap-staticdev-1.10.1-r0.cortexa9t2hf_neon.rpm
DIRETÓRIO DE PROCESSAMENTO DAS RECEITA
$ ls -1 tmp/work/core2-64-poky-linux/libpcap/1.10.1-r0/
build
configure.sstate
debugsources.list
deploy-rpms
deploy-source-date-epoch
image
libpcap-1.10.1
libpcap.spec
license-destdir
package
packages-split
pkgdata
pkgdata-pdata-input
pkgdata-sysroot
pseudo
recipe-sysroot
recipe-sysroot-native
source-date-epoch
sysroot-destdir
temp
LOGS DE PROCESSAMENTO
$ ls tmp/work/core2-64-poky-linux/libpcap/1.10.1-r0/temp/
depsig.do_deploy_source_date_epoch run.do_unpack
depsig.do_deploy_source_date_epoch.2949190 run.do_unpack.2949177
depsig.do_package run.emit_pkgdata.3006016
depsig.do_package.3006016 run.extend_recipe_sysroot.2947221
depsig.do_packagedata run.extend_recipe_sysroot.2949182
depsig.do_packagedata.3006753 run.extend_recipe_sysroot.3001129
depsig.do_package_qa run.extend_recipe_sysroot.3001312
depsig.do_package_qa.3006796 run.extend_recipe_sysroot.3005808
depsig.do_package_write_rpm run.extend_recipe_sysroot.3006016
depsig.do_package_write_rpm.3006795 run.extend_recipe_sysroot.3006017
depsig.do_populate_lic run.extend_recipe_sysroot.3006795
depsig.do_populate_lic.2949191 run.extend_recipe_sysroot.3006796
depsig.do_populate_sysroot run.fixup_perms.3006016
depsig.do_populate_sysroot.3006017 run.package_convert_pr_autoinc.3006016
log.do_compile run.packagedata_translate_pr_autoinc.3006753
log.do_compile.3005561 run.package_depchains.3006016
log.do_configure run.package_do_filedeps.3006016
log.do_configure.3001312 run.package_do_pkgconfig.3006016
log.do_deploy_source_date_epoch run.package_do_shlibs.3006016
log.do_deploy_source_date_epoch.2949190 run.package_do_split_locales.3006016
log.do_fetch run.package_fixsymlinks.3006016
log.do_fetch.2947221 run.package_get_auto_pr.3006753
HOMEPAGE = ""
SECTION = ""
LICENSE = ""
LIC_FILES_CHKSUM = ""
SRC_URI = ""
SRC_URI[sha256sum] = ""
DEPENDS = ""
inherit <some_class>
EXEMPLO 1: HELLO.C
DESCRIPTION = "Hello World application"
HOMEPAGE = "git://mygitserver.com/hello.git"
SECTION = "tests"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=7363621101019373746565758497289305"
SRC_URI = "git://mygitserver.com/hello.git;protocol=https;branch=main"
SRCREV = "6a4be9e9946df310d9402f995f371c7deb8c27ba"
S = "${WORKDIR}/git"
TARGET_CC_ARCH += "${LDFLAGS}"
do_compile() {
do_install() {
install -d ${D}${bindir}
}
EXEMPLO 2: AUTOTOOLS
SUMMARY = "GNU Hello World application"
HOMEPAGE = "https://hello.gnu.org"
SECTION = "tests"
LICENSE = "GPL-2.0-or-later"
LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
SRC_URI = "${GNU_MIRROR}/hello/hello-${PV}.tar.gz"
SRC_URI[sha256sum] = "d21b2d1fd78c1efbe1f2c16dae1cb23f8fd231dcf891465b8debe636a9054b0c"
DEPENDS = "zlib"
inherit autotools
EXTRA_OECONF = "--enable-debug"
EXEMPLO 3: AUTOTOOLS
SUMMARY = "X11 Code Viewer"
DESCRIPTION = "Allow viewing of X11 code in a fancy way which allows easier \
HOMEPAGE = "http://www.example.org/xcv/"
SECTION = "x11/applications"
LICENSE = "GPL-2.0"
PV = "0.9+git${SRCPV}"
# upstream does not yet publish any release so we have to fetch last working version from GIT
SRCREV = "6a5e79ae8a0f4a273a603b2df1742972510d3d8f"
SRC_URI = "git://xcv.example.org/xcv;protocol=http \
file://toolbar-resize-fix.patch"
S = "${WORKDIR}/xcv/"
inherit autotools
do_configure:prepend() {
rm ${S}/aclocal.m4
do install() {
PADRÃO DE RECEITAS
Existe um guia de estilo de receitas oficial do OpenEmbedded.
https://www.openembedded.org/wiki/Styleguide
DESENVOLVENDO RECEITAS
YOCTO PROJECT
VAR1 = "C"
VAR1 = "C"
CONCATENAÇÃO
O operador += pode ser usado para concatenar no final de uma variável (append), e o
operador =+ para concatenar no começo de uma variável (prepend).
VAR = "1"
VAR =+ "0"
VAR += "2"
VAR:remove = "1"
Uma variável chamada OVERRIDES contém valores separados por dois-pontos (:).
Estes valores podem ser usados para condicionar o valor de uma variável.
OVERRIDES (CONT.)
No exemplo abaixo, qual será o valor da variável VAR após o parsing das atribuições?
OVERRIDES = "linux-gnueabi:arm:armv7a:mx6:mx6dl:colibri-imx6:poky"
VAR = "1"
VAR:mx6 = "2"
VAR:ppc = "3"
Mais informações sobre esta mudança estão disponíveis no Release Migration Guide
do Yocto Project.
ARQUIVOS DE APPEND
Arquivos do tipo append possuem a extensão .bbappend e possibilitam modificar o
comportamento de uma receita sem alterar sua implementação original.
Podem ser utilizados para aplicar patches, customizar flags de compilação, instalar
arquivos adicionais, etc; flexibilizando bastante a manutenção dos metadados da
distribuição.
IMX_PATCH = " \
file://0001-add-conf-for-multichannel-support-in-imx.patch \
file://0005-add-ak4458-conf-for-multichannel-support.patch \
file://0006-add-conf-for-iMX-XCVR-sound-card.patch \
"
SRC_URI:append:imx-nxp-bsp = "${IMX_PATCH}"
PACKAGE_ARCH:imx-nxp-bsp = "${MACHINE_SOCARCH}"
EXEMPLO 2: IPROUTE2_%.BBAPPEND
do_install:append () {
install -d ${D}/usr/include/tc
cp -a ${B}/include ${D}/usr/include
cp -a ${B}/tc/*.h ${D}/usr/include/tc
}
EXEMPLO 3: MTD-UTILS_%.BBAPPEND
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
inherit systemd
SYSTEMD_PACKAGES = "${PN}"
SYSTEMD_SERVICE:${PN} = "ubihealthd.service"
SYSTEMD_AUTO_ENABLE = "disable"
do_install:append() {
install -d ${D}${systemd_unitdir}/system
sed -i -e 's,@SBINDIR@,${sbindir},g' \
-e 's,@SYSCONFDIR@,${sysconfdir},g' \
${D}${systemd_unitdir}/system/*.service
}
INSPECIONANDO APPENDS
O comando bitbake-layers pode ser utilizado para listar as receitas de append
existentes:
$ bitbake-layers show-appends
alsa-lib_1.2.1.2.bb:
/opt/labs/ex/layers/meta-freescale/recipes-multimedia/alsa/alsa-lib_%.bbappend
alsa-state.bb:
/opt/labs/ex/layers/meta-freescale-3rdparty/recipes-bsp/alsa-state/alsa-state.bbappend
/opt/labs/ex/layers/meta-freescale/recipes-bsp/alsa-state/alsa-state.bbappend
/opt/labs/ex/layers/meta-toradex-nxp/recipes-bsp/alsa-state/alsa-state.bbappend
base-files_3.0.14.bb:
/opt/labs/ex/layers/meta-lmp/meta-lmp-base/recipes-core/base-files/base-files_%.bbappend
/opt/labs/ex/layers/meta-toradex-torizon/recipes-core/base-files/base-files_%.bbappend
base-passwd_3.5.29.bb:
/opt/labs/ex/layers/meta-toradex-torizon/recipes-core/base-passwd/base-passwd_3.5.29.bbappend
bind_9.11.32.bb:
/opt/labs/ex/layers/meta-virtualization/recipes-core/bind/bind_%.bbappend
busybox_1.31.1.bb:
/opt/labs/ex/layers/meta-yocto/meta-poky/recipes-core/busybox/busybox_%.bbappend
/opt/labs/ex/layers/meta-virtualization/recipes-core/busybox/busybox_%.bbappend
/opt/labs/ex/layers/meta-security/recipes-core/busybox/busybox_%.bbappend
/opt/labs/ex/layers/meta-lmp/meta-lmp-base/recipes-core/busybox/busybox_%.bbappend
...
INCLUDE E REQUIRE
O BitBake permite que receitas incluam arquivos com as diretivas include e require.
No caso da diretiva include, se o arquivo não for encontrado, o processamento
continua normalmente.
meta-openembedded/meta-oe/recipes-extended/libmodbus
├── libmodbus
├── libmodbus_3.0.6.bb
├── libmodbus_3.1.7.bb
└── libmodbus.inc
$ cat meta-openembedded/meta-oe/recipes-extended/libmodbus/libmodbus_3.0.6.bb
require libmodbus.inc
SRC_URI[md5sum] = "c80f88b6ca19cabc4ceffc195ca07771"
SRC_URI[sha256sum] = "046d63f10f755e2160dc56ef681e5f5ad3862a57c1955fd82e0ce036b69471b6"
VARIABLE FLAGS
Variable flags (varflags) é um recurso do BitBake para associar informações extras à
variáveis e tarefas.
No exemplo abaixo, a variável FOO tem duas flags, a e b, com os valores 123 e 456
respectivamente.
FOO[a] = "123"
FOO[b] = "456"
PACKAGECONFIG[f1] = "\
--with-f1, \
--without-f1, \
build-deps-for-f1, \
runtime-deps-for-f1, \
runtime-recommends-for-f1, \
packageconfig-conflicts-for-f1"
PACKAGECONFIG[f2] = "..."
PACKAGECONFIG[selinux] = "--enable-selinux,--disable-selinux,libselinux,libselinux"
PE (Package Epoch) é por padrão vazia, mas deve ser usada caso o esquema de
versionamento do pacote seja alterado.
PR (Package Revision) contém r0 por padrão, mas deve ser modificada caso haja
alteração na receita.
BITBAKE -S
$ bitbake -s
...
liburi-perl-native :5.08-r0
libusb1 :1.0.24-r0
libusb1-native :1.0.24-r0
libuv :1.42.0-r0
libuv-native :1.42.0-r0
libva :2.12.0-r0
libva-initial :2.12.0-r0
libva-utils :2.12.0-r0
libvorbis :1.3.7-r0
libwebp :1.2.1-r0
libwpe :1.10.1-r0
libx11 1:1.7.2-r0
libx11-native 1:1.7.2-r0
libxau 1:1.0.9-r0
libxau-native 1:1.0.9-r0
libxcb :1.14-r0
libxcb-native :1.14-r0
libxcomposite 1:0.4.5-r0
libxcomposite-native 1:0.4.5-r0
VERSÕES E PRIORIDADES
Se existir mais de uma versão da mesma receita, por padrão o BitBake seleciona a
versão mais recente.
Na dúvida sobre qual versão será selecionada, verifique com bitbake -e:
$ bitbake busybox -e | grep ^PV=
PV="1.34.1"
INSPECIONANDO AS VERSÕES
O comando bitbake-layers pode ser utilizado para inspecionar as versões de receitas
existentes em múltiplas camadas:
$ bitbake-layers show-overlayed
podman:
meta-toradex-torizon 3.4.1+gitAUTOINC+a6493ae690
meta-virtualization 2.0.1+gitAUTOINC+a11c4ead10
python3-colorama:
meta-virtualization 0.3.9
meta-python 0.4.3
python3-docker:
meta-lmp-base 4.2.1
meta-virtualization 4.2.0
python3-docker-compose:
meta-lmp-base 1.26.0
meta-virtualization 1.25.4
python3-scapy:
meta-security 2.4.3
meta-python 0.25
python3-websocket-client:
meta-virtualization 0.57.0
meta-python 0.56.0
...
DEPURANDO RECEITAS
Diversas técnicas podem ser utilizadas para depurar problemas em receitas:
Análise dos logs de processamento da receita.
Inspeção de variáveis.
$ ls -1 temp/log.*
temp/log.do_cleansstate
temp/log.do_cleansstate.2772038
temp/log.do_compile
temp/log.do_compile.2779663
temp/log.do_configure
temp/log.do_configure.2778094
...
$ ls -1 temp/run.*
temp/run.do_configure
temp/run.do_configure.2778094
temp/run.do_fetch
temp/run.do_fetch.2776775
temp/run.do_patch
temp/run.do_patch.2776970
...
LOGS DO BITBAKE
Problemas gerais do BitBake podem ser visualizados com o parâmetro -D, que pode
ser definido múltiplas vezes para aumentar o nível de debug.
PV="1.35.0"
1.35.0
CACHES E EXECUÇÃO DE TAREFAS
Utilize a opção -c do BitBake para executar uma tarefa específica da receita:
$ bitbake unzip -c compile
Se a tarefa já tiver sido executada, uma nova execução não terá efeito. Para forçar a
execução da tarefa, podemos remover seu cache da compilação.
$ bitbake unzip -c cleansstate && bitbake unzip
OpenEmbedded pkgdata tool - queries the pkgdata files written out during do_package
options:
subcommands:
lookup-pkg Translate between recipe-space package names and runtime package names
package-info Show version, recipe and size information for one or more packages
lsof
lsof-dbg
lsof-dev
lsof-doc
lsof-src
lsof:
/usr/sbin/lsof
util-linux-libblkid: /lib/libblkid.so.1
util-linux
Ao processar uma receita, o sistema de build irá realizar várias checagens para evitar
problemas comuns, e reportá-los ao desenvolvedor.
...
ERROR: busybox-1.34.1-r0 do_package: QA Issue: busybox: Files/directories were installed but not ship
/usr/share
/usr/share/udhcpc
/usr/share/udhcpc/default.script
Please set FILES such that these items are packaged. Alternatively if they are unneeded, avoid insta
busybox: 3 installed and not shipped files. [installed-vs-shipped]
/home/sprado/workspace/yocto/training/layers/poky/meta/recipes-core/busybox/busybox_1.34.1.bb:do_pa
Summary: There were 2 ERROR messages shown, returning a non-zero exit code.
TRATANDO ERROS DE QA
Apesar de ser possível ignorar as verificações de QA, quando encontrá-las, é
recomendado procurar entender o motivo e corrigí-lo.
https://docs.yoctoproject.org/ref-manual/qa-checks.html
CUSTOMIZANDO RECEITAS
YOCTO PROJECT
CUSTOMIZAÇÃO DE IMAGENS
CUSTOMIZANDO IMAGENS
Durante o desenvolvimento de uma distribuição Linux com o Yocto Project, será
necessário customizar a imagem final gerada, por diversos motivos:
Adicionar ou remover componentes de software (packages).
Modificar o tamanho, formato e tipo (ext4, f2fs, btrfs, etc) da imagem final
gerada.
Etc!
ONDE CUSTOMIZAR?
Uma imagem pode ser customizada de diferentes formas:
As alterações podem ser realizadas no arquivo local.conf.
Por este motivo, o local.conf pode ser utilizado para modificações simples e
prototipação, mas seu uso não é recomendado para customizar imagens de
produção.
RECEITAS DE IMAGEM
Receitas de imagem permitem uma maior flexibilidade e controle na customização
da imagem final.
build-appliance-image core-image-minimal-initramfs.bb
build-appliance-image_15.0.0.bb core-image-minimal-mtdutils.bb
core-image-base.bb core-image-ptest-all.bb
core-image-minimal.bb core-image-ptest-fast.bb
core-image-minimal-dev.bb core-image-tiny-initramfs.bb
https://docs.yoctoproject.org/ref-manual/images.html
LICENSE = "MIT"
inherit core-image
IMAGE_ROOTFS_SIZE ?= "8192"
Ou então podemos nos basear em uma receita existente utilizando a diretiva require:
require recipes-core/images/core-image-minimal.bb
DESCRIPTION = "Small image capable of booting a device with support for the \
Minimal MTD Utilities, which let the user interact with the MTD subsystem in \
IMAGE_INSTALL += "mtd-utils"
ADICIONANDO PACOTES
As variáveis IMAGE_INSTALL e CORE_IMAGE_EXTRA_INSTALL podem ser utilizadas em
uma receita de imagem para adicionar pacotes à imagem.
IMAGE_INSTALL += "mtd-utils"
...
NOTE: Tasks Summary: Attempted 717 tasks of which 717 didn't need to be rerun and all succeeded.
CORE_IMAGE_EXTRA_INSTALL += "pcre"
$ bitbake core-image-minimal
...
libkmod2 core2_64 29
...
PACKAGE GROUPS
Package groups (grupo de pacotes) permitem agrupar pacotes de software com um
objetivo comum. Exemplos:
Pacotes de software para habilitar um stack gráfico.
Um package group nada mais é do que uma receita que herda a classe packagegroup
para agrupar pacotes de funcionalidade comum.
LOCALIZAÇÃO DOS PACKAGE GROUPS
Normalmente, os package groups ficam em um diretório chamado packagegroups
no diretório de receitas da camada:
$ ls poky/meta/recipes-core/packagegroups/
nativesdk-packagegroup-sdk-host.bb
packagegroup-base.bb
packagegroup-core-boot.bb
packagegroup-core-buildessential.bb
packagegroup-core-eclipse-debug.bb
packagegroup-core-nfs.bb
packagegroup-core-sdk.bb
packagegroup-core-ssh-dropbear.bb
packagegroup-core-ssh-openssh.bb
packagegroup-core-standalone-sdk-target.bb
packagegroup-core-tools-debug.bb
packagegroup-core-tools-profile.bb
packagegroup-core-tools-testapps.bb
packagegroup-cross-canadian.bb
packagegroup-go-cross-canadian.bb
packagegroup-go-sdk-target.bb
packagegroup-rust-cross-canadian.bb
packagegroup-self-hosted.bb
PACKAGEGROUP-CORE-ECLIPSE-DEBUG.BB
SUMMARY = "Remote debugging tools for Eclipse integration"
inherit packagegroup
RDEPENDS:${PN} = "\
gdbserver \
tcf-agent \
openssh-sftp-server \
"
USANDO PACKAGE GROUPS
Um package group pode ser adicionado a uma imagem normalmente através das
variáveis IMAGE_INSTALL e CORE_IMAGE_EXTRA_INSTALL.
Por exemplo, existe um package group para adicionar suporte ao Weston na imagem:
$ ls poky/meta/recipes-graphics/packagegroups/packagegroup-core-weston.bb
Para instalar este package group na imagem, basta adicioná-lo nas variáveis
IMAGE_INSTALL ou CORE_IMAGE_EXTRA_INSTALL.
IMAGE_INSTALL += "packagegroup-core-weston"
IMAGE FEATURES
As features de imagem permitem habilitar alguma "funcionalidade" na imagem
gerada através das variáveis IMAGE_FEATURES ou EXTRA_IMAGE_FEATURES.
https://docs.yoctoproject.org/ref-manual/features.html#image-features
IMPLEMENTAÇÃO DAS IMAGE FEATURES
$ cat poky/meta/classes/core-image.bbclass | grep FEATURE_PACKAGES
FEATURE_PACKAGES_weston = "packagegroup-core-weston"
FEATURE_PACKAGES_x11 = "packagegroup-core-x11"
FEATURE_PACKAGES_x11-base = "packagegroup-core-x11-base"
FEATURE_PACKAGES_x11-sato = "packagegroup-core-x11-sato"
FEATURE_PACKAGES_tools-debug = "packagegroup-core-tools-debug"
FEATURE_PACKAGES_eclipse-debug = "packagegroup-core-eclipse-debug"
FEATURE_PACKAGES_tools-profile = "packagegroup-core-tools-profile"
FEATURE_PACKAGES_tools-testapps = "packagegroup-core-tools-testapps"
FEATURE_PACKAGES_nfs-server = "packagegroup-core-nfs-server"
FEATURE_PACKAGES_nfs-client = "packagegroup-core-nfs-client"
FEATURE_PACKAGES_ssh-server-dropbear = "packagegroup-core-ssh-dropbear"
FEATURE_PACKAGES_ssh-server-openssh = "packagegroup-core-ssh-openssh"
FEATURE_PACKAGES_hwcodecs = "${MACHINE_HWCODECS}"
https://docs.yoctoproject.org/ref-manual/classes.html#useradd-bbclass
https://docs.yoctoproject.org/ref-manual/classes.html#extrausers-bbclass
EXEMPLO: USERADD
inherit useradd
USERADD_PACKAGES = "${PN}"
do_install:append () {
EXTRA_USERS_PARAMS = "\
groupadd developers; \
userdel nobody; \
groupdel -g video; \
"
PERMISSÕES DE ARQUIVOS E DIRETÓRIOS
Por padrão, o sistema de build utiliza o arquivo fs-perms.txt armazenado em
poky/meta/files/ para definir as permissões de arquivos e diretórios do rootfs gerado.
Isso pode ser necessário caso queira aplicar configurações de permissão globais na
imagem (configurações associadas a uma aplicação devem ser feitas na receita
correspondente).
# and group of listed files and directories are in sync across the system.
...
# Fixup locales
...
ADICIONANDO ARQUIVOS À IMAGEM
Uma necessidade comum durante a customização de imagens é a adição de arquivos
(blobs, shell scripts, arquivos de configuração, etc).
Caso os arquivos não estejam associados a nenhum software, podemos criar uma
receita específica para adicioná-los à imagem.
EXEMPLO: ADICIONANDO ARQUIVOS
DESCRIPTION = "Some closed source library from hell"
LICENSE = "CLOSED"
SRC_URI = "http://hell.com/mylib.so;unpack=false"
do_install() {
install -d ${D}${libdir}
FILES_${PN} = "${libdir}/mylib.so"
POST-INSTALL SCRIPTS
Pacotes podem conter scripts de pós-instalação (post-install), que permitem a
execução de comandos durante sua instalação (durante a geração do rootfs ou em
tempo de execução).
São úteis para preparar o rootfs para determinado pacote (criar diretórios e arquivos
temporários, configurar permissões, alterar arquivos de configuração, etc).
# commands to execute
...
pkg_postinst:${PN} () {
touch $D${sysconfdir}/shells
$ cat poky/meta/recipes-connectivity/avahi/avahi_0.8.bb
...
pkg_postinst:avahi-daemon () {
if [ -z "$D" ]; then
fi
}
POST-INSTALL NO BOOT
Às vezes, é necessário adiar a execução de um script de pós-instalação até o primeiro
boot do dispositivo.
Útil quando queremos por exemplo que o script de pós-instalação seja executado
diretamente no target.
...
pkg_postinst_ontarget:${PN}() {
}
ROOTFS_POSTPROCESS_COMMAND
Usado bastante em classes, uma forma fácil de executar um comando após a criação
do rootfs é através da variável ROOTFS_POSTPROCESS_COMMAND.
Por exemplo, o código abaixo tem o objetivo de alterar a senha do usuário admin :
run_set_admin_pass () {
sed 's%^admin:[^:]*:%admin:$6$3WWbKfr1$4vblknvGr6FcDe:\
%' ${IMAGE_ROOTFS}/etc/shadow \
${IMAGE_ROOTFS}/etc/shadow.new;
mv ${IMAGE_ROOTFS}/etc/shadow.new \
${IMAGE_ROOTFS}/etc/shadow ;"
Uma lista dos tipos de imagens existentes está disponível no guia de referência do
Yocto Project.
https://docs.yoctoproject.org/ref-manual/variables.html#term-IMAGE_TYPES
--output=${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.jffs2 \
${EXTRA_IMAGECMD}"
ALTERANDO O TAMANHO DA IMAGEM
A variável IMAGE_ROOTFS_SIZE pode ser utilizada para definir o tamanho final do
rootfs (em KBs).
IMAGE_ROOTFS_SIZE = "1048576"
Se a variável IMAGE_ROOTFS_SIZE não for definida, ou se seu valor não for suficiente
para suportar o sistema gerado, o rootfs será gerado através da multiplicação do
tamanho do rootfs pela variável IMAGE_OVERHEAD_FACTOR, que por padrão tem o
valor 1.3, gerando uma image 30% maior que o valor mínimo necessário.
Para ter mais controle sobre a seleção de pacotes, opções de compilação e outras
configurações de baixo nível, podemos criar uma distribuição customizada para a
plataforma alvo.
poky/meta-poky/conf/distro/
├── include
├── poky-altcfg.conf
├── poky-bleeding.conf
├── poky.conf
└── poky-tiny.conf
CRIANDO UMA DISTRIBUIÇÃO
Para criar uma distribuição, podemos usar como base os arquivos de configuração
do Poky (poky/meta-poky/conf/distro/poky.conf) ou do OpenEmbedded-Core
(poky/meta/conf/distro/defaultsetup.conf).
https://docs.yoctoproject.org/ref-manual/features.html#distro-features
PACKAGEGROUP-CORE-FULL-CMDLINE.BB
SUMMARY = "Standard full-featured Linux system"
DESCRIPTION = "Package group bringing in packages needed for a more traditional full-featured Linux s
PR = "r6"
inherit packagegroup
...
RDEPENDS:packagegroup-core-full-cmdline-sys-services = "\
at \
cronie \
logrotate \
"
LIBPCAP_1.10.1.BB
SUMMARY = "Interface for user-level network packet capture"
...
"
PACKAGECONFIG[bluez5] = "--enable-bluetooth,--disable-bluetooth,bluez5"
PACKAGECONFIG[dbus] = "--enable-dbus,--disable-dbus,dbus"
PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6,"
PACKAGECONFIG[libnl] = "--with-libnl,--without-libnl,libnl"
...
RUNTIME PACKAGE MANAGEMENT
Com o Yocto Project, é possível construir uma imagem com suporte a gerenciamento
de pacotes em tempo de execução.
No host, cada vez que pacotes são alterados, é necessário regerar o índice de pacotes
com o comando abaixo:
$ bitbake package-index
CUSTOMIZANDO IMAGENS
YOCTO PROJECT
DESENVOLVIMENTO DE BSP
CAMADA DE BSP
De forma geral, um BSP (Board Support Package) contém todo o código-fonte
necessário para uma plataforma de hardware suportar determinado sistema
operacional (no nosso caso o kernel Linux).
poky/meta-yocto-bsp/
├── conf
├── lib
├── README.hardware.md
├── recipes-bsp
├── recipes-graphics
│ └── xorg-xserver
CRIANDO UMA CAMADA DE BSP
Antes de criar uma camada de BSP, verifique se já não existe alguma implementação
pronta para a plataforma alvo.
https://layers.openembedded.org/layerindex/branch/kirkstone/machines/
CRIANDO UMA CAMADA DE BSP (CONT.)
Uma camada de BSP possui a mesma estrutura de outras camadas e pode ser criada
seguindo os seguintes passos:
Crie uma camada com o comando bitbake-layers create-layer.
https://docs.yoctoproject.org/bsp-guide/index.html
ESQUELETO DE UMA CAMADA DE BSP
$ tree meta-labworks-bsp
meta-labworks-bsp
├── classes
├── conf
│ ├── layer.conf
│ └── machine
│ └── my-machine.conf
├── recipes-bsp
│ └── u-boot
├── recipes-core
├── recipes-graphics
└── recipes-kernel
└── linux
ARQUIVO DE CONFIGURAÇÃO DA MACHINE
Uma das principais tarefas na implementação de uma camada de BSP está na
definição do arquivo de configuração da machine.
include conf/machine/include/soc-family.inc
MACHINEOVERRIDES =. "qemuall:"
Para que uma receita possa indicar que ela irá prover determinado software
(bootloader, kernel, etc), existe o mecanismo de pacote virtual.
Por exemplo, uma receita de kernel irá utilizar a variável PROVIDES para indicar que
irá prover o pacote virtual do kernel Linux:
PROVIDES += "virtual/kernel"
PREFERRED_VERSION_u-boot-toradex = "2020.04%"
VARIÁVEIS DO U-BOOT
Variável Descrição
UBOOT_MACHINE Nome do arquivo de configuração da placa no U-Boot
UBOOT_SUFFIX Extensão da imagem do U-Boot (ex: .bin)
SPL_BINARY Nome do arquivo do SPL (ex: MLO)
UBOOT_ENTRYPOINT Ponto de entrada da imagem do U-Boot
UBOOT_LOADADDRESS Endereço de carga do U-Boot
UBOOT_LOCALVERSION Concatena uma string na versão do U-Boot
VARIÁVEIS DO KERNEL
Variável Descrição
KERNEL_IMAGETYPE Nome da imagem do kernel (ex: zImage)
KERNEL_DEVICETREE Nome dos arquivos de device tree (.dtb)
KERNEL_EXTRA_ARGS Argumentos adicionais para passar para o make
KERNEL_MODULE_AUTOLOAD Módulos para carregar automaticamente no boot
SERIAL_CONSOLES Porta serial (TTY) para iniciar a aplicação getty
ADICIONANDO PACOTES
Variável Descrição
MACHINE_ESSENTIAL_EXTRA_RDEPENDS Pacotes obrigatórios para instalar
específicos da machine (afeta
imagens que incluem o
packagegroup-core-boot, incluindo
a core-image-minimal)
MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS Pacotes recomendados para
instalar específicos da machine
(afeta imagens que incluem o
packagegroup-core-boot, incluindo
a core-image-minimal)
MACHINE_FEATURES
A variável MACHINE_FEATURES permite especificar as funcionalidades suportadas por
uma plataforma de hardware. Exemplos:
touchscreen: o hardware tem uma interface de touchscreen.
https://docs.yoctoproject.org/ref-manual/features.html#ref-features-machine
EXEMPLO: PACKAGEGROUP-BASIC.BB
SUMMARY = "Basic task to get a device online"
PR = "r13"
...
RRECOMMENDS:${PN} = "\
${MACHINE_EXTRA_RRECOMMENDS} \
tzdata \
cpufrequtils \
htop \
"
...
EXEMPLO: MATCHBOX-PANEL-2_2.11.BB
SUMMARY = "Simple GTK+ based panel for handheld devices"
DESCRIPTION = "A flexible always present 'window bar' for holding application \
HOMEPAGE = "http://matchbox-project.org"
BUGTRACKER = "http://bugzilla.yoctoproject.org/"
...
...
...
MACHINE FEATURES VS DISTRO FEATURES
Machine features e distro features trabalham de forma conjunta para adicionar o
suporte à determinada funcionalidade na distribuição gerada.
DISTRO_FEATURES="acl alsa argp bluetooth debuginfod ext2 ipv4 ipv6 largefile pcmcia usbgadget
usbhost wifi xattr nfs zeroconf pci 3g nfc x11 vfat seccomp largefile opengl ptest multiarch
HOMEPAGE = "http://irda.sourceforge.net/"
BUGTRACKER = "http://sourceforge.net/p/irda/bugs/"
...
RRECOMMENDS:${PN} = "\
kernel-module-pxaficp-ir \
kernel-module-irda \
kernel-module-ircomm \
kernel-module-ircomm-tty \
kernel-module-irlan \
kernel-module-irport \
kernel-module-irtty \
kernel-module-irtty-sir \
kernel-module-sir-dev \
...
MACHINE: BEAGLEBONE-YOCTO.CONF
#@TYPE: Machine
PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
XSERVER ?= "xserver-xorg \
xf86-video-modesetting \
"
EXTRA_IMAGEDEPENDS += "virtual/bootloader"
DEFAULTTUNE ?= "cortexa8hf-neon"
include conf/machine/include/arm/armv7a/tune-cortexa8.inc
WKS_FILE ?= "beaglebone-yocto.wks"
include conf/machine/include/imx-base.inc
include conf/machine/include/arm/armv7a/tune-cortexa9.inc
KBUILD_DEFCONFIG:use-nxp-bsp ?= "colibri_imx6_defconfig"
imx6dl-colibri-aster.dtb imx6dl-colibri-iris.dtb \
imx6dl-colibri-iris-v2.dtb"
KERNEL_DEVICETREE:use-mainline-bsp = "imx6dl-colibri-eval-v3.dtb"
KERNEL_IMAGETYPE = "zImage"
IMX_DEFAULT_BOOTLOADER = "u-boot-toradex"
PREFERRED_PROVIDER_u-boot-default-script = "u-boot-script-toradex"
UBOOT_SUFFIX = "img"
SPL_BINARY = "SPL"
UBOOT_CONFIG[spl] = "colibri_imx6_defconfig,,u-boot.img"
UBOOT_MAKE_TARGET = ""
/opt/labs/ex/layers/poky/meta \
/opt/labs/ex/layers/poky/meta-poky \
/opt/labs/ex/layers/poky/meta-yocto-bsp \
/opt/labs/ex/layers/meta-labworks \
/opt/labs/ex/layers/meta-labworks-bsp \
"
HOMEPAGE = "http://www.denx.de/wiki/U-Boot/WebHome"
SECTION = "bootloaders"
LICENSE = "GPL-2.0-or-later"
LIC_FILES_CHKSUM = "file://Licenses/README;md5=30503fd321432fc713238f582193b78e"
require recipes-bsp/u-boot/u-boot.inc
PV = "2020.07+git${SRCPV}"
SRC_URI = " \
git://git.toradex.com/u-boot-toradex.git;branch=${SRCBRANCH} \
file://fw_env.config \
"
SRCBRANCH = "toradex_2020.07"
SRCREV = "ab862daf5d5a2eebf305c5c125f0463b0ff34161"
UBOOT_INITIAL_ENV = "u-boot-initial-env"
PROVIDES += "u-boot"
B = "${WORKDIR}/build"
S = "${WORKDIR}/git"
EXEMPLO: LINUX-YOCTO-CUSTOM.BB
inherit kernel
require recipes-kernel/linux/linux-yocto.inc
SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git;protocol=git;nocheckout=1
LINUX_VERSION ?= "4.2"
LINUX_VERSION_EXTENSION:append = "-custom"
SRCREV_machine="64291f7db5bd8150a74ad2036f1037e6a0428df2"
PV = "${LINUX_VERSION}+git${SRCPV}"
COMPATIBLE_MACHINE = "(^$)"
EXEMPLO: HELLO-MOD_0.1.BB
SUMMARY = "Example of how to build an external Linux kernel module"
DESCRIPTION = "${SUMMARY}"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e"
inherit module
SRC_URI = "file://Makefile \
file://hello.c \
file://COPYING \
"
S = "${WORKDIR}"
RPROVIDES:${PN} += "kernel-module-hello"
ESTENDENDO UM BSP
Muitos fabricantes fornecem BSPs baseados no Yocto Project prontos para serem
utilizados com suas plataformas de hardware.
Neste caso, ao invés de criar uma camada de BSP do zero, podemos simplesmente
estender o BSP do fabricante.
A configuração do kernel pode ser aberta diretamente pelo BitBake através da tarefa
do_menuconfig.
$ bitbake virtual/kernel -c menuconfig
Porém, a configuração não será persistente, e poderá ser perdida em uma eventual
limpeza da compilação do kernel.
CONFIGURANDO O KERNEL (CONT.)
Para um maior controle, customizações na configuração do kernel podem ser salvas
junto com os metadados, em uma camada de BSP.
Uma receita de append do kernel pode ser criada para adicionar este arquivo na
variável SRC_URI.
SOBRESCREVENDO A CONFIGURAÇÃO (CONT.)
$ tree recipes-kernel/
recipes-kernel
└── linux
├── files
│ └── defconfig
└── linux-toradex_%.bbappend
$ cat recipes-kernel/linux/linux-toradex_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://defconfig"
FRAGMENTOS DE CONFIGURAÇÃO
Fragmentos de configuração permitem definir partes da configuração do kernel em
arquivos com extensão .cfg.
Uma receita de append do kernel pode ser criada para adicionar os fragmentos de
configuração na variável SRC_URI.
FRAGMENTOS DE CONFIGURAÇÃO (CONT.)
$ tree recipes-kernel/
recipes-kernel
└── linux
├── files
│ └── ntfs.cfg
└── linux-yocto_%.bbappend
$ cat recipes-kernel/linux/files/ntfs.cfg
CONFIG_NTFS_FS=y
$ cat recipes-kernel/linux/linux-yocto_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://ntfs.cfg"
APLICANDO PATCHES NO KERNEL
Manter alguns patches na camada de BSP para aplicar no kernel pode ser necessário
quando optamos por não ter nosso próprio repositório de kernel.
Para aplicar patches no kernel podemos seguir o mesmo processo que já estudamos
no treinamento.
recipes-kernel/
└── linux
├── files
│ └── 0001-fixbug.patch
└── linux-toradex_%.bbappend
$ cat recipes-kernel/linux/linux-toradex_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://0001-fixbug.patch"
ADVANCED METADATA
Outra forma de configurar o kernel é através de um recurso chamado Advanced
Metadata.
https://docs.yoctoproject.org/kernel-dev/advanced.html
EXEMPLO: ADVANCED METADATA
$ tree meta-labworks/recipes-kernel/linux/
meta-labworks/recipes-kernel/linux/
├── files
│ ├── 0001-fix-tpm2-bug.patch
│ ├── tpm2.cfg
│ └── tpm2.scc
└── linux-yocto_%.bbappend
$ cat meta-labworks/recipes-kernel/linux/files/tpm2.scc
patch 0001-fix-tpm2-bug.patch
$ cat meta-labworks/recipes-kernel/linux/files/tpm2.cfg
CONFIG_HW_RANDOM_TPM=y
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS_CORE=y
CONFIG_TCG_TIS=y
$ cat meta-labworks/recipes-kernel/linux/linux-yocto_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
Configurar outras variáveis de ambiente úteis para a compilação (CC, CFLAGS, etc)
poky-glibc-x86_64-meta-toolchain-cortexa9t2hf-neon-colibri-imx6-training-toolchain-4.0.1.host.mani
poky-glibc-x86_64-meta-toolchain-cortexa9t2hf-neon-colibri-imx6-training-toolchain-4.0.1.sh
poky-glibc-x86_64-meta-toolchain-cortexa9t2hf-neon-colibri-imx6-training-toolchain-4.0.1.target.ma
poky-glibc-x86_64-meta-toolchain-cortexa9t2hf-neon-colibri-imx6-training-toolchain-4.0.1.testdata.
=================================================================
Extracting SDK..............................................done
Setting it up...done
Each time you wish to use the SDK in a new shell session, you need to source the environment setup sc
$ . /opt/poky/4.0.1/environment-setup-cortexa9t2hf-neon-poky-linux-gnueabi
$ ls -l /opt/poky/4.0.1/
total 36
$ echo $CC
$ $CC --version
This is free software; see the source for copying conditions. There is NO
$ cat main.c
$ file main
main: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /li
TAREFA POPULATE_SDK
Um SDK completo com o sysroot baseado em uma receita de imagem pode ser
gerado processando a tarefa populate_sdk:
$ bitbake core-image-minimal -c populate_sdk
poky-glibc-x86_64-core-image-minimal-cortexa9t2hf-neon-colibri-imx6-training-toolchain-4.0.1.host.
poky-glibc-x86_64-core-image-minimal-cortexa9t2hf-neon-colibri-imx6-training-toolchain-4.0.1.sh
poky-glibc-x86_64-core-image-minimal-cortexa9t2hf-neon-colibri-imx6-training-toolchain-4.0.1.targe
poky-glibc-x86_64-core-image-minimal-cortexa9t2hf-neon-colibri-imx6-training-toolchain-4.0.1.testd
=================================================================
Extracting SDK................................................................................done
Setting it up...done
Each time you wish to use the SDK in a new shell session, you need to source the environment setup sc
$ . /opt/labs/ex/build/y/environment-setup-cortexa9t2hf-neon-poky-linux-gnueabi
$ ls -l /opt/poky/4.0.1/
total 36
$ echo $CC
$ $CC --version
This is free software; see the source for copying conditions. There is NO
$ cat main.c
$ file main
main: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /li
POPULATE_SDK: AUTOTOOLS
$ ls
$ cat hello.c
#include <stdio.h>
$ cat configure.ac
AC_INIT(hello,0.1)
AM_INIT_AUTOMAKE([foreign])
AC_PROG_CC
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
$ cat Makefile.am
bin_PROGRAMS = hello
hello_SOURCES = hello.c
POPULATE_SDK: AUTOTOOLS (CONT.)
$ source /opt/poky/4.0.1/environment-setup-cortexa9t2hf-neon-poky-linux-gnueabi
$ autoreconf
$ ls
$ ./configure ${CONFIGURE_FLAGS}
$ echo $CONFIGURE_FLAGS
--with-libtool-sysroot=/opt/poky/4.0.1/sysroots/cortexa9t2hf-neon-poky-linux-gnueabi
$ make
$ tree install/
install/
└── usr
└── local
└── bin
└── hello
TAREFA POPULATE_SDK_EXT
Um SDK completo com o sysroot baseado em uma receita de imagem e ferramentas
adicionais pode ser gerado processando a tarefa populate_sdk_ext:
$ bitbake core-image-minimal -c populate_sdk_ext
poky-glibc-x86_64-core-image-training-cortexa9t2hf-neon-colibri-imx6-training-toolchain-ext-4.0.1.host
poky-glibc-x86_64-core-image-training-cortexa9t2hf-neon-colibri-imx6-training-toolchain-ext-4.0.1.sh
poky-glibc-x86_64-core-image-training-cortexa9t2hf-neon-colibri-imx6-training-toolchain-ext-4.0.1.targe
poky-glibc-x86_64-core-image-training-cortexa9t2hf-neon-colibri-imx6-training-toolchain-ext-4.0.1.testd
============================================================================
Extracting SDK.......................................................done
Setting it up...
Extracting buildtools...
Each time you wish to use the SDK in a new shell session, you need to source the environment setup sc
$ . /home/sprado/poky_sdk/environment-setup-cortexa9t2hf-neon-poky-linux-gnueabi
$ ls /home/sprado/poky_sdk/
bitbake-cookerdaemon.log preparing_build_system.log
buildtools site-config-cortexa9t2hf-neon-poky-linux-gnue
cache sstate-cache
conf sysroots
downloads tmp
environment-setup-cortexa9t2hf-neon-poky-linux-gnueabi version-cortexa9t2hf-neon-poky-linux-gnueabi
layers workspace
POPULATE_SDK_EXT: UTILIZANDO
$ source ~/poky_sdk/environment-setup-cortexa9t2hf-neon-poky-linux-gnueabi
SDK environment now set up; additionally you may now run devtool to perform development tasks.
$ echo $CC
$ $CC --version
This is free software; see the source for copying conditions. There is NO
$ cat main.c
$ file main
main: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib
DEVTOOL
A grande diferença do SDK gerado com a tarefa populate_sdk para o SDK gerado com
a tarefa populate_sdk_ext é a presença da ferramenta devtool.
Possui um design parecido com o Git, com sub-comandos para cada uma das
funcionalidades suportadas.
A ferramenta devtool não está somente limitada ao SDK, e pode ser utilizada no
ambiente de build do Yocto Project.
COMANDOS INTERESSANTES
devtool add: cria uma receita a partir do código-fonte de uma aplicação.
devtool deploy-target: instala os pacotes gerados por uma receita no target (via SSH).
...
$ tree -L 3 workspace/
workspace/
├── appends
│ └── fping_4.4.bbappend
├── conf
│ └── layer.conf
├── README
├── recipes
│ └── fping
│ └── fping_4.4.bb
└── sources
└── fping
├── aclocal.m4
├── CHANGELOG.md
├── ci
├── compile
├── ...
└── src
RECEITA GERADA: FPING_4.4.BB
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
#
# The following license files were not able to be identified and are
# COPYING
LICENSE = "Unknown"
LIC_FILES_CHKSUM = "file://COPYING;md5=c6170fbadddfcd74f011515291d96901"
SRC_URI = "http://www.fping.org/dist/fping-${PV}.tar.gz"
SRC_URI[md5sum] = "10e50c164ddff6941eff5fef41c21e3d"
SRC_URI[sha1sum] = "8be8be5b8dc5c0dd3505db79b8fe1438fe4ef590"
SRC_URI[sha256sum] = "9f854b65a52dc7b1749d6743e35d0a6268179d1a724267339fc9a066b2b72d11"
SRC_URI[sha384sum] = "1647b4cf07d751961fbe37bde12292dbc3820e396fe37271d088168a605588a7b4def9f14ac6978
SRC_URI[sha512sum] = "8c9ff78edee10ce8e02a0d6189d4a2d91cc60954740c15730f8f1a17d037ee9f565828fa0dcd47a
# NOTE: if this software is not capable of being built in a separate build directory
# from the source, you should replace autotools with autotools-brokensep in the
# inherit line
inherit autotools
DEVTOOL EDIT-RECIPE
$ devtool edit-recipe fping
--- a/fping_4.4.bb
+++ b/fping_4.4.bb
@@ -8,15 +8,14 @@
# The following license files were not able to be identified and are
# COPYING
-LICENSE = "Unknown"
+HOMEPAGE = "http://www.fping.org/"
+LICENSE = "BSD"
LIC_FILES_CHKSUM = "file://COPYING;md5=c6170fbadddfcd74f011515291d96901"
SRC_URI = "http://www.fping.org/dist/fping-${PV}.tar.gz"
-SRC_URI[md5sum] = "10e50c164ddff6941eff5fef41c21e3d"
-SRC_URI[sha1sum] = "8be8be5b8dc5c0dd3505db79b8fe1438fe4ef590"
SRC_URI[sha256sum] = "9f854b65a52dc7b1749d6743e35d0a6268179d1a724267339fc9a066b2b72d11"
-SRC_URI[sha384sum] = "1647b4cf07d751961fbe37bde12292dbc3820e396fe37271d088168a605588a7b4def9f14ac697
-SRC_URI[sha512sum] = "8c9ff78edee10ce8e02a0d6189d4a2d91cc60954740c15730f8f1a17d037ee9f565828fa0dcd47
# NOTE: if this software is not capable of being built in a separate build directory
# from the source, you should replace autotools with autotools-brokensep in the
DEVTOOL BUILD/DEPLOY-TARGET
$ devtool build fping
...
NOTE: Tasks Summary: Attempted 621 tasks of which 595 didn't need to be rerun and all succeeded.
...
# fping --version
...
INFO: -r argument used on fping, removing source tree. You will lose any unsaved work
$ tree layers/meta-labworks/recipes-fping/
layers/meta-labworks/recipes-fping/
└── fping
└── fping_4.4.bb
DEVTOOL UPGRADE
$ devtool upgrade --version 5.0 fping
...
# fping --version
...
$ ls layers/meta-labworks/recipes-fping/fping/
fping_5.0.bb
DEVTOOL MODIFY
$ devtool modify fping
$ cd workspace/sources/fping
# fping --version
$ tree layers/meta-labworks/recipes-fping/
layers/meta-labworks/recipes-fping/
└── fping
├── fping
│ └── 0001-change-version-message.patch
└── fping_5.0.bb
DEVTOOL --HELP
$ devtool --help
usage: devtool [--basepath BASEPATH] [--bbpath BBPATH] [-d] [-q] [--color COLOR] [-h] <subcommand> .
options:
--bbpath BBPATH Explicitly specify the BBPATH, rather than getting it from the metadata
subcommands:
Getting information:
https://www.yoctoproject.org/software-item/
Históricos de build.
Toaster.
Uma mensagem de aviso será exibida se a licença declarada na variável LICENSE não
for encontrada.
DIRETÓRIO COMMON-LICENSES/
$ ls poky/meta/files/common-licenses/
...
ARQUIVO LICENSES.CONF
$ cat meta/conf/licenses.conf
# Standards are great! Everyone has their own. In an effort to standardize licensing
# names, common-licenses will use the SPDX standard license names. In order to not
# break the non-standardized license names that we find in LICENSE, we'll set
# We should really discuss standardizing this field, but that's a longer term goal.
# For now, we can do this and it should grab the most common LICENSE naming variations.
# AGPL variations
SPDXLICENSEMAP[AGPL-3] = "AGPL-3.0-only"
SPDXLICENSEMAP[AGPL-3+] = "AGPL-3.0-or-later"
SPDXLICENSEMAP[AGPLv3] = "AGPL-3.0-only"
SPDXLICENSEMAP[AGPLv3+] = "AGPL-3.0-or-later"
SPDXLICENSEMAP[AGPLv3.0] = "AGPL-3.0-only"
SPDXLICENSEMAP[AGPLv3.0+] = "AGPL-3.0-or-later"
SPDXLICENSEMAP[AGPL-3.0] = "AGPL-3.0-only"
SPDXLICENSEMAP[AGPL-3.0+] = "AGPL-3.0-or-later"
# BSD variations
SPDXLICENSEMAP[BSD-0-Clause] = "0BSD"
DESABILITANDO UMA LICENÇA
Durante o desenvolvimento de um produto, pode ser necessário evitar o uso de
software de determinada licença.
Por exemplo, a licença GPLv3 possui uma cláusula para impedir o que é
normalmente chamado de Tivoization (restrições no hardware que previnem o
usuário de atualizar o software no dispositivo).
Esta restrição pode ser impeditiva para alguns produtos comerciais.
Para estes casos, a variável INCOMPATIBLE_LICENSE pode ser utilizada para previnir
com que receitas de determinada licença sejam processadas.
INCOMPATIBLE_LICENSE = "GPL-3.0* LGPL-3.0* AGPL-3.0*"
SOFTWARES PROPRIETÁRIOS E COMERCIAIS
Receitas podem utilizar o valor CLOSED para definir que um software é proprietário.
LICENSE = "CLOSED"
O Yocto Project é capaz de ajudar nestes três requisitos para garantir aderência às
licenças de software.
DISTRIBUINDO O CÓDIGO-FONTE
A classe archiver e a variável ARCHIVER_MODE podem ser utilizadas para gerar um
diretório com o código-fonte dos componentes de software utilizados na
distribuição:
INHERIT += "archiver"
ARCHIVER_MODE[src] = "original"
0001-du-l-works-fix-to-use-145-instead-of-144.patch login-utilities.cfg
0001-mktemp-add-tmpdir-option.patch longopts.cfg
0001-sysctl-ignore-EIO-of-stable_secret-below-proc-sys-ne.patch makefile-libbb-race.patch
0001-testsuite-check-uudecode-before-using-it.patch mdev
0001-testsuite-use-www.example.org-for-wget-test-cases.patch mdev.conf
0001-Use-CC-when-linking-instead-of-LD-and-use-CFLAGS-and.patch mdev-mount.sh
busybox-1.34.1.tar.bz2 mount-via-label.cfg
busybox-cron pgrep.cfg
busybox-cross-menuconfig.patch rcK
busybox-httpd rcS
busybox-klogd.service.in recognize_connmand.patch
busybox-syslog.default resize.cfg
busybox-syslog.service.in rev.cfg
busybox-udhcpc-no_deconfig.patch run-ptest
busybox-udhcpd series
default.script sha1sum.cfg
defconfig sha256sum.cfg
fail_on_no_media.patch simple.script
find-touchscreen.sh syslog
getopts.cfg syslog.cfg
hwclock.sh syslog.conf
inetd syslog-startup.conf
inetd.conf unicode.cfg
DISTRIBUINDO O TEXTO DA LICENÇA
Por padrão, as licenças de todos os componentes de software processados pelo
BitBake são mantidos no diretório de build em tmp/deploy/licenses.
Porém, algumas licenças requerem que o texto da licença seja distribuído na imagem
junto com os artefatos gerados (biblioteca, executável, etc).
COPY_LIC_DIRS = "1"
LICENSE_CREATE_PACKAGE = "1"
LICENSE: GPLv2
LICENSE: GPLv2
...
# ls /usr/share/common-licenses/busybox/
https://docs.yoctoproject.org/singleindex.html#shared-state-cache
BUILDHISTORY_COMMIT = "1"
buildhistory/
├── images
│ └── qemux86_64
│ └── glibc
│ └── core-image-minimal
│ ├── build-id.txt
│ ├── depends.dot
│ ├── depends-nokernel.dot
│ ├── depends-nokernel-nolibc.dot
│ ├── depends-nokernel-nolibc-noupdate.dot
│ ├── depends-nokernel-nolibc-noupdate-nomodules.dot
│ ├── files-in-image.txt
│ ├── image-files
│ │ └── etc
│ │ ├── group
│ │ └── passwd
│ ├── image-info.txt
│ ├── installed-package-info.txt
│ ├── installed-package-names.txt
│ ├── installed-package-sizes.txt
│ └── installed-packages.txt
├── metadata-revs
└── packages
ANALISANDO O HISTÓRICO DE BUILD
O histórico de build pode ser analisado diretamente com o Git.
$ git log
O histórico de build pode também ser disponibilizado através de uma interface Web:
https://git.yoctoproject.org/buildhistory-web/about/
ANALISANDO O HISTÓRICO COM GIT
$ git log --oneline
9e0bb5bf49e5 (HEAD -> master) Build 20211222192916 of poky 3.4 for machine qemux86-64 on sprado-offic
ca3d6aa3424a (tag: build-minus-1) Build 20211222185937 of poky 3.4 for machine qemux86-64 on sprado-o
9117fee4f44a (tag: build-minus-2) Build 20211222185640 of poky 3.4 for machine qemux86-64 on sprado-o
...
--- a/images/qemux86_64/glibc/core-image-minimal/files-in-image.txt
+++ b/images/qemux86_64/glibc/core-image-minimal/files-in-image.txt
--- a/images/qemux86_64/glibc/core-image-minimal/image-info.txt
+++ b/images/qemux86_64/glibc/core-image-minimal/image-info.txt
options:
subcommands:
edit Edit the recipe and appends for the specified target. This obeys $VISUAL if set, o
setvar Set a variable within a recipe
newappend Create a bbappend for the specified target in the specified layer
https://docs.yoctoproject.org/toaster-manual/intro.html
https://docs.yoctoproject.org/toaster-manual/start.html
https://www.yoctoproject.org/software-item/build-appliance/
https://www.yoctoproject.org/software-overview/downloads/
CROPS
CROPS (CROss PlatformS) é um projeto que provê um container Docker com um
ambiente de desenvolvimento integrado do Yocto Project, possibilitando manter um
ambiente de compilação em qualquer sistema operacional compatível com o Docker
(Windows, Linux, MacOS, etc).
https://github.com/crops/poky-container
https://autobuilder.yoctoproject.org/
CONSIDERAÇÕES FINAIS
LINKS
Site oficial do Yocto Project:
https://www.yoctoproject.org/
http://www.openembedded.org/wiki/Main_Page
Documentação do projeto:
https://docs.yoctoproject.org/
LIVROS
Embedded Linux Development with Yocto Project - Otavio Salvador/Daiane Angolini
OBRIGADO!