OpenEmbedded/bb

Материал из b4wiki

Перейти к: навигация, поиск

Содержание

Заголовок пакета

Каждый пакет начинается с заголовка. Информация из заголовка напрямую попадает в пакет.

  • DESCRIPTION - информация о пакете. Что за пакет и для чего предназначен. Дефолтное описание: "Version ${PV}-${PR} of package ${PN}".
  • HOMEPAGE - домашняя страничка, где лежат релизы и более подробная информация. Дефолтная страничка - Unknown.
  • SECTION - используется для категоризации пакетов по группам. Дефолтное значение - base.
  • PRIORITY - как видно из названия (С) День Радио ;) - приоритет пакета. Дефолтное значение - optional.
  • LICENSE - лицензия, по которой распространяется приложение. Также используется в src_distribute классе. Дефолтная лицензия - unknown.

Исходные коды: получение и обработка

Каждый (почти каждый) *.bb файл содержит информацию об исходных кодах - где взять, как пропатчить, как собрать и тд. За дислокацию исходных кодов отвечает перменная SRC_URI. SRC_URI поддерживает несколько типов URI:

  • http и https - указывает на файлы, которые надо скачать. Копия этих файлов будет сохранена локально и не будет скачиваться повторно. Понимает архивы - будут распакованы автоматически.
  • cvs,svn и git - тоже указывает фалы для скачивания при помощи указанной VCS
  • files - файлы, которые включены в пакет и распространяются вместе с ним.
  • patches - тоже что и files, только интерпретируются как патчи и OpenEmbedded их автоматически применит перед сборкой. ( Это видимо устарело - сейчас патчи прописывают в files )

Пример:

 SRC_URI = "\
 http://www.busybox.net/downloads/busybox-${PV}.tar.gz \
 \
 file://udhcpscript.patch;patch=1 \
 file://B921600.patch;patch=1 \
 file://r24785.patch;patch=1;status=merged \
 file://find-touchscreen.sh \
 file://busybox-cron \
 file://busybox-httpd \
 file://busybox-udhcpd \
 file://default.script \
 file://hwclock.sh \
 file://mount.busybox \
 file://syslog \
 file://syslog.conf \
 file://umount.busybox \
 file://defconfig \
 file://mdev \
 file://mdev.conf"

Зависимости: сборка и запуск

Для кого deb и rpm не только три веселых буквы, но и пакет с программами - тот знаком с зависимостями. Зависимости могут быть двух типов - для сборки и для запуска. Для обработки с зависямостями предусмотрены 2 переменные:

  • DEPENDS - список зависимостей для сборки пакета. Каждый элемент списка - другой *.bb пакет.
  • RDEPENDS - список зависимостей для запуска программ из пакета. Все что в списке - будет установлено перед установкой этого пакета.

Причем если что-то из зависимостей динамически слинковано с какой-то либой - эта либа будет автоматически добавлена в зависимости.

Пакет

После того как все скачано, собрано и готово к уптреблению - надо это все собрать в пакет (ipk или deb - по желанию). Для этого надо все что должно попасть в пакет из диркетории ${S} (директория с исходными кодами и собранными программами) положить в директорию ${D} (как бы rootfs для 1 пакета). Для этого существует метод do_install. Вот пример из b4-drv-exp:

  do_install() {
    install -m 0755 \
      -d ${D}/lib/modules/${KERNEL_VERSION}/extra
    for i in `find ${S} -name \*.ko`
    do
      install -m 0644 $i \
         ${D}/lib/modules/${KERNEL_VERSION}/extra/
    done
   
    install -m 0755 -d ${D}/etc/init.d
    install -m 0755 ${S}/scripts/etc/init.d/exp \
      ${D}/etc/init.d/exp
 }

Сейчас в голове, наверное, возникает жуткая картина - написание одного и того же do_install для 5 версий одного пакета. Все не так плохо - можно функцию do_install вытащить в отдельный файл, и положить там же где и *.bb файлы с разными версиями этого пакета. А там где внутри *.bb файла должен быть метод do_install просто подключить этот файл директивой include <filename.ext>. Если же одинаковый do_install будет использоваться в нескольких разных пакетах (include тут уже не поможет) - то do_install можно вынести в класс (про классы позже) и подключать при помощи inherit <classname>. Теперь надо обозначить какие файлы из ${D} класть в пакет: для этого служит переменная FILES_${PN}. Скорей всего в ${D} лежит только необходимое и его целиком надо запаковать в пакет:

FILES_${PN} = "/*"

Один *.bb файл может собираться в несколько пакетов. Для таких случаев есть переменная PACKAGES:

PACKAGES = "${PN} ${PN}-doc ${PN}-dev \
   ${PN}-dbg ${PN}-locale"

Для распределения файлов по пакетам служат переменные:

  FILES_${PN}
  FILES_${PN}-doc
  FILES_${PN}-dev
  FILES_${PN}-dbg
  FILES_${PN}-locale

В этом случае надо еще и рассказать BitBake`у что предоставляет наш пакет. Пакет, как минимум, всегда предоставляет сам себя. Далее есть еще две переменные:

  • PROVIDES - cписок того, что предоставляет данный пакет в compile-time.
  • RPROVIDES - список того, что предоставляет данный пакет в run-time.

Если пакет предоставляет только сам себя - можно не инициализировать PROVIDES и RPROVIDES ничем. В противном случае это будет выглядить примерно так (на примере external-toolchain):

  PROVIDES = "\
   linux-libc-headers \
   virtual/${TARGET_PREFIX}gcc \
   virtual/${TARGET_PREFIX}gcc-initial \
   virtual/${TARGET_PREFIX}gcc-intermediate \
   virtual/${TARGET_PREFIX}binutils \
   virtual/${TARGET_PREFIX}libc-for-gcc \
   virtual/libc \
   virtual/libintl \
   virtual/libiconv \
   "
 
  RPROVIDES = "glibc-utils libsegfault \
    glibc-thread-db \
    libgcc-dev libgcc libstdc++-dev libstdc++"

Пример обычного *.bb файла

В данном случае это пакет с драйверами и служебными скриптами для карт расширения от B4:

 DESCRIPTION = "b4 exp module - provides acces to expansion cards"
 PACKAGES = "b4-drv-exp"
 RDEPENDS = "b4-drv-base b4-drv-bridge"
 SRC_URI = "svn://srv/b4/branch;module=drv.oe/arch/exp/base;rev=HEAD\
            svn://srv/b4/branch;module=drv.oe/char/dsfifo;rev=HEAD\
            svn://srv/b4/branch;module=drv.oe/arch/exp/unknown;rev=HEAD\
            svn://srv/b4/branch;module=drv.oe/scripts/etc/init.d;rev=HEAD\
            svn://srv/b4/branch;module=drv.oe/include;rev=HEAD"
  
 do_compile() {
         unset LDFLAGS
         oe_runmake BITBAKE=1 -C ${STAGING_KERNEL_DIR}/ \
         M=${S}/arch/exp/base/ CFLAGS="${CFLAGS} ${EXTRA_FLAGS}" modules
         oe_runmake BITBAKE=1 -C ${STAGING_KERNEL_DIR}/ \
         M=${S}/char/dsfifo CFLAGS="${CFLAGS} ${EXTRA_FLAGS}" modules
         oe_runmake BITBAKE=1 -C ${STAGING_KERNEL_DIR}/ \
         M=${S}/arch/exp/unknown CFLAGS="${CFLAGS} ${EXTRA_FLAGS}" modules
 }
  
 inherit b4drv
  
 do_install() {
         install -m 0755 -d ${D}/lib/modules/${KERNEL_VERSION}/extra
         for i in `find ${S} -name \*.ko`
         do
           install -m 0644 $i ${D}/lib/modules/${KERNEL_VERSION}/extra/
         done
 
         install -m 0755 -d ${D}/etc/init.d
         install -m 0755 ${S}/scripts/etc/init.d/exp ${D}/etc/init.d/exp
 }
    
 pkg_postinst() {
 #!/bin/sh
 depmod -a
 update-rc.d exp remove -f
 update-rc.d exp start 86 S .
 /bin/chmod +x /etc/init.d/exp
 }
  
 pkg_postrm() {
 #!/bin/sh
 update-rc.d -f exp remove
 }

pkg_postinst() и pkg_postrm() - соотвественно скрипты postinst и postrm для пакета.

А вот класс, который он использует:

 # This needed for getting kernel version from kernel sources
 inherit linux-kernel-base
 KERNEL_VERSION = "${@get_kernelversion('${STAGING_KERNEL_DIR}')}"
 
 SECTION = "kernel"
 LICENSE = "GPL"
 DEPENDS += "linux-b4-2.6"
 MAINTAINER = "y.ludkevich@metrotek.spb.ru"
 HOMEPAGE = "b4open.ru"
 PRIORITY = "required"
 PACKAGE_ARCH = "b4"
 
 # Setting sources dir
 S = "${WORKDIR}/drv.oe"
 
 COMPATIBLE_HOST = "arm.*-linux"
 COMPATIBLE_MACHINE ?= '(b4)'
 
 # Adding modules to package
 FILES_${PN} = "/*"
 # Setting CFLAGS
 CFLAGS ="-D__KERNEL__ -I${STAGING_KERNEL_DIR}/include\
        -I${S}/include -Wall -Werror\
        -fno-common -D__LINUX_ARM_ARCH__=5"
 
 do_install() {
         install -m 0755 -d ${D}/lib/modules/${KERNEL_VERSION}/extra
         for i in `find ${S} -name \*.ko`
         do
           install -m 0644 $i ${D}/lib/modules/${KERNEL_VERSION}/extra/
         done
 }

Как видно - в класс вынесены все общее, используемое во всех b4-drv*.bb файлах. Внутри класса можно подключать другой класс.

разное