Ошибка сборки vhci_hcd deb-пакета для Linux 6.1/6.12
Исправление ошибки 'отказано в доступе' при сборке vhci_hcd для ядер Linux 6.1 и 6.12. Правка Makefile, использование DESTDIR, debian/rules и dh_auto_install для корректной упаковки deb-пакета без записи в /usr/include.
Почему сборка пакета vhci_hcd завершается ошибкой при попытке создать deb-пакет для ядра Linux 6.1 и 6.12?
При сборке vhci_hcd для ядер Linux 6.1 и 6.12 возникает следующая ошибка:
make[2]: выход из каталога «/usr/src/linux-headers-6.12.48+deb13-amd64»
mkdir -vp /usr/include/linux && cp -vf usb-vhci.h /usr/include/linux/
'usb-vhci.h' -> '/usr/include/linux/usb-vhci.h'
cp: невозможно создать обычный файл '/usr/include/linux/usb-vhci.h': Отказано в доступе
make[1]: *** [Makefile:41: default] Ошибка 1
make[1]: выход из каталога «/home/nihi1ist/.src/vhci-hcd/1.15.1/usb-vhci-hcd-1.15.1»
dh_auto_build: error: make -j12 "INSTALL=install --strip-program=true" returned exit code 2
make: *** [debian/rules:19: binary] Ошибка 2
dpkg-buildpackage: ошибка: debian/rules binary subprocess returned exit status 2
Что я делаю не так при сборке пакета vhci_hcd?
vhci_hcd сборка ошибка возникает потому, что upstream Makefile при установке пытается скопировать заголовок прямо в системный каталог /usr/include/linux/, из‑за чего в процессе создания deb-пакета команда cp падает с «Отказано в доступе» для ядер Linux 6.1 и 6.12. Правильный путь — не писать в /usr/include во время сборки пакета: использовать staging (например, debian/tmp) через DESTDIR или поправить Makefile/debian/rules (или временно — fakeroot/ручная установка для теста), а не собирать/устанавливать в систему от root.
Содержание
- Почему vhci_hcd сборка завершается ошибкой (отказано в доступе)
- Правильный способ упаковки Debian: debian/tmp, DESTDIR и dh_install
- Исправление Makefile: примеры патча и шаблоны INSTALL/DESTDIR
- debian/rules и dh_auto_install: переопределение и примеры
- Особенности сборки для linux 6.1 и linux 6.12
- Пошаговое решение: команды и проверка
- Отладка и проверка: как убедиться, что всё ок
- Источники
- Заключение
Почему vhci_hcd сборка завершается ошибкой (отказано в доступе)
В логе видно прямо проблемную строку: Makefile выполняет
mkdir -vp /usr/include/linux && cp -vf usb-vhci.h /usr/include/linux/
(см. исходный Makefile проекта). Такая команда пытается записать файл в системный каталог /usr/include, а процесс сборки deb-пакета запускается не с реальными root‑правами и не должен изменять систему. В результате cp падает с «Отказано в доступе» — обычная реакция ОС на попытку записи в защищённый каталог. Подчёркиваю: даже если вы используете fakeroot, это не даёт права на создание реальных файлов в /usr/include — fakeroot лишь фальсифицирует метаданные при упаковке, но не снимает ограничений файловой системы. См. пример в Makefile: https://raw.githubusercontent.com/linuxbuh/vhci_hcd/main/Makefile.
Почему это плохо для Debian-пакета? Debian-процесс сборки ожидает, что файлы будут установлены в staging-папку (обычно debian/tmp), а затем инструменты dh_* перенесут их в пакет; прямые записи в /usr во время сборки нарушают политику и ломают dh_auto_install/dpkg-buildpackage. Подробно про поведение dh_install и staging смотрите в документации Debian: https://manpages.debian.org/testing/debhelper/dh_install.1.en.html и https://www.debian.org/doc/manuals/maint-guide/dother.en.html.
Правильный способ упаковки Debian: debian/tmp, DESTDIR и dh_install
Идея простая: не писать в системные каталоги при сборке. Вместо этого — установить файлы в staging (например, debian/tmp) и позволить dh_install/debhelper положить их в пакет. Общая практика:
- upstream Makefile должен поддерживать
DESTDIR(и/илиPREFIX), чтобы установка шла в$(DESTDIR)$(PREFIX)/...; - при сборке в
debian/rulesзапускаютmake install DESTDIR=$(CURDIR)/debian/tmp(илиdh_auto_install -- DESTDIR=$(CURDIR)/debian/tmp), после чегоdh_installкопирует изdebian/tmp.
Пример запуска вручную (что делает dh_auto_install автоматически):
make install DESTDIR=$(pwd)/debian/tmp
Документация debhelper: https://manpages.debian.org/testing/debhelper/dh_install.1.en.html.
Если upstream Makefile уже поддерживает DESTDIR — всё просто. Если нет — нужно править Makefile или в debian/rules вручную скопировать нужные файлы в debian/tmp.
Исправление Makefile: примеры патча и шаблоны INSTALL/DESTDIR
Если Makefile содержит жёстко прописанный путь /usr/include/linux, замените установку на использование DESTDIR и стандартных переменных. Пример «правильной» установки:
Было (проблемный кусок):
mkdir -vp /usr/include/linux && cp -vf usb-vhci.h /usr/include/linux/
Станет (рекомендуется):
INSTALL ?= install -Dm644
PREFIX ?= /usr
DESTDIR ?=
install:
$(INSTALL) usb-vhci.h "$(DESTDIR)$(PREFIX)/include/linux/usb-vhci.h"
Такая правка разрешает сборщику употреблять DESTDIR=$(CURDIR)/debian/tmp и избежать записи в систему. Если вы не можете править upstream напрямую, создайте патч в debian/patches (quilt) и применяйте его при сборке пакета.
Заметьте: использование install -D сохраняет права и создает промежуточные директории корректно. Простые cp/mkdir с абсолютными путями — плохая практика для пакетов.
debian/rules и dh_auto_install: переопределение и примеры
Частый и удобный способ — добавить в debian/rules переопределение dh_auto_install, чтобы передать DESTDIR:
Пример минимального debian/rules (debhelper/dh):
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_install:
dh_auto_install -- DESTDIR=$(CURDIR)/debian/tmp
Запуск dh_auto_install с дополнительными аргументами передаст их make’у (если Makefile поддерживает DESTDIR). После этого dh_install найдёт файлы в debian/tmp и упакует их в .deb. Подробности: https://manpages.debian.org/testing/debhelper/dh_install.1.en.html и обсуждение типичных проблем в сообществе: https://unix.stackexchange.com/questions/84162/building-debian-package-fails-at-dh-auto-install-stage.
Если Makefile полностью игнорирует DESTDIR, в override_dh_auto_install можно вручную создать нужные каталоги и скопировать файлы в debian/tmp через install -Dm644 ....
Особенности сборки для linux 6.1 и linux 6.12
Отдельно: помимо проблемы с путями, код модуля может требовать небольшого обновления для новых версий ядра. В репозитории уже упоминались совместимые правки (например, замена show_debug_output на debug_output_show, добавление нужных include), см. обсуждение: https://github.com/linuxbuh/vhci_hcd/issues/1. Также убедитесь, что установлены заголовки для нужного ядра (linux-headers-6.12...) и что вы собираете модуль против корректного каталога сборки — часто используют:
make KVERSION="$(uname -r)" KSRC=/lib/modules/$(uname -r)/build
или по инструкции из README: https://github.com/linuxbuh/vhci_hcd/blob/main/README.md и примеры в сторонних форках: https://github.com/augin/vhci_hcd. Если модуль не компилируется под 6.12 — возможно, нужны патчи к исходникам (API-измения).
Пошаговое решение: команды и проверка
- Проверьте Makefile на жёсткие
/usr/includeупоминания:
grep -n "/usr/include" Makefile
- Если есть — исправьте Makefile на использование
DESTDIR/PREFIXили добавьте секциюinstallсinstall -Dm644 .... - Если не хотите менять upstream прямо сейчас — в
debian/rulesпереопределитеdh_auto_installи вручную скопируйте файлы вdebian/tmp:
mkdir -p debian/tmp/usr/include/linux
install -Dm644 usb-vhci.h debian/tmp/usr/include/linux/usb-vhci.h
- Соберите пакет обычной командой (без sudo):
dpkg-buildpackage -us -ucилиdebuild -us -uc
- Проверьте содержимое staging и итогового пакета:
ls debian/tmp/usr/include/linux/usb-vhci.hdpkg -c ../vhci_hcd_*.deb | grep usb-vhci.h
Если сборка всё ещё требует прав доступа — это признак того, что где-то остались абсолютные записи в Makefile или что вы пытались выполнять install вне staging.
Отладка и проверка: как убедиться, что всё ок
- Внимательно следите за выводом
dh_auto_installв логе сборки: он должен показывать установку вdebian/tmp, а не в/usr. - После успешной сборки проверьте
.debчерезdpkg -c— нужный заголовок и файлы должны быть внутри пакета, а не в вашей системе. - Для тестовой загрузки модуля используйте ручную установку модулей (только для проверки):
sudo insmod drivers/usb/usbip/usbip-core.ko && sudo insmod drivers/usb/usbip/vhci-hcd.ko(см. инструкции установки модулей: https://askubuntu.com/questions/1303403/how-to-install-usbip-vhci-hcd-drivers-on-an-aws-ec2-ubuntu-kernel-version). Но не используйтеsudo make installдля формирования пакета — это обходной путь, а не решение.
Если после всех правок остаются ошибки, сверяйтесь с issue-трекером проекта и логами компиляции — возможно, требуется адаптация к API ядра 6.12 (см. обсуждения в репозитории).
Источники
- https://raw.githubusercontent.com/linuxbuh/vhci_hcd/main/Makefile
- https://unix.stackexchange.com/questions/84162/building-debian-package-fails-at-dh-auto-install-stage
- https://manpages.debian.org/testing/debhelper/dh_install.1.en.html
- https://www.debian.org/doc/manuals/maint-guide/dother.en.html
- https://github.com/linuxbuh/vhci_hcd/issues/1
- https://askubuntu.com/questions/1303403/how-to-install-usbip-vhci-hcd-drivers-on-an-aws-ec2-ubuntu-kernel-version
- https://askubuntu.com/questions/347711/how-to-add-permissions-to-files-installed-by-dpkg-buildpackage-or-debuild
- https://debian-user.debian.narkive.com/tegfXASJ/usr-include-bits-local-lim-h-36-linux-limits-h-permission-denied
- https://github.com/augin/vhci_hcd
- https://github.com/linuxbuh/vhci_hcd/blob/main/README.md
- https://vhci.a-singer.de/
- https://www.howtoforge.com/how-to-set-up-a-usb-over-ip-server-and-client-with-debian-lenny-p2
- https://unix.stackexchange.com/questions/542305/dpkg-dh-install-copy-files-from-the-build-directory-rather-than-the-debian-tmp
Заключение
Вы ничего магического не делаете — дело в Makefile и в политике сборки Debian: пакет пытается писать в /usr/include/linux/, а при создании deb-пакета так делать нельзя. Решение — заставить установку писать в staging (debian/tmp) через DESTDIR/PREFIX или исправить Makefile/debian/rules (переопределение dh_auto_install), проверить совместимость с ядрами linux 6.1/6.12 и, при необходимости, внести небольшие патчи в код модуля. После этого vhci_hcd сборка и упаковка в deb-пакет пройдут корректно.