illumium.org

Главная › Блоги › Блог kayo

Собираем софт для 32х-битных машин в 64х-битной системе

kayo — Пнд, 31/10/2011 - 00:34

Сказать по правде, не часто возникает необходимость собирать что-либо для x86_32, поскольку почти всё моё рабочее оборудование имеет архитектуру x86_64, а что касается пакетов для дистрибутивов, то их сборка обычно происходит на специально предназначенных для этого сервисах Launchpad.Net, Build.OpenSUSE.Org и им подобных. Однако бывают случаи, когда нам нужно просто скомпилировать программу, не создавая пакет, либо собрать пакет средствами этих сервисов по каким-либо причинам не представляется возможным.

Присказка об OpenEmbedded и BitBake

Когда впервые возникла потребность в сборке под 32-битную систему, у меня была как раз вторая ситуация. Есть такой проект, как OpenEmbedded, это по сути «большая энциклопедия рецептов» для полностью автоматизированной сборки всего, что только можно собрать, под любое железо. Проект использует систему сборки BitBake, которая путём анализа так называемых «рецептов» делает всё, что требуется, чтобы достичь цель: выкачивает необходимые исходники, корректным образом конфигурирует всё под задачу, собирает и вуаля. Однако на практике это оказывается куда суровее, чем в теории:

  1. Необходим интернет, чтобы стягивать исходники.
  2. Даже если у нас уже получены все необходимые исходники, все вместе они могут занимать гигабайты места на диске.
  3. Сборка обычно, дело весьма не быстрое, даже при параллелизации процесса занимает несколько часов, а то и суток.
  4. Как вы понимаете, в процессе сборки занимается ещё больше места на диске, в основном потому, что файловые системы не очень компактно хранят огромные количества мелких файлов.

Всё из выше сказанного делает практически невозможным создание пакетов, которые будут собираться с нуля на специализированных сервисах с использованием OpenEmbedded. И, наверно, единственный путь — собрать пакеты под все требуемые архитектуры самостоятельно и вместо пакета исходных текстов создать бинарный пакет.

Сказка о Chroot, Debootstrap и Linux32

Собственно так и было решено поступить. Системы с amd64 у меня всегда под боком, однако для сборки нам также непременно понадобится i386 окружение. Конечно, ничто не мешает установить все необходимые 32-битные пакеты в 64-битную систему, однако мне не хотелось засорять корневую фс неведомым хламом, который при случае не просто будет вычистить, поэтому решено было использовать отдельное chroot окружение. Нам потребуется утилита debootstrap, она поможет создать начальный экземпляр корневой файловой системы с нужным дистрибутивом и архитектурой. Всё довольно тривиально, и разобраться во всех тонкостях работы данной утилиты, думаю не составит особого труда. В моём случае потребовалось следующее:

sudo apt-get install debootstrap
sudo mkdir /usr/local/ubuntu-i386
sudo debootstrap --arch i386 oneiric /usr/local/ubuntu-i386 http://archive.ubuntu.com/ubuntu

Если всё прошло гладко, то можно приступить к chroot-ингу в наше новое окружение. То что мы должны сделать: примонтировать всё что нужно в наше окружение, а затем погрузиться в него, после завершения работы должны не забыть отмонтировать всё, что примонтировали. В общем действий не мало, поэтому я написал простенький скрипт dive.sh и положил его в каталог /usr/local/ubuntu-i386:

#!/bin/sh

path="$PWD"
[ -z "$_" ] && path="$path/somehere" || path="$path/$_"

# корень окружения
home="$(echo "$path" | sed -r -e 's/\/{2,}/\//g' -e 's/\/(\.\/)+/\//g' -e 's/\/[^\/]*$//')"

# что будем монтировать
mnts="proc sys dev dev/pts home"
# что будем отмонтировать
umnt="home dev/pts dev sys proc"

# монтируем
for n in $mnts; do
  mount -o bind /$n $home/$n 
done

# погружаемся
chroot $home

# немножко релаксируем, пока все ресурсы не освободились
sleep 1

# отмонтируем
for n in $umnt; do
  umount $home/$n
done

Теперь если выполнить скрипт от рута, мы попадём в новое окружение, однако нам скорее всего не понравиться то, что мы там увидим, поэтому наведём порядок. Первое, что нам скорее всего захочется сделать, это настроить локали:

# Ставим нужный пакет
apt-get install locale
# Генерируем нужные локали
locale-gen en_US.UTF-8 ru_RU.UTF-8

Теперь может потребоваться создать пользователей, я добавил себя, чтобы работать со своими файлами в реальном домашнем каталоге, который мы пробиндили выше:

# Добавляем пользователя с такими же uid и gid, как и в родительской системе
# Группа с именем пользователя создаётся автоматически
adduser kayo --uid 1000 -gid 1000
# Пробуем стать только что созданным пользователем
su - kayo
# Смотрим, что у нас в домашнем каталоге, должно быть много хорошо знакомых файлов ^_^
# Заодно проверяем, чтобы у файлов был правильный владелец и группа
ls -al
# Выходим
exit

Теперь можно ставить всё что угодно на наше усмотрение, я в первую очередь поставил build-essential и bitbake:

apt-get install build-essential bitbake

При этом, потребовалось добавить подгруппу universe после main в /etc/apt/sources.list, потому что bitbake нет в main-е. BitBake поругался на то, что у меня оболочка не Bash, поэтому установил её и сделал по умолчанию:

apt-get install bash
dpkg-reconfigure dash
# Выбираем bash

Проделав это, вы уже будете многим довольны, однако это ещё далеко не всё. Например, если попробуете выполнить uname -a, то получите сведения о том, что вы находитесь вовсе не в i386 системе, а в x86_64, многие системы сборки получают информацию о системе хоста от этой утилиты, поэтому необходимо с ней что-то делать. Первая мысль была написать фэйк этой утилиты, однако погуглив немного, наткнулся на уже готовое решение, которое называется linux32:

# Ставим
apt-get install linux32
# Пробуем обмануть себя
linux32
# Проверяем, что получилось
uname -a
# Должны увидеть уже не x86_64

Данная утилита использует механизм LD_PRELOAD, добавляя разделяемую библиотеку, с фэйками функций, выдающих информацию об архитектуре, во всём остальном функциональность ни коим образом не страдает. Теперь можем добавить эту команду после chroot в наш скрипт.

Но и это ещё не всё, запустив BitBake, я получил множество сообщений об ошибках, оказалось, что программа использует разделяемую память shm, а соответствующее устройство не примонтировано, поэтому в список монтирования и отмонтирования добавим следующее: run, run/shm, и на всякий случай run/lock.

Для удобства я также сделал возможность с запуска скрипта с ключом user, чтобы, падая в окружение, сразу становиться обычным пользователем, и вот что в итоге у меня получилось:

#!/bin/sh

path="$PWD"
[ -z "$_" ] && path="$path/somehere" || path="$path/$_"

home="$(echo "$path" | sed -r -e 's/\/{2,}/\//g' -e 's/\/(\.\/)+/\//g' -e 's/\/[^\/]*$//')"

mnts="proc sys run run/shm run/lock dev dev/pts home"
umnt="home dev/pts dev run/lock run/shm run sys proc"

for n in $mnts; do
  mount -o bind /$n $home/$n 
done

if [ "$1" = "user" ]; then
  opts="su - kayo"
fi

chroot $home linux32 $opts
sleep 1

for n in $umnt; do
  umount $home/$n
done

Вот и всё, удачного погружения.

  • bitbake
  • chroot
  • cross developing
  • debootstrap
  • linux32
  • openembedded
  • Бортовой журнал Иллюмиума

Отправить комментарий

Содержимое этого поля является приватным и не будет отображаться публично.
  • Доступные HTML теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Syntax highlight code surrounded by the {syntaxhighlighter SPEC}...{/syntaxhighlighter} tags, where SPEC is a Syntaxhighlighter options string or "class="OPTIONS" title="the title".

Подробнее о форматировании

CAPTCHA
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.
                  ____   _   _  _     ____  
_ _ __ __ / ___| | | | || | | _ \
| | | | \ \/ / | | _ | | | || |_ | |_) |
| |_| | > < | |_| | | | |__ _| | __/
\__, | /_/\_\ \____| |_| |_| |_|
|___/
Введите код, изображенный в стиле ASCII-арт.
RSS-материал

Навигация

  • Подшивки
  • Фотоальбомы

«Иллюмиум» на якоре.

Работает на Drupal, система с открытым исходным кодом.

(L) 2010, Illumium.Org. All rights reversed ^_~