Die Unit ... existiert doppelt

Rund um die LCL und andere Komponenten
Benutzeravatar
Jim Knopf
Beiträge: 98
Registriert: So 18. Mai 2014, 15:16
OS, Lazarus, FPC: Win10
CPU-Target: 64Bit
Wohnort: Klagenfurt
Kontaktdaten:

Die Unit ... existiert doppelt

Beitrag von Jim Knopf »

Hi zusammen,

benutze zwar Delphi seit sehr langem, bin aber total neu bei Lazarus. Nun möchte ich eine Komponente übernehmen. Klappt bis inklusive Kompilieren prima, aber dann kommt diese Meldung:

Bild

Meine Ordnerstruktur ist so:
c:\lazarus\ (lazarus itself)
c:\lazarus comps\ (alle Komponenten)

Das Package sieht so aus, in den Einstellungen sind keine speziellen Pfade eingetragen

Bild

Könnt ihr mir bitte einen Tipp geben, was ich falsch mache?

Viele Grüße
Martin

sstvmaster
Beiträge: 582
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 3.8
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Die Unit ... existiert doppelt

Beitrag von sstvmaster »

Schau mal ob in dem Verzeichnis C:\lazarus comps\Patchwork die Datei fileutils existiert.
Wenn ja, mal umbennen, zb. fileutil.pas.bak.
Dann das lib Verzeichnis löschen und noch mal neu Kompilieren.

Das Problem ist bei dir das es die Datei fileutil 2x gibt aber Lazarus nicht weis welche es nehmen soll.

Empfehlung von mir, benenne die fileutil.pas im Patchwork Ordner und schau was passiert.


LG Maik
Zuletzt geändert von sstvmaster am Sa 21. Aug 2021, 00:00, insgesamt 1-mal geändert.
LG Maik

Windows 10,
- Lazarus 3.8 (stable) + fpc 3.2.2 (stable)
- Lazarus 4.99 (trunk) + fpc 3.3.1 (main/trunk)

wp_xyz
Beiträge: 5156
Registriert: Fr 8. Apr 2011, 09:01

Re: Die Unit ... existiert doppelt

Beitrag von wp_xyz »

Schwer zu sagen... Poste mal die lpk-Datei - "Vertrauen ist gut, Kontrolle ist besser". Und welche Units verwendet keofile.pas? Reichen da die in der FCL enthaltenen Units aus? Und zur Verzeichnis-Struktur: Du musst alle Packages in eigenen Unterordnern von "c:\Lazarus comps" unterbringen, so dass kein Package die Sourcen der anderen erreichen kann - das war das Problem bei TMS. Und das Leerzeichen in "c:\Lazarus comps" stößt mir auch auf, wahrscheinlich kein Problem, aber mach zur Sicherheit da mal lieber ein "c:\lazarus_comps" draus.

Benutzeravatar
Jim Knopf
Beiträge: 98
Registriert: So 18. Mai 2014, 15:16
OS, Lazarus, FPC: Win10
CPU-Target: 64Bit
Wohnort: Klagenfurt
Kontaktdaten:

Re: Die Unit ... existiert doppelt

Beitrag von Jim Knopf »

Anscheinend habe ich unwissentlich was verschwiegen, wie ich aufgrund der Fragen bemerke.

In der Interface-uses der (nun umbenannten Unit ›KeoFile‹ auf ›PwFile‹) ist angegeben:
unit PwFile;
{$MODE Delphi}
interface
uses SysUtils, LCLIntf, LCLType, LMessages, Messages, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls;


Aufgrund der fehlenden Bibliotheken hatte ich dann in den Einstellungen des Packages Patchwork ›andere Units‹ hinzugefügt:
C:\lazarus\lcl\;C:\lazarus\components\lazutils\;C:\lazarus\lcl\widgetset\

Es kam immer noch der Fehler
lclproc.pas(22,2) Fatal: Cannot open include file "lcl_defines.inc"

Aufgrunddessen hatte ich dann beim 2. Einstellungsfeld Include-Dateien (-Fi): hinzugefügt
C:\lazarus\lcl\include\

Und nun eben habe ich bemerkt, dass er in dem Verzeichnis der Patchwork-Komponenten diese Dateistruktur aufgebaut hat:

Bild

wobei in c:\lazarus comps\Patchwork\lib\x86_64-win64\
169 *.o und *.ppu-Files aufgetaucht sind.

wp_xyz
Beiträge: 5156
Registriert: Fr 8. Apr 2011, 09:01

Re: Die Unit ... existiert doppelt

Beitrag von wp_xyz »

Jim Knopf hat geschrieben: Sa 21. Aug 2021, 00:17 In der Interface-uses der (nun umbenannten Unit ›KeoFile‹ auf ›PwFile‹) ist angegeben:
unit PwFile;
{$MODE Delphi}
interface
uses SysUtils, LCLIntf, LCLType, LMessages, Messages, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls;


Aufgrund der fehlenden Bibliotheken hatte ich dann in den Einstellungen des Packages Patchwork ›andere Units‹ hinzugefügt:
C:\lazarus\lcl\;C:\lazarus\components\lazutils\;C:\lazarus\lcl\widgetset\
Das ist falsch. Du darfst den Pfad "andere units" nicht so erweitern, dass er in andere Packages weist, denn dann will dein Package evtl versuchen, die anderen Packages neu kompilieren, so dass deren Units ins Ausgabeverzeichnis deines Projektes bzw. Packages gelangen, und damit sind diese übersetzten Units tatsächlich doppelt vorhanden (denn sie wurden ja schon von den anderen Packages in die dortigen Ausgabeverzeichnisse kompiliert). Nur wenn dein Projekt/Package sehr umfangreich und in Unterordnern strukturierst ist, darfst (musst) du diese Unterverzeichnisse unter "andere Units" eintragen.

Der richtige Weg ist, das Package, in dem sich die benötigten Units befinden, unter "Benötigte Packages" einzutragen. LCLIntf, LCLType sind ganz typische Units der LCL, und die sind in dem gleichnamigen Package "LCL". Öffne den Projekt-Editor und wähle "Hinzufügen" > "Neue Anforderung" (oder Rechtsklick auf "Benötigte Packages" > "Neue Anforderung"). In dem erscheinenden Dialog suchst du in der Listbox den Eintrag "LCL" (oder oben in der Filterzeile eintippen, dann aber unbedingt nochmals in der Listbox anklicken). Mit "OK" wird dann das gewählte Package "LCL" unter "Benötigte Packages" eingetragen, und du hast alle Units dieses Packages zur Auswahl.

Dasselbe Vorgehen brauchst du später, wenn du dein eigenes Package "Packwork" oder das "TMS UI Pack" Package in einem Projekt verwenden möchtest.
Zuletzt geändert von wp_xyz am Sa 21. Aug 2021, 11:25, insgesamt 1-mal geändert.

wp_xyz
Beiträge: 5156
Registriert: Fr 8. Apr 2011, 09:01

Re: Die Unit ... existiert doppelt

Beitrag von wp_xyz »

Jim Knopf hat geschrieben: Sa 21. Aug 2021, 00:17 Und nun eben habe ich bemerkt, dass er in dem Verzeichnis der Patchwork-Komponenten diese Dateistruktur aufgebaut hat:

Bild

wobei in c:\lazarus comps\Patchwork\lib\x86_64-win64\
169 *.o und *.ppu-Files aufgetaucht sind.
Die Verzeichnis-Struktur ist so richtig.

In "Backup" legt die IDE Backup-Versionen der geänderten Dateien ab.

In "lib" werden die kompilierten Units abgelegt (nachdem du z.B. im Package-Editor auf "Kompilieren" geklickt oder gleich die IDE neu übersetzt hast (im "Tools" Menü). Dabei legt die IDE für jedes "Widgetset" (sowas wie: Betriebssystem) einen eigenen Unterordner an (Das bedeutet: du kannst dieselben Units für 32-Bit-Windows (lib/i386-win32) und für 64-Bit Windows (lib/x86_64-win64) kompilieren.) Dass hier soviele Dateien vorhanden sind, ist eine Folge davon, dass wegen der Erweiterung des Suchpfads auch LCL-Units dort hineinkompiliert wurden. Wiegesagt, diese Dateien dürfen da nicht sein - lösche einfach das lib-Verzeichnis, es wird beim nächsten Kompilieren neu angelegt. Oder wähle im Package-Editor den Eintrag "Weitere" > "Sauber rekompilieren" - damit wird das Ausgabeverzeichnis vor dem Kompilieren automatisch geleert.

"ConverterBackup" ist das Backup-Verzeichnis des Delphi-Konverters - du hast offenbar die Delphi-Units mit Hilfe des Konverters in der IDE nach Lazarus umwandeln lassen; der Konverter schreibt dann die Ausgangs-Delphi-Dateien in diesen Ordner. Den kannst du wieder löschen, wenn die Konvertierung erfolgreich war (natürlich nur, wenn du die Delphi-Dateien irgendwo anders noch zur Verfügung hast).

Die "patchwork.pas"-Datei wurde von der IDE erzeugt und enthält eine "uses"-Anweisung mit allen Units des Packages, sowie ggfs. die Registrierungsaufrufe (wenn "Registriere Unit" markiert ist).
Zuletzt geändert von wp_xyz am Sa 21. Aug 2021, 11:28, insgesamt 2-mal geändert.

Benutzeravatar
Jim Knopf
Beiträge: 98
Registriert: So 18. Mai 2014, 15:16
OS, Lazarus, FPC: Win10
CPU-Target: 64Bit
Wohnort: Klagenfurt
Kontaktdaten:

Re: Die Unit ... existiert doppelt

Beitrag von Jim Knopf »

Hallo wp_xyz,

einmal mehr ein dickes Danke!

Es scheint nun nur noch ein kleiner Schritt zum Erfolg zu sein - es kommt nämlich noch die Meldung

Bild

Und in der generierten Patchwork.pas ist tatsächlich eine leere Register-Methode. Was braucht er noch ausser der Register-Methode in der Komponenten-Unit pwFiles.pas ...?

{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install the package.
}

Code: Alles auswählen

unit Patchwork;

{$warn 5023 off : no warning about unused units}
interface

uses
  LazarusPackageIntf;

implementation

procedure Register;
begin
end;

initialization
  RegisterPackage('Patchwork', @Register);
end.
Viele Grüße
Martin

wp_xyz
Beiträge: 5156
Registriert: Fr 8. Apr 2011, 09:01

Re: Die Unit ... existiert doppelt

Beitrag von wp_xyz »

Ich weiß natürlich nicht, was in deiner PwFile-Unit steht. Aber das Häkchen "Registriere Unit" solltest du nur setzen, wenn die betreffende Unit eine "Register"-Prozedur enthält, so wie bei Komponenten, die in die Komponenten-Palette aufgenommen werden sollte. Normale "Code-Units" haben das nicht.

Und wenn es nichts zu registrieren gibt, kannst du im Package-Editor unter "Einstellungen" > "Package-Einstellungen" > "IDE-Integration" > "Package-Typ" den Eintrag "Laufzeit" wählen. Das hat den Vorteil, dass du nicht die IDE langwierig neu kompilieren musst. (Und dass die IDE nicht so leicht abstürzen kann, wenn dein Code Fehler enthält.)

Sind dagegen Registrierungen vorhanden, wird häufig der Package-Typ "Entwicklungs- und Laufzeit" genommen, damit steht das Package genauso zur Laufzeit zur Verfügung genauso wie bei dem reinen Laufzeit-Package, aber es wird auch in die IDE reinkompiliert, was bewirkt, dass zur Entwicklungszeit z.B. ein neuer Eintrag in der Komponenten-Palette vorhanden ist, oder ein neuer Property-Editor, usw.

Strenggenommen ist das aber nicht richtig, weil damit auch Code in deine Anwendung aufgenommen wird, den eigentlich nur die IDE benötigt. Daher werden Packages immer häufiger in ein "Nur-Laufzeit" und ein "Nur-Designzeit" Package aufgespalten. Für den Anfang würde ich das aber zunächst noch ignorieren.

Benutzeravatar
Jim Knopf
Beiträge: 98
Registriert: So 18. Mai 2014, 15:16
OS, Lazarus, FPC: Win10
CPU-Target: 64Bit
Wohnort: Klagenfurt
Kontaktdaten:

Re: Die Unit ... existiert doppelt

Beitrag von Jim Knopf »

Hi wp_xyz,

Habe mit den Package-Einstellungen probiert und auch in den Wikis und im Netz gesucht, aber ich bekomms nicht auf die Reihe.
In Delphi 5 war das so einfach: Ich will doch nur die Komponente kompilieren und dann in einem eigenen Reiter ›Patchwork‹ oben stehen haben und aufrufen können.

Auch hab ich lang gesucht, wie man die PNG-Datei der Komponente in eine *.res-Datei verwandelt (und dass sie dann in der Komponentenpalette verwendet wird) und bin auch nicht fündig geworden. Solltest Lust haben, es dir anzusehen, habe ich die Komponentenunit und das PNG unten in eine Zip-Datei gepackt. Kannst du auch gerne verwenden. Ist eine ›FileRunner‹-Komponente, die einen beliebigen Ordner durchackert und man unter OnFile die Files abhandeln kann.

Viele Grüße
Martin
Dateianhänge
FileRunner.zip
(2.63 KiB) 55-mal heruntergeladen

Benutzeravatar
Jim Knopf
Beiträge: 98
Registriert: So 18. Mai 2014, 15:16
OS, Lazarus, FPC: Win10
CPU-Target: 64Bit
Wohnort: Klagenfurt
Kontaktdaten:

Re: Die Unit ... existiert doppelt

Beitrag von Jim Knopf »

Sorry, ich bin mittlerweile etwas durch den Wind - hatte vergessen, die UnitPwFile.pas ins Package aufzunehmen ... Funzt jetzt. Bliebe nur noch die Frage mit der PNG übrig.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Die Unit ... existiert doppelt

Beitrag von Winni »

Hi!

PNG als Resource

Da hat Lazarus inzwischen die bequeme Lösung ohne Resource-Compiler oder andere Tools:

Project --> Options --> Resources --> Add (oben auf der Seite)

Hier kannst Du dann deine gewünschte PNG-Datei auswählen.

Fertig

Winni

Benutzeravatar
Jim Knopf
Beiträge: 98
Registriert: So 18. Mai 2014, 15:16
OS, Lazarus, FPC: Win10
CPU-Target: 64Bit
Wohnort: Klagenfurt
Kontaktdaten:

Re: Die Unit ... existiert doppelt

Beitrag von Jim Knopf »

Winni hat geschrieben: Sa 21. Aug 2021, 14:40 Da hat Lazarus inzwischen die bequeme Lösung ohne Resource-Compiler oder andere Tools:
Danke Winni. Aber ich meinte nicht für die Applikation, sondern für die Komponente. Also das Pendant zum Ressourcenerstellen mit dem Bildeditor in Delphi. Oder einen Tipp, wo ich eine Anleitung dazu finde.

wp_xyz
Beiträge: 5156
Registriert: Fr 8. Apr 2011, 09:01

Re: Die Unit ... existiert doppelt

Beitrag von wp_xyz »

Ich mache mir für die Erzeugung des Paletten-Icons immer eine Batch-Datei mit folgendem Inhalt:

Code: Alles auswählen

lazres patchworkreg.res filerunner.png filerunner_150.png filerunner_200.png
lazres ist der Lazarus-Resource-Compiler, den findest du im Ordner tools deiner Lazarus-Installation: Projekt in Lazarus laden und kompilieren, dann die exe irgendwo hinkopieren, wo sie gefunden werden kann (oder ins Verzeichnis deiner Komponente, wo sich auch die Batch-Datei befindet). Der erste Parameter ist der Name der zu erzeugenden res-Datei; das "reg" habe ich angehängt, weil das Package sowieso eine "patchwor.res" erzeugt, und dann gäbe es einen Namenskonflikt. Die folgenden Parameter sind die Namen der png-Dateien, die in die Resource eingebunden werden sollen. Falls es bei einem großen Package sehr viele Dateien sind, kannst du auch @Dateiliste.txt eintragen, wobei DateiListe.txt der Name einer Text-Datei ist, die nur die Bild-Dateinamen enthält, jeweils in einer eigenen Zeile. Ich gebe oben neben dem von dir schon vorgesehenen filerunner.png auch noch filerunner_150.png und filerunner_200.png an und ich würde dir raten, das Icon noch in den Größen 32x32 (150% --> filerunner_150.png) und 48x48 (200% --> filerunner_200.png) zu machen, denn diese Bilder verwendet die IDE, wenn du auf einem hochauflösenden Bildschirm arbeitest (150% --> 120 ppi, 200% --> 196 ppi). Ohne diese Zusatzdateien wird das Paletten-Icon bei höheren Auflösungen sehr unansehnlich. (Tipp: Icons als svg-Datei designen, z.b. mit Inkscape, dann kann man leicht verschiedene png-Größen ableiten).

Das von winni vorgeschlagene Verfahren habe ich bei Packages noch nicht probiert und weil es im Package-Editor auch keine Resourcen-Lasche gibt, bezweifle ich, ob es bei Packages anwendbar ist (bei Projekten dagegen sehr wohl).

Wenn nun die patchworkreg.res-Datei vorhanden ist, musst du sie noch im Kopf der der Quelldatei, in der die zugehörige Komponente registriert wird, als {$R patchworkreg.res} eintragen.

Bei vielen Komponenten kannst du alle Registrierungen in einer einzigen "Registrierungs-Unit" zusammenfassen, und du kannst auch alle Icons in dieselbe Res-Datei schreiben. Dadurch wird das ganze oft deutlich übersichtlicher.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Die Unit ... existiert doppelt

Beitrag von Winni »

Hi!

Anscheinend brauchst Du die PNG Datei als separate Resource.

Dann der "altmodische" Weg an der Befehhlszeile

Code: Alles auswählen

lazres MyPNG.RES MyPng.png 
Nun hast Du die Resource MyPNG.RES, die Du in Dein Project laden kannst:

Code: Alles auswählen

....
Implementation
{$R MyPNG.RES}
...
Winni

wp_xyz
Beiträge: 5156
Registriert: Fr 8. Apr 2011, 09:01

Re: Die Unit ... existiert doppelt

Beitrag von wp_xyz »

Weil ich jetzt bei Winni gesehen habe, dass er das .RES groß geschrieben hat, noch ein Tipp aus leidvoller Erfahrung. Wenn du vorhast, ein Projekt oder ein Package plattformübergreifend zu verwenden, würde ich konsequent alles klein schreiben. Denn unter Linux ist PatchWork.REG etwas anderes als PatchWork.reg oder patchwork.reg. Nur bei Units kannst du beim "Speichern unter" den Dateinamen in gemischter "CamelCase"-Schreibweise angeben, dann taucht er genauso im Unit-Header auf ("unit PatchWork"), aber im Dateisystem steht die Datei als "patchwork.pas". Das hat den Vorteil, dass du in der Uses-Zeile mehr Freiheiten hast, den Unitnamen zu schreiben, z.B. funktioniert auch "uses Patchwork" (kleines "w"), denn wenn die IDE die Datei "Patchwork.pas" nicht findet, dann sucht sie nach "patchwork.pas". Nachteil ist, dass diese klein geschriebenen Dateinamen schwerer zu lesen sind, aber daran gewöhnt man sich, und nimmt es gerne in Kauf, wenn man in Linux stundenlang nach der Ursache von "Unit nicht gefunden" gesucht hat, obwohl man 100% sicher ist, dass es sie gibt.

Antworten