Datenbanken, Log Files etc. Cross Platform ablegen
-
Hi zusammen,
für eine Applikation (in C++) habe ich Log Files und eine sqlite Datenbanken, ggf. auch mal irgendwann ne Konfigurationsdatei etc.
Ich bin kein Profi für Betriebssysteme, aber zumindest unter Linux gibt es da ja Verzeichnisse, wo die hingehören (wenn die App auf dem PC Installiert ist) z.B. /var/myApp vlt. für die Datenbank und /var/logs/myApp (-> Wobei ich mir da auch nicht so 100% sicher bin).
Oder ggf. auch sowas wie /home/myUser/.myApp/... -> Grade Konfigurationsdateien sehe ich oft dortWie legt man das Zeug in die richtige Pfade ab? Ich würde instinktiv jetzt erstmal sagen, dass keiner alle Pfade für Windows, Linux, Mac Os (und potentiell andere) kennt und riesige Logik hat, um da alle Pfade cross Plattform mäßig zu bestimmen.
Als Build System nutze ich CMake. Das bestimmt zumindest Cross Platform mäßig, wohin ich meine App installieren kann. Das Modul:
https://cmake.org/cmake/help/v3.0/module/GNUInstallDirs.html
hat auch noch ein paar andere Variablen, die ich meine App bekannt machen könnte. Notfalls würde das vlt. gehen, aber die definierten Pfade sind jetzt relativ allgemein.Vlt. hat da jemand mehr Ahnung, das Problem sollte ja eig. so ziemlich jede App haben.
-
Um was für eine Applikation handelt es sich denn bzw. Um was für Daten?
Sollen die Daten von mehreren Nutzern auf dem selben system genutzt werden?
Oder sind das eher nutzer bezogene Daten?Das ganze ist in "XDG Base Directory Specification" spezifziert. (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
Vor dieser spezifikation war es üblich solche Daten in $HOME/.<appname> abzulegen.
Einstellungen sehe ich da als "nutzer bezogen" an
Dafür gibt es den Pfad $HOME/.config/<appname> ($XDG_CONFIG_HOME default: $HOME/.config)Für Daten $HOME/.local/share/<appname> ($XDG_DATA_HOME default: $HOME/.local/share)
Durch die XDG hat der Nutzer die möglichkeit den Pfad z.b. für die Konfigurationen zu ändern ohne dass die Applikationen angepasst werden müssen.
-
@firefly Ja es handelt sich um Nutzerbezogene Daten. Zumindest glaube ich, dass das am meisten Sinn ergibt
Es ist auf jedenfall interessant zu wissen, wo so Daten tendenziell abgelegt werden. Glaube das Wissen schadet jedenfalls nicht.
Für meine Applikation würde ich allerdings ungern da ein Experte auf dem Gebiet werden wollen. Insbesondere die Freedesktop specs sind ja tendenziell auch erstmal nur für Linux.
Gibt es denn da eine Lib, die unter anderem die Freedesktop Spec miteinbezieht für Linux, aber eben auch für Windows / Mac Os läuft?
Vlt. sowas in die Richtung https://github.com/sago007/PlatformFolders. Das hatte ich jetzt mal beim ersten Suchen gefunden
-
Ich persönlich kenne jetzt nur Qt wo sowas abstrahiert ist
-
@firefly sagte in Datenbanken, Log Files etc. Cross Platform ablegen:
Ich persönlich kenne jetzt nur Qt wo sowas abstrahiert ist
Ich denke mal: https://doc.qt.io/qt-5/qstandardpaths.html
Das sieht schon ziemlich nach dem aus, was ich suche. Da ich auch QT würde das an sich auch passen, auch wenn ich immer etwas versuche den Einfluss von QT möglichst auf Graphische Oberflächen zu begrenzen.
Wenn jemand noch eine vergleichbare Alternative kennt, gerne melden.
Eine andere Frage, die mir noch dazu einfällt: Wie ist da dein Setup für die Entwicklung? Da möchte man ja ungern, dass direkt irgendwelche Daten sonst wo hin geschrieben werden.
Direkt von QT gibt eshttps://doc.qt.io/qt-5/qstandardpaths.html#setTestModeEnabled
das schreibt Daten dann zumindest in ein spezielles directory. Aber vermutlich möchte man während der Entwicklung, die Daten eher irgendwie im Projekt selbst haben.
-
wxWidgets als GUI Bibliothek kapselt das auch weg. Ich habe auch keine Schmerzen dabei, die Pfade von der GUI Lib regeln zu lassen, da Datenhaltung und eigentliche Logik eh nix voneinander wissen.
Unsere Anwendung kann, neben klassischem Setup, auch als "portable" Version betrieben werden. Das ist ganz praktisch für Demos von USB-Stick, oder Testversionen für den Fachbereich. Meine "Entwicklungsversion" denkt sie sei eine portable Version, für die alle entsprechenden Daten im Anwendungsverzeichnis abgelegt sind.
-
@Schlangenmensch sagte in Datenbanken, Log Files etc. Cross Platform ablegen:
Unsere Anwendung kann, neben klassischem Setup, auch als "portable" Version betrieben werden. Das ist ganz praktisch für Demos von USB-Stick, oder Testversionen für den Fachbereich. Meine "Entwicklungsversion" denkt sie sei eine portable Version, für die alle entsprechenden Daten im Anwendungsverzeichnis abgelegt sind.
Kannst du näher ausführen wie ihr das realisiert? Nutzt ihr dafür CMake?
-
@Leon0402
Eine übliche Variante das zu erreiche ist ein Config-File im selben Verzeichnis mit der .exe zu haben.
Da drinnen stehen dann z.B. Pfade zu weiteren Verzeichnissen, evtl. auch zu weiteren Config-Files. Hilfreich ist dabei wenn man relative Pfade in diesem ersten Config-File relativ zum Verzeichnis des ersten Config-Files selbst interpretiert, also nicht relativ zum aktuellen Verzeichnis.Im Reporitory hat man dann zwei solche "erste" Config-Files, eines für die "installierte" Version und eines für die "portable" Version.
Was das Build-System (CMake oder was auch immer) dann tun muss ist beim lokalen Bauen das "portable" Config-File ins selbe Verzeichnis wie die .exe zu kopieren. Und beim Erstellen des Installers muss halt das andere Config File verwendet werden.
-
@hustbaer hmm aber die Pfade für die installierte Version würden ja bereits von Qt kommne, daher stelle ich mir das mit der Config eher schwierig vor, die wird ja vermutlich eher json oder vergleichbares sein.
Darüber hinaus würden zumindest unter Linux config files ja auch nicht im selben Verzeichnis liegen dürfen. Also wenn man es selbst installiert ist es vlt. okay, aber spätestens wenn das ganze vom Package Manager installiert wird, landen die binaries irgendwo in einem /bin Ordner in dem keine Configs liegen dürfen (sollten).Was mir vlt. einfallen würde wäre eine Art Wrapper um QStandard Paths zu bauen. Und dann entweder per Makro oder per CMake
configure_file
die Pfade abhängig von einer CMake VariablePortable
dann eben von QStandardPaths zu übernehmen oder relativ ins Verzeichnis zeigen zu lassen.
-
@Leon0402
Also erstmal meine ich hier kein Config-File in dem Sinn dass darin auch vom Benutzer änderbare Dinge gespeichert würden. Daran wo/wie man diese speichert ändert man nichts, das lässt man einfach so wie es war. Nennen wir das neue Config-FilePConfig
damit keine Verwirrung entsteht.Beispiel 1: Die Anwendung schreibt in ein fixes Log-Verzeichnis. Im "installierten" Modus soll das
/var/log/foo
sein, im "portable" Mode soll es<exe-dir>/log
sein. InPConfig
macht man dann z.B. einen EintraglogDir
. Für die portable Variante schreibt manlogDir ./log
rein und für die intallierte Variante schreibt manlogDir /var/log/foo
rein.Beispiel 2: Die Anwendung soll in ein vom User-konfigurierbares Log-Verzeichnis schreiben. Der Default soll gleich wie in Beispiel 1 sein. In dem Fall macht man einen
defaultLogDir
Eintrag inPConfig
- entsprechend demlogDir
Eintrag aus Beispiel 1. Und verwendet ihn halt nur wenn der Benutzer nichts konfiguriert hat.die Pfade für die installierte Version würden ja bereits von Qt kommne, daher stelle ich mir das mit der Config eher schwierig vor, die wird ja vermutlich eher json oder vergleichbares sein.
Das Format kannst du bestimmen. Und wenn du die Pfade für die installierte Version von Qt bekommst, dann kannst du z.B. im installierten Fall das Config-File auch einfach weglassen. D.h. die Regel ist dann: wenn
PConfig
existiert, dann nimm die Pfade von dort (und füttere sie evtl. auch nach Qt rein, wenn das Framework die Pfade auch selbst verwendet). Andernfalls nimm die Pfade die du von Qt bekommst.Darüber hinaus würden zumindest unter Linux config files ja auch nicht im selben Verzeichnis liegen dürfen. Also wenn man es selbst installiert ist es vlt. okay, aber spätestens wenn das ganze vom Package Manager installiert wird, landen die binaries irgendwo in einem /bin Ordner in dem keine Configs liegen dürfen (sollten).
- Trifft das auch auf read-only Files zu? Wie gesagt, das File muss nicht änderbar sein, da sollen nur ein paar Dinge drin stehen die der Benutzer nicht ändern können muss. Alles was der Benutzer ändern kann sollte man wo anders speichern.
- Du kannst es auch so machen dass die Defaults bei nicht vorhandenem oder leerem
PConfig
File passend für die installierte Version sind.
Was mir vlt. einfallen würde wäre eine Art Wrapper um QStandard Paths zu bauen. Und dann entweder per Makro oder per CMake configure_file die Pfade abhängig von einer CMake Variable Portable dann eben von QStandardPaths zu übernehmen oder relativ ins Verzeichnis zeigen zu lassen.
So ein Wrapper könnte schon Sinn machen. Was ich persönlich nicht mag, ist wenn die portable Version und die installierte unterschiedliche gebaut werden müssen. Daher verwende ich da eben lieber solche Config-Files dafür. Und die müssen dann eigentlich "neben" der EXE liegen. Fixer Pfad macht bei "portable" keinen Sinn, und relativer Pfad ausser
.
macht mMn. auch wenig Sinn.Wenn es dich nicht stört dass du zwei verschiedene Binaries brauchst, ist das aber natürlich auch eine Möglichkeit.
-
Man kann das ganze auch etwas abändern: Vorausgesetzt es gibt schon ein Config-File, kann man dieses erstmal "neben" dem EXE File suchen. Wenn man es dort findet, nimmt man es von dort. Wenn nicht, geht man davon aus dass man "installiert" ist, und sucht es dort wo es in der "installierten" Variante liegt.
So braucht man nur ein Config-File, nicht eins für "fixe" und eins für änderbare Einstellungen.
Wichtig ist hauptsächlich dass man relative Pfade im Config-File erlaubt, und diese relativ zum Verzeichnis des Config-Files interpretiert.
Was ich beim "Konfigurieren duch Weglassen des Files" aber doof finde, ist dass man dann eine unsichtbare Abhängigkeit darauf hat dass das File nicht existieren darf. Daher finde ich es besser das File mit zu installieren wenn möglich.
-
@hustbaer sagte in Datenbanken, Log Files etc. Cross Platform ablegen:
@Leon0402
Also erstmal meine ich hier kein Config-File in dem Sinn dass darin auch vom Benutzer änderbare Dinge gespeichert würden. Daran wo/wie man diese speichert ändert man nichts, das lässt man einfach so wie es war. Nennen wir das neue Config-File PConfig damit keine Verwirrung entsteht.Okay, das hatte ich vermutet
@hustbaer sagte in Datenbanken, Log Files etc. Cross Platform ablegen:
Trifft das auch auf read-only Files zu? Wie gesagt, das File muss nicht änderbar sein, da sollen nur ein paar Dinge drin stehen die der Benutzer nicht ändern können muss. Alles was der Benutzer ändern kann sollte man wo anders speichern.
Soweit ich weiß, habe es jedenfalls noch nie gesehen. Aber das muss nichts unbedingt heißen.
Ich denke aber der Hauptgrund gegen eine "Install Config File" wäre aber auch, dass ich QT verwenden will. Klar könnte man dann auch ne Config File für Windows, Linux, Mac Os etc. haben, aber leichter wäre es natürlich über die Abstraktion. Dann machen sich andere Gedanken, was jetzt und potentiell in Zukunft die richtigen Pfade sind.
@hustbaer sagte in Datenbanken, Log Files etc. Cross Platform ablegen:
Wenn es dich nicht stört dass du zwei verschiedene Binaries brauchst, ist das aber natürlich auch eine Möglichkeit.
Ich bin mir nicht sicher Ich glaube erstmal an sich nicht. Die Build Zeiten kann man ja beschleunigen, indem man die Config in ne Lib abwandelt. Das mache ich bereits so für die Versionsnummer. Also sprich eine eigene Library AppVersion & AppConfig. Ändert man die Config, muss man quasi nix neu kompilieren.
@hustbaer sagte in Datenbanken, Log Files etc. Cross Platform ablegen:
Man kann das ganze auch etwas abändern: Vorausgesetzt es gibt schon ein Config-File, kann man dieses erstmal "neben" dem EXE File suchen. Wenn man es dort findet, nimmt man es von dort. Wenn nicht, geht man davon aus dass man "installiert" ist, und sucht es dort wo es in der "installierten" Variante liegt.
Wäre auch keine schlechte Möglichkeit. Damit würde man den Nachteil mit dem Neubuilden auch nochmal vermeiden.
Gibt es eigentlichen einen Standard, was die portable Version angeht? Daher wie sowas auszusehen hat. Ich könnte natürlich einmal meinen build Ordner zippen und dann könnte man das wohl mit Fantasie als portable bezeichnen Schätze mal üblich ist aber eher, dass man nur einen Ordner mit nur binary und libs hat, oder?
-
@Leon0402
Im Archiv für eine portable Version sind normalerweise nur die Files drin die nötig sind um das Programm zu verwenden + ggf. Dokumentation in Form von plain Text, HTML oder Markdown files. Wenn du willst kannst du gerne noch das .pdb/.dbg File dazupacken. Mehr ist eigentlich nicht üblich.Anmerkung dazu: ein File mit Infos über verwendete Third-Party Libraries kann je nach Lizenz dieser nötig sein, wenn es sonst nirgends in der Software ersichtlich ist (About Dialog o.ä.). Und wenn deine Software unter GPL steht sollte natürlich noch die Info enthalten sein wo man sich den Source Code besorgen kann. Beides gilt natürlich auch für installierte Programme.
-
@Leon0402 Sorry für die späte Antwort, ich habe die letzte Woche nur über's Smartphone mitgelesen und da @hustbaer eigentlich alles zu dem Thema gesagt hat, habe ich mir das frickelige Tippen gespart.
Wir machen es noch etwas anders. Unsere Software ist momentan Windows only und da haben wir eine kleine, nicht so schöne Abhängigkeit drinnen. Das Setup für die normale installierte Version schreibt einen Eintrag in die Registry mit einem Pfad zur Exe. Wenn der Eintrag existiert und mit dem Pfad zur ausgeführten Datei übereinstimmt ist es eine normale installierte Version, ansonsten die Portable.
Bei Debian Distributionen könnte man vlt gucken, ob man via dpkg -L oder dpkg-query das auch über die Pfade erledigen kann.
Aber das ist halt frickelig, da das für alle Distributionen irgendwie anders ist, daher wäre es für Crossplatform wahrscheinlich am einfachsten, wenn das Setup eine Configdatei mit der entsprechenden Information anlegt.Wir erstellen unsere Setups mit Innosetup [https://jrsoftware.org/isinfo.php] aber das ist halt Windows only. Ich habe mich noch nicht damit auseinander gesetzt, wie man das am geschicktesten als Paket für Linuxdistributionen anbieten würde.
-
Hallo,
da es keine gute Stimmen für die Linux TTS-Engines gibt und jährlich Lizenzkosten erhebt, suche ich nach einer Möglichkeit, wie ich die MS TTS api in Linux c++ Programmen einbinden kann. Entweder über wine oder via Virtualbox etc.Kennt sich damit jemand aus?
VG
-
@Nerdy22
Was ist eine TTS-Engine? Und inwiefern hat das etwas mit diesem Thread zu tun?
-
text-to-speech engine.
mit dem thread hat es allerdings immernoch nichts zutun.
-
Ah. In dem Fall: klar kann man das irgendwie machen. Also speziell wenn VirtualBox eine Option ist muss das gehen. Im Worst-Case muss man sich z.B. ein Netzwerk-Service/Web-Service basteln das den Text entgegennimmt, in die TTS Engine reinwirft, und die produzierte Waveform über's Netz zurückschickt. Und das lässt man dann auf Wine laufen. Bzw. wenn es mit Wine nicht funktioniert, dann funktioniert es mit an Sicherheit grenzender Wahrscheinlichkeit auf VirtualBox, KVM oder was man sonst so als Hypervisor rumliegen hat.