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 .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 erweitert; TMPROOT=$TMPROOT/$$ und mit mkdir angelegt -> hier werden die fertigen Binarys erwartet. Ueber /proc/ wird ermittelt wieviele cpu`s das hostsystem hat, und $NUMCPU auf 2x 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 "" 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 SrcPatch() Wendet einen patch in einem Verzeichniss an. Patchfiles koennen dabei unkomprimiert oder gz bzw bz2 komprimiert vorliegen. ARGUMENTE: SrcPatch \ UnPack() unkomprimiertes oder mit compress, gzip oder bzip2 comprimiertes tar Archive in verzeichniss entpacken ARGUMENTE: UnPack \ 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 GetCVS() Dient dem Checkout von Addon File fuer pkgs. Ist weiter oben genauer beschrieben! ARGUMENTE: GetCVS <$TMPROOT> GenDependics() Gibt eine Liste aller Librarys der im Uebergebenen Pfad befindlichen binary Files zurueck ARGUMENTE: GenDependics StripPkg() Durchsucht den angegebenen Pfad nach binary files, und entfernt unnoetige debugging informationen aus diesen. ARGUMENTE StripPkg ClearHostSysNameing() Wird beim ./configure aufruf eine --target oder --host angegeben, nehmen manche makes dies zum anlass die erzeugten Files nach dem schema $TARGET- zu benennen. So sind diese files meistens im Betrieb nicht brauchbar. Die Funktion untersucht einen Pfad auf solche files, und benennt diese nach um. ARGUMENTE: ClearHostSysNameing 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 ClearTargetNameing() Siehe ClearHostSysNameing. Jedoch wird hier nicht Umbenannt, sondern ein link mit angelegt. ARGUMENTE: ClearTargetNameing 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 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 Asc2Oct() Erstellt aus einem Rechtebuchstaben (r,w oder x) den entsprechenden Octalwert (4,2 oder 1). Hilfsfunktion fuer GetFlags() ARGUMENTE: Asc2Oct MakeMgtFiles() Erstellt aus einem vorgegebenen Tree die .md5, .frg und .drg files fuer ein ViitorPackage der pwd muss beim aufruf im zu untersuchenden Verzeichniss stehen. ARGUMENTE: MakeMgtFiles 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.