Pascal-Auferstehungen – von Delphi nach Lazarus

Delphi-Windowsprogramme nach Linux portieren mit Lazarus für FreePascal

Quizzy II mit WINE unter Mint Linux 22
Quizzy II mit WINE unter Mint Linux 22

Mit Delphi 12.1 „Athens“ hatten wir zuletzt TinDat für Quizzy für Windows 64-Bit wiederbelebt und mit DosBox-x Tin Quizzy Classic für moderne Rechner. Aber was ist mit Linux als Zielplattform? Auch das geht!

Ältere DOS-/Windowsprogramme wie Tin Quizzy Classic oder TinDat für Quizzy laufen nicht mehr so ohne weiteres auf neueren Betriebssystemen. Für Dos-Programme gibt es inzwischen sehr brauchbare Emulatoren, z. B. DosBox oder DosBox-x, was mit ein paar Kniffen sogar in Webbrowsern funktioniert. Damit lässt sich Tin Quizzy Classic (also die DOS-Version) recht problemlos auf neueren Computern emulieren.

Tin Quizzy II Windows-Version mit Wine unter Linux

Etwas schwieriger wird es, wenn es sich um Windows-Programme handelt, wie z. B. Tin Quizzy II (6.9) für Windows 32-Bit, denn das geht in DosBox nur über den Umweg einer Installation von Windows 95 oder Windows 98, was zwar unter DosBox-x erstaunlich gut funktioniert – trotzdem raten wir davon ab, denn dafür braucht es eine gültige Windows-Uralt-Lizenz und einen kompletten Windows-PC neu aufzusetzen für ein einziges Programm ist dann doch etwas arg umständlich.

Um Windows-Programme unter Linux (z. B. Mint Linux, aber auch auf einem Raspberry Pi mit Raspi OS) zu emulieren, gibt es die bekannte Anwendung Wine – und das funktioniert natürlich auch mit der aktuellen Quizzy-Version, Tin Quizzy II (6.9) für Windows 32-Bit recht gut, wenn man dabei beachtet, dass Quizzy gerne Zugriff auf seine Fragedateien haben möchte.

Deshalb reicht es nicht, einfach nur die Quizzy-Programmdatei mit Wine aufzurufen – sonst erhält man eine Fehlermeldung.

Wenn man Quizzy II nicht das Programmverzeichnis mitgibt, findet es seine Fragedateien nicht.
Wenn man Quizzy II bei Wine nicht das Programmverzeichnis mitgibt, findet es seine Fragedateien nicht.

Damit Quizzy seine Fragedateien findet, sollte das Verzeichnis schon gerade aktiv sein. Das erreicht man beispielsweise, wenn man mit einer Bash-Shell (Konsole) ins Quizzy-Verzeichnis wechselt und Wine dann damit aufruft.

Ruft man Quizzy aus dem richtigen Verzeichnis per Konsolenbefehl auf, findet es seine Dateien.
Ruft man Wine und Quizzy aus dem richtigen Verzeichnis per Konsolenbefehl auf, findet es seine Dateien.

Dann erhält man ein funktionieres Tin Quizzy II unter Linux inklusive einem moderneren Intro mit Peaches-In-Wonderland Song:

Quizzy II mit WINE unter Mint Linux 22
Quizzy II mit WINE unter Mint Linux 22

Analog lässt sich natürlich auch TinDat unter Linux betreiben.

Relevanz?

Man könnte sich jetzt natürlich fragen, ob es mehr als eine Spielerei ist, Windows-Programme auf Linux laufen zu lassen.

Allerdings schwindet die Dominanz von Windows: Durch die überaus zweifelhafte Politik von Microsoft, einerseits älteren PCs den Umstieg auf Windows 11 zu verwehren, andererseits 2025 dann den Support für Windows 10 zu kappen, dürfte Linux in seinen Varianten Ubuntu, Debian, Mint in Zukunft deutlich wichtiger werden – zumindest bei Benutzern, die noch gut funktionierende PCs nicht einfach wegwerfen wollen, weil es dafür kein Windows mit Sicherheitsupdates mehr gibt. Und intakte Hardware einfach wegzuwerfen ist eigentlich nicht sehr nachhaltig.

Insofern macht es durchaus Sinn, sich damit zu beschäftigen, wie Windows-Programme unter Linux laufen. Denn wer auf Linux umsteigt, möchte seine Lieblingssoftware vielleicht nicht vermissen.

TinDat als natives Linux-Programm mit Lazarus

FreePascal und die IDE Lazarus

Natürlich befriedigt es einen Linux-Fan nicht besonders, wenn er Windows-Programme unter Linux emulieren muss. Besser wäre natürlich, wenn es sich um echte Linux-Programme handeln würde – doch dazu muss man sie neu kompilieren und zunächst einmal den Quelltext portieren. Geht das überhaupt? Natürlich geht das! Und der Zeitaufwand ist sogar recht überschaubar!

Generell ist auch Embarcadero Delphi in der Lage, für Linux Programme zu erzeugen – allerdings erst in der doch recht teuren Architect-Version – und auch dort wird nur eine X86er-Plattform unterstützt, kein ARM (wie z. B. den Raspberry Pi). Aber genau dafür gibt es ja auch noch FreePascal bzw. Lazarus – was sogar ziemlich gut auf einem Raspberry Pi läuft.

Die Lazarus-IDE sieht für Delphi-Kenner sehr vertraut aus.
Die Lazarus-IDE sieht für Delphi-Kenner sehr vertraut aus.

Die Pascal-Entwicklungs-IDE Lazarus ist in Linux-Distributionen nicht standardmäßig vorinstalliert, lässt sich aber mit dem Paket-Manager von Ubuntu, Debian, Mint-Linux oder Raspberry Pi OS problemlos nachinstallieren. Mit Lazarus wird dann auch gleich ein aktuelles FreePascal mitinstalliert und alle nötigen Laufzeitbibliotheken.

Startet man Lazarus zum ersten Mal, erleben Delphi-Kenner sofort ein Deja-Vue: Das Programm ähnelt einem klassischen Delphi ganz erstaunlich. Auch die Programmierung gestaltet sich vertraut. Formulare kann man visuell zusammenklicken, wie in Delphi. Statt der VCL benutzt Lazarus eine visuelle Komponentenbibliothek namens LCL, die weitgehend kompatibel ist.

Man muss in Lazarus auch nicht ganz neu anfangen, sondern kann vorhandene Delphi-Projekte mit einem Konvertierungstool in ein Lazarus-Projekt umwandeln. Dieses findet sich im Menü unter dem Punkt „Werkzeuge | Delphi-Umwandlung“.

Lazarus bringt ein Konvertier-Tool mit, mit dem man vorhandene Delphi-Projekte oder Formulare für Lazarus und FreePascal konvertieren kann.
Lazarus bringt ein Konvertier-Tool mit, mit dem man vorhandene Delphi-Projekte oder Formulare für Lazarus und FreePascal konvertieren kann.

Der Konverter bietet verschiedene Optionen und kümmert sich darum, vorhandene Delphi-Projekte für Lazarus anzupassen. Dabei werden vor allem die binären Delphi-Formulardateien (*.dfm) in das Lazarusformat übertragen. In der aktuellen 3er-Version von Lazarus funktioniert das recht problemlos, allerdings sind an einigen Stellen noch manuelle Eingriffe erforderlich – also ganz automatisch funktioniert es nicht.

Manuelle Nachbesserungen

Ressourcen anpassen

Zunächst einmal müssen aus dem Quelltext alle Verweise auf DFM-Formular-Ressourcen verschwinden und durch die Lazarus-Pendants ersetzt werden.

Folglich tauscht man in allen Units

{$R *.dfm} 

aus durch

{$R *.lfm} 

Units und Systemfunktionen anpassen

Außerdem müssen in einem Linux-System die Units „WinTypes“, „WinProcs“, „Windows“ entfernt werden und die Unit „LclType“ eingebunden werden. Man kann das alternativ auch mit einer bedingten Kompilerdirektive ausklammern, falls man plattformübergreifend programmieren möchte für Windows und Linux.

unit Tin1; 
interface 
uses 
    SysUtils, {$IFDEF Windows} Windows, {$ENDIF} Messages, Classes, Graphics, Controls, 
    LCLType, Forms, Dialogs, StdCtrls, ExtCtrls, Buttons, Menus, clipbrd, QUZCLS;  

const 
... 

Dass die Unit „Windows“ unter Linux nicht zur Verfügung steht, bedeutet aber auch, dass alle Windows-spezifischen Funktionen durch plattformübergreifende LCL-Pendants ersetzt werden müssen. Windows-Routinen benutzte TinDat einige, beispielsweise „Shellexecute“ oder „Application.Helpcommand“, um sekundäre Programmdateien aufzurufen.

Beides lässt sich allerdings recht elegant ersetzen durch den Befehl „OpenDocument“. Dazu muss allerdings noch die Unit „LCLIntf“ eingebunden werden:

 
uses LCLIntf; 
... 
OpenDocument('tindathelp.pdf'); 
... 

Unterschiede der Pascal-Dialekte

Zudem gibt es kleine Unterschiede zwischen dem Delphi-Pascal und FreePascal. Beispielsweise muss man Pointer etwas expliziter markieren. Während Delphi Funktionszuweisungen wie die folgende anstandslos kompilierte:

Application.OnHint:=DisplayHint;

möchte Lazarus/FreePascal das Ganze etwas expliziter haben, damit der Compiler es durchgehen lässt:

Application.OnHint:=@DisplayHint;

Das kleine „@“ macht den Unterschied.

Stringbehandlung

Etwas haariger wird es, wenn die Konversionsroutinen angepasst werden sollen, die DOS-ASCII-Texte (wie die alten Quizzy-Dateien) in Unicode umwandeln sollen (und zurück).

Unter Windows benutzte TinDat dazu die Windows-Funktion „OemToCharA“, die es aber unter Linux nicht gibt. Um Unicode-Spezifika kümmerte sich ansonsten Delphi selbst.

Lazarus unter Linux bringt für diverse String-Konversionen die Klasse WidestringManager mit, welche sehr mächtig ist. WidestringManager ist unter Linux (was ein Unix-System ist) in der plattformspezifischen Unit „cwstring“ implementiert.

Um diese Unit einzubinden, empfiehlt sich wieder ein bedingter Kompiler-Befehl, der nur zum Tragen kommt, wenn der Kompiler unter einem Unix-System kompiliert:

 
Interface 
uses 
    {$IFDEF Windows} Windows, {ENDIF} Forms, LCLIntf, LCLType, LMessages, 
    SysUtils {$IFDEF unix}, cwstring {$ENDIF} ; ...

Mit dem WidestringManager lässt sich dann die Konversionsroutine neu schreiben, die DOS-Texte für den Editor importiert. Die für deutsche DOS-Texte benötigte ASCII-Codepage ist 437:

 
function DOS2WinTxt(dtxt: RawByteString): UnicodeString; 
(* Diese Funktion konvertiert DOS-Umlaute zu Windows-Umlauten *) 
    var tmp: UnicodeString;
        FCodePage: TSystemCodePage = 437;  
begin 
    Result := dtxt; 
    if Length(Result) <> 0 then 
    begin 
        widestringmanager.Ansi2UnicodeMoveProc(PChar(dtxt), FCodePage, 
           tmp, Length(dtxt)); 
        Result := tmp; 
    end; 
end; 

Analog verfährt man mit der Routine „widestringmanager.Unicode2AnsiMoveProc“, um Unicode-Text wieder ins DOS-Text-Format zurückzuübersetzen:

function Win2DOSTxt(wtxt: UnicodeString): RawByteString;
(* Diese Funktion konvertiert Windows-Umlaute zu DOS-Umlauten *)
    var ACodePage: TSystemCodePage = 437;
begin
     Result := wtxt;
     if Length(Result) <> 0 then
     widestringmanager.Unicode2AnsiMoveProc(Pointer(wtxt), RawByteString(Result), 
        ACodePage, Length(wtxt));
end; 

Ein obskurer Laufzeitfehler – manchmal

Bisweilen kommt es, wenn man ein Delphi-Projekt zu einem Lazarus-Projekt umwandelt, noch zu obskuren Laufzeitfehlern, da angeblich eine Fensterklasse nicht gefunden wird. Dieser Fehler ist darauf zurückzuführen, dass die Fensterklassen der Anwendung nicht ordentlich initialisiert wurden, weil in der Projekthauptdatei eine wichtige Zeile fehlt. Der Konverter vergisst das wohl einzufügen – aber wenn man weiß, woran es liegt, ist das recht schnell verbessert.

Man kann den Fehler unterbinden, wenn man den Befehl „Application.Initialize;“ der Projekt-Hauptdatei hinzufügt:


program Tindat;

uses
    Forms, Interfaces,
    TIN1 in 'TIN1.PAS' {TindatFrm},
    NDATDLG in 'NDATDLG.PAS' {NeueDatDlg},
    ABOUT in 'ABOUT.PAS' {AboutBox},
    SEARDLG in 'seardlg.pas' {TFindDialog},
    QUZCLS in 'QUZCLS.PAS',
    HAJUNIT in 'HAJUNIT.PAS',
    QUZTEXTE in 'QUZTEXTE.PAS';

{$R *.res}

begin

    Application.Initialize; //Hier muss die Initialisierung hinzugefügt werden.
    Application.Scaled:=True;
    Application.CreateForm(TTindatFrm, TindatFrm);
    Application.CreateForm(TAboutBox, AboutBox);
    Application.Run;
end.

Bei der Gelegenheit kann man dann auch gleich die obsoleten Theming-Befehle von Delphi entfernen. Denn Lazarus und die LCL unterstützen keine Themes/Styles – stattdessen wird immer die Systemoptik des Linux-Fenstermanagers benutzt. (Was unter Linux auch sinnvoller ist.)

Sofern diese Handarbeiten verrichtet wurden, lässt sich das Projekt dann unter Lazarus kompilieren und ausführen.

Feinschliff

TinDat ist somit eine Linux-Anwendung geworden. Allerdings fallen beim Programm dann immer noch einige kleine Schönheitsfehler auf:

Erstens hat der Konverter das ursprüngliche Anwendungs-Icon unterschlagen, man muss dieses in den Projekteinstellungen wieder neu festlegen:

In den Projekteinstellungen lässt sich auch das Anwendungs-Icon einstellen und ebenso, ob die GUI sich an die dpi-Einstellungen des Systems anpassen soll.
In den Projekteinstellungen lässt sich auch das Anwendungs-Icon einstellen und ebenso, ob die GUI sich an die dpi-Einstellungen des Systems anpassen soll.

Bei dieser Gelegenheit sollte man dann auch gleich noch die Anwendungssprache auf „German“ umstellen, sonst benutzen Systemmeldungen und Standarddialoge die englische Sprache statt der deutschen:

Die Sprache für die Dialogboxen lässt sich in den Projekteinstellungen festlegen.
Die Sprache für die Dialogboxen lässt sich in den Projekteinstellungen festlegen.

Außerdem unterscheidet sich die Skalierung von Delphi und Lazarus – daher sollte man alle Formulare und Dialoge überprüfen, ob Schrift, Labels und Schaltflächen noch die richtige Größe haben und entsprechend anpassen. Sinnvollerweise sollte man in den Projekteinstellungen auch die LCL-Skalierung („DPI-Anpassung“) aktivieren, damit sich die Größe an die jeweiligen Monitor-DPI anpasst – sonst könnte es später bei den Benutzern böse Überraschungen geben.

Somit ist aus der Windows-Version von TinDat eine native Linux-Version geworden, die auf allen unterstützten Linuxplattformen läuft, sowohl auf x86er-PCs, als auch auf ARM-Plattformen (wenn man sie mit Lazarus dort kompiliert).

TinDat als ausgeführtes Linux-Programm im Debugger von Lazarus
TinDat als ausgeführtes Linux-Programm im Debugger von Lazarus
TinDat 1.2 für Linux
TinDat 1.2 für Linux

Auf ähnliche Weise müsste es übrigens auch möglich sein, Programme für andere unterstützte Plattformen zu erstellen – beispielsweise auch MacOS oder gar OS/2.

Weitere Hilfen und Dokumentationen

Auch wenn derzeit andere Programmiersprachen gehyped werden, finden Pascal-Programmierer im Netz weiterhin sehr viele Hilfen zu FreePascal, Lazarus und dessen GUI-Bibliothek LCL. Seit Pascal im Tiobe-Index wieder in den Top-20 ist, werden es sogar wieder mehr.

Eine gute Anlaufstelle für plattformübergreifendes Pascal ist das offizielle Wiki zu FreePascal:

Dort gibt es sowohl eine ausführliche Dokumentation zum Pascal-Dialekt FreePascal und seinen Besonderheiten, als auch zur LCL, also der „Lazarus Component Library“ – dem Pendant zu Delphis VCL.

Nützlich zu wissen ist, dass es übrigens auch von Borlands DOS-GUI Turbovision eine FreePascal-Variante gibt, die sich Freevision nennt. Damit lassen sich auch Turbovision-Programme nach Linux etc. portieren.

Zu Freevision hat der Nutzer sechshelme ein sehr ausführliches Tutorial auf GitHub bereitgestellt:

Nicht zuletzt sei auf die große Community-Website Delphi-PRAXiS verwiesen – anders als der Name vermuten lässt, thematisiert das dortige Forum nicht nur Delphi-Fragen, sondern beschäftigt sich auch mit anderen Pascal-Varianten, wie FreePascal oder auch Oxygene:

 

About Martin Dühning 1507 Articles
Martin Dühning, geb. 1975, studierte Germanistik, kath. Theologie und Geschichte in Freiburg im Breisgau sowie Informatik in Konstanz, arbeitet als Lehrkraft am Hochrhein-Gymnasium in Waldshut und ist Gründer, Herausgeber und Chefredakteur von Anastratin.de.

2 Comments

  1. Wow vielen lieben Dank dir für all die Arbeit, die du dir damit gemacht hast, lieber Martin!
    Obwohl ich grundsätzlich auch native Builds für Linux präferiere, geb ich mich bei TinDat damit zufrieden, es mit Wine laufen zu lassen. Auch weil ich mich frage, wie es dann mit der Kompatibilität der selbstkompilierten Variante ausschauen würde, hinsichtlich zukünftiger Betriebssystemupdates, insb. der der Hauptversionen. Das würde dann doch jedes Mal ein erneutes Kompilieren von TinDat erfordern, oder?

    Alles Liebe,
    Sarah

    • Noch ist die Linux-Version ja experimentell. Ansonsten gibt es bei TinDat nicht so viele Abhängigkeiten mit anderen Bibliotheken, dass ständig eine neue Version bei jeder Linuxversion erforderlich wäre. Dafür ist die Programmdatei unter Linux dann allerdings auch gut 7 MB groß (wobei ich das schon runtergebrochen habe von den ursprünglichen 27 MB der Debug-Version).

Comments are closed.