Вопрос или проблема
У меня есть окружение chroot с qemu-armhf на машине amd64 (в основном для компиляции кода для Raspberry Pi). Таким образом, оно может запускать как armhf, так и amd64 бинарные файлы, но быстрее выполнять последние.
Существуют определенные пакеты (например, make), для которых я установил версию amd64 внутри chroot, чтобы получить более высокую скорость. Это хорошо работает до тех пор, пока мне не нужно установить другой пакет armhf с помощью apt-get, и если он имеет make в качестве зависимости, тогда я получаю это:
Следующие пакеты имеют неудовлетворенные зависимости:
build-essential : Зависит: make, но он не будет установлен
dpkg-dev : Зависит: make, но он не будет установлен
E: Неудовлетворенные зависимости. Попробуйте 'apt-get -f install' без пакетов (или укажите решение).
Если я попробую команду, которую предложили, то она говорит, что хочет установить make:armhf
и удалить make:amd64
. Я не хочу, чтобы это происходило. Как мне объяснить APT, что make:armhf
уже установлен (потому что я хочу, чтобы он использовал make:amd64
для удовлетворения зависимостей) без фактической установки?
Я пробовал использовать apt-mark manual make
, но он говорит, что он не установлен.
Я знаю, что это, вероятно, не лучший способ, но я смотрел файл /var/lib/dpkg/status
, чтобы попытаться разобраться, как он считает, что работают определения пакетов, и попытаться обмануть его, чтобы согласился, что make:amd64 также удовлетворяет make:armhf.
В частности, я заметил, что “libbz2-1.0” – это пакет, который указан как установленный дважды; один раз как:
Architecture: armhf
Multi-Arch: same
Pre-Depends: multiarch-support
и один раз как:
Architecture: amd64
Multi-Arch: foreign
Pre-Depends: multiarch-support
Поэтому я попытался дублировать записи для “make” аналогично, установив все вышеуказанные значения. Но теперь APT просто говорит, что “make” и “make:amd64” конфликтуют. Почему это конфликт, когда делает make, но не когда это делает libbz2-1.0? (Я надеюсь, что это не особый случай для библиотек; это выглядит как ошибка.)
Согласно этому ответу, я пытался создать фиктивный пакет с помощью equivs
и установить его (после удаления моих ручных манипуляций выше), но установка вызывает следующие ошибки:
# dpkg -i /var/cache/apt/archives/make_3.81-8.2_amd64.deb (реальный amd64 make)
# dpkg -i make_3.81-8.2_armhf.deb (фиктивный armhf зависит от вышеуказанного)
Подготовка к замене make 3.81-8.2 (используя make_3.81-8.2_armhf.deb) ...
Распаковка заменяющего make ...
dpkg: проблемы с зависимостями предотвращают настройку make:
make зависит от make:amd64 (= 3.81-8.2).
Таким образом, снова проблема заключается в том, что он считает make:armhf заменой для make:amd64, и я не знаю, как объяснить ему, что я хочу, чтобы эти два пакета сосуществовали. (Кажется, у него нет проблемы с идеей сосуществования двух пакетов libbz2, например.)
Я не много играл с системами multiarch, поэтому вполне возможно, что есть лучший способ, чем тот, который я предлагаю здесь. Я не тестировал свое предложение, не уверен, что оно не противоречит какой-то особенности multiarch.
Вы можете использовать equivs для создания фиктивных пакетов только для зависимостей.
- Создайте файл управления с помощью
equivs-control make.control
- Отредактируйте файл управления: установите
Package: make
,Architecture: armhf
,Depends: make:amd64
, иMulti-Arch: foreign
. Вы также можете установитьVersion
в соответствии с версией amd64 make. - Создайте фиктивный пакет:
equivs-build make.control
- Установите фиктивный пакет в chroot
Если это не удовлетворяет dpkg, другой подход, который будет работать, но менее удобен, – это не устанавливать amd64 make внутри chroot, а вместо этого сделать доступным корневой каталог хоста внутри chroot (с помощью привязки каталога, см. Предоставление /bin и /lib внутри chroot-тюрьмы для примеров), или по крайней мере бинарный файл make
и его зависимости (которые для make
– это просто libc). Добавьте каталог, в котором монтируется бинарный файл, в PATH. Создайте фиктивный пакет, как указано выше, но просто объявите make
как установленный, не добавляя никаких Depends
или заголовков Multi-Arch
.
Это сообщение означает “если установлены два пакета с различной архитектурой с одинаковым именем, они должны быть точно одной и той же версии.”
Это связано с тем, что оба предоставляют /usr/share/doc/.../changelog.Debian
и несколько других, и конфликт файлов здесь допустим, если оба устанавливают один и тот же файл.
Однако это не сработает для make
, потому что оба пакета предоставляют различные /usr/bin/make
.
Я полагаю, вы можете использовать --auto-deconfigure
, чтобы разрешить dpkg установить пакеты, зависимые от make
, в состояние unpacked
(состояние installed
), что вызовет повторное выполнение их postinst
, и это позволит удалить make:amd64
в пользу make:armhf
.
Ответ или решение
Для решения проблемы с наличием конфликтов зависимостей в среде chroot, где вы используете пакеты разных архитектур, необходимо продумать стратегию, которая позволит APT не требовать установки armhf версии пакета make
, если у вас уже установлена amd64 версия. Давайте рассмотрим несколько подходов к данной задаче.
Понимание конфликта зависимостей
Когда вы работаете в среде с множественными архитектурами (multiarch), важно понимать, что APT предъявляет строгие требования к версиям пакетов. Если два пакета (например, make:armhf
и make:amd64
) имеют одинаковое имя и предоставляют одни и те же файлы (что особенно критично для бинарных файлов), они должны быть одинаковой версии. В противном случае может возникнуть конфликт.
Подход 1: Создание фиктивного пакета с помощью equivs
-
Создание конфигурационного файла:
Сначала создайте контроллерный файл с помощью командыequivs-control make.control
. -
Редактирование контроллера:
В контроллере укажите следующие параметры:Package: make Architecture: armhf Depends: make:amd64 Multi-Arch: foreign Version: 3.81-8.2 # или текущая версия вашего amd64 пакета
-
Создание фиктивного пакета:
Выполните командуequivs-build make.control
, чтобы создать фиктивный пакет. -
Установка фиктивного пакета:
Установите созданный пакет в вашу среду chroot. Это должно позволить APT считать, что зависимостьmake:armhf
удовлетворена, учитывая установленныйmake:amd64
.
Подход 2: Использование способа с привязкой (bind mount)
Если создание фиктивного пакета не дает желаемого результата, вы можете использовать привязку каталогов из родительской системы:
-
Создание привязок:
Присоедините необходимые бинарные файлы из родительской системы в вашу chroot среду (например,/bin
,/lib
и т.д.) с помощью командыmount --bind
. -
Обновление переменной PATH:
Обновите вашу переменную PATH, чтобы она содержала путь к бинарным файлам, которые вы примонтировали. -
Создание фиктивного пакета:
Создайте фиктивный пакет, который объявляет, чтоmake
установлен, но не содержит зависимости и заголовков Multi-Arch.
Примечания о конфликте
Обратите внимание, что в случае libbz2-1.0
, пакет не вызывает конфликтов благодаря соглашению о многопоточности. Однако для make
, поскольку они имеют разные бинарные файлы, создание двух одинаковых имен пакетов с различными архитектурами требует точного соблюдения версий и может вызвать конфликт.
Заключение
Использование фиктивных пакетов с equivs
или создание привязок может помочь в управлении зависимостями в вашей chroot среде. При этом важно контролировать версии пакетов и архитектуры, чтобы избежать ненужных конфликтов. Если ни один из предлагаемых подходов не работает, возможно, стоит рассмотреть возможность использования другой версии или метода установки пакетов.