LINUX.ORG.RU

Distributed Build and Package System


0

0

Почитал тут про Portage систему Gentoo и задумался. Сразу скажу - всё это, наверно, полнейшая ересь.

Тем, кто в теме Portage не читать: {
В Portage пакеты распространяются в исходниках и каждый используя свои use-флаги собирает их по-своему. На этапе сборки пакета Portage смотрит на пользовательские use-флаги и в соответствии с Ebuild-файлом задаёт системе сборки/установки свои опции. В итоге пользователь получает пакет со своими фичами.

Как я понимаю, всё это возможно благодаря той или иной модульности распространяемых пакетов и возможностям систем сборки. В итоге пользователь при обновлении того или иного пакета может скачать не весь файл пакета, а только последовательность патчей к исходникам для их обновления и частичной пересборки.
}

Возникла следующая вопрос/идея:
При сборке одних и тех же пакетов разными пользователями часто(и я думаю, для некоторых пакетов очень часто) используется некоторое количество одинаковых опций и некоторое количество объектных файлов на одной архитектуре и с одинаковыми CFLAG'ами(ну и, видимо, с одной версией компилятора) может полностью совпадать.

Возможно ли создать такую систему сборки, где пользователи собирая пакет смогут выложить свои откомпилированные объектные файлы на сервер для последующего использования другими пользователями этой же системы сборки?

Например первый пользователь собирает пакет yet-another-text-editor с "--withonly a b" и выкладывает объектники на серв. Затем когда второй пользователь собирает этот же пакет с "--withonly b c", то наша система пакетосборки определяет, что на сервере есть уже откомпилированные файлы этого пакета и использует их (main.o, b.o). Тогда после загрузки дерева сборки пользователю остаётся только дособрать фичу «c» и слинковать программу.

Возможно ли такое в современных условиях?
Подойдёт ли для сего изврата что-либо из систем сборки(automake, CMake, etc)?

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

★★★★

emerge --buildpkgonly && emerge --usepkgonly

Ы

init_6 ★★★★★
()

Не помню где, но где-то было обсуждение этой идеи - помню что инициативные товарищи собирались поднять большую децентрализованную Ъ-сеть со специально написанным для неё Ъ-ПО. Но ничем, ясен пень, это не закончилось :D

quasimoto ★★★★
()

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

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

не сочтите за насмешку, но я зря писал так много буков, раз всё так просто - облачный Portage xD

jeuta ★★★★
() автор топика

да, возможно. Я вот поставил напоиграться в Gentoo пакетный менеджер Nix из NixOS http://nixos.org

В целом, довольно неплохо работает: сборка из исходников, можно прикрутить кросскомпиляцию, файлы default.nix отдалённо напоминают «ебилды», только чище, проще. При всём при том работает бинарная сборка, то есть там есть такие substitutes: если сборка из исходников приведёт к сборке такого же точно бинарного пакета, то будет качаться бинарный пакет.

Все зависимости ЯВНО прописываются в default.nix , зависимости времени сборки. Что-то неявно добавляет сам Nix — версию конпелятора, флаги его сборки, и т.п. От этих зависимостей-флагов считается хеш от содержимого, он используется как адрес в /nix/store. Туда собирается бинарный пакет (аналогичный image в /var/tmp/portage/cat-name/pkg-name/{workdir,image), и на него проставляются симлинки в «профиле» ~/.nix-profile.

Работает сборка из исходников nix-build, работает «подписка на канал» nix-channel --add ... /nixpkgs-unstable; nix-channel --update; работает скачка собранных бинарников при обновлении через nix-env -u '*'

Правда, есть минусы: идеология пакетного менеджера другая, и прямого аналога USE-флагам нету — в default.nix они явно прописывают ключи к ./configure. В итоге егойный glibc например сдуру собран с локалью ru ISO-8851-1 и ругается что нет ru_RU.UTF-8 (и ругается всё остальное: перл, баш, и т.п.).

В итоге в nixpkgs имеем весёлые пакеты вида foo-X.XX-bar-Y.YY : например, дрова nvidia + ядро, библиотеки хаскелля + конкретная версия ghc. Это как-то коряво.

Что-то вроде USE-флагов можно добавить в Nix, но тогда поползёт вся бинарная сборка.

Вот если бы этот /nix/store зашарить в торрент или что-то вроде dijjer proxy, был бы профит.

Из систем сборки: вроде Scons умеет такое.

anonymous
()

>Например первый пользователь собирает пакет yet-another-text-editor с "--withonly a b" и выкладывает объектники на серв. Затем когда второй пользователь собирает этот же пакет с "--withonly b c", то наша система пакетосборки определяет, что на сервере есть уже откомпилированные файлы этого пакета и использует их (main.o, b.o). Тогда после загрузки дерева сборки пользователю остаётся только дособрать фичу «c» и слинковать программу.

Возможно ли такое в современных условиях?

Подойдёт ли для сего изврата что-либо из систем сборки(automake, CMake, etc)?

USE-флаги «foo -bar» в /etc/make.conf, /etc/portage/package.use/* подхватываются emerge, emerge запускает ebuild.sh .../xyzzy-1.234.ebuild fetch unpack configure compile install qmerge clean, затем в ebuild.sh отображаются в конечном итоге в фазе configure на ключи configure --enable-feature=foo --disable-feature=bar

если взять сделать build1 USE=«foo -bar» emerge =cat-name/xyzzy-1.234,
получится в /var/tmp/portage/cat-name/xyzzy-1.234/workdir/ каталог с исходниками. Затем там делается ./configure --enable-feature=foo --disable-feature=bar => получается множество A объектников .o в workdir. Затем оно соберётся в /var/tmp/portage/cat-name/xyzzy-1.234/image в фазе install и установится в фазе qmerge

затем делается допустим build2 USE="-foo bar" emerge =cat-name/xyzzy-1.234 => получится множество B объектников

делаем snapshot /var/tmp/portage/cat-name/xyzzy-1.234/ в вариантах build1, build2

пересечение множеств А и В (P) => «общие» объектники, которые не зависят от USE-ключей foo и bar. Разность множеств B\A = P U (use: "-foo bar")

Если запускать в workdir make -n в вариантах build1 и build2, можно такие множества объектников «вычислить».

Затем можно воссоздать множество B, имея исходное А: скопировать в build2 перед фазой compile после configure множество А, удалив «лишние» объектники, вычислив P (распарсив выхлоп make -n).


Проблемы:
1. нужно где-то хранить эти множества A, B, P — в каком-то иммутабельном хранилище вроде /nix/store или ccache. То есть, хранить все собираемые объектники всех билдов
2. объектники в общем виде могут зависеть от любых неявных зависимостей: версии компилятора, всего что нашло configure. Поэтому нужна воспроизводимость билдов, неявные зависимости сделать явными
3. Среди этих множеств А, B, P можно ввести «отношение эквивалентности». В том смысле, что мн. А эквивалентно B эквивалентно P, если удалить из множества «лишние» объектники
4. Множества могут пересекаться. То есть, один и тот же объектник из А в build1 и из B в build2 может быть собран по-разному, физически не включая из-за configure. Такие пересечения нужно выкидывать из P и пересоздавать заново.
5. Хранить это всё в каком-то «облачном portage», расшаривать через какой-то P2P, скачивать друг с друга. Если сделать что-то по образу /nix/store, то у множеств будут разные хеши и разные пути в /nix/store. Ну тут DHT в помошь, правда не совсем ясно с маршрутизацией по этим «отношениям эквивалетности».

anonymous
()

Portage в среднем не очень хорош в плане «воспроизводимости билдов». Можно сделать eselect gcc ... или прописать в PATH другую версию gcc => объектники могут измениться. Могут быть какие-то «неявные» зависимости (./configure надетектит чего-нибудь по установленным путям, либо какая-то переменная окружения будет лишняя, на которую сдетектит configure, либо «поломаться ABI», либо пропадёт /usr/lib/libfoo.so.la и libtool её не задетектит) => объектники могут измениться.

Nix в плане «воспроизводимости билдов» получше (все зависимости прописываются явно, некоторые вычисляются по другим явно заданным), но у него есть свои проблемы (нет вот этого аналога USE-флагам, все эти configure --enable-featue=foo --disable-feature=bar задаются ЯВНО)

anonymous
()

> Возможно ли создать такую систему сборки, где пользователи собирая пакет смогут выложить свои откомпилированные объектные файлы на сервер для последующего использования другими пользователями этой же системы сборки?

вот это в общем и целом работает в Nix. Но, минус — все ключики задаются явно, собираются пакетики для какой-то усреднённой конфигурации в «канале» nixpkgs-unstable.

Допустим, каналы мог бы делать каждый сам себе свой, и собирать со своими ключами в такой канал. Потом такие каналы расшаривались бы в какой-то P2P, и маршрутизация в этом P2P была бы по DHT, по «отношениям эквивалентности»: ищется любой такой канал, соответствующий максимально подходящему множеству из P, A, B. Что-то из скачанных объектников выкидывается и пересобирается заново (потому что выхлоп make -n для этих конфигураций был бы разный). Потом собранное со всеми объектниками опять «расшаривается в канал». Каналы расшариваются в «облако», облако соответствует этому множеству P.

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

anonymous
()

ещё есть любопытный пакетный менеджер/дистрибутив Conary http://en.wikipedia.org/wiki/Conary_(package_manager) .

Любопытен он тем, что все эти его пакеты, derivation и troves имеют прямую аналогию с системами контроля версий (я как бы подозреваю, что внутре у него Git). И можно было бы тегами налепить вот эти «отношения эквивалентности», и выбирать потом пакеты по ним.

anonymous
()

Можно distcc + ccache для этого использовать, но для distcc нужна обязательно одинаковая версия компилятора на всех нодах фермы.

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

наверно, только так, чтобы всё это пользовалось большой кучей людей

Ну так где все эти люди с гентами на бортах и с хорошими каналами?)

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

Хорошо написал, я примерно тоже самое думал. Только я думал проверять все файлы чем-нить типа cmp, и при разнице даже в байт - объявлять файлы разными.

Сделать переборку для всех комбинаций флагов и сделать соответствующее кол-во пакетов. Допустим так же 2 флага, получается 4 части пакета:
packagename - packagename -foo -bar
packagename_foo - packagename +foo -bar
packagename_bar - packagename -foo +bar
packagename_foo_bar - packagename +foo +bar

packagename - это базовая часть, которая идёт ко всем флагам. packagename_foo содержит файлы, которые надо добавить к базовой части, чтобы получить packagename +foo, а также список файлов, которые не нужны, и можно (и даже нужно) удалить.

соответственно, packagename +foo -bar - качает packagename и packagename_foo, а для packagename +foo +bar - все 4.

Как это распространяется? Создаётся ебилд, в нём сорцы - оригинальные сорцы + в зависимости от флагов - части пакета. Ложится в оверлей этот ебилд, перекрывая собой оригинальный пакет. При установке всё нужное скачивается и по очереди распаковывается (на этом же этапе отрабатывает функция удаления лишних файлов). После этого всё линкуется и инсталлируется.

Проблема такой системы - CFLAGS/CXXFLAGS на машине пользователя фактически ни на что не влияют. А собирать с учётом разных CFLAGS/CXXFLAGS - дело не из коротких.

Также, при переборке флагов не делать переборку всех флагов. Флаги хочу делить на 4 категории: перебираемые, всегда включенные, всегда выключенные и всегда стандартные.

Всё вышесказанное - пока что только теория.

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