Pbuild

Aus Wiki des Deutschsprachige Xbaseentwickler e. V.
Zur Navigation springen Zur Suche springen

PBuild ist der ProjectBuilder von Alaska Software.

PBuild steht in der Tradition eines make unter Unix. Unter Xbase++ dient PBuild sowohl der Erstellung einer Projekt-Definitions-Datei, der Verwaltung der Abhängigkeiten, als auch dem Erstellen der Objekte (Plural, wohlgemerkt).


Wie erstellt man eine Projekt-Definitions-Datei (Erweiterung .xpj)?

Es geht sicherlich manuell anhand vorhandener Beispiele, es geht aber auch automatisch. Für den automatischen Betrieb benötigen wir eine Liste der Module, die das Projekt ausmachen. Vorzugsweise als Textdatei, mit einem Dateinamen je Zeile, getrennt durch CRLF. Dies geht recht einfach und schnell über den DIR-Befehl. Erzeugt wird die Projekt-Definitions-Datei dann mit

dir *.prg /b > project.txt
pbuild @project.txt

Der Befehl dir mit dem Parameter /b erzeugt eine einfache Liste mit einem Dateinamen je Zeile, getrennt jeweils durch CRLF. Der danach folgende Aufruf von PBuild liest die Datei ein und erstellt eine rudimentäre XPJ-Datei, wobei PBuild in diesem Fall einige "Vermutungen" anstellt über die Art des Programms.

Es besteht die Möglichkeit, abweichende Namen für die List-Datei zu verwenden, wobei die resultierende XPJ-Datei dann diesen abweichenden Namen reflektiert.

Da ein Aufruf von PBuild ohne Parameter versucht, standardmässig die project.xpj abzuarbeiten, muss der Aufruf dann immer um den Namen der XPJ-Datei ergänzt werden.

Dies kann hilfreich sein, wenn man verschiedene Objekte über verschiedene XPJ-Dateien erstellt, indem man z.B. DLLs mit einer dll.xpj und das Programm mit einer exe.xpj erstellt.

Aufbau einer Projekt-Datei

[PROJECT]
   COMPILE       = xpp
   COMPILE_FLAGS = /q
   DEBUG         = yes
   GUI           = no
   LINKER        = alink
   LINK_FLAGS    = 
   RC_COMPILE    = arc
   RC_FLAGS      = /v
   PBUILD        = @project.txt
   MAKE          = 
   PROJECT.XPJ

Standard-Schlüsselwörter der automatisch erzeugen Projekt-Datei

COMPILE = xpp

legt fest, dass als Compiler xpp.exe aufgerufen werden soll. Ein abweichender Eintrag macht keinen Sinn.


COMPILE_FLAGS = /q

legt fest, dass an xpp.exe lediglich der Schalter /q (für quiet) übergeben wird.

Weitere brauchbare Schalter, die bei der Fehlervermeidung helfen wären:

/w -> Warnungen anzeigen wenn der Compiler auf nicht deklarierte Variablen, oder Feldnamen ohne Aliasangabe stößt.

/wi -> Warnungen anzeigen für nicht initialisierte Variablen

/wu -> Warnungen anzeigen für nicht benutzte lexikalische Variablen (also Variablen, die zwar angegeben sind, aber nicht benutzt werden. Gilt auch für Variablen, denen zwar ein Wert zugeordnet wurde, die aber nicht weiter in Benutzung sind)


DEBUG = yes

aktiviert die Debugging-Unterstützung


GUI = no

legt fest, dass es sich um ein Text-Modus Programm handeln soll (!)


LINKER = alink

definiert ALink von Alaska Software als Linker für das Erstellen des abschliessenden Programms (oder der DLLs)


LINK_FLAGS =

Im Standard erhält ALink keine weiteren Schalter.


RC_COMPILE = arc

bestimmt arc.exe als Compiler für Resourcen, die in das Programm/die DLL eingebunden werden sollen. Auch dieses Programm wird von Alaska bereitgestellt.


RC_FLAGS = /v

übergibt /v als Schalter an arc.exe (wobei /v für "verbose mode" steht).


PBUILD = @project.txt

hierzu gibt es keine Dokumentation, dem Anschein nach wird hier nur festgehalten, aus welcher Datei die aktuelle Projekt-Datei erzeugt wurde


MAKE = 

hierzu gibt es leider keine Dokumentation.


Im Anschluss an diese vorgegebenen Schlüsselwörter kommen benutzerdefinierte, wie das standardmässige generierte

PROJECT.XPJ

mit dem ein Eintrag definiert wird, der abzuarbeiten ist


weitere Schlüsselwörter

Es gibt noch weitere Schlüsselwörter, die für Spezialfälle benötigt werden:



INCLUDE=

Dieses Schlüsselwort definierte weitere Pfade, in denen nach .CH-Dateien gesucht werden soll


LIB=

Dieses Schlüsselwort definierte weitere Pfade, in denen nach .LIB-Dateien gesucht werden soll


OBJ_DIR= obj\

Standardmässig werden Objekte im Verzeichnis abgelegt, in dem PBuild ausgeführt wird. Über OBJ_DIR kann ein (!) Verzeichnis spezifiziert werden, in dem .OBJ-Dateien abgelegt werden. Der Linker greift ebenfalls auf dieses Verzeichnis zu, wenn es spezifiziert ist.


OBJ_FORMAT=COFF/OMF

POST_BUILD=

POST_CLEAN=

PRE_BUILD=del "obj\*.obj"
PRE_BUILD=del "programm.exe"

Dinge die vor der Erzeugung erledigt werden. Im Beispiel hier Löschung der Objektdateien im entsprechenden Verzeichnis und des eigentlichen Programmfiles. PRE_BUILD kann mehrfach hintereinander mit verschiedenen Aufgaben belegt werden.


PRE_CLEAN=


Kommentare

Ein Kommentar wird durch // eingeleitet. Eine Möglichkeit wie in Xbase, einen auch über mehrere Zeilen gehenden Kommentar in /* ... */ einzuschliessen, gibt es hier nicht.


Benutzer-definierte Bereiche

Mit den bisherigen Angaben wird das Umfeld der Projekterstellung festgelegt, nicht jedoch, WAS getan werden soll.

Der letzte Eintrag im ersten Abschnitt weisst PBuild an, nach einem Abschnitt mit dem gleichen Namen zu suchen. In dem obigen Beispiel erwartet PBuild einen Abschnitt [PROJECT.XPJ]

Unter diesem Eintrag werden die Ziel-Objekte aufgelistet:

[PROJECT.XPJ]
   Meine.DLL
   Meine.EXE

Während die beiden Einträge PROJECT.XPJ / [PROJECT.XPJ] beliebig benannt werden können (auch HUGO / [HUGO] würde funktionieren), sind die Angaben hier die Namen, unter denen die erzeugten Objekte im Zielverzeichnis erzeugt werden.

Jeder Eintrag in diesem Abschnitt muss wiederum als neuer Abschnitt definiert werden:

[Meine.DLL]
   MeineDll.prg
   MeineIrgendwas.prg

[Meine.exe]
   meineexe.prg
   nocheineandere.prg

Die Namen müssen, was Gross- und Kleinschreibung angeht, nicht identisch sein, d.h. MEINE.EXE, meine.exe und Meine.Exe werden als übereinstimmend angesehen.



Generieren der Abhängigkeiten

Wer mit make unter Unix, Linux oder auch Windows gearbeitet hat, weiss, dass make "tiefer" hineinschaut. Nehmen wir an, in meineexe.prg wird meine.ch verwendet. Wenn meine.ch geändert wird, muss meineexe.prg neu compiliert werden. Diese Abhängigkeit ist aus dem o.a. Beispiel nicht abzuleiten.

Wenn PBuild /g aufgerufen wird, liest PBuild die betroffenen Programme und analysiert die Abhängigkeiten, dazu gehören eben auch eingebundene Include-Dateien, oder die Tatsache, dass PBuild annimmt, dass MEINE.EXE von MEINE.DLL abhängig ist.

Um die benutzerdefinierten Einträge von den automatisch generierten zu unterscheiden, erzeugt PBuild hinter jeder Definition einen Bereich, der mit // $START-AUTODEPEND eingeleitet und mit // $STOP-AUTODEPEND beendet wird.

Einträge zwischen diesen beiden Merkern werden beim nächsten Aufruf PBuild /g ersetzt. Wer dort also eigene Anweisung einfügt, muss sie jedesmal wieder ergänzen. Daher: Finger weg von diesen Abschnitten!