Использование готового инструментария сборки

OpenEmbedded позволяет использовать готовые инструментарии сборки и библиотеки.

Инструментарий сборки

Предположим что инструментарий сборки предоставляет C и С++ компиляторы, ассемблер и другие необходимые при работе утилиты. В качестве примера будет использоваться инструментарий сборки gcc 3.4.4 для архитектуры ARM с использованием glibc. Предполагается что он прописан в PATH и в его состав входят следующие исполняемые файлы:

ls pre-built/cross/bin

arm-linux-g++
arm-linux-ld
arm-linux-ranlib
arm-linux-ar
arm-linux-g77
arm-linux-readelf
arm-linux-as
arm-linux-gcc
arm-linux-gcc-3.4.4
arm-linux-c++
arm-linux-size
arm-linux-c++filt
arm-linux-nm
arm-linux-strings
arm-linux-cpp
arm-linux-objcopy
arm-linux-strip
arm-linux-objdump

Готовые библиотеки

Кроме инструментария сборки необходимы заголовочные файлы и библиотеки. Каталог PRE_BUILT, содержащий их имеет следующую структуру:

ls $PRE_BUILT
include
lib
qt2

Где каталог include содержит заголовочные файлы, а каталог lib содержит разделяемые и статические библиотеки. Дополнительно присутствует подкаталог qt2, имеющий аналогичную $PRE_BUILT структуру.

Настройка OpenEmbedded

Если ваша платформа и дистрибутив не входят в OpenEmbedded, то они должны быть добавлены в файл local.conf. Кроме этого вам потребуется BitBake и текущая версия OpenEmbedded.

Скрипт настройки окружения

Для удобства стоит создать скрипт настройки окружения. Его будет необходимо запускать перед началом работы с OpenEmbnedded. Называться он будет build_source и содержит следующие параметры:

BITBAKE_PATH=/where/is/bitbake/bin
TOOLCHAIN=/where/is/toolchain/bin
HOST_TOOLS=/where/is/hosttools/bin
export PRE_BUILT=/where/is/pre-built

export PATH=$BITBAKE_PATH:$TOOLCHAIN:$HOST_TOOLS:$PATH
export OEDIR=$PWD
export LOCALDIR=$PWD/secret-isv
                    

Для проверки скрипта запустите команду source build_source, затем команду env для проверки правильности настройки окружения.

Создание local.conf

Создайте локальный файл настроек со следущими параметрами:

DL_DIR = "${OEDIR}/sources"
BBFILES := "${OEDIR}/openembedded/recipes/*/*.bb ${LOCALDIR}/recipes/*/*.bb"
BBFILE_COLLECTIONS = "upstream local"
BBFILE_PATTERN_upstream = "^${OEDIR}/openembedded/recipes/"
BBFILE_PATTERN_local = "^${LOCALDIR}/recipes/"
BBFILE_PRIORITY_upstream = "5"
BBFILE_PRIORITY_local = "10"
BBMASK = ""
                    

Где ${OEDIR}/openembedded - это репозиторий OpenEmbedded. До этого предполагалось, что он находится в текущей рабочей директории. Дополнительно добавлен каталог ${LOCALDIR} который совмещается с репозиторием OpenEmbedded как специальная коллекция BitBake.

Далее описываем, что сборка производится для ARM и оптимизируется для xscale и iwmmxt.

#
# machine stuff
#
MACHINE = "secret-killer"
PACKAGE_EXTRA_ARCHS = "armv4 armv4t armv5te iwmmxt xscale""
TARGET_CC_ARCH = "-mcpu=xscale -mtune=iwmmxt"
TARGET_ARCH = "arm"
PACKAGE_ARCH="xscale"
                

Описываем что сборка производится для linux и glibc и программной плавающей точкой вместо использования сопроцессора.

INHERIT += " package_ipk debian"
TARGET_OS  = "linux"
TARGET_FPU = "soft"
DISTRO = "secret-disro"
DISTRO_NAME = "secret-distro"
DISTRO_VERSION = "x.y.z"
DISTRO_TYPE = "release"
                

Если ваш инструментарий сборки использует uclibc вам необходимо изменить TARGET_OS на linux-uclibc.

Заменяем инструментарий сборки из bitbake.conf на готовый инструментарий сборки:

export CC="${CCACHE}arm-linux-gcc-3.4.4 ${HOST_CC_ARCH}"
export CXX="${CCACHE}arm-linux-g++ ${HOST_CC_ARCH}"
export CPP="arm-linux-gcc-3.4.4 -E"
export LD="arm-linux-ld"
export AR="arm-linux-ar"
export AS="arm-linux-as"
export RANLIB="arm-linux-ranlib"
export STRIP="arm-linux-strip"
                

Добавляем заголовочные файлы и библиотеки из PRE_BUILT в пути заголовочных файлов и библиотек . Аналогично добавляем для специальной версии Qt в каталоге PRE_BUILT:

#
# укажите где расположены каталоги lib и include для OE
#
TARGET_CPPFLAGS_append = " -I${PRE_BUILT}/include "
TARGET_LDFLAGS_prepend = " -L${PRE_BUILT}/qt2/lib -L${PRE_BUILT}/lib \
-Wl,-rpath-link,${PRE_BUILT}/lib -Wl,-rpath-link,${PRE_BUILT}/qt2/lib "

# special to Qt/Qtopia
QTDIR  = "${PRE_BUILT}/qt2"
QPEDIR = "${PRE_BUILT}"
palmtopdir = "/opt/Qtopia"
palmqtdir  = "/opt/Qtopia"
                

Указываем BitBake что библиотека C, компилятор и Qtopia уже имеются. Эти строки блокируют сборку binutils, gcc initial, glibc, gcc.

ASSUME_PROVIDED += " virtual/${TARGET_PREFIX}gcc "
ASSUME_PROVIDED += " virtual/libc "
ASSUME_PROVIDED += " virtual/qte "
ASSUME_PROVIDED += " virtual/libqpe "
ASSUME_PROVIDED += " libqpe-opie "
                
Сохраняем файл и запускаем для проверки следующие команды:
source build_source
bitbake your-killer-app
                

Если они завершились успешно, то подключение готового инструментария сборки прошло успешно.

Полезные приемы

Если у вас имеются дополнительные готовые библиотеки, то их можно подключить при помощи дополнительных строк с ASSUME_PROVIDED в вашем local.conf. Для проверки запустите bitbake -vvv PACKAGE в ее ответе, вы увидите какие пакеты были подключены при помощи ASSUME_PROVIDED.

Возможные проблемы

Если при сборке вы видите похожие сообщения:
NOTE: Couldn't find shared library provider for libqtopia.so.1
NOTE: Couldn't find shared library provider for libqtopia2.so.2
NOTE: Couldn't find shared library provider for libqpe.so.1
NOTE: Couldn't find shared library provider for libpthread.so.0
NOTE: Couldn't find shared library provider for libstdc++.so.6
NOTE: Couldn't find shared library provider for libqte.so.2
NOTE: Couldn't find shared library provider for libgcc_s.so.1
NOTE: Couldn't find shared library provider for libc.so.6
NOTE: Couldn't find shared library provider for libm.so.6

То это указывает на то, что OpenEmbedded пытается автоматически добавить зависимости выполнения (RDEPENDS) в пакет. При этом используется система shlibs для добавления, в результате пакеты предоставляющие эти библиотеки не находятся, так как они были подключены как готовые. Из-за этого, необходимые пакеты не добавляются в RDEPENDS созданого пакета. Результаты такого поведения могут быть фатальны. К примеру если вы используете OpenEmbedded для создания образов, вы можете получить образ без установленной libc. Для обхода этой проблемы можно создать рецепты для установки каждый из необходимых библиотек и воспользоваться ${BOOTSTRAP_EXTRA_RDEPENDS}, чтобы быть уверенным в том что пакеты добавляются при компоновке образа.

Но, вместо этого лучше использовать параметр ASSUME_SHLIBS. К примеру, для библиотек приведенных выше, это будет выглядеть так (указана только часть библиотек):

ASSUME_SHLIBS = "libqtopia2.so.2:qtopia2_2.4 libc.so.6:libc"

Формат элемента списка shlib_file_name:package[_version]. Если указана версия, то она учитывается на минимально допустимая в зависимостях.