3.1. Явная сборка внутри hasher
Соберём пакет из одного исходного файла. Для начала загрузим необходимую для работы библиотеку. Для разработки используются специальные devel-версии пакетов с библиотеками. Как правило, devel-версии включают в себя всё, что не нужно в процессе эксплуатации: примеры, документацию в разных форматах, .h-файлы, профили для различных инструментов сборки, а также специально оформленную символьную ссылку на файл с библиотекой, установленный из основного пакета. По этой причине вместе с devel-пакетом ставится и основной:
@user:
[user@VM ~]$ hsh-install libncurses-devel
<13>Jul 11 02:07:34 rpmi: libncurses6-6.3.20220618-alt4 sisyphus+327286.4600.14.1 1711486705 installed
<13>Jul 11 02:07:34 rpmi: libtinfo-devel-6.3.20220618-alt4 sisyphus+327286.4600.14.1 1711486705 installed
<13>ul 11 02:07:34 rpmi: libncurses-devel-6.3.20220618-alt4 sisyphus+327286.4600.14.1 1711486705 installed
[user@VM ~]$
Рассмотрим ближе структуру devel-библиотеки:
@builder
[builder@localhost ~]$ rpm -ql libncurses-devel
конфигурационные файлы библиотеки:
/usr/bin/ncurses6-config
/usr/bin/ncurses6-config
заголовочные файлы:
/usr/include/curses.h
/usr/include/eti.h
/usr/include/form.h
/usr/include/menu.h
/usr/include/ncurses
/usr/include/ncurses.h
/usr/include/ncurses/curses.h
/usr/include/ncurses/eti.h
/usr/include/ncurses/form.h
/usr/include/ncurses/menu.h
/usr/include/ncurses/ncurses.h
/usr/include/ncurses/panel.h
/usr/include/ncurses/tic.h
/usr/include/ncurses/unctrl.h
/usr/include/panel.h
/usr/include/unctrl.h
специальные символические ссылки на файлы динамической библиотеки и файлы компоновки
pkg-config:
/usr/lib64/libcurses.so
/usr/lib64/libform.so
/usr/lib64/libmenu.so
/usr/lib64/libncurses.so
/usr/lib64/libpanel.so
/usr/lib64/pkgconfig/form.pc
/usr/lib64/pkgconfig/menu.pc
/usr/lib64/pkgconfig/ncurses.pc
/usr/lib64/pkgconfig/panel.pc
набор документации и
man:
/usr/share/doc/ncurses-6.3.20220618
/usr/share/doc/ncurses-6.3.20220618/announce.html
/usr/share/doc/ncurses-6.3.20220618/demo.cc
/usr/share/doc/ncurses-6.3.20220618/hackguide.doc
/usr/share/doc/ncurses-6.3.20220618/hackguide.html
/usr/share/doc/ncurses-6.3.20220618/index.html
/usr/share/doc/ncurses-6.3.20220618/ncurses-intro.doc
/usr/share/doc/ncurses-6.3.20220618/ncurses-intro.html
/usr/share/man/man1/ncurses5-config.1.xz
/usr/share/man/man1/ncurses6-config.1.xz
/usr/share/man/man1/ncurses5-config.1.xz
/usr/share/man/man1/ncurses6-config.1.xz
<...>
/usr/share/man/man3/wvline_set.3x.xz
[builder@localhost ~]$
Перейдём к сборке пакета. В качестве тестовой программы рассмотрим программу, которая считывает приходящие символы и выводит их вместе с ASCII-кодом:
@builder:
RPM/SOURCES/pkg-ncurses-1.0.c
#include <curses.h>
int main(void) {
WINDOW* win;
WINDOW* frame;
char c = 0;
initscr();
noecho();
cbreak();
move(4, 10);
printw("window:");
refresh();
frame = newwin(LINES - 8, COLS - 18, 4, 9);
box(frame, 0, 0);
mvwaddstr(frame, 0, (int)((COLS - 25) / 2), "Рамка");
wrefresh(frame);
win = newwin(LINES - 10, COLS - 20, 5, 10);
keypad(win, TRUE);
scrollok(win, TRUE);
while((c = wgetch(win)) != 27) {
wprintw(win, " %d: %s\n", c, keyname(c));
wrefresh(win);
}
delwin(win);
endwin();
return 0;
}
Поскольку для сборки пакета появилась новая подзадача — компиляция исходников в исполняемые файлы, меняется и spec-файл. Для описания команд по сборке итоговых файлов пакета используется директива %build:
@builder:
RPM/SPECS/pkg-ncurses.spec
Name: pkg-ncurses
Version: 1.0
Release: alt1
Summary: Test pkg with ncurses library
License: GPL-3.0-or-later
Group: Development/Other
Source: %name-%version.c
BuildRequires: libncurses-devel
%description
This is a small testing package with ncurses functionality
%build
gcc %SOURCE0 -lncurses -o %name
%install
install -D -pm 755 %name %buildroot%_bindir/%name
%files
%_bindir/*
%changelog
* Thu Jul 03 2025 UsamG1t <usamg1t@altlinux.org> 1.0-alt1
- InitialBuild
Сборка пакета проходит успешно, и наряду с обычным двоичным пакетом собирается пакет с debuginfo, хранящий в себе информацию, необходимую для отладки:
@builder
[builder@localhost ~]$ tree RPM
RPM
├── BUILD
├── RPMS
│ ├── noarch
│ └── x86_64
├── SOURCES
│ └── pkg-ncurses-1.0.c
├── SPECS
│ └── pkg-ncurses.spec
└── SRPMS
7 directories, 2 files
[builder@localhost ~]$
[builder@localhost ~]$ rpmbuild -ba RPM/SPECS/pkg-ncurses.spec
<...>
Wrote: /usr/src/RPM/SRPMS/pkg-ncurses-1.0-alt1.src.rpm (w2.lzdio)
Wrote: /usr/src/RPM/RPMS/x86_64/pkg-ncurses-1.0-alt1.x86_64.rpm (w2.lzdio)
Wrote: /usr/src/RPM/RPMS/x86_64/pkg-ncurses-debuginfo-1.0-alt1.x86_64.rpm (w2.lzdio)
[builder@localhost ~]$ tree -A RPM/
RPM/
├── BUILD
│ └── pkg-ncurses
├── RPMS
│ ├── noarch
│ └── x86_64
│ ├── pkg-ncurses-1.0-alt1.x86_64.rpm
│ └── pkg-ncurses-debuginfo-1.0-alt1.x86_64.rpm
├── SOURCES
│ └── pkg-ncurses-1.0.c
├── SPECS
│ └── pkg-ncurses.spec
└── SRPMS
└── pkg-ncurses-1.0-alt1.src.rpm
8 directories, 6 files
[builder@localhost ~]$
Попробуем установить пакет в это же окружение:
@user
[user@VM ~]$ hsh-shell --rooter
@rooter
[root@localhost .in]# rpm -i /usr/src/RPM/RPMS/x86_64/pkg-ncurses-1.0-alt1.x86_64.rpm
<13>Jul 3 05:26:57 rpm: pkg-ncurses-1.0-alt1 1751520368 installed
[root@localhost .in]#
[root@localhost .in]# which pkg-ncurses
/usr/bin/pkg-ncurses
[root@localhost .in]# pkg-ncurses
┌────────────Рамка─────────────┐
│ 72: H │
│ 101: e │
│ 108: l │
│ 108: l │
│ 111: o │
│ 44: , │
│ 32: │
│ 105: i │
│ 115: s │
│ 32: │
│ 105: i │
│ 116: t │
│ 32: │
│ 109: m │
│ 101: e │
│ 32: │
│ 121: y │
│ 111: o │
│ 117: u │
│ 32: │
│ 108: l │
│ 111: o │
│ 111: o │
│ 107: k │
│ 105: i │
│ 110: n │
│ 103: g │
│ 32: │
│ 102: f │
│ 111: o │
│ 114: r │
│ 63: ? │
└──────────────────────────────┘
Во время разработки окружение hasher должно содержать сборочные зависимости. Для эксплуатации пакета достаточно установить только эксплуатационные. Эксплуатационные зависимости можно указывать явно, но в большинстве случаев они добавляются в .rpm-пакет автоматически в процессе сборки:
@builder
[builder@localhost ~]$ rpmbuild -ba RPM/SPECS/pkg-ncurses.spec
<...>
Finding Requires (using /usr/lib/rpm/find-requires)
Executing: /bin/sh -e /usr/src/tmp/rpm-tmp.BxgcRM
find-requires: running scripts (cpp,debuginfo,files,lib,pam,perl,pkgconfig,pkgconfiglib,python,python3,rpmlib,shebang,shell,static,symlinks,systemd-services)
Requires: /lib64/ld-linux-x86-64.so.2, libc.so.6(GLIBC_2.2.5)(64bit), libc.so.6(GLIBC_2.34)(64bit), libncurses.so.6()(64bit) >= set:njzUlMJGoZaFrOm1ipLX6ub3NlTS2FoKH5pxjl802, libtinfo.so.6()(64bit) >= set:liZK
bfJOyUPV1IqfEUb0, rtld(GNU_HASH)
Requires(rpmlib): rpmlib(SetVersions)
<...>
Wrote: /usr/src/RPM/SRPMS/pkg-ncurses-1.0-alt1.src.rpm (w2.lzdio)
Wrote: /usr/src/RPM/RPMS/x86_64/pkg-ncurses-1.0-alt1.x86_64.rpm (w2.lzdio)
Wrote: /usr/src/RPM/RPMS/x86_64/pkg-ncurses-debuginfo-1.0-alt1.x86_64.rpm (w2.lzdio)
[builder@localhost ~]$
Скопируем пакет из hasher и попробуем установить его в чистое окружение без предварительной установки Ncurses. Чтобы у @rooter была возможность обратиться к полученному пакету, необходимо будет перенести его в директорию общего доступа для всех трёх пользователей — специальную директорию .in:
@user
[user@VM ~]$ cp hasher/chroot/usr/src/RPM/RPMS/x86_64/pkg-ncurses-1.0-alt1.x86_64.rpm
[user@VM ~]$ hsh --init
<...>
[user@VM ~]$ cp pkg-ncurses-1.0-alt1.x86_64.rpm hasher/chroot/.in/
[user@VM ~]$ hsh-shell --rooter
Поскольку библиотека является не только сборочной, но и эсплуатационной зависимостью пакета, её отсутствие не позволяет установить пакет:
@rooter
[root@localhost .in]# rpm -i pkg-ncurses-1.0-alt1.x86_64.rpm
error: Failed dependencies:
libncurses.so.6()(64bit) >= set:mi6NHG6gUJ4yHTS2FoKH5hxjh80KggmL6K9X2A2 is needed by pkg-ncurses-1.0-alt1.x86_64
[root@localhost .in]#
Для решения проблемы необходимо установить все недостающие зависимости (которые, вообще говоря, могут и сами потребовать каких-либо других зависимостей и т. д.). Также файлы, передаваемые в директорию .in в hasher, автоматически удаляются из неё при нарушении условий целостности сессии (одним из таких условий является установка пакетов в hasher), вследствие чего их необходимо вновь добавить.
При установке библиотеки для эксплуатации следует пользоваться не devel-версией, а обычной. В репозитории Sysiphus часто встречаются несколько версий библиотек: старые, для корректной работы некоторых устаревших пакетов, и обновлённые. Обновлённые библиотеки имеют формат именования lib<имя_библиотеки>#, где номер в конце обозначает версию библиотеки. Старые библиотеки не имеют нумерации. В devel-версиях формат именования всегда lib<имя_библиотеки>-devel, но ссылка в них указывает на обновлённую библиотеку. Поскольку мы работаем с обновлённой библиотекой, необходимо установить её:
@user
[user@VM ~]$ hsh-install libncurses6
<13>Jul 11 02:14:27 rpmi: libncurses6-6.3.20220618-alt4 sisyphus+327286.4600.14.1 1711486705 installed
[user@VM ~]$ cp pkg-ncurses-1.0-alt1.x86_64.rpm hasher/chroot/.in
[user@VM ~]$ hsh-shell --rooter
@rooter
[root@localhost .in]# rpm -i pkg-ncurses-1.0-alt1.x86_64.rpm
<13>Jul 11 02:14:41 rpm: pkg-ncurses-1.0-alt1 1752199720 installed
[root@localhost .in]# rpmquery --requires pkg-ncurses
/lib64/ld-linux-x86-64.so.2
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.34)(64bit)
libncurses.so.6()(64bit) >= set:mi6NHG6gUJ4yHTS2FoKH5hxjh80KggmL6K9X2A2
rpmlib(SetVersions)
libtinfo.so.6()(64bit) >= set:liZKbfJOyUPV1IqfEUb0
rtld(GNU_HASH)
rpmlib(PayloadIsLzma)
[root@localhost .in]#