ViitorMake/DOC/Module_Programming_Guide
kueller d0126e908f V961 Tree Umbau
git-svn-id: svn://svn.compuextreme.de/Viitor/V961/ViitorMake@4277 504e572c-2e33-0410-9681-be2bf7408885
2008-05-03 16:58:54 +00:00

408 lines
21 KiB
Plaintext

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 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)
ungetestet mangels system: Intel CPU mit EMT64
sparc64-Viitor$VERSION-linux-gnu = Ultrasparc2 CPU im Multilib Modus
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 "forece" (-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 inconsistenten 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
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).
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 legt ein daraus
resultierendes *.dep in $DISTDIR/$SRCPATH ab.
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 checksums der files
in {bin,man,dev}.md5 sowie FileRechte ({bin,man,dev}.frg) und Directory
Rechte {bin,man,dev}.drg gespeichert.
Aus den resultierenden Files wird dann ein tar.bz2 archiv mit der Endung "tbz"
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
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>
GetCVS() Dient dem Checkout von Addon File fuer pkgs. Ist weiter
oben genauer beschrieben!
ARGUMENTE: GetCVS <CVS 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>
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>
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>
ClearTargetNameing()
Siehe ClearHostSysNameing. Jedoch wird hier nicht
Umbenannt, sondern ein link mit <binname> angelegt.
ARGUMENTE: ClearTargetNameing <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>
NoOpt() Schaltet die Optimierung (durch $CFLAGS und $CXXFLAGS)
fuer den aktuellen build in 2 stufen aus.
Hinfaellig ab der Viitor Version 961, da hier keine
CFLAGS mehr gesetzt werden, und die Optimierung im
Module explizit durch Verwendung von $BUILDOPTIONS und
$BUILDOPTIONS32 selektiert werden muss.
ARGUMENTE: NoOpt [0|1|2]
0 Optimierung off
2 Optimierung off
* Optimierung O3 entfernen alles andere
beibehalten
RestoreOpt() Schaltet die mit NoOpt ausgeschaltene Optimierung wieder
ein wird durch CleanUp() aufgerufen!
InstallOldKernelh()
Tauscht /usr/src/linux durch die Kernelheader eines
2.4.x kernels aus. Hilft oft bei kompile Problemen die
aus api aenderungen am aktuellen Kernel resultieren.
Muss fuer die V961 neu geschrieben werden, sofern sie
noch benoetigt wird.
ARGUMENTE: InstallOldKernelh [1]
1 Installieren
* Orginal Kernel wieder herstellen
Wird so von CleanUp aufgerufen.
UseOldGcc() Leider hat sich im laufe der gcc Entwicklung auch das
Verstaendniss der C Syntax im gcc angepasst.
Daraus resultiert, das der aktuelle gcc (V961 verwendet
den gcc 4.1.1) oft aeltere sourcen (ANSI C, oder gar
Kerningham Richi C) als fehler anmeckert.
Daher werden in Viitor verschiedene gcc Versionen
verwendet. die Aelteste Version stellt der gcc/2.95.x
dar, mit Viitor V961 nicht mehr erstellt wird, da diesem
eine Unterstuetzung fuer 64 Bit vollstaendig fehlt.
Ansonsten wird noch eine 3.3.x mitgeliefert, welche sich
als sehr zuverlaessig erwiesen hat.
Mittels dieser Funktion kann die zu verwendende gcc
version umgeschalten werden.
ARGUMENTE; UseOldGcc [1|2]
1 gcc-2.95-3 Verwenden
2 gcc-3 Verwenden
* System default gcc verwenden
Wird so von CleanUp verwendet.
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>.md5,
<prefix>.frg 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
Fix_Input_h() Einige Programme, die Joysticks, maus oder tastatur
verwenden sind von den deklarationen in
/usr/src/linux/include/linux/input.s bzw.
/usr/include/linux/input.h abhaengig. Da in Kernel 2.6.x
permanent aenderungen der api stattfinden, macht dieses
file in aktuellen versionen haeufig probleme.
Mit dieser Routine wird eine "saubere" input.h aus dem
Kernel 2.4.x tree temporaer eingespielt, die nachher
durch CleanUp wieder aufgeraeumt wird.
UseKernelh() Die mit V961 eingefuehrten gepatchten kernel Header files
von linuxfromscratch sind leider nicht komplett. Werden kernel
Includes benoetigt, die in den linuxfromscratch packeten nicht
enthalten sind, kann mit UserKenrelh 1 auf die unter
/usr/src/linux/include/linux installierten header umgeswitcht
werden. Cleanup, oder ein UserKernelh 0 switcht wieder auf
die gepatchten includes zurueck.
ARGUMENTE: UseKernelh [1|0]
1 = auf /usr/src/linux/include/linux switchen
0 = /usr/include/linux.orig wieder herstellen
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.