Written by m4r3k and tagged by linux, openSUSE, packages.
Vytvořit si balíček pro openSUSE není nic moc těžkého, někteří lidé však stále instalují programy pomocí svaté trojice, nebo používají checkinstall. Proto jsem se rozhodl (na požadavek Ilfirina) napsat takový lehký úvod jak s opravdovým balíkařením vůbec začít. Prosím neberte tento návod jako vyčerpávající dokumentaci k RPM balíkaření. O tu se postarali jiní.
Dále pokud chcete tvořit kvalitní balíčky tak by také nebylo naškodu některé věci konzultovat s dokumentací. Jak vidíte, tak odkaz na dokumentaci směřuje na můj server. Je to způsobeno tím, že se mi nedaří najít SPC v PDF na webu Novellu. Kdyby někdo věděl kde je, tak nechť mi dá vědět v diskusi. Nejaktuálnější verzi SPC tak najdete v openSUSE wiki.
Rozhodl jsem se to udělat formou tutoriálu a vytváření balíčku tak ukážu na programu Q7Z. Vytvoříme si tedy adresář Q7Z a do něj stáhneme balík se zdrojovým kódem.
mkdir q7z cd q7z wget http://downloads.sourceforge.net/k7z/Q7Z-0.7.1.tar.bz2
A nyní vytvoříme základní spec soubor. K tomu můžeme použít můj spec skeleton pro Vim. Pomocí libovolného editoru tedy v adresáři q7z vytvořte textový soubor Q7Z.spec a zkopírujte do něj následující řádky:
#
# This file and all modifications and additions to the pristine
# package are under the same license as the package itself.
#
# norootforbuild
Name: specRPM_CREATION_NAME
Version:
Release:
Summary:
Group:
License:
URL:
Source:
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
BuildRequires:
%description
Authors:
--------
Name Surname
%prep
rm -rf $RPM_BUILD_ROOT
%setup
%build
%configure
make %{?jobs:-j%jobs}
%install
%makeinstall
%clean
rm -rf $RPM_BUILD_ROOT
%post
%postun
%files
%defattr(-,root,root,0755)
%doc ChangeLog README COPYING
%changelog
* specRPM_CREATION_DATE - specRPM_CREATION_AUTHOR_MAIL
Nyní přepište značku specRPM_CREATION_NAME na Q7Z a do políčka Version: napište 0.7.1. Políčko Release: vyplňte číslem 0. V sekci Summary: má být stručná popis balíčku, ten zkopírujeme z webu tvůrců.
Q7Z is a P7Zip GUI for Linux, which attempts to simplify data compression and backup.
Dalším políčkem je Group:, do toho patří kategorie balíčku. Vybereme tedy tu nejvhodnější, kterou v SUSE package convention nalezneme. A tou je Productivity/Archiving/Compression. Co napsat do políčka License: zjistíme snadno tak, že se podíváme na to co je napsáno v souboru Doc/LICENSE.txt třeba pomocí příkazu head Doc/LICENCE.txt. Jak vidíte, tak licence je GPLv2. Toto tedy zapíšeme do políčka License:.
Políčko URL: obsahuje adresu stránky s programem, v našem případě tedy http://k7z.sourceforge.net/7Z/Q7Z/. Řádek Source: říká programu /usr/bin/build ve kterém archivu najde zdrojové soubory. V našem případě by tam tedy mělo být napsáno http://downloads.sourceforge.net/k7z/%{name}-%{version}.tar.bz2. Makro %{version} bude programem /usr/bin/build expandováno na obsah políčka Version: a usnadní nám to tak příští aktualizaci. V poli BuildRequires: jsou zapsány balíčky, které jsou třeba k sestavení balíčku. To zjistíme například na stránkách projektu. Vyplníme ho tedy takto: python python-qt4 tar make.
Nyní následuje část %description, která obsahuje delší popis balíčku včetně jmen autorů. Já ji vyplnil následovně:
%description
Q7Z is an archiving tool that can update existing archives quickly, backup a folder to a storage location, create or extract a protected archive, and increase efficiency by using archiving profiles.
Authors:
--------
Chris Giles chris.g.27@gmail.com
Fáze %prep se stará o rozbalení zdrojových kódů, patchování a další podobné věci. V našem příkladu ji vyplníme následovně:
%prep
rm -rf $RPM_BUILD_ROOT
%setup -n %{name}
%setup -n %{name} říká rozbal zdrojový balík a přepni se do adresáře %{name}. Je to způsobeno tím, že ten kdo tento zdrojový balík tvořil nedodržel nepsaná pravidla, že v archivu xyz-abc.tar by měl být adresář se zdrojovými kódy pojmenován xyz-abc. Kdyby byl zdrojový balík zabalen takto, tak bychom mohli -n %{name} vynechat.
Další částí je %build, co do ní napsat snadno vyčtete v souboru Doc/INSTALL:txt. Já ji vyplnil následovně:
%build
cd Build
make %{?jobs:-j%jobs}
Tato část bývá pro drtivou většinu balíčků podobná. Většinou obsahuje volání makra %configure a na druhou stranu zase neobsahuje cd Build. Ale většinou se stačí podívat do nějakého souboru INSTALL.txt, nebo na web tvůrců.
Poté před sebou máme ještě část %install, opět stačí pouze pročíst soubor INSTALL.txt a zjistíte, že v tomto případě by tam mělo být zapsáno následující:
%install cd Build %makeinstall
Další části až na část %files a %changelog můžeme v tomto případě směle vynechat. Část %post obsahuje příkazy, které se mají provést po instalaci balíčku a část %postun naopak příkazy, které se mají provést po odinstalaci balíčku.
Část %changelog vyplníme tak, že text specRPM_CREATION_DATE nahradíme za datum ve formátu Sat Feb 02 2008 a text specRPM_CREATION_AUTHOR_MAIL za náš e-mail. Dále přidáme k changelogu ještě záznam co jsem provedli za úpravy. U nových balíčků tam píšu - new package created. Má část %changelog tedy vypadá následovně:
%changelog * Sat Feb 02 2008 - marekstopka@gmail.com - new package created
Nyní přijde na řadu dle mého nejotravnější část celého balíkaření a to zjistit kam se instalují všechny soubory, abychom je mohli zapsat do části %files. K tomu se budeme muset pokusit balíček sestavit. A k tomu, abychom mohli balíček pomocí utility /usr/bin/build sestavit budeme potřebovat rpm balíčky, které potřebuje tento balíček ke svému sestavení. Já to řeším tak, že mám na svém disku celý strom rpm balíčků distribuce. Ten stáhnete pomocí následujícího skriptu:
WGET_PARAM='-c'
DIR='~/packages' # Directory where packages should be downloaded
install -d $DIR/rpms/{i586,i686,noarch,x86_64}
cd $DIR/rpms/i586 && wget $WGET_PARAM ftp://mirror.karneval.cz/pub/linux/opensuse/distribution/10.3/repo/oss/suse/i586/*
cd $DIR/rpms/i686 && wget $WGET_PARAM ftp://mirror.karneval.cz/pub/linux/opensuse/distribution/10.3/repo/oss/suse/i686/*
cd $DIR/rpms/noarch && wget $WGET_PARAM ftp://mirror.karneval.cz/pub/linux/opensuse/distribution/10.3/repo/oss/suse/noarch/*
cd $DIR/rpms/x86_64 && wget $WGET_PARAM ftp://mirror.karneval.cz/pub/linux/opensuse/distribution/10.3/repo/oss/suse/x86_64/*
Nicméně, pokud chcete sestavovat balíčky jen pro x86_64 tak můžete odstranit část s i586 a i686, pokud chcete balíčky jen pro i585 tak můžete zase odstranit část s x86_64 (tedy musíte ponechat i586, i686 a noarch).
Pokud máte staženo tak je ještě potřeba nainstalovat utilitu /usr/bin/build, která je v balíčku build, takže stačí spustit příkaz zypper install build.
Buildíme balíček #1
Nyní, pokud máme staženo tak vyexportujeme proměnou BUILD_RPMS a nastavíme ji cestu na adresář, kde jsou staženy naše balíčky. To provedeme příkazem export BUILD_RPMS=~/packages/rpms/. Nyní už nám nic nebrání spustit jako root příkaz /usr/bin/build Q7Z.spec. Tento by měl skončit s následující chybou:
cp: cannot stat `ChangeLog': No such file or directory cp: cannot stat `README': No such file or directory cp: cannot stat `COPYING': No such file or directory error: Bad exit status from /var/tmp/rpm-tmp.73327 (%doc) Checking for unpackaged file(s): /usr/lib/rpm/check-files /var/tmp/Q7Z-0.7.1-0.pm.0-buildroot error: Installed (but unpackaged) file(s) found: /usr/bin/Q7Z.pyw /usr/share/applications/kde/Q7Z.desktop /usr/share/apps/Q7Z/Desktop/Context/Q7Z.marker /usr/share/apps/Q7Z/Desktop/Context/Q7Zc.desktop /usr/share/apps/Q7Z/Desktop/Context/Q7Zc.desktop.top /usr/share/apps/Q7Z/Desktop/Context/Q7Ze.desktop /usr/share/apps/Q7Z/Desktop/Context/Q7Ze.desktop.top /usr/share/apps/Q7Z/Desktop/KMenu/Q7Z.desktop /usr/share/apps/Q7Z/Desktop/Profiles/Default.txt /usr/share/apps/Q7Z/Desktop/Profiles/Flash.txt /usr/share/apps/Q7Z/Desktop/Profiles/Local.txt /usr/share/apps/Q7Z/Desktop/Profiles/Remote.txt /usr/share/apps/Q7Z/Desktop/Profiles/Secure.txt /usr/share/apps/Q7Z/Desktop/Profiles/Storage.txt /usr/share/apps/Q7Z/Doc/AUTHORS.txt /usr/share/apps/Q7Z/Doc/COPYING.txt /usr/share/apps/Q7Z/Doc/ChangeLog.txt /usr/share/apps/Q7Z/Doc/INSTALL.txt /usr/share/apps/Q7Z/Doc/ISSUES.txt /usr/share/apps/Q7Z/Doc/LICENCE.txt /usr/share/apps/Q7Z/Doc/NEWS.txt /usr/share/apps/Q7Z/Doc/README.txt /usr/share/apps/Q7Z/Doc/TODO.txt /usr/share/apps/Q7Z/Doc/Testing.txt /usr/share/apps/Q7Z/Source/Display.py /usr/share/apps/Q7Z/Source/Event.py /usr/share/apps/Q7Z/Source/Help.py /usr/share/apps/Q7Z/Source/Images/actions/1downarrow.png /usr/share/apps/Q7Z/Source/Images/actions/1leftarrow.png /usr/share/apps/Q7Z/Source/Images/actions/1uparrow.png /usr/share/apps/Q7Z/Source/Images/actions/2downarrow.png /usr/share/apps/Q7Z/Source/Images/actions/2uparrow.png /usr/share/apps/Q7Z/Source/Images/actions/ark_addfile.ico /usr/share/apps/Q7Z/Source/Images/actions/ark_addfile.png /usr/share/apps/Q7Z/Source/Images/actions/ark_extract.ico /usr/share/apps/Q7Z/Source/Images/actions/ark_extract.png /usr/share/apps/Q7Z/Source/Images/actions/button_cancel.png /usr/share/apps/Q7Z/Source/Images/actions/button_ok.png /usr/share/apps/Q7Z/Source/Images/actions/edit_add.png /usr/share/apps/Q7Z/Source/Images/actions/edit_remove.png /usr/share/apps/Q7Z/Source/Images/actions/endturn.ico /usr/share/apps/Q7Z/Source/Images/actions/endturn.png /usr/share/apps/Q7Z/Source/Images/actions/exit.png /usr/share/apps/Q7Z/Source/Images/actions/fileclose.png /usr/share/apps/Q7Z/Source/Images/actions/fileopen.png /usr/share/apps/Q7Z/Source/Images/actions/filesave.png /usr/share/apps/Q7Z/Source/Images/actions/filesaveas.png /usr/share/apps/Q7Z/Source/Images/actions/ledgreen.png /usr/share/apps/Q7Z/Source/Images/actions/ledpurple.png /usr/share/apps/Q7Z/Source/Images/actions/ledred.png /usr/share/apps/Q7Z/Source/Images/actions/ledyellow.png /usr/share/apps/Q7Z/Source/Images/actions/messagebox_info.png /usr/share/apps/Q7Z/Source/Images/actions/reload.png /usr/share/apps/Q7Z/Source/Images/actions/revert.png /usr/share/apps/Q7Z/Source/Images/actions/stop.png /usr/share/apps/Q7Z/Source/Images/apps/Q7Z.ico /usr/share/apps/Q7Z/Source/Images/apps/Q7Z.png /usr/share/apps/Q7Z/Source/Images/apps/aboutEric.png /usr/share/apps/Q7Z/Source/Images/apps/ckhome2.png /usr/share/apps/Q7Z/Source/Images/apps/fmtools-ico32.png /usr/share/apps/Q7Z/Source/Images/apps/gnu-head-sm.jpg /usr/share/apps/Q7Z/Source/Images/apps/package_settings.png /usr/share/apps/Q7Z/Source/Images/apps/pyqt-logo.png /usr/share/apps/Q7Z/Source/Images/apps/python-logo.png /usr/share/apps/Q7Z/Source/Images/apps/qt4-logo.png /usr/share/apps/Q7Z/Source/Images/devices/3floppy_unmount.png /usr/share/apps/Q7Z/Source/Images/devices/cdrom_unmount.png /usr/share/apps/Q7Z/Source/Images/devices/dvd_unmount.png /usr/share/apps/Q7Z/Source/Images/devices/hdd_unmount.png /usr/share/apps/Q7Z/Source/Images/filesystems/folder.png /usr/share/apps/Q7Z/Source/Images/filesystems/folder_tar.png /usr/share/apps/Q7Z/Source/Images/filesystems/www.png /usr/share/apps/Q7Z/Source/Images/mimetypes/7-Zip.png /usr/share/apps/Q7Z/Source/Images/mimetypes/BZip2.png /usr/share/apps/Q7Z/Source/Images/mimetypes/GZip.png /usr/share/apps/Q7Z/Source/Images/mimetypes/Tar.png /usr/share/apps/Q7Z/Source/Images/mimetypes/Zip.png /usr/share/apps/Q7Z/Source/Images/mimetypes/txt.png /usr/share/apps/Q7Z/Source/Import.py /usr/share/apps/Q7Z/Source/Input.py /usr/share/apps/Q7Z/Source/List.py /usr/share/apps/Q7Z/Source/Main.py /usr/share/apps/Q7Z/Source/Main.qrc /usr/share/apps/Q7Z/Source/Main.ui /usr/share/apps/Q7Z/Source/Main_rc.py /usr/share/apps/Q7Z/Source/Profile.py /usr/share/apps/Q7Z/Source/Q7Z.pyw /usr/share/apps/Q7Z/Source/Settings.py /usr/share/apps/Q7Z/Source/Settings.qrc /usr/share/apps/Q7Z/Source/Settings.ui /usr/share/apps/Q7Z/Source/Settings_rc.py /usr/share/apps/Q7Z/Source/Thread.py /usr/share/apps/Q7Z/Source/Ui_Main.py /usr/share/apps/Q7Z/Source/Ui_Settings.py /usr/share/apps/dolphin/servicemenus/Q7Zc.desktop /usr/share/apps/dolphin/servicemenus/Q7Ze.desktop /usr/share/apps/konqueror/servicemenus/Q7Zc.desktop /usr/share/apps/konqueror/servicemenus/Q7Ze.desktop /usr/share/icons/hicolor/32x32/actions/ark_addfile.ico /usr/share/icons/hicolor/32x32/actions/ark_addfile.png /usr/share/icons/hicolor/32x32/actions/ark_extract.ico /usr/share/icons/hicolor/32x32/actions/ark_extract.png /usr/share/icons/hicolor/32x32/actions/endturn.ico /usr/share/icons/hicolor/32x32/actions/endturn.png /usr/share/icons/hicolor/32x32/apps/Q7Z.png
Z toho vyvodíme, že soubory ChangeLog, READE, COPYING nejsou v root adresáři, opravíme tedy řádek %doc na %doc Doc/ChangeLog.txt Doc/README.txt Doc/COPYING.txt a seznam ostatních nezabalených souborů zkopírujeme a upravíme do následující podoby:
%files %defattr(-,root,root,0755) %doc Doc/ChangeLog.txt Doc/README.txt Doc/COPYING.txt /usr/bin/Q7Z.pyw /usr/share/applications/kde/Q7Z.desktop /usr/share/apps/Q7Z/* /usr/share/apps/dolphin/servicemenus/* /usr/share/apps/konqueror/servicemenus/* /usr/share/icons/hicolor/32x32/actions/* /usr/share/icons/hicolor/32x32/apps/Q7Z.png
No a nyní je na řadě poslední krok. Vzhledem k tomu, že se jedná o program napsaný v pythonu tak je u něj nesmyslné rozlišovat architektury a tak mu nastavíme architekturu na noarch. Přidáme tedy BuildArch: noarch někam do části kde jsme definovali cestu ke zdrojovým souborům. Dále je pak potřeba ještě doplnit závislosti, které si rpm nedokáže zjistit samo jako je například python-qt4. Přidáme tedy k BuildArch i Requires: python-qt4
Nyní je na čase províst finální build pomocí příkazů:
export BUILD_RPMS=~/packages/rpms/ /usr/bin/build Q7Z.spec
Na konci by nám měli v adresáři /var/tmp/build-root vypadnout balíčky /usr/src/packages/RPMS/noarch/Q7Z-0.7.1-1.noarch.rpm a /usr/src/packages/SRPMS/Q7Z-0.7.1-1.src.rpm.
![]()
Screenshot našeho vybuilděného prográmku.
Výsledný spec soubor
#
# This file and all modifications and additions to the pristine
# package are under the same license as the package itself.
#
# norootforbuild
Name: Q7Z
Version: 0.7.1
Release: 1
Summary: Q7Z is a P7Zip GUI for Linux, which attempts to simplify data compression and backup.
Group: Productivity/Archiving/Compression
License: GPLv2
BuildArch: noarch
URL: http://k7z.sourceforge.net/7Z/Q7Z/
Source: http://downloads.sourceforge.net/k7z/%{name}-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
BuildRequires: python python-qt4 p7zip tar make
Requires: python-qt4
%description
Q7Z is an archiving tool that can update existing archives quickly, backup a folder to a storage location, create or extract a protected archive, and increase efficiency by using archiving profiles.
Authors:
--------
Chris Giles chris.g.27@gmail.com
%prep
rm -rf $RPM_BUILD_ROOT
%setup -n %{name}
%build
cd Build
make %{?jobs:-j%jobs}
%install
cd Build
%makeinstall
%clean
rm -rf $RPM_BUILD_ROOT
%post
%postun
%files
%defattr(-,root,root,0755)
%doc Doc/ChangeLog.txt Doc/README.txt Doc/COPYING.txt
/usr/bin/Q7Z.pyw
/usr/share/applications/kde/Q7Z.desktop
/usr/share/apps/Q7Z/*
/usr/share/apps/dolphin/servicemenus/*
/usr/share/apps/konqueror/servicemenus/*
/usr/share/icons/hicolor/32x32/actions/*
/usr/share/icons/hicolor/32x32/apps/Q7Z.png
%changelog
* Sat Feb 02 2008 - marekstopka@gmail.com
- new package created
February 2nd, 2008 at 12:59 pm
A já nemohu nic víc než velice poděkovat.
Článek tohoto typu mi velice chyběl. Je na čase naučit se buildit :-)
February 2nd, 2008 at 1:34 pm
2Ilfirin: A kvůli komu jsem to asi psal? No přece kvůli tobě, aby si dal konečně klid ;-) :-p lol
February 2nd, 2008 at 2:18 pm
2M4r3k: :-) . Ale spíš jsem myslel, že mě dáš do jabber blacklistu, než že ten článek opravdu napíšeš :-D ;-)
February 3rd, 2008 at 12:37 am
Tak, byla to makačka (staženo 11.7GB v balíčcích), ale můj Q7Z balíček je již na světě. Pln elánu se vrhnám na další ;-)
February 4th, 2008 at 12:13 pm
hned prvy komentar v prvej casti na abclinuxu ;)
http://forge.novell.com/modules/xfref_library/detail.php?reference_id=1544
a odtial odkaz sem:
http://developer.novell.com/wiki/index.php/SUSE_Package_Conventions
February 5th, 2008 at 7:48 pm
Dobrý, vyzkouším a až zase někdy budu potřebovat balíček, tak už třeba taky nebudu otravovat :-)
February 8th, 2008 at 3:41 pm
Thanks za návod, ale asi bude radšej naďalej používať checkinsatll. Toto je skôr na very clean building, ked človek robí niečo pre pre nejaký repozitár, bo tu si sa to dá ešte všeliak tweak a navyše to pracuje s celym RPM stromom w chrootnutom systéme atď…..