На компиляцию библиотеки D-Bus я потратил 2 дня. Задача не такая уж и тривиальная. При компиляции постоянно возникали какие-то проблемы, на которые прямых ответов в сети нет, есть только некоторые намёки. Теперь хочется поделиться своим опытом и с другими. Мне будет очень приятно, если руководствуясь этой статьей у кого-нибудь получится собрать D-Bus сразу, не прилагая существенных усилий
Исходные данные
Сборка библиотеки D-Bus выполняется для процессора arm.
Уточню, что библиотека dbus нужна мне для последующей сборки bluez
Для сборки нужен toolchain. Я использую toolchain, собранный для использования библиотеки glibc (думаю для сборки с uClibc отличий быть не должно)
Директория с бинарниками кросс-компилятора должна находится у вас в переменной PATH. Иными словами компилятор (например arm-unknown-linux-gnueabi-gcc) должен запускаться прямо из текущей директории.
Исходники можно взять здесь.
На момент написания статьи последняя версия была D-Bus 1.4.0
Для меня удобней написать отдельный сборочный скрипт (чем запускать команды непосредственно в консоли).
Итак, создаём файл crosscompile.sh.
Добавляем права на запуск (команда chmod +x crosscompile.sh)
Добавляем туда строки:
SYS_ROOT="${HOME}/programs/newArm2/toolchain/my_system/sys-root"
export LDFLAGS="-L${SYS_ROOT}/lib"
export CROSS_INCLUDE_DIR="-I${SYS_ROOT}/usr/include/"
./configure \
--prefix=/home/vit/programs/newArm2/compiled/dbus \
--host=arm-unknown-linux-gnueabi \
--without-x \
--enable-abstract-sockets \
&& make && make install
Внимание: обратите внимание на последнюю строчку. make должно выполнятся только в случае если завершится configure. Дело в том, что если configure не находит какую-то библиотеку, он всё-равно создаёт файлы необходимые для make, при этом make нормально запускается, но собирает всё для системы x86.
SYS_ROOT - путь к файловой системе хоста (она должна быть создана при помощи toolcain).
CROSS_INCLUDE_DIR - путь к каталогу с заголовочными файлами для кросс-компиляции
LDFLAGS - здесь указывается каталог, в котором лежат библиотеки, скомпилированные для arm
--prefix это путь, куда будет установлена библиотека dbus
--host указывает на префикс кросс-компилятора. Нужно заменить его на ваш компилятор. Иногда я встречал прямое указание компилятора, линкера и других утилит, например СС=arm-unknown-linux-gnueabi-gcc LD=arm-unknown-linux-gnueabi-ld. Работать будет, но этого делать не надо, для этого вы и указываете параметр --host, а нужное название команды подставляется в конец автоматически
Для сборки достаточно выполнить:
./crosscompile.sh
Очень важно после сборки проверить для какой системы вы собрали библиотеки. Иногда бывает, что сборка и установка успешно завершаются, а вот библиотеки оказываются не для arm, a для x86.
Для этого идём в папку, указанную в префикс, и выполняем (надо подставить свой номер библиотеки)
info lib/libdbus-1.so.3.5.2
Если видим там, что-то вроде
lib/libdbus-1.so.3.5.2: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, not stripped
,то всё замечательно. Если же там
lib/libdbus-1.so.3.5.2: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
, то дело плохо. Скорее всего ./configure выдало ошибку, но вы этого не заметили. Уберите из скрипта последнюю строчку && make && make install и бакслеш из конца предпоследней, и попробуйте запустить ещё раз.
Собранная библиотека находится в некой папке $HOME/programs/newArm2/compiled/dbus. Чтобы добавить её в вашу будущую систему, необходимо вручную скопировать все файлы в папку sys-root вашего тулчейна, ту самую, которую вы указали в переменной SYS_ROOT.
Сообщение на этапе компиляции выглядит следующим образом:
make[2]: Entering directory `/home/vit/programs/newArm2/dbus-1.4.0/tools'
CC dbus-launch.odbus-launch.c:
In function 'kill_bus_when_session_ends':
dbus-launch.c:478: error: impossible constraint in 'asm'
dbus-launch.c:479: error: impossible constraint in 'asm'
dbus-launch.c:507: error: impossible constraint in 'asm'
Скорее всего переменная CROSS_INCLUDE_DIR указана неверно, и компилятор берёт заголовочный файлы для системы под которой проходит сборка.
Сообщение на этапе конфигурации выглядит следующим образом:
checking for XML_ParserCreate_MM in -lexpat... no
configure: error: Could not find expat.h, check config.log for failed attempts
Узнать что случилось поможет вам config.log. Но сообщение об ошибке надо искать не в самом конце, а за несколько страниц до конца.
Причин тут может быть две.
Библиотека expat у вас не собрана. Для сборки dbus придётся сначала собрать библиотеку expat.
Если вы точно знаете, что библиотека libexpat у вас уже собрана и скопирована в sys_root, значит путь, прописанный в LDFLAGS на неё не указывает. Скорее всего библиотека лежит не в lib, а в usr/lib.
Самым правильным решением было бы добавить путь в LDFLAGS:
export LDFLAGS="-L${SYS_ROOT}/lib -L${SYS_ROOT}/usr/lib"
Но всякий раз, когда я указываю более одного пути в LDFLAGS, configure начинает проваливаться намного раньше. (Если кто-то знает почему - оставьте, пожалуйста, сообщение в комментариях).
Я решил эту проблему следующим образом: в папке sys_root/lib создал символическую ссылку на библиотеку libexpat, лежащую в sys_root/usr/lib:
ln -s ../usr/lib/libexpat.so libexpat.so
На всякий случай отмечу, что при использовании символической ссылки ничего менять в LDFLAGS не надо.
После этого проблема исчезла