Crosscompiling - erste Eindrücke

Für Fragen von Einsteigern und Programmieranfängern...
Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Crosscompiling - erste Eindrücke

Beitrag von Aliobaba »

Hallo,

Schon vor vielen, vielen Jahren hatte ich noch unter Suse 5.3 und 6.1 (!!!) einen Samba-Server geschäftlich am Laufen. Und immer wieder versuchte ich die Migration von Windows auf Linux auch auf dem Desktop: Es scheiterte stets! Und immer waren es (wahrscheinlich) viele winzige Kleinigkeiten, die für mich als Anfänger so große Hürden aufbauten, die ich einfach nicht überwinden konnte. Und immer wieder musste ich Linux frustriert in die Ecke legen.

Aber jetzt sieht's ganz anders aus :-) !! Kubuntu 14.04 ist installiert und was soll ich sagen: Ich bin begeistert!!!! Ich denke, diesmal ist der "Absprung" endgültig geschafft. Immer wieder entdecke ich neue Features, die mich wirklich begeistern!!

Unter Windows habe ich mit Lazarus das Programm "MyMemoryDB" ( http://www.mymemorydb.n-bay.de/ ) erstellt, das für mich mittlerweile zur zentralen "Wissens-Datenbank" während meiner Arbeiten am Computer geworden ist. Jeder interessante Link, dem ich begegne, und jede wichtige Textstelle, die ich lese, landet, versehen mit den passenden Schlagworten, in "meinem" Programm. Ich brauchte also "MyMemoryDB" dringend auch unter Linux, da ich jetzt ja seit ca. 4 wochen fast nur noch mit "Linux" "unterwegs" bin. "VirtualBox" wäre da eine Lösung gewesen, wenn auch eine holprige (und fast "ehrenrührige"). Zum Glück stellte ich bald fest, dass "MyMemoryDB" völlig problemlos, "optisch" nahezu mit identischem Aussehen und nur wenig langsamer mit allen Features auch unter "Wine" läuft; ich brauchte nur die "Exe" starten - alles andere lief automatisch -- Toll, einfach Toll!! Trotzdem: Gerne hätte ich "MyMemoryDB" auch nativ unter Linux zum Laufen gebracht. Und da stellte ich sehr bald fest, dass es eben nicht so ist, dass man denselben Quellcode nur mit einem anderen Compiler kompilieren muss - und schon hat man ein lauffähiges Windows Programm.

Das erste Starten war zwar recht vielversprechend; nach Installation der Zeos-Komponenten erstellte der Kompiler tatsächlich eine immerhin lauffähige Linux-Version. Schnell wurde die Linux-Version immer besser; der Austausch in "uses" von "ShellAPI" mit "LCLIntf" und das Umgehen der wenigen Befehle, die in "uses" den Eintrag "Windows" brauchten, war kein Problem.

Natürlich bemerkte ich auch Unterschiede im Aussehen des Programms: "Bold"-dargestellte Texte brauchen unter Linux "mehr Platz" - nun gut, ein Button muss den Text ja nicht unbedingt in "Bold" enthalten, und manche Edit-Felder hatten unter Windows und Linux verschiedene Größen, was auch unangenehm ist, was man (ich) aber beherrschen kann. Derartige "Designproblem" machen aber auch anderen Usern dieses Forums offensichtlich erhebliche Schwierigkeiten, wie man nach Beschäftigung mit der Suchfunktion hier immer wieder sehen kann.

Mein Hauptproblem aber ist die unterschiedliche Dateistruktur bei Linux und Windows. Ich liebe nämlich bei Windows-Programmen "portable Apps", also Programme, die ich einfach samt Ordner irgendwo hinkopiere (und auch beliebig oft kopiere) - und gut ist's. Mit dem Befehl "ExtractFilePath(ParamStr(0))" habe ich unter Windows stets die richtigen relativen Orte der notwendigen untergeordneten Ordner. "GetAppConfigDir" ist leider nicht die Lösung. Kann man unter Linux tatsächlich einen Ordner, der ein Programm enthält, nicht mehrmals an verschiedene Stellen des Dateisystems kopieren und hierarchische "Unterordner" sind - relativ zum Programmordner - dann auch an der richtigen Stelle, so dass z.B. ein "Ini-File" stets "an der richtigen Stelle" relativ zum Programmordner ist: Hat hier jemand eine Lösung? Ich könnte ja durchaus darauf verzichten "MyMemoryDB" mehrmals zu installieren - aber die gesamte Ordnerstruktur zweimal "pflegen" zu müssen und das Programm entsprechend umschreiben zu müssen macht mir schon erhebliche Bauchschmerzen.

Kann mir jemand weitere Tips geben oder Literaturstellen nennen, so dass ich "MyMemoryDB" doch noch unter Linux zum Laufen kriege und trotzdem nur EINE Quellcode-Datei pflegen muss? Oder lautet der ultimative Tip:"Bleib bei "Wine"?

Danke schonmal!

Aliobaba

Das: http://wiki.lazarus.freepascal.org/Cross_compiling/de und das: http://wiki.lazarus.freepascal.org/Cros ... nder_Linux kenne ich, liest sich aber für mich als Anfänger recht kompliziert und behandelt das Portieren von Linux nach Windows; ich bräuchte aber den anderen Weg.
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Crosscompiling - erste Eindrücke

Beitrag von Scotty »

Ich glaube, du hast eine FAQ gestellt. Die Antwort wäre hier: http://wiki.lazarus.freepascal.org/Mult ... eichnis.22

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Crosscompiling - erste Eindrücke

Beitrag von Aliobaba »

Danke, Scotty,

ich kenne diese Seite schon; aber das ist ja mein Problem: ich komme (käme) um einen grundlegenden Umbau des gesamten Programms nicht herum - außerdem verstehe ich viele Dinge schlicht nicht. Und so wie es scheint müsste ich mich wohl von dem Gedanken verabschieden, den gesamten Programmordner einfach irgendwo in der Dateihierarchie hin kopieren zu können - und es läuft ("portable app" eben); auch mit mehreren und verschiedenen "Programm"installationen"" auf einem einzigen PC. .... da ist Windows irgendwie flexibler!?

Es muss doch eine Möglichkeit geben - so dachte ich jedenfalls - , dass ein Programm unter Linux "weiß", von welchem Ordner aus es gestartet wurde!!! Sonst kann doch Linux auch viel, viel mehr als Windows und ist 1000* flexibler.

Aliobaba

Eine Idee hätte ich soeben: Ich frage den User vor dem allerersten Start des Programms nach dem gesamten Pfad, lasse ihn eingeben (macht unter Windows der Befehl: "ExtractFilePath(ParamStr(0)) " ), starte das Programm mit diesen Angaben neu und speichere diesen Pfad auf die Festplatte. Wenn diese Eingaben richtig waren, dann startet das Programm auch und "weiß" zukünftig auch, "wo es ist". Nur: Elegant ist das nicht :( Aber vielleicht hat ja noch jemand eine bessere Idee.

(Das Beispielprogramm der FAQ werde ich aber auch nochmal versuchen, zu verstehen! Danke!)
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: Crosscompiling - erste Eindrücke

Beitrag von Dragon »

Ok ich hab mal eben schnell ein Beispiel zusammengeschrieben das eigentlich das machen sollte was du willst so weit ich das verstanden habe so solltest du dein Programm entsprechend modifiezieren können.
Ich hoffe ich konnte helfen

Code: Alles auswählen

 
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  {ifdef linux}                                                     //code wird nur auf linux ausgeführt
  Memo1.caption := 'es geht';    //erzeugt zu speichernde daten
  createdir('./speicherort');    //erzeugt ordner am lageplatz der auszuführenden datei
  Memo1.Lines.Savetofile('./speicherort/testfile.txt'); //speichert textdatei im soeben erzeugtem ordner
  Memo1.caption := '';                                              //setzt daten in der memo zurüch
  {endif}
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  {ifdef Linux}
  Memo1.Lines.loadfromfile('./speicherort/testfile.txt');    // lädt datei aus unterordner speicherort
  {endif}
end;
 
end.
 

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Crosscompiling - erste Eindrücke

Beitrag von mschnell »

Aliobaba hat geschrieben: Mit dem Befehl "ExtractFilePath(ParamStr(0))" habe ich unter Windows stets die richtigen relativen Orte der notwendigen untergeordneten Ordner.
Möglicherweise ist die Grund-Ursache Deines Problem, dass das unter Windows genau der falsche Ort ist. (Auch) unter Windows sollten Executables immer in einem schreibgschützen Platz liegen, während die ini-Dateien und ähnliches anderswo sind.

Eigentlich gibt es - je nach Programm - (mindestens) drei verschiedene Initialisierungs-Varanten (die auch gleichzeitig aktiv sein können). Für alle gibt es unterschiedlich Orte wo man sie speichern sollte.

1) nur vom Administrator veränderbare Programm-Installations-spezifische Einstellung. Für alle User schreibgeschützt.
2) User spezifische Einstellungen: Nur für den jeweils aktiven User änderbar und lesbar, pro User eine Kopie
3) Für alle User gemeinsam zu nutzende Einstellungen: von allen Usern les- und schreibbar, es gibt nur eine Kopie

Vielleicht solltest Du Dein Programm so umbauen, dass die ini Datei(en) sowohl in Windopwsa als auch in Linux an sinnvollen Plätzen liegen.

-Michael

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Crosscompiling - erste Eindrücke

Beitrag von Christian »

Hallo Aliobaba (komischer Name) :)

Das hört sich für mich sehr danach an als ob du dich in die Materie noch weiter einlesen solltest.
Jedes OS hat seine Eigenarten und Spezialitäten. Wenn man die ausßer acht lässt stösst man meisst dem Nutzer vorn Kopf weil der sich mit seinem OS auskennt und nicht mit deinem Programm.

Unter Linux spielt sich alles an Datenerhebung im Home Verzeichnis den Nutzers ab. Portable Apps gibts unter Linux sehr wenig bis nicht, weil man sie schlicht nicht braucht.
Es ist hyperbequem sien Homeverzeichnis auf nen anderen Computer zu sichern und alle programme funktionieren so wie auf der anderen Maschiene. Oder ne OS neuinstallation...
Davon träumen Windows Nutzer nur und haben deshalb PortableApps erfunden (zugegeben ne tolle Erfindung).

Unter OSX befinden sich meisst wieder alle Daten im Programmordner und man kann Programme einfach samt Ordner verschieben und kopieren.

Wenn du unter Linux nun anfängst nen Portable Konzept hochzuziehn wirds niemand verstehn. Wenn du das dennoch machen willst, musst deine Executables mit im Home Ordner ablegen. Dort ist der einzige Platz wo du alles ablegen könntest, und auch jederzeit hinschreiben kannst. Dann hast aber ne reine Installation für nur einen Benutzer.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Crosscompiling - erste Eindrücke

Beitrag von Aliobaba »

Hallo und vielen vielen Dank für die Antworten!

@mschell:
"Möglicherweise ist die Grund-Ursache Deines Problem, dass das unter Windows genau der falsche Ort ist. (Auch) unter Windows sollten Executables immer in einem schreibgschützen Platz liegen, während die ini-Dateien und ähnliches anderswo sind. "


... schon, aber an diese Vorgaben halten sich ja diese "portableApps" nicht - und trotzdem sind sie eine feine Sache.

@Christian:
Die Vorteile des "home"-Verzeichnisses" liegen auf der Hand, das Übertragen von Programmen auf andere PC's ist eine feine Sache (gutes Beispiel: sein persönliches e-mail Programm). Und "portableApps" bieten hier eine gute Lösung. Nur: Mein Programm ist eben schon fertig und ich möchte so wenig wie möglich daran noch verändern - es funktioniert nämlich alles recht gut.

@ Dragon:
Danke, Danke, Danke": hab's eben sowohl mit Linux als auch mit Windows ausprobiert: Läuft super!!

Code: Alles auswählen

 
procedure TForm1.Button1Click(Sender: TObject);
begin
  {ifdef linux}                                                     //code wird nur auf linux ausgeführt
    Memo1.caption := 'es geht';    //erzeugt zu speichernde daten
    createdir('./speicherort');    //erzeugt ordner am lageplatz der auszuführenden datei
    Memo1.Lines.Savetofile('./speicherort/testfile.txt'); //speichert textdatei im soeben erzeugtem ordner
    Memo1.caption := '';                                              //setzt daten in der memo zurüch
  {endif}
  {IFDEF Win32}
    Memo1.caption := 'es geht';    //erzeugt zu speichernde daten
    createdir('./speicherort');    //erzeugt ordner am lageplatz der auszuführenden datei
    Memo1.Lines.Savetofile('./speicherort/testfile.txt'); //speichert textdatei im soeben erzeugtem ordner
    Memo1.caption := '';                                              //setzt daten in der memo zurüch
  {ENDIF}
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  {ifdef Linux}
      Memo1.Lines.loadfromfile('./speicherort/testfile.txt');    // lädt datei aus unterordner speicherort
  {endif}
  {IFDEF Win32}
      Memo1.Lines.loadfromfile('./speicherort/testfile.txt');    // lädt datei aus unterordner speicherort
  {ENDIF}
end;                 
 
Das hilft mir nun sehr!! Und so einfach: Wie immer im Leben: Man muss es nur wissen, wie's geht!
Danke nochmal!

Schönes Wochenende noch!
Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: Crosscompiling - erste Eindrücke

Beitrag von Dragon »

Aliobaba hat geschrieben: Danke, Danke, Danke": hab's eben sowohl mit Linux als auch mit Windows ausprobiert: Läuft super!!
Gerngeschehen
Aliobaba hat geschrieben: Schönes Wochenende noch!
Danke, gleichfalls.

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Crosscompiling - erste Eindrücke

Beitrag von Aliobaba »

Hallo,

kleiner Nachtrag (vielleicht gibt's ja noch mehr Anfänger): Die {IFDEF} Anweisung muss natürlich so {$IFDEF} lauten. Das Programm von Dragon habe ich ein klein wenig ergänzt, dann sieht man sehr schön, dass Lazarus auch wirklich die Programmteile nicht kompiliert, die nicht in den Programmcode aufgenommen werden sollen.
Auch wenn man das kompilierte Programmfile in beliebige Ordner kopiert, werden die "Unterordner" da erstellt, wo man sie erwartet. :D

Nochmals Danke! Das hilft mir wirklich sehr!

Aliobaba

Code: Alles auswählen

  
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  {$ifdef linux}
    Memo1.caption := 'es geht_Linux';    //erzeugt zu speichernde daten
    createdir('./speicherort_Linux');    //erzeugt ordner am lageplatz der auszuführenden datei
    Memo1.Lines.Savetofile('./speicherort_Linux/testfile_linux.txt'); //speichert textdatei im soeben erzeugtem ordner
    Memo1.caption := '';                                              //setzt daten in der memo zurüch
  {$endif}
  {$IFDEF Win32}
    Memo2.caption := 'es geht_Windows';    //erzeugt zu speichernde daten
    createdir('./speicherort_Windows');    //erzeugt ordner am lageplatz der auszuführenden datei
    Memo2.Lines.Savetofile('./speicherort_Windows/testfile_windows.txt'); //speichert textdatei im soeben erzeugtem ordner
    Memo2.caption := '';                                              //setzt daten in der memo zurüch
  {$ENDIF}
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  {$ifdef Linux}
      Memo1.Lines.loadfromfile('./speicherort_Linux/testfile_linux.txt');    // lädt datei aus unterordner speicherort
  {$endif}
  {$IFDEF Win32}
      Memo2.Lines.loadfromfile('./speicherort_Windows/testfile_windows.txt');    // lädt datei aus unterordner speicherort
  {$ENDIF}
end;
 
end.
 
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: Crosscompiling - erste Eindrücke

Beitrag von Dragon »

Aliobaba hat geschrieben:kleiner Nachtrag (vielleicht gibt's ja noch mehr Anfänger): Die {IFDEF} Anweisung muss natürlich so {$IFDEF} lauten.
hoppla habe die "$" zeichen vergessen :lol:(sorry) hat bei mir aber trotzdem ohne probleme compiliert und funktioniert.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2807
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Crosscompiling - erste Eindrücke

Beitrag von m.fuchs »

Zwei Dinge, die ich gerne anmerken würde.
Dragon hat geschrieben:

Code: Alles auswählen

 
  createdir('./speicherort');    //erzeugt ordner am lageplatz der auszuführenden datei
 
Das ist Quark. Das Verzeichnis wird NICHT am Lageplatz der ausführenden Datei erzeugt. Sondern in dem Verzeichnis, in dem wir uns gerade befinden. Das kann also durchaus in die Hose gehen.
Aliobaba hat geschrieben:Mit dem Befehl "ExtractFilePath(ParamStr(0))" habe ich unter Windows stets die richtigen relativen Orte der notwendigen untergeordneten Ordner.
Und warum benutzt du das unter Linux nicht?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: Crosscompiling - erste Eindrücke

Beitrag von Dragon »

m.fuchs hat geschrieben:Das ist Quark. Das Verzeichnis wird NICHT am Lageplatz der ausführenden Datei erzeugt. Sondern in dem Verzeichnis, in dem wir uns gerade befinden. Das kann also durchaus in die Hose gehen.
Was genau kann denn da schief gehen ich hatte da noch nie irgendwelche Probleme.

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Crosscompiling - erste Eindrücke

Beitrag von Aliobaba »

Hallo,
m.fuchs hat geschrieben: Das ist Quark. Das Verzeichnis wird NICHT am Lageplatz der ausführenden Datei erzeugt. Sondern in dem Verzeichnis, in dem wir uns gerade befinden. Das kann also durchaus in die Hose gehen.
... aber wenn ich das Programm starte, dann bin ich doch im Programmverzeichnis [Wenn ich nicht von einem Link aus starte ...?? :shock: ] und wenn ich dann sofort dieses Verzeichnis in einer Variable speichere, müsste das doch funktionieren - vorausgesetzt, ich kann mir die Information geben lassen, welchen "absoluten Pfad" der aktuell aufgerufene relative Pfad soeben hat:
Geht das?
m.fuchs hat geschrieben: Und warum benutzt du das [ "ExtractFilePath(ParamStr(0))" ] unter Linux nicht?
Funktioniert angeblich nicht: http://wiki.lazarus.freepascal.org/Mult ... g_Guide/de :
"Eine Sorge, wenn man Anwendungen zwischen Linux und Windows portiert, ist das Dateisystem. Viele Programmierer sind gewöhnt, ExtractFilePath(ParamStr(0)) oder Application.ExeName aufzurufen um den Ort der ausführbaren Datei zu erhalten, und dann nach den notwendigen Dateien für die Programmausführung (Bilder, XML Dateien, Datenbankdateien, etc) zu suchen basierend auf dem Ort der ausführbaren Datei. Das ist falsch unter Linux. Die Zeichenkette bei ParamStr(0) kann nicht nur das Verzeichnis des executable enthalten, ebenso variiert es zwischen verschiedenen Shell-Programmen (sh, bash, etc). "

Aliobaba

[Nachtrag zu meiner Frage "Geht das?": Evtl so: pwd > Pfad.txt
DESCRIPTION
Print the full filename of the current working directory.
]
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2807
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Crosscompiling - erste Eindrücke

Beitrag von m.fuchs »

Naja, es funktioniert in etwa genauso gut oder genauso wenig wie die Lösung mit ./. Aber wenn es erst einmal nur für dich ist und nicht veröffentlich werden soll, dann reicht das doch.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
theo
Beiträge: 10867
Registriert: Mo 11. Sep 2006, 19:01

Re: Crosscompiling - erste Eindrücke

Beitrag von theo »

So ist es offiziell gedacht: http://lazarus-ccr.sourceforge.net/docs ... igdir.html
Alles andere muss man auf eigene Verantwortung machen.

Antworten