Next: Ďalšie zostavovacie systémy, Previous: Nastavenie, Up: Návod na zadávanie balíkov [Contents][Index]
Vyššie uvedený príklad zadania balíka „Ahoj svet“ je taký jednoduchý ako sa len dá. Avšak, zadania balíkov môžu byť zložitejšie a Guix si poradí aj s omnoho náročnejšími balíkmi. Pozrime sa teda na iné, zložitejšie zadanie balíka (mierne upravené v porovnaní s pôvodným zadaním):
(define-module (gnu packages version-control) #:use-module ((guix licenses) #:prefix license:) #:use-module (guix utils) #:use-module (guix packages) #:use-module (guix git-download) #:use-module (guix build-system cmake) #:use-module (gnu packages compression) #:use-module (gnu packages pkg-config) #:use-module (gnu packages python) #:use-module (gnu packages ssh) #:use-module (gnu packages tls) #:use-module (gnu packages web)) (define-public my-libgit2 (let ((commit "e98d0a37c93574d2c6107bf7f31140b548c6a7bf") (revision "1")) (package (name "my-libgit2") (version (git-version "0.26.6" revision commit)) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/libgit2/libgit2/") (commit commit))) (file-name (git-file-name name version)) (sha256 (base32 "17pjvprmdrx4h6bb1hhc98w9qi6ki7yl57f090n9kbhswxqfs7s3")) (patches (search-patches "libgit2-mtime-0.patch")) (modules '((guix build utils))) ;; Odstrániť pribalený softvér. (snippet '(delete-file-recursively "deps")))) (build-system cmake-build-system) (outputs '("out" "debug")) (arguments `(#:tests? #true ; Preveriť výsledok zostavenia (predvolené). #:configure-flags '("-DUSE_SHA1DC=ON") ; Zisťovanie rozporov v odtlačkoch SHA-1 #:phases (modify-phases %standard-phases (add-after 'unpack 'fix-hardcoded-paths (lambda _ (substitute* "tests/repo/init.c" (("#!/bin/sh") (string-append "#!" (which "sh")))) (substitute* "tests/clar/fs.h" (("/bin/cp") (which "cp")) (("/bin/rm") (which "rm"))))) ;; Bohatší výstup pri preverovaní zostavenia (replace 'check\n" (lambda* (#:key tests? #:allow-other-keys)\n" (when tests?\n" (invoke \"./libgit2_clar\" \"-v\" \"-Q\"))))\n" (add-after 'unpack 'make-files-writable-for-tests (lambda _ (for-each make-file-writable (find-files "." ".*"))))))) (inputs (list libssh2 http-parser python-wrapper)) (native-inputs (list pkg-config)) (propagated-inputs ;; Tieto dve knižnice sa nachádzajú v „Requires.private“ v libgit2.pc. (list openssl zlib)) (home-page "https://libgit2.github.com/") (synopsis "Library providing Git core methods") (description "Libgit2 is a portable, pure C implementation of the Git core methods provided as a re-entrant linkable library with a solid API, allowing you to write native speed custom Git applications in any language with bindings.") ;; GPLv2 s odkazovou výnimkou (license license:gpl2))))
(V prípade, že chcete zmeniť len pár polí v pôvodnom zadaní balíka by ste sa mali spoľahnúť na dedičnosť namiesto skopírovania celého zadania. Viď nižšie.)
Pozrime sa teraz na tieto polia zblízka.
git-fetch
git-fetch
Narozdiel od funkcie url-fetch
, git-fetch
vyžaduje
git-reference
, ktorú určuje Git repozitár a príslušná úprava. Úpravou
sa rozumie akýkoľvek odkaz Git ako napríklad značka. Teda, ak je
version
označená, tak je možné použiť priamo číslo verzie. Niekedy
majú značky verzií perdponu v
. V tomto prípade môžete použiť
(commit (string-append "v" version))
.
Aby sme sa uistili, že sa zdrojový kód z Git repozitára uloží do priečinka s
výstižným názvom, použijeme (file-name (git-file-name name version))
.
Keď zadávate balík pre program s určitým číslom úpravy, môžete pre odvodenie
správneho označenia verzie použiť funkciu git-version
podľa pokynov v
príručke prispievateľa do Guixu (see Version Numbers in GNU Guix
Reference Manual).
Pýtate sa ako získať správny odtlačok sha256
? Vyvolaním guix
hash
na miestnej kópii repozitára v požadovanej úprave, asi takto:
git clone https://github.com/libgit2/libgit2/ cd libgit2 git checkout v0.26.6 guix hash -rx .
guix hash -rx
vypočíta odtlačok SHA256 celého priečinka
nezahŕňajúc pod-priečinok .git (see Invoking guix hash in GNU Guix Reference Manual).
Do budúcna bude snáď guix download
schopný vykonávať tieto kroky
za vás, tak ako je tomu pri bežných sťahovaniach súborov.
Kusy kódu predstavujú malé časti Scheme kódu v úvodzovkách, t.j. bežne nevykonávané, ktoré sa používajú na plátanie zdrojových súborov. Je to taká Guixová náhrada za dobre známe .patch súbory. Vďaka úvodzovkám sa daný kód vykoná len vtedy, keď sa odošle démonovi Guixu na zostavenie. V praxi môžeme použiť toľko kusov kódu, koľko potrebujeme.
Kusy kódu môžu vyžadovať prídavné moduly Guilu, ktoré je možné načítať
pomocou poľa modules
.
Jestvujú tri rôzne druhy vstupov. V skratke:
Vyžadované pri zostavovaní ale nie pri spúšťaní. V prípade inštalácie balíka prostredníctvom náhrady sa tieto vstupy nebudú inštalovať.
Inštalované do úložiska ale nie do profilu a prítomné pri zostavovaní.
Inštalované do úložiska aj do profilu a prítomné pri zostavovaní.
See package Reference in GNU Guix Reference Manual pre viac podrobností.
Správne rozlišovanie medzi jednotlivými druhmi vstupov je dôležité: ak je možné závislosť zaradiť ako input namiesto propagated input, tak by sa to tak malo urobiť. Inak bezdôvodne „znečistí“ používateľský profil.
Napríklad, ak inštalujete grafický program, ktorý závisí na nejakom nástroji spúšťanom v príkazovom riadku, tak vám pravdepodobne ide len o tú grafickú časť. Nie je teda potrebné siliť inštaláciu nástroja spúšťaného v príkazovom riadku do používateľského profilu. Závislosti sú spravované balíkmi a nie používateľmi. Vstupy umožňujú spravovať závislosti bez toho, aby to nejako zaťažovalo používateľov pridávaním neužitočných programov či knižníc do ich profilu.
Rovnako to platí aj pre native-inputs: po inštalácii programu môžu byť závislosti vyžadované pri zostavovaní bezpečne odstránené zberačom odpadkov. Okrem toho, ak je dostupná binárna náhrada, stiahnu sa len inputs a propagated inputs: native inputs nie sú pri inštalácii balíka prostredníctvom náhrady potrebné.
Poznámka: Tu a tam nájdete úryvky, v ktorých sú vstupy zapísané pomerne odlišne, teda asi takto:
;; „Pôvodný tvar“ zápisu vstupov (inputs `(("libssh2" ,libssh2) ("http-parser" ,http-parser) ("python" ,python-wrapper)))Toto je „pôvodný tvar“, v ktorom má každá položka zoznamu vstupov pridelenú menovku (reťazec). Tento tvar je stále podporovaný ale odporúčame vám používať už len vyššie uvedený tvar. Viď See package Reference in GNU Guix Reference Manual pre viac podrobností.
Tak ako môže mať balík viacero vstupov, môže mať aj viacero výstupov.
Každý výstup má osobitný priečinok v úložisku.
Používateľ si môže vybrať, ktorý výstup nainštaluje; pomáha to šetriť úložné miesto a predchádzať znečisteniu používateľského profilu nechcenými programami či knižnicami.
Oddeľovanie výstupov je voliteľné. Ak sa pole outputs
vynechá,
predvoleným a jediným výstupom (celý balík) bude "out"
.
Často vidíme oddelené výstupy s názvom debug
alebo doc
.
Oddelené výstupy by ste mali používať len vtedy, keď sa to oplatí: ak je
výstup značne veľký (možno porovnať pomocou guix size
), alebo ak je
balík modulárny.
Pole arguments
obsahuje páry kľúč-hodnota používané pri nastavovaní
postupu zostavenia.
Ten najjednoduchší argument #:tests?
možno použiť na vynechanie
testov po zostavení balíka. Je to užitočné najmä v prípade, keď balík
neobsahuje žiadnu testovaciu súpravu. Je dôrazne odporúčané ponechať
testovaciu súpravu povolenú, ak je nejaká dostupná.
Ďalším bežným argumentom je :make-flags
určujúci zoznam dodatočných
príznakov, ktoré sa majú použiť pri spúšťaní nástroja make ako keby ste
pridali priamo do príkazového riadku. Napríklad, nasledovné príznaky
#:make-flags (list (string-append "prefix=" (assoc-ref %outputs "out")) "CC=gcc")
sú chápané ako
$ make CC=gcc prefix=/gnu/store/...-<out>
Toto nastaví prekladač jazyka C na gcc
a premennú prefix
(cieľový priečinok inštalácie v prípade nástroja Make) na (assoc-ref
%outputs "out")
, čo predstavuje globálnu premennú prítomnú pri zostavovaní,
ktorá udáva cestu k cieľovému priečinku v úložisku (niečo ako
/gnu/store/...-my-libgit2-20180408).
Podobným spôsobom môžete nastaviť aj príznaky nastavenia:
#:configure-flags '("-DUSE_SHA1DC=ON")
Dostupná je aj premenná %build-inputs
. Predstavuje tabuľku, ktorá
priraďuje názvy vstupov k ich priečinkom v úložisku.
Kľúčové slovo phases
predstavuje postupnosť krokov zostavovacieho
systému. Medzi bežné kroky patria unpack
, configure
,
build
, install
a check
. Ak chcete o týchto krokoch
zistiť viac, musíte nájsť to správne zadanie zostavovacieho systému v
‘$GUIX_CHECKOUT/guix/build/gnu-build-system.scm’:
(define %standard-phases
;; Standard build phases, as a list of symbol/procedure pairs.
(let-syntax ((phases (syntax-rules ()
((_ p ...) `((p . ,p) ...)))))
(phases set-SOURCE-DATE-EPOCH set-paths install-locale unpack
bootstrap
patch-usr-bin-file
patch-source-shebangs configure patch-generated-file-shebangs
build check install
patch-shebangs strip
validate-runpath
validate-documentation-location
delete-info-dir-file
patch-dot-desktop-files
install-license-files
reset-gzip-timestamps
compress-documentation)))
Alebo cez REPL:
(add-to-load-path "/path/to/guix/checkout") ,use (guix build gnu-build-system) (map first %standard-phases) ⇒ (set-SOURCE-DATE-EPOCH set-paths install-locale unpack bootstrap patch-usr-bin-file patch-source-shebangs configure patch-generated-file-shebangs build check install patch-shebangs strip validate-runpath validate-documentation-location delete-info-dir-file patch-dot-desktop-files install-license-files reset-gzip-timestamps compress-documentation)
Ak chcete vedieť čo sa počas jednotlivých krokov odohráva, preštudujte si príslušné funkcie.
Napríklad, v čase písania týchto riadkov, bolo zadanie kroku unpack
v
zostavovacom systéme GNU nasledovné:
(define* (unpack #:key source #:allow-other-keys)
"Unpack SOURCE in the working directory, and change directory within the
source. When SOURCE is a directory, copy it in a sub-directory of the current
working directory."
(if (file-is-directory? source)
(begin
(mkdir "source")
(chdir "source")
;; Preserve timestamps (set to the Epoch) on the copied tree so that
;; things work deterministically.
(copy-recursively source "."
#:keep-mtime? #true))
(begin
(if (string-suffix? ".zip" source)
(invoke "unzip" source)
(invoke "tar" "xvf" source))
(chdir (first-subdirectory "."))))
#true)
Všimnite si volanie chdir
: zmení súčasný priečinok na umiestnenie,
kde boli rozbalené zdrojové súbory. To znamená, že kroky nasledujúce po
unpack
použijú priečinok so zdrojovými súbormi ako ich pracovný
priečinok. Preto môžeme priamo narábať so zdrojovými súbormi. Teda aspoň
dovtedy, kým niektorý ďalší krok nezmení pracovný priečinok na iný.
Zoznam krokov %standard-phases
zostavovacieho systému upravujeme
pomocou makra modify-phases
určujúceho aké úpravy sa majú vykonať, čo
môže vyzerať asi takto:
(add-before krok novy-krok funkcia)
: Spustiť
funkcia s názvom novy-krok pred krok.
(add-after krok novy-krok funkcia)
: Tak isto, ale
za krok.
(replace krok funkcia)
.
(delete krok)
.
Funkcia prijíma parametre inputs
a outputs
v tvare
kľúčových slov. Každý vstup (či už pôvodný, rozšírený alebo
nie) a výstupný priečinok je označený svojim názvom v týchto premenných.
Takže (assoc-ref outputs "out")
predstavuje priečinok úložiska
hlavného výstupu balíka. Funkcia kroku vyzerá nasledovne:
(lambda* (#:key inputs outputs #:allow-other-keys)
(let ((bash-directory (assoc-ref inputs "bash"))
(output-directory (assoc-ref outputs "out"))
(doc-directory (assoc-ref outputs "doc")))
;; ...
#true))
Funkcia musí po úspešnom vykonaní vrátiť #true
. Nie je veľmi
spoľahlivé opierať sa o návratovú hodnotu posledného výrazu keďže nie je
isté, že to bude práve #true
. Koncové #true
zaisťuje, že bude
po úspešnom vykonaní vrátená správna hodnota.
Ak ste boli pozorní, mohli ste si všimnúť obrátenú úvodzovku a čiarku v poli parametrov. Vskutku, zdrojový kód zostavenia v zadaní balíka by sa nemal vykonávať na strane klienta, ale až vtedy, keď sa odovzdá démonovi Guixu. Toto odovzdávanie zdrojového kódu medzi dvoma procesmi nazývame oddialené vykonanie.
Pri prispôsobovaní phases
budete často potrebovať funkcie
zodpovedajúce systémovým volaniam (make
, mkdir
, cp
,
atď.), ktoré sú zvyčajne dostupné na Unixových systémoch.
Niektoré z nich, ako napríklad chmod
, sú priamo dostupné v jazyku
Guile. Viď úplný zoznam v See Guile reference manual.
Guix poskytuje ďalšie pomocné funkcie, užitočné najmä v súvislosti so správou balíkov.
Niektoré z týchto funkcií sa nachádzajú v ‘$GUIX_CHECKOUT/guix/guix/build/utils.scm’. Väčšinou napodobňujú správanie pôvodných Unixových systémových príkazov:
which
Rovnaká ako systémový príkaz ‘which’.
find-files
Podobná príkazu ‘find’.
mkdir-p
Rovnaká ako príkaz ‘mkdir -p’, ktorý v prípade potreby vytvorí aj všetky nadradené priečinky.
install-file
Podobná ako príkaz ‘install’ na inštaláciu súboru do priečinka (aj
nejestvujúceho). Guile má funkciu copy-file
, ktorá funguje ako príkaz
‘cp’.
copy-recursively
Ako ‘cp -r’.
delete-file-recursively
Ako ‘rm -rf’.
invoke
Vyvolať spustiteľný súbor. Toto by ste mali používať namiesto
system*
.
with-directory-excursion
Vykoná telo funkcie v odlišnom pracovnom priečinku a následne obnoví pôvodný pracovný priečinok.
substitute*
Funkcia podobná príkazu sed
.
Viď See Build Utilities in GNU Guix Reference Manual pre viac podrobností o pomocných funkciách.
Licencia v našom predošlom príklade je uvedená s predponou vzhľadom na
spôsob akým bol načítaný modul licenses
v tomto balíku:
#:use-module ((guix licenses) #:prefix license:)
. Spôsob načítavania
modulov v Guile (see Using Guile Modules in Guile reference
manual) používateľovi dáva úplnú kontrolu nad menným priestorom. Môže sa
tak predísť rozporom, povedzme, medzi premennou ‘zlib’ zo súboru
‘licenses.scm’ (názov licencie) a premennou ‘zlib’ zo
súboru ‘compression.scm’ (názov balíka).
Next: Ďalšie zostavovacie systémy, Previous: Nastavenie, Up: Návod na zadávanie balíkov [Contents][Index]