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ü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 .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). 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 "" 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 GetGit() Dient dem Checkout von Addon File fuer pkgs. Ist weiter oben genauer beschrieben! ARGUMENTE: GetGit <$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 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 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 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 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 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 .cont 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 MakeFifo() Legt einen Fifo an und gibt den Filenamen zurück. wird von ExecCommand benötigt (paralles abarbeiten von Shell Commands) ExecCommand() Führt commandos nach einem InitDirspatch parallelisiert aus. InitDispatch() Initialisiere Pralell Shell Execution Environment DispatchCmd() Aufü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 ü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 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.