Hlavní navigace

Vytváření FreeBSD balíčku

19. 4. 2004
Doba čtení: 7 minut

Sdílet

Každý někdy narazil na situaci, že nenašel ve své distribuci nabalíčkovaný program, který nutně potřeboval. Pokud příslušný balíček nedodává ani výrobce, nastávají tu dvě možnosti. Buďto si to můžeme nabalíčkovat sami, nebo můžeme program přeložit a nainstalovat nezávisle na balíčkovacím systému použitém v distribuci.

V našem případě se rozhodneme vynaložit určité úsilí a zvolíme první možnost. Bylo by dobré, aby námi vynaložené úsilí na balíčkování přineslo co největší efekt.

Ideální stav:

  1. Balíčkovací systém musí umožňovat jednoduché věci jednoduše a přitom nesmí bránit zásahu do jakékoliv části procesu.
  2. Máme možnost snadno umístit námi vytvořený balíček do distribuce.

Realita:

  1. Balíčkovací systém distribuce těžko ovlivníme
  2. V případě komerčních distribucí je to problematické. Lepší šanci máme v případě komunitní distribuce.

Všeobecně se tvrdí, že nejlepší balíčkovací systém má v současnosti projekt Debian. V rámci objektivity je nutno poznamenat, že uživatelé NetBSD totéž tvrdí o svém balíčkovacím systému pkgsrc.

Systém Debianu je možná nejlepší, ale jednoduchý rozhodně není, pro bližší seznámení viz seriál na Rootu. Přestože je Debian komunitní distribucí, umístění vámi vytvořeného balíčku do officiální distribuce není snadné. Buď seženete nějakého existujícího Debian maintainera, který o balíček projeví zájem, nebo se stanete officiálním maintainerem Debianu sami. V tomto případě musíte ovšem absolvovat zdlouhavou a otravnou proceduru. Osobně jsem o tom uvažoval, ale po přečtení výše zmíněných dokumentů jsem rychle ztratil zájem.

Balíčkovací systém ve FreeBSD

má samá pozitíva. Narozdíl od Debianu je velice jednoduchý a přitom udělá vše, co od něj očekáváme. Jediné, co musíme udělat pro nabalíčkování programu, je napsat krátký Makefile, který provede stažení, kompilaci a instalaci programu. Realita je ještě jednoduší, než se na první pohled zdá. Onen zmíňovaný Makefile již pro nás napsali vývojáři FreeBSD. Ve většině případů stačí jen nastavit pár proměnných a zavolat onen připravený Makefile. Jména proměných můžeme odkoukat z Makefile jiných aplikací, Porter's Handbo­oku nebo přímo z /usr/ports/Mk/bsd­.port.mk.

Umístění vámi nabalíčkovaného programu do officiálního stromu portů je naprosto bezproblémová záležitost. Není třeba nikam posílat fotokopii pasu ani gpg klíč podepsaný FreeBSD commiterem. FreeBSD core team totiž officiálně nepodporuje aplikace v port tree, a proto je do port tree umožněno příspívat všem uživatelům FreeBSD. Toto rozhodnutí má za následek to, že FreeBSD obsahuje více balíčků než jakákoliv jiná distribuce.

V další části si ukážeme výrobu balíčku přímo na praktickém příkladu. Budeme balíčkovat program memtest86.

Začínáme

Začneme vytvořením adresáře se jménem shodným s názvem portu.

~% mkdir ~/myports/memtest86
~% cd ~/myports/memtest86

Dalším krokem je vytvoření Makefile. Vzhledem k tomu, že se mi nepodařilo nalézt templatový Makefile pro nové porty, použijeme jako template Makefile z některého existujícího portu:

~/myports/memtest86% head -n 7 /usr/ports/benchmarks/webbench/Makefile > Makefile 

Upravíme v Makefile datum vytvoření, autora a CVS keyword. Výsledek je následující:

# New ports collection makefile for:    memtest86
# Date created:         27 Mar 2004
# Whom:                 Radim Kolar
#
# $FreeBSD$
#

Přidáme řádky označující jméno portu, verzi a kategorii:

~/myports/memtest86% cat >> Makefile
PORTNAME=     memtest86
PORTVERSION=  3.1a
CATEGORIES=   sysutils

^D

Makefile musí vědět, odkud získat zdrojové texty pro kompilaci. Domovská stránka programu memtest86 je www.memtest86­.com. Na stránce najdeme sekci pro download. V našem případě je program k dostání ve dvou verzích .tar.gz a .zip. Pro nás je výhodnější použít verzi .tar.gz. Archiv stáhneme a přesuneme do adresáře /usr/ports/dis­tfiles.

Do Makefile přidáme URL adresáře obsahujícího archiv:

~/myports/memtest86% cat >> Makefile
MASTER_SITES=   http://www.memtest86.com/

^D

Maintainer

Dalším důležitým krokem je rozhodnutí, zda budeme chtít námi vytvořený balíček dlouhodobě udržovat, či nikoliv. Jedná se o to, čí email adresa bude v položce MAINTAINER. Pokud balíčkujeme náš oblíbený program, od kterého si vždy stahujeme ty nejnovější verze, je vhodné být maintainerem. Naopak, pokud je jediným naším požadavkem pouhá přítomnost v port tree, uvedeme email ports@freebsd.org.

Pokud jde o provádění změn v balíčku, ve FreeBSD portech existuje třístupňová hierarchie: 1. CVS commiter, 2. Package maintainer, 3. BFU. Jako package maintainer nejste tedy všemocní, ale víceméně můžete schvalovat patche posílané BFU. Pokud se do 14 dnů k navrhované patchi nevyjádříte, bude commitnuta. Triviální patche jsou ovšem commitnuty bez vašeho vědomí. To je třeba mít stále na paměti. Pokud se chystáme změnit námi spravovaný balíček, uděláme si nejprve jeho update.

~/myports/memtest86% cat >> Makefile
MAINTAINER=     ports@freebsd.org
COMMENT=        Stand alone memory test for x86 architecture computers

^D 

Problémy, problémy

Program memtest86 je platformově závislý na Intel32. Na ostatních architekturách pravděpodobně nepůjde přeložit. Při testování jsem zjistil, že si s tímto problémem nemusím lámat hlavu, protože nejde přeložit ani na FreeBSD 5.2.1 na Intelu32.

ld --warn-constructors --warn-common -static -T memtest_shared.lds -o memtest_shared head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o config.o linuxbios.o memsize.o pci.o controller.o && \
ld -shared -Bsymbolic -T memtest_shared.lds -o memtest_shared head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o config.o linuxbios.o memsize.o pci.o controller.o
head.o: In function `startup_32':
head.o(.text+0x7): undefined reference to `_GLOBAL_OFFSET_TABLE_'
Segmentation fault (core dumped)
gmake: *** [memtest_shared] Error 139 

Co s tím uděláme? Je pravděpodobné, že by memtest86 šel přeložit v emulátoru Linuxu emulujícím verze Redhatu v rozmezí 6 až 8. Zvolil jsem metodu nejmenšího odporu: distribuční balík totiž obsahuje i již přeložený memtest86, a to ve verzích pro CD-ROM i FD. Všechny problémy vyřeší jedna řádka:

~/myports/memtest86% cat >> Makefile
NO_BUILD=       yes

^D 

Instalace

V našem případě nenecháme program, aby se nainstaloval tam, kam jeho autor uznal za vhodné (na /dev/fd0), ale provedeme instalaci ručně. Zajímají nás jen tři soubory: README, memtest.iso a precomp.bin. Dokumentace přijde do/usr/local/sha­re/doc/memtes­t86, zbytek do /usr/local/sha­re/memtest86. ISO image uložíme v komprimované formě. Makefile pro porty nám přednastaví proměnné DATADIR a DOCSDIR.

~/myports/memtest86% cat >> Makefile
do-install:
        ${MKDIR} ${DATADIR}
        ${INSTALL_DATA} ${WRKSRC}/precomp.bin ${DATADIR}/floppy.bin
        ${INSTALL_DATA} ${WRKSRC}/memtest.iso ${DATADIR}
        ${GZIP_CMD} ${DATADIR}/memtest.iso
.if !defined(NOPORTDOCS)
        ${MKDIR} ${DOCSDIR}
        ${INSTALL_DATA} ${WRKSRC}/README ${DOCSDIR}
.endif

^D 

Nyní ještě řekneme balíčkovacímu systému, co všechno jsme nainstalovali.

~/myports/memtest86% cat >> Makefile
.if !defined(NOPORTDOCS)
PORTDOCS=README
.endif
PLIST_FILES=%%DATADIR%%/floppy.bin %%DATADIR%%/memtest.iso.gz
PLIST_DIRS=%%DATADIR%%

^D 

a ukončíme náš Makefile

~/myports/memtest86% echo ".include <bsd.port.mk>" >>  Makefile 

Poslední věcí, která nám ještě chybí, je soubor pkg-descr, který obsahuje podrobnější popis programu. Použijeme první odstavec z domovské stránky memtestu.

~/myports/memtest86% cat > pkg-descr
Memtest86 - A Stand-alone Memory Diagnostic

Memtest86 is thorough, stand alone memory test for
x86 architecture computers. BIOS based memory tests
are a quick, cursory check and often miss many of
the failures that are detected by Memtest86.

WWW: http://www.memtest86.com/

^D

Testujeme

Otestujeme si naše dílko:

~/myports/memtest86% make
===>  Extracting for memtest86-3.1a
>> No checksum file (/home/hsn/myports/memtest86/distinfo).
===>  Patching for memtest86-3.1a
===>  Configuring for memtest86-3.1a 

Chybí nám soubor distinfo, který obsahuje kontrolní součet a délku originálního archivu. Tento soubor vytvoříme pomocí make makesum a vypadá takto:

MD5 (memtest86-3.1a.tar.gz) = 6c43d4aba3fdfa135c462a02b3ae5b39
SIZE (memtest86-3.1a.tar.gz) = 142729 

Teď by již mělo být vše v pořádku. Překontrolujeme port programem portlint.

~/myports/memtest86% portlint -a
looks fine.

Vše je v pořádku, můžeme instalovat:

~/myports/memtest86% make install
===>  Installing for memtest86-3.1a
===>  Generating temporary packing list
===>  Checking if sysutils/memtest86 already installed
===>  Switching to root credentials for 'install' target
Password:
/bin/mkdir -p /usr/local/share/memtest86
install  -o root -g wheel -m 444 /home/hsn/myports/memtest86/ work/memtest86-3.1a/precomp.bin /usr/local/share/memtest86/floppy.bin
install  -o root -g wheel -m 444 /home/hsn/myports/memtest86/ work/memtest86-3.1a/memtest.iso /usr/local/share/memtest86
/usr/bin/gzip -nf -9 /usr/local/share/memtest86/memtest.iso
/bin/mkdir -p /usr/local/share/doc/memtest86
install  -o root -g wheel -m 444 /home/hsn/myports/memtest86/ work/memtest86-3.1a/README /usr/local/share/doc/memtest86
===>  Registering installation for memtest86-3.1a
===>  Returning to user credentials 

(Pozn. ed.: pár mezer do výpisu přidáno kvůli sazbě –Johanka)

Odeslání do FreeBSD port tree

Nové porty se ve FreeBSD přijímají ve formátu shar. Vytvoříme tedy shar archiv:

root_podpora

~/myports/memtest86% make clean
===>  Cleaning for memtest86-3.1a
~/myports/memtest86% cd ..
~/myports% shar `find memtest86` > memtest86.shar

Poslední věcí, kterou ještě musíme udělat, je odeslání shar archivu. Shar archivy se posílají jako přílohy k bug reportu. K odeslání bug reportu do centrální GNATS databáze slouží program send-pr. Jako kategorii uvedeme ports a jako Synopsis uvedeme new port: memcheck86. Do textu bugreportu vložíme shar archiv a odešleme. Za pár dnů bude náš port commitnut do officiálního stromu portů.

Docela jednoduché, ne?

Byl pro vás článek přínosný?