ViitorMake/DOC/Module_Programming_Guide

395 lines
19 KiB
Plaintext
Raw Permalink Blame History

ViitorLinux genpkg Module Programming Guide
Hier wird versucht einen Ueberblick ueber die Funktionalitaet von genpkg
zu geben, sowie die daraus resultierenden Richtlinien zur Module
Programmierung von genpkg Modulen dargestellt werden.
genpkg ist das Basisscript, das, von Modulen gesteuert, die Erzeugung aller
Packete der ViitorLinux Distribution erledigt.
genpkg wird durch das File defsys im gleichen Verzeichniss konfiguriert. Hier
werden ueber Variablen die Pfade zu den Sourcen, zum "Make" Verzeichniss, in
welchem die Sourcen entpackt, und die binarys erzeugt werden, usw eingestellt.
Ausserdem wird die System Optimierung fuer das Zielsystem ($TARGET, $CPU)
eingestellt.
Dabei ist $TARGET von $CPU abhaengig. Aktuell werden folgende
TARGET definitionen unterstuetzt:
i586-Viitor$VERSION-linux-gnu = Pentium,
K6 prozessoren
i686-Viitor$VERSION-linux-gnu = PentiumII,
PentiumIII,
PentiumIV...
athlon-Viitor$VERSION-linux-gnu = AMD Athlon K7,
Duron usw.
Ausserdem K8, AMD64,Turion im 32 BIT Modus.
x86_64-Viitor$VERSION-linux-gnu = AMD K8 (opteron),
amd64
turion als multilib (32/64 BIT)
Intel CPU mit EMT64
sparc64-Viitor$VERSION-linux-gnu = Ultrasparc2 (In Entwicklung)
Die Funktion der Pfad Variablen ist im File defsys hinreichend
dokumentiert. Daher wird hier nicht naeher darauf eingegangen.
Im Module koennen ueber die Variable $MKPKG diverse FLAGS angegeben werden.
Hier wird eine Binaere Auswertung der Zahlen vorgenommen und pro gesetztem Bit
eine entsprechendes Verhalten festgelegt.
BIT1 (1):Wenn binaerpacket schon existiert, entsprechenden Warnhinweis
Unterdruecken
BIT2 (2):Package mit "forec" (-f bei installpkg) installieren.
d.H. das package wird ohne rueckfrage, auch wenn es bereits
installiert ist eingespielt
BIT3 (4):Sources nicht entpacken. Modul kuemmert sich selber darum
Dies ist vor allem bei inkonsistenten srcarchive- srcdir- und
Modulenamen notwendig
BIT5 (8):pkg erzeugung wird unterbunden. Nach dem build muss
Sich das Modul selber darum kuemmern. Ist dann notwendig,
wenn ein "make install" die binarys partout nicht unter
$TMPROOT plazieren will.
BIT6 (16):pkginstallation nach dem build wird unterdrueckt. Vor allem
wichtig wenn das pkg beim installieren benoetigte files
(bash, tar, usw) ueberschreibt - dies fuehrt zum
installations abbruch.
BIT7 (32):dependics als "forced" ein *.dep eintragen. Damit wird eine
Installation ohne vorhandene dependics unterbunden.
BIT8 (64):Aufraeumen des source verzeichnisses nach dem Build unterlassen
BIT9 (128):Vorhandene Patches NICHT automatisch anwenden
BIT10 (256):installpkg mit -o (overwrite existing files) ausf<73>hren
Bits in einer Variablen koennen mit
(( VARIABLE = $VARIABLE | DEZIMALWERT )) (Binaere ODER Verknuepfung)
gesetzt werden.
Wird die Variable und der Testwert mit & verknuepft, so ist das ergebniss <> 0,
wenn das passende Bit gesetzt ist -> von diesem Mechanissmuss macht genpkg
intensiven Gebrauch.
MKPKG = 6 # setzt BIT2 und BIT3 (2 + 4 = 6)
(( TEST = $MKPKG & 1 ))
#TEST ist jetzt 0 bit 1 ist in 6 nicht enthalten
(( TEST = $MKPKG & 2 ))
#TEST ist jetzt 2 da bit2 in 6 enthalten ist
(( TEST = $MKPKG & 4 ))
#TEST ist jetzt 4, da bit3 in 6 enthalten ist
(( TEST = $MKPKG & 8 ))
#TEST ist jetzt 0, da BIT4 nicht in 6 enthalten ist
(( TEST = $MKPKG & 3 ))
#TEST ist jetzt 2, da 3 BIT1 UND BIT2 Abfragt, und nur BIT2 gesetzt ist.
Obiges Beispiel verdeutlicht kurz die Funktionalitaet der bitgesteuerten
Abfragen, wie sie in genpkg Verwendung finden.
Eine Weitere wichtige Variable im Modul ist $SRCPATH.
Diese muss den pfad Anteil innerhalb des Viitor source trees enthalten,
in welchem das Sourcefile zu finden ist.
Der Pfad zu den Sourcen wird mit $LFSSROURCE/$LFSPATH zusammengesetzt.
$LFSSOURCE wird hierbei aus defsys gewonnen.
Der Ablauf von genpkg;
genpkg bekommt als Argument den Namen des zu verwendenden Modules uebergeben.
Ueber die Funktion (in functions/functions definiert) UnPack werden in
$LFSSOURCE/$SRCPATH gefundene source archive (tar.gz, tar.bz2) nach
$MKPKG (aus defsys) entpackt. Weiterhin wird geprueft ob gleichnamige files
mit <ARCHPATTERN>.patch.* existieren.
Sofern diese vorhanden sind, und BIT9 (128) in $MKPKG NICHT gesetzt ist,
werden die patches mit "patch -p1" im gerade entpackten sourcetree eingespielt.
Weiterhin wird $TMPROOT um <PKGNAME> erweitert; TMPROOT=$TMPROOT/<pkgname>$$ und
mit mkdir angelegt -> hier werden die fertigen Binarys erwartet.
Ueber /proc/ wird ermittelt wieviele cpu`s das hostsystem hat, und $NUMCPU auf
2x<anzahl der cpu's> gesetzt -> das kann spaeter im Modul verwendet werden,
um eine optimale scalierung des make prozesses auf Multiprozessor
Systemen zu erreichen (z.B. mit make -j $NUMPCU).
Weiterhin wird $TARGET (aus defsys) auf 64 (bit) getestet;
echo $TARGET|grep -q 64
Wenn der TARGET string (z.B. mit x86_64-ViitorV961|sparc64-ViitorV961)
64 enthaelt, wird die Variable MK64BIT auf 'true' gesetzt -> damit kann
im Modul gesteuert werden, ob 32 bit binarys erzeugt werden muessen, und
ob libs nach */lib64 installiert werden sollen.
Unter /tmp/genpkg wird ein file (touch) angelegt, das dem Modulenamen
entspricht, um doppellaeufe bei automatischen builds zu vermeiden, und
einen spaeteren Einstig an gleicher stelle (Clusterbuild) zu
ermoeglichen. Alle Module, fuer welche unter /tmp/genpkg ein file
existiert, werden im Clusterbuild nicht mehr angefasst (der Pfad kann
mittels der Option -b veraendert werden).
Als kleiner Bonus dazu, wird der komplette Build Ouput in diesem File
gespeichert.
Nach diesen Vorbereitungen fuehrt genpkg die Funktion premk() aus dem Modul
aus. Hier koennen vorbereitende Massnahmen (build dir ausserhalb
des sourcetrees anlegen, patchen usw.) vorgenommen werden. Zum
Ausfuehrungszeitpunkt von premk() steht der PWD im vorher von genpkg
entpackten sourcetree.
Nach Durchlauf von premk() wird, sofern $MK64BIT == "true" und eine
Funktion mk32() definiert ist, diese aufgerufen. Beim Build eines
Multilib 64 Bit Systems muss die mk32() Funktion die 32BIT Development
Librarys erzeugen und nach $TMPROOT installieren. So dass binaer
Packages die fuer 32 BIT Uebersetzt wurden auch auf der 64 BIT
Installation funktionieren.
Direkt anschliessend wird die mk() Routine aus dem Modul gestartet ->
diese sollte aus dem sourcetree nun die Binarys erzeugen, und nach $TMPROOT
installieren.
Ist mk() durchgelaufen, fuehrt genpkg weitere Operationen auf $TMPROOT aus,
naemlich ein 'strip --strip-debug' um unnoetige Informationen in den binarys
zu beseitigen, und damit der Platzverschwendung Herr zu werden.
Ausserdem versucht genpkg Librarys zu identifizieren (intensiver gebraucht von
ldd) die von den erzeugten Binarys benoegigt werden und erzeugt daraus ein
bzip2 comprimiertes dep file.
Jetzt wird postmk() gestartet, das dem $TMPROOT noch Konfigfiles hinzufuegen
kann, oder diverse Umbauarbeiten vornehmen kann, und so $TMPROOT in den
letztendlichen installierbaren Zustand bringt.
Ist postmk() durchlaufen, trennt genpkg binarys von statischen libs und
includes, sowie von info oder manpages, baut aus den entsprechenden Teilen
bin.tar, dev.tar und man.tar archive.
Ausserdem werden diverse Fileinformationen gesammelt, die später die
Informationen in /var/install/contents ergeben, und als {bin,man,dev}.cont
gespeichert. Die Verzeichniss Rechte werden nach {bin,man,dev}.drg gespeichert.
Aus den resultierenden Files wird dann ein "Viitor Archive" generiert.
d.H. es werden die Filegrössen berechnet und so eine Statuszeile
der einzelnen Files generiert.
Hieran werden dann die Datenefiles der reihe nach bzip2 gepackt angehängt.
Die Reihenfolge in einem Viitor Archive (*.vpg) ist folgendermassen:
StatusZeile
dep
meta
bin.drg
bin.cont
bin.tar
dev.drg
dev.cont
dev.tar
man.drg
man.cont
man.tar
preinstall
Dieses File wird nach $DISTTARGET/$SRCPATH geschrieben.
Aus dem obigen Ablauf ergibt sich die anschliessende Aufrufreihenfolge
fuer die in den Modulen definierten Funktionen:
premk() -> mk32() -> mk() -> postmk()
Nach durchlauf von postmk() sollte in jedem fall (ausser der pkgbuild
wird mit MKPKG unterbunden) unter $TMPROOT der komplette pkgtree so
liegen, wie der spaeter, nach der installation, in / erscheinen soll.
Viele pkgs brauchen noch einige Konfigurations file, oder init files
fuer den korrekten Betrieb unter Linux. Solche Files koennen im CVS als
einzelnes Project hinterlegt werden, und mittels GetCVS() in der premk()
Funktion in das package eingespielt werden.
Dabei erhalten folgende, im Projektroot optional vorhandene
Verzeichnisse, eine Sonderbehandlung:
etc/ Alle hier vorhandenen files erhalten das Recht 644
etc/init.d Hier gefundene files erhalten das Recht 755
etc/sysconfig Hier gefundene files erhalten das Recht 644
etc/sysconfig/profile.d Hier gefundene files erhalten das Recht 755
locale/ Hier gefundene files werden mittels msgfmt als
Language files nach /usr/share/locale/
installiert
init/ Ein hier vorgefundenes genpkg wird gesourced,
und kann links anlegen, oder die projektdaten
noch anderweitig aufbereiten. (links werden im
CVS nicht gespeichert!!). Das Verzeichniss wird
nach beendigung von init/genpkg geloescht!
CVS alle vorhandenen CVS Verzeichnisse werden
geloescht
.svn Subversion status files werden ebenfalls aufgeraeumt
Nach dieser Aufbereitung werden alle vorhandenen Verzeichnisse und files
1:1 nach $TMPROOT kopiert.
Um das zu erreichen, sind leider, jenachdem wie sauber configure/make der pkg
gebaut wurden, relativ haeufig diverse verrenkungen notwendig. Viele
dieser probleme koennen durch Routinen aus der funktionssammlung unter
functions/functions behoben werden. Daher hier eine kleine Uebersicht
und kurzbeschreibung der dort vorhandenen Routinen:
CheckError() Internee Fehlerbehandlung mit Abbruch.
Funktion wertet den Rueckgabewert des zuletzt
ausgefuehrten Kommandos aus, und beendet genpkg wenn der
Rueckgabewert <> 0. Dabei wird $1 als abbruchmeldung
ausgegeben
ARGUMENTE: Checkerror "<Fehlermeldung>"
CleanUp() Hier nur der vollstaendigkeit halber. Wertet diverse von
genpkg gesetzte flags aus, und raeumt basierend darauf
die Umgebung, sowie evntl. entpackte sourcen und files
auf. Wird normalerweise nur von internen genpkg
funktionen aufgerufen, und hat im Modul nichts verloren
(bitte hier CheckError() verwenden -> das greift auf
CleanUp zurueck.
ARGUMENTE: KEINE
GetSuffix() Ermittelt aus einem beliebigen Filenamen den Suffix
ARGUMENTE: GetSuffix <FileName>
SrcPatch() Wendet einen patch in einem Verzeichniss an.
Patchfiles koennen dabei unkomprimiert oder gz bzw bz2
komprimiert vorliegen.
ARGUMENTE: SrcPatch <Pfad in dem patch angewand werden soll> \
<Patchfile das verwendet werden soll>
UnPack() unkomprimiertes oder mit compress, gzip oder bzip2
comprimiertes tar Archive in verzeichniss entpacken
ARGUMENTE: UnPack <Verzeichniss in dem entpackt werden soll> \
<Tar Archiv das entpackt werden soll.>
ArchiveName() Wandelt den Namen eines beliebigen Source Archives in
den dazu passenden Viitor Archive Namen um. und gibt
diesen aus. (Typischerweise Verwendung mit
ERGEBNISS=`ArchivName()`
ARGUMENTE: ArchiveName <src filename>
GetGit() Dient dem Checkout von Addon File fuer pkgs. Ist weiter
oben genauer beschrieben!
ARGUMENTE: GetGit <Subversion Projetct Name> <$TMPROOT>
GenDependics() Gibt eine Liste aller Librarys der im Uebergebenen Pfad
befindlichen binary Files zurueck
ARGUMENTE: GenDependics <Zu untersuchender Pfad>
StripPkg() Durchsucht den angegebenen Pfad nach binary files, und
entfernt unnoetige debugging informationen aus diesen.
ARGUMENTE StripPkg <Verzeichniss in welchem gesucht werden soll>
ClearHostSysNameing32()
Siehe ClearHostSysNameing. Hier geht es um TARGET32, wie
von mk32() verwendet. und ist beim Multilib Build fuer
die 32 Bit Version der Binarys
ARGUMENTE: ClearHostSysNameing <Zu untersuchendes Verzeichniss>
ClearHostSysNameing()
Wird beim ./configure aufruf eine --target oder --host
angegeben, nehmen manche makes dies zum anlass die erzeugten
Files nach dem schema $TARGET-<binname> zu benennen. So
sind diese files meistens im Betrieb nicht brauchbar.
Die Funktion untersucht einen Pfad auf solche files, und
benennt diese nach <binname> um.
ARGUMENTE: ClearHostSysNameing <Zu untersuchendes Verzeichniss>
MakeCheck() Wrapper fuer "make check". Prueft ein FLAG, das z.B. bei
makeViitor mit der Option -c gesetzt wird, und fuehrt
nur wenn das FLAG gesetzt ist ein
make $*
aus.
ARGUMENTE: MakeCheck <Optionen fuer make>
CleanTextFiles entfernt aus allen files in $TMPROOT den string aus $TMPROOT
GetFlags() Rechnet Rechte strings wie sie von ls -l ausgegeben
werden in Ihre Oktalen Entsprechungen um und gibt den
passenden Oktalwert aus.
Hilfsfunktion fuer MakeMgtFiles()
ARGUMENTE: GetFlags <rechtestring z.B. -rwxr-x--s>
Asc2Oct() Erstellt aus einem Rechtebuchstaben (r,w oder x) den
entsprechenden Octalwert (4,2 oder 1).
Hilfsfunktion fuer GetFlags()
ARGUMENTE: Asc2Oct <Rechtebuchstabe>
MakeMgtFiles() Erstellt aus einem vorgegebenen Tree die <prefix>.cont
und <prefix>.drg files fuer ein ViitorPackage
der pwd muss beim aufruf im zu untersuchenden
Verzeichniss stehen.
ARGUMENTE: MakeMgtFiles <prefix>
SetConfig() $PKG_CONFIG_PATH steuert pkg-config. und gibt diesem an,
wo die files zur Linker Configuration von libraries zu
finden sind. Die Entsprechenden Konfigurationen werden
von den entsprechenden Libraries mitgebracht, und beim
"make install" eingespielt.
Mit Viitor64 liegen diese sowohl unter */lib/pkgconfig
als auch unter */lib64/pkgconfig. Je nachdem ob fuer
32 BIT oder fuer 64 BIT gebaut wird, muss nun das
richtige configfile gewaehlt werden. Welche verwendet
werden bestimmen die pfade in $PKG_CONFIG_PATH.
SetConfig sorgt jetzt mittels sed dafuer, das entweder
nur die lib64 ("s/lib/lib64/") oder nur die lib
("s/lib64/lib") verzeichnisse durchsucht werden.
ARGUMENTE: SetConfig [32|64|0]
32 PKG_CONFIG_PATH auf lib umstellen
64 PKG_CONFIG_PATH auf lib64 umstellen
0 Orginal PKG_CONFIG_PATH wieder herstellen
X11R7_Fix() Mit der Umstellung der X11 Version auf 7.x.x wird in
Viitor auch aus /usr/X11R6 ein /usr/X11R7. Einige
packages suchen die X11 supportfiles jedoch fix unter
/usr/X11R6. X11R7_Fix legt /usr/X11R6 als Link nach
/usr/X11R7 an, so das solche packages generiert werden
koennen. Dies wird nach Erstellung des Packages von
CleanUp wieder entfernt
MakeFifo() Legt einen Fifo an und gibt den Filenamen zur<75>ck.
wird von ExecCommand ben<65>tigt (paralles abarbeiten
von Shell Commands)
ExecCommand() F<>hrt commandos nach einem InitDirspatch parallelisiert
aus.
InitDispatch() Initialisiere Pralell Shell Execution Environment
DispatchCmd() Auf<75>hrungsroutine f<>r Prallel Execution Environment
EndDispatch() Wartet daruaf das Alle Commands im Parallel Excution
Environment sich beenden, und beendet dann das PEE.
GenDynLib32() Baut aus einer statischen Library entsprechende
Dynamische Pendantes. Hierzu ist es notwendig das die
Objectfiles der statischen Library mit -fPIC <20>bersetzt
wurden. Als Argumente muss der Absolute (!) Pfad zur
Statischen Library, sowie die Version der zu
erzeugenden Dynamischen Library angegeben werden.
Diese Funktion muss speziell bei einem Multilib (64Bit)
build verwendet werden, wenn eine 32 Bit Library
gebaut werden soll (aus eine 32 Bit Statischen Lib)
GenDynLib() Siehe GenDynLib32(). Baut 64 Bit Libs bei einem
Multilib Build, und 32 Bit libs bei einerm 32 Bit Build
extractfile() Extrahiert Files aus einem Viitor Archive.
Aufruf mit: extractfile <ArchiveName> <FileName>
wobei Filename der name eines Archive Bestandteils sein
muss (wie weiter oben beschrieben)
Wird bei der Modulerstellung bemerkt, das weitere Routinen sinnvoll
sind, so koennen diese in functions/functions erstellt werden, und
stehen damit in allen Modulen zur Verfuegung. Hierbei ist zu beachten,
das Systemaenderungen wie sie z.B. durch UseOldGcc(), InstallOldKernelh,
X11R7_Fix oder Fix_Input_h vorgenommen werden auch zuverlaessig wieder
Rueckgaengig gemacht werden. Hierzu kann CleanUp erweitert werden.
CleanUp() wertet die BITS der Variablen CLEANUP_FLAGS aus, und Raeumt je
nach gesetzten Bits auf:
BIT1: SRC Tree loeschen - wird von genpkg nach auspacken der sourcen
gesetzt
BIT2: TMPROOT loeschen - wird von genpkg nach anlegen des $TMPROOT
gesetzt
BIT3: Orginal Kernel wieder herstellen (InstallOldKernelh rueckgaengig
machen).
BIT4: System GCC wieder verwenden (UseOldGcc aufraeumen)
BIT5: /usr/X11R6 entfernen (X11R7_Fix)
BIT6: input.h wieder herstellen (Fix_Input_h)
Innerhalb von genpkg werden zur laufzeit diverse Variablen gesetzt und
verwendet. Einige dieser Variablen koennen innerhalb von premk(), mk()
und postmk() umdefiniert werden, um genpkg so zu speziellem verhalten zu
bewegen:
PKGNAME: Definiert den zu erzeugenden pkgname fuer das ViitorPackage.
DSTPKGNAME: PKGNAME ohne Endung *.tbz (nach premk und mk!).
Wird fuer die erzeugung des *.dep pkgnamens verwendet.