[devel] buildreq-src: II. алгоритм работы.

Igor Vlasenko vlasenko на imath.kiev.ua
Ср Мар 16 01:09:29 MSK 2016


Продолжение темы. предыдущие письма см.
https://lists.altlinux.org/pipermail/devel/2016-March/201087.html
https://lists.altlinux.org/pipermail/devel/2016-March/201102.html



buildreq-src: алгоритм работы.
_______________________________________________________

Алгоритм работы библиотеки SourceAnalyzer достаточно прост.

Первый этап называется Filter.

Исходный архив распаковывается и библиотека пытается определить
типы имеющихся там файлов. К примеру: текст на perl,
текст на python, конфигурационный файл для Autoconf, 
для AutoMake, CMake или QMake, файл swig, и т.д.

Затем идет второй этап, называемый Collector.

Для каждого опознанного типа файлов запускается 
родной для этого файла парсер+анализатор текста
с целью поиска зависимостей.

Эти зависимости ищутся в "сыром" виде, т.е. в виде
списков фактически требуемых *.pc, lib*.so, *.h, *.pm файлов и т.д.

Например: найден configure.ac - для него запускается 
анализатор конфигурационных файлов для Autoconf, 
(в модуле ...::Collector::Plugins::Autoconf).
найден скрипт на perl --- запустится анализатор зависимостей Perl.
(в модуле ...::Collector::Plugins::Perl).
Их алгоритм - это безусловная (наивная) вычитка текста в поисках внешних
зависимостей. Например, если в скрипте на perl встретилась команда
 use SDL;
то анализатор зависимостей Perl распознает ее 
как зависимость исходного текста на perl(SDL.pm).
AM_PATH_SQLITE3 в configure.ac распознается как зависимость на
sqlite3 (/usr/bin/sqlite3) в $PATH. А директива
 PKG_CHECK_MODULES([ASSOGIATE], [
  glib-2.0 >= 2.8.0
  glibmm-2.4 >= 2.8.0
 ])
распознается как зависимости на pkgconfig(glib-2.0) и pkgconfig(glibmm-2.4).

Естественно, не все так найденные зависимости нам нужны. К примеру
AC_CHECK_HEADER(Windows.h,[...
AC_SEARCH_LIBS(win32.dll,...
дадут зависимость на Windows.h и win32.dll, что для сборки под
Linux очевидно не нужно.
Для борьбы с ненужными зависимостями в библиотеке SourceAnalyzer
используются механизмы черного и белого списков.

В черный список я стараюсь вручную заносить то, что заведомо
к Linux не относится.

Белый список состоит из списков библиотек, *.pc, заголовочных файлов 
и т.д., которые на данный момент физически присутствуют в Сизифе.
Белый список формируется автоматически из содержимого основного
Sisyphus и плюс autoimports/Sisyphus 
(есть белые списки и для других бранчей)
и ежедневно обновляется репокопом.

Без белого списка программы, использущие библиотеку SourceAnalyzer
не запустятся с криком (к примеру)

FATAL: DistroMap repository data for altlinux:sisyphus is missing!
run distrodb-update-repocop-db-altlinux-sisyphus!

Поэтому нужно будет перед/после/для первого запуска buildreq-src
запустить
$ distrodb-update-repocop-db-altlinux-sisyphus
которая скачает базу distrodb в ~/.cache/distrodb.

После этого buildreq-src будет нормально работать,
но дней через пять-семь, не прекращая работать, 
будет ругаться, что база distrodb устарела и ее пора обновить.
Чтобы обновить, опять запустите
$ distrodb-update-repocop-db-altlinux-sisyphus

Алгоритм отсева зависимостей такой:
зависимости из черного списка молча игнорируются,
из белого молча принимаются, остальные (серые)
не принимаются, но майнтайнеру выдается сообщение вида

INFO: SourceAnalyzer: nothing in devel-libs provides mcr.
INFO: SourceAnalyzer: nothing in devel-libs provides ultim.
INFO: SourceAnalyzer: nothing in headers provides libmcr.h.
INFO: SourceAnalyzer: nothing in headers provides MathLib.h.
SourceAnalyzer: some deps weren't found. Is DistroMap database outdated?

чтобы майнтайнер разобрался. В этих сообщениях может быть
зависимость на пакет, которого нет в Сизифе,
может быть зависимость на артефакт, которому место в черном списке (сообщайте!)
могут быть и ошибки парсинга или другой мусор,
и в целом достаточно полезные сообщения.

К примеру (пакет csync2):

INFO: SourceAnalyzer: nothing in perl provides perl(/etc/csync2id.cfg).

означает, что где-то в исходниках всплыло requires '/etc/csync2id.cfg'.
Это должно навести на мысль, что надо проверить, упакован ли 
в пакет сам файл /etc/csync2id.cfg.
Впрочем, /etc/csync2id.cfg - это конфиг для contrib/csync2id.pl,
а csync2 не упаковал и сам csync2id. Если по невниманию, 
то польза от сообщения для майнтайнера есть.


Затем идет третий этап, называемый Resolver.

найденные в "сыром" виде зависимости пробиваются по базе distrodb
и преобразуются в имена пакетов.
Есть ряд опций, которые управляют этим процессом.
Процитирую buildreq-src --help :

SourceAnalyzer::DependencyResolver Options:
Options for special dependencies management.
Special dependencies are dependencies like type(name).
They are often stricter than dependencies on package names.
Generation of such dependencies is ruled by options --sourcedep-*.
  --sourcedep-resolve=<types>             replace all special dependencies with package names.
  --sourcedep-keep-explicit=<types>       keep special dependencies even if their packages are mentioned in the spec.
  --sourcedep-allow-unknown=<types>       keep all special dependencies, even not found in the repository.
    <types> is a comma separated list of possible types and metacommands:
    all,none,path,perl,pkgconfig,nopath,noperl,nopkgconfig.
Examples:
  --sourcedep-resolve=pkgconfig,perl      use package names instead of pkgconfig(name) or perl(Name.pm)
  --sourcedep-resolve=all         always use package names
  --sourcedep-keep-explicit=pkgconfig     skip pkgconfig(name) dependency if its package is present (default).
  --sourcedep-allow-unknown=pkgconfig     add pkgconfig(name) dependency even if its package is not found.
  --sourcedep-resolve=noperl              use perl(name) instead of  package names
Options for selecting a package among multiple candidates.
  --sourcedep-select-dependency name=package      Select explicit package if the dependency <name> is provided by several packages.

На этом этапе нас ждет следующая неприятность.
Пусть мы выяснили, что нашим исходникам нужны артефакты
%_libdir/libpng.so %_libdir/pkg-config/libpng.pc /usr/include/png.h
пробиваем эти артефакты по базе distrodb и нас ждет сюрприз - их
предоставляют сразу 2 пакета: libpng12-devel и libpng-devel.
Какой выбрать?

buildreq-src поступит так: если в спек файле уже есть один из этих пакетов,
(в том числе и в старой секции BEGIN/END SourceDeps), то он и будет выбран.
Если в спек файле ничего нет, то заработает эвристика, которая 
не всегда справляется, но в случае png выберет libpng-devel.
Если же эвристика не справится, то будет выдано предупреждение вида

WARNING: SourceAnalyzer: multiple provides in devel-libs for otr: libotr2-devel libotr-devel

и в BuildRequires попадут одновременно libotr2-devel libotr-devel,
чтобы майнтайнер рассудил человеческим умом и удалил лишнее.

Выбор можно указать и из командной строки (см. buildreq-src --help)

  --sourcedep-select-dependency otr=libotr2-devel

также, возможно, добавится в будущем интерактивный диалог.

Q & A: 

> эвристика работы утилиты требует наличия установленных
> потенциальных пакетов -devel?

Нет, не требует.
buildreq-src нужен, когда мы не знаем, чего устанавливать.

Если мы уже знаем и установили все потенциальные пакеты -devel,
то уже актуальна вторая задача - убрать лишнее,
для чего есть /usr/bin/buildreq из rpm-utils от at на .

В следующем письме 

buildreq-src: баги и фичи.
__________________________

Продолжение следует.



-- 

I V


Подробная информация о списке рассылки Devel