LINUX.ORG.RU

Как напечатать список пакетов-зависимостей изнутри .ebuild?

 


0

2

У меня есть некий рантайм, который использует компоненты, не являющиеся обычными .so-библиотеками. Для каждой компоненты есть отдельный .ebuild, который её устанавливает. Есть финальный .ebuild, который через portage-зависимости подключает нужные компоненты (т.е. их .ebuild-файлы в переменной DEPEND).

Вопрос - как изнутри этого финального .ebuild напечатать список всех используемых компонент рантайма (точнее как распечатать список .ebuild файлов тех компонентов, которые являются зависимостями финальной выполняемой программы)?

Это нужно мне для того, чтобы создать симлинки в директории программы до артефактов, устанавливаемых для каждой компоненты, потому что загрузчик рантайма без этих симлинков не может их найти. (у загрузчика ld нет таких проблем, потому что он видит версии в ELF и умеет по версиям грузить нужный .so-файл с указанной версией)

И просмотреть нужно все зависимости рекурсивно, потому что компоненты могут зависеть от других компонентов. Нельзя просто взять и разобрать содержимое DEPEND только у устанавливаемого пакета с выполняемой программой.

Нормально ли использовать equery изнутри ebuild (в src_install)? У меня есть ощущение, что если пакет ещё не установлен, то и equery не сработает.

★★☆

Последнее исправление: Einstok_Fair (всего исправлений: 5)

как распечатать список .ebuild файлов тех компонентов, которые являются зависимостями финальной выполняемой программы

Это ненужно, так как в portage существует порядок установки зависимостей. Встроенные команды позволяют обращаться за пределы изолирования к корневому каталогу. Если у тебя есть ебилд, который описывает установку библиотеки и эта библиотека находится в числе зависимостей основной программы, то она будет установлена в системе ДО того, как будет установлен основной пакет. Можно быть уверенным, что твоя библиотека будет расположена именно в /usr/lib64/blahbla.so.1.

Установка происходит в порядке:

  • foo/bar1 -> foo/bar2 -> foo/target_package

где foo/bar2 зависит от foo/bar1, а foo/target_package зависит от foo/bar2

Если твоя программа не соблюдает FHS стандарт и для запуска требует файлы именно в том каталоге в котором расположены бинарники, то все, включая бинарники и дата файлы, нужно положить в /opt/${P}, как это было задумано автором. Ну а потом создать враппер/скрипт, для его запуска, который обычно кладут в /opt/bin/${PN}. Иногда в таком случае приходится создавать сим. ссылки к библиотекам

Пример ебилда (обрати внимание на dosym ../../..):

# Copyright 1999-2018 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=6

inherit eutils unpacker

DESCRIPTION="Baldur's Gate: Enhanced Edition"
HOMEPAGE="https://www.baldursgate.com/"
SRC_URI="gog_baldur_s_gate_enhanced_edition_2.5.0.9.sh"

LICENSE="GOG-EULA"
SLOT="0"
KEYWORDS="-* ~amd64 ~x86"
RESTRICT="bindist fetch"

DEPEND="app-arch/unzip"
RDEPEND="dev-libs/expat[abi_x86_32(-)]
	dev-libs/json-c[abi_x86_32(-)]
	dev-libs/openssl:0[abi_x86_32(-)]
	media-libs/openal[abi_x86_32(-)]
	virtual/opengl[abi_x86_32(-)]
	x11-libs/libX11[abi_x86_32(-)]"

QA_PREBUILT="/opt/${PN}/BaldursGate"

S="${WORKDIR}/data/noarch"

pkg_nofetch() {
	einfo "Please buy and download \"${SRC_URI}\" from"
	einfo "https://www.gog.com/game/baldurs_gate_enhanced_edition"
	einfo "and copy it into your DISTDIR directory."
}

src_unpack() {
	unpack_zip "${DISTDIR}/${SRC_URI}"
}

src_install() {
	local ABI="x86"
	local dir="/opt/${PN}"

	dodoc -r "game/Manuals/."
	rm -r "game/Manuals" || die "rm failed"

	insinto "${dir}"
	doins -r "game/."
	fperms +x "${dir}/BaldursGate"

	dodir "${dir}/lib"
	dosym "../../../usr/$(get_libdir)/libjson-c.so" "${dir}/lib/libjson.so.0"

	newicon "support/icon.png" "${PN}.png"
	make_wrapper ${PN} "./BaldursGate" "${dir}" "${dir}/lib"
	make_desktop_entry "${PN}" "Baldur's Gate: Enhanced Edition" "${PN}" "Game;RolePlaying"
}

В остальных случаях ld загрузчик работает как обычно (берет инфу из /etc/ld.so.cache).

linxon
()

про разницу DEPEND и RDEPEND тоже нужно знать.

DEPEND — перечисляют зависимости, которые необходимы во время сборки

RDEPEND — рантайм зависимости, которые необходимы только для запуска

Если в DEPEND ебилда выше написано:

DEPEND="app-arch/unzip"
RDEPEND="dev-libs/expat[abi_x86_32(-)]
...

то ей либо нужны /usr/include/unzip/blahbla.h файлы во время сборки, либо просто нужен ZIP распаковщик , чтобы расспаковать исходники, например

linxon
()
Ответ на: комментарий от linxon

библиотека будет расположена именно в /usr/lib64/blahbla.so.1.

Обрати здесь внимание на то, что в имени библиотеки указана версия. ld так умеет (грузить по версии нужную библиотеку), а рантайм который я опакечиваю - не умеет. Только из-за этого мне нужны симлинки.

Теперь дальше - устанавливаются компоненты заранее, и они не знают, в каких приложениях они будут востребованы. Значит симлинки для приложения должны создаваться .ebuild-ом самого приложения.

В функции src_install нет доступа к файловой системе, в которую происходит установка. Такой доступ есть в pkg_preinst, а будут ли там работать все перечисленные обёртки типа dosym ?

Einstok_Fair ★★☆
() автор топика
Ответ на: комментарий от Einstok_Fair

Не знаю поможет ли и понравится ли:

Есть в ebuild функция конфигурации. Она не выполняется при emerge имя_пакета. А выполняется отдельно уже после того как пакет стандартно установлен в систему со всеми своими зависимостями. Именно в этой функции я горожу все костыли для подобных «энтнрпрайз» пакетов. В функции конфигурации можно делать ВСЕ над рутовой системой. Единственное неудобство - необходимость запускать эмерже пакет && эмерже -конфиг пакет.

anonymous
()
Ответ на: комментарий от anonymous

Ну и зачем предлагать решение с неудобством, если выше выписано точно такое же решение, но без этого неудобства?

Einstok_Fair ★★☆
() автор топика
Ответ на: комментарий от Einstok_Fair

устанавливаются компоненты заранее, и они не знают, в каких приложениях они будут востребованы. Значит симлинки для приложения должны создаваться .ebuild-ом самого приложения

В функции src_install нет доступа к файловой системе

мануал

D 	Path to the temporary install directory. For example: "${PORTAGE_BUILDDIR}/image". 

Во время установки в режиме изолирования создается временный корневой каталог ${PORTAGE_BUILDDIR}/image, в который кладется образ программы — результат выполнения src_install. Потом идет проверка коллизий, расчет хеш суммы и слияние, перемещение всего из ${D} в реальным /

dosym действительно является оберткой ln -s и работает только с ${PORTAGE_BUILDDIR}/image

Еще раз посмотри как сделал автор ебилда выше. Он поместил симлинк в /opt/${PN}/lib/libjson.so.0, которая ссылается на ../../../usr/lib64/libjson-c.so

linxon
()
Ответ на: комментарий от linxon

при этом предполагается, что в системе уже установлен `dev-libs/json-c`

```bash RDEPEND=«dev-libs/expat[abi_x86_32(-)] dev-libs/json-c[abi_x86_32(-)] ```

больше ничего не нужно изобретать в этом плане

linxon
()
Ответ на: комментарий от linxon

ebuild в своей директории image видит только свои файлы, которые он сам устанавливает. А нужно создать симлинки на файлы из других компонентов, файлы которые уже находятся в файловой системе. .ebuild не видит их в функции src_install.

Einstok_Fair ★★☆
() автор топика
Последнее исправление: Einstok_Fair (всего исправлений: 1)
Ответ на: комментарий от Einstok_Fair

В данном случае да. Проверь. Ну и man глянь для дополнительных опций отображения graph.

Только я ничего не понял зачем всё это.

grem ★★★★★
()
Ответ на: комментарий от Einstok_Fair

ну а в чем проблема? Зачем нужно получать какой-то список?

символическая ссылка, созданная с помощью dosym, заработает после слияния с корнем, а пока она находится в директории image конечно же будет считаться битой. Ибо доступа к файлу ../../../usr/lib64/libjson-c.so относительно расположения этой ссылки в ${PORTAGE_BUILDDIR}/image/opt/${PN}/lib/libjson.so.0 — нет.

Две точки в пути подразумевают шаг назад или переход на поддиректорию относительно расположения файла /opt/${PN}/lib/libjson.so.0

Ты можешь указать абсолютный путь, чтобы не путать себя. Но это не рекомендуется.

dosym "/usr/$(get_libdir)/libjson-c.so" "${dir}/lib/libjson.so.0"

Оба варианта будут работать после премещения всего, включая твои симлинки с image в корень. Вот только если ты укажешь АБСОЛЮТНЫЙ путь, то могут возникнуть проблемы во время работы в chroot, например. Если ты загрузишься с livecd и примонтируешь корень своей рабочей системы, куда-нибудь в /mnt/gentoo , то перейдя на /mnt/gentoo/opt/${PN}/lib/ увидишь битую ссылку libjson.so.0, которая ссылается на несуществующий /usr/lib64/libjson-c.so.

вызывать сторонние программы вроде equery, eix или firefox — нельзя. Для этого есть внутренний EAPI, который имеет все что нужно, для установки подобных пакетов. Изучай еклассы

linxon
()
Ответ на: комментарий от Einstok_Fair

Не нужно сомневаться, что зависимости будут или НЕ будут установлены после инсталяции основной программы. Портаж гарантирует, что нужный пакет будет установлен перед инсталяцией основного...

linxon
()
Ответ на: комментарий от linxon

ну а в чем проблема? Зачем нужно получать какой-то список?

В том, что каждая компонента устанавливается сама-по-себе, приложение устанавливается само-по-себе. Тем не менее, в результате, рядом с файлом приложения должны образоваться симлинки для каждой ранее установленной компоненты (именно той версии, какая нужна приложению), иначе загрузчик рантайма не найдёт компоненты, потому что загрузчик рантайма не является ld.

Две точки в пути подразумевают шаг назад или переход на поддиректорию относительно расположения файла /opt/${PN}/lib/libjson.so.0

Я тебе уже говорил, что загрузчик не ld. В стартовом посте и здесь

Einstok_Fair ★★☆
() автор топика
Последнее исправление: Einstok_Fair (всего исправлений: 1)
Ответ на: комментарий от linxon

Портаж гарантирует, что нужный пакет будет установлен перед инсталяцией основного.

Верно. Однако кроме процесса установки существует процесс динамической загрузки. А у меня компоненты - не ELF файлы.

Einstok_Fair ★★☆
() автор топика
Последнее исправление: Einstok_Fair (всего исправлений: 1)
Ответ на: комментарий от linxon

вызывать сторонние программы вроде equery, eix или firefox — нельзя.

Это ты вот ему расскажи.

Einstok_Fair ★★☆
() автор топика
Последнее исправление: Einstok_Fair (всего исправлений: 1)
Ответ на: комментарий от Einstok_Fair

Ну… Я привел пример того, как примерно создаются симлинки на необходимые компоненты. Пусть это будет библиотека, директория или картинка — не важно. Если компонентов слишком много и имена неизвестны, то можно пробежаться средствами шелл сделав find в указанную директорию

Например вот так:

find "/path/to/program/components" | while read x; do
    dosym "$x" "/opt/${PN}/components/$(basename $x)"
done

ничего плохого в этом нет, думаю…

Если этот вариант не подходит, то сделать все одиним ебилдом как thirdparty указать дополнительные ссылки в SRC_URI на компоненты. Загрузить, расспаковать и разместить куда нужно через src_install

linxon
()
Ответ на: комментарий от linxon

Например вот так:

В твоём примере использование dosym намекает, что дело происходит в функции src_install. В этой функции нельзя делать find по корневой системе, потому что она недоступна из функции src_install.

Я уже писа́л об этом.

Einstok_Fair ★★☆
() автор топика
Последнее исправление: Einstok_Fair (всего исправлений: 2)
Ответ на: комментарий от linxon

А читать ты можешь все, что угодно

Нет, читать я могу не всё что угодно, а только то, что есть в SYSROOT, т.е. в системе сборки. А то что в ROOT, т.е. в системе установки - не могу.

Einstok_Fair ★★☆
() автор топика
Последнее исправление: Einstok_Fair (всего исправлений: 1)
Ответ на: комментарий от Einstok_Fair

Если бы портаж работал с таким подходом, то насколько был бы большим список исключений, доступных для чтения файлов и каталогов. Нет, читать ты можешь все что угодно. Проверь

linxon
()
Ответ на: комментарий от linxon

Нет, читать ты можешь все что угодно.

Только прочитанное совпадать не будет в системах где происходит сборки и установка.

Einstok_Fair ★★☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.