Dynamic/Static linking von Qt / GTK /...



  • Hallo,

    ich bin relativ neu in der C++-Programmierung, also habt ein wenig Geduld mit meiner Unwissenheit. Habe vor ~25 Jahren mal in C (unter DOS) programmiert, bin dann aber auf Java umgestiegen, und nun haben wir den Salat: immer wenn ich ein Tool zum Download zur Verfügung stelle, muss ich erwähnen, dass eine JRE installiert sein muss, etc. Deshalb (und aus beruflichen Gründen) haben ich mich jetzt mit der C++-Programmierung auseinander gesetzt. Das klappt so ganz gut, nun möchte ich aber auch Programme mit einer GUI (unter Linux) programmieren, und hier fangen die Probleme an, weil ich KEINE Ahnung habe...

    Was ich weiß:
    - es gibt diverse Bibliotheken dafür, Qt, GTK, usw. Ok. In Qt arbeite ich mich gerade ein

    Was ich nicht weiß:
    - Wenn man nun ein Programm mit Qt GUI (Open Source) vertreibt, ist es dann besser, wenn man die Qt Bibliotheken dynamisch oder statisch verlinkt? (Es geht nicht um die Lizenz, sondern eher um die technische Frage). Was sind die Vorteile von beiden Arten des Verlinkens?

    - wenn ich dynamisch verlinke, dann bedeutet dass, das die Qt Bibliotheken nicht in meinem "Paket" mit drin sind, oder? Dann habe ich im Bezug zu meiner oben genannten Java-Problematik ja nichts gewonnen, ich muss immer darauf hinweisen, dass man Qt installieren muss (statt wie früher, dass man eine JRE installieren muss).

    - Ich verwende Netbeans für C++ zum Entwickeln. Kennt jemand von euch ein gutes Tutorial, dass sich mit dem Packaging / Deployment mit Netbeans auskennt, also Fragen beantwortet wie: "Wie verlinkt man Bibliotheken dynamisch/statisch" ...

    Sorry, wenn die Fragen ziemlich Nooby-mäßig klingen, aber auch wenn Java und C++ in einigen Punkten syntaktisch übereinstimmen, sind es doch zwei völlig verschiedene Welten 🙂

    Gruß,
    Andreas



  • Du kannst die Dlls auch in deinem installationspaket mitliefern.
    Dann muss der Benutzer keine zusätzlichen Pakete installieren.

    Rein theoretisch kann man das auch mit der JRE machen, diese mit dem installationspaket mitliefern.



  • für die open source variante ist es glaube ich nicht erlaubt statisch zu linken, aber normal reicht da der parameter static im projekt. kann dir aber nicht genaueres dazu sagen.

    Wenn du deine apps mal als debian package anbieten solltest, kannst du ja auch mitteilen, dass die qt pakete notwendig sind. die werden dann automatisch mitinstalliert. das ist alles unter linux weniger das problem.



  • calinied schrieb:

    Habe vor ~25 Jahren mal in C (unter DOS) programmiert

    Ist meines Erachtens leichter geworden. Viel leichter. Sowohl unter Windows als auch Linux - was ich als Index dafür werte, dass meine Theorie, dass es weniger auf die Sprache als auf das Framework ankommt, gar nicht mal so falsch ist.

    calinied schrieb:

    Was ich weiß:
    - es gibt diverse Bibliotheken dafür, Qt, GTK, usw. Ok. In Qt arbeite ich mich gerade ein

    Real programmers use xlib.
    *SCNR*

    calinied schrieb:

    Was ich nicht weiß:
    - Wenn man nun ein Programm mit Qt GUI (Open Source) vertreibt, ist es dann besser, wenn man die Qt Bibliotheken dynamisch oder statisch verlinkt? (Es geht nicht um die Lizenz, sondern eher um die technische Frage). Was sind die Vorteile von beiden Arten des Verlinkens?

    Wegen Vor- und Nachteilen.

    In der Regel solltest du immer dynamisch linken. Sprich, nur dann statisch linken, wenn du gute Gründe dafür hast. Sowas wie "ich nutze hier undefiniertes Verhalten der Libs aus, das mit späteren Versionen die Anwendung brechen kann". Oder wenn du die zu importierenden Symbole verstecken willst.

    calinied schrieb:

    - wenn ich dynamisch verlinke, dann bedeutet dass, das die Qt Bibliotheken nicht in meinem "Paket" mit drin sind, oder? Dann habe ich im Bezug zu meiner oben genannten Java-Problematik ja nichts gewonnen, ich muss immer darauf hinweisen, dass man Qt installieren muss (statt wie früher, dass man eine JRE installieren muss).

    Java ist VM und Bibliotheken. C++ ist der Compiler+Linker und Bibliotheken, und Compiler+Linker wird nur dann benötigt, wenn du den Source mitausliefern willst. Ansonsten kompilierst du die Version für den Kunden und stellst ihm diese zur Verfügung, und er braucht dann nur noch die Lib, nichts mehr (ähhh, stimmt nicht ganz, X-Server wird auch noch gebraucht :))

    Bei Java wird (meines Wissens?) der meiste Code aber bereits mit der VM ausgeliefert, deswegen merken die Anwender nur dann, dass was fehlt, wenn du exotischere Funktionen benötigst. C++ kommt aber von C, und C ist minimalistisch. Da ist alles, was nicht durch Featureset der Sprache oder durch einen Standard definiert wird (und das ist nicht viel, weil der Anspruch besteht, dass das auf jeder noch so kaputten Architektur läuft - Maschinen mit Einer-Komplement, Maschinen ohne Block-Device-Support - gibt einen Grund, warum man - zumindest mit C90 - die Größe von Dateien nur durch Durchlaufen ermitteln kann. Weil stat / GetFileSize halt nicht überall verfügbar ist), als "exotisch" zu betrachten. Weil "läuft ja nicht überall". Qt wird bestimmt nicht überall laufen.*

    Wenn du den Leuten den Source zur Verfügung stellst, damit die sich das kompilieren können, machst du das für gewöhnlich über ./configure && make && make install . configure ist in der Regel ein Skript, welches prüft, was der installierte Compiler so kann, welche Libs installiert sind, etc. Basierend auf diesen Infos wird ein Makefile generiert, dass, nachdem configure durchgelaufen ist, mit make aufgerufen werden kann. Mit diesem Befehl baust du das Projekt - installierst es aber noch nicht. Das passiert dann mit make install . Sprich: auf die Abhängigkeit "Qt" prüfst du in configure , und wenn es das da nicht gibt, erstellst du halt das Makefile nicht.

    EDIT:

    *Nicht, dass wir uns falsch verstehen: "exotisch" heißt hier nicht, dass es wirklich exotisch ist, sondern nur, dass es halt nicht mehr überall kompiliert. Oder läuft. Aber meistens tut es das. Speicherreservierung beispielsweise geht auf Linux und Windows nur über betriebssystemspezifische Funktionen, die die C-Standards nicht mal mit Namen erwähnen. Der Standard sagt nur: " malloc muss Speicherbereich zurückgeben", nicht "Muss intern VirtualAlloc auf Windows / mmap oder brk/sbrk auf Linux aufrufen". Was das malloc , oder der new-Operator, oder whatever ... trotzdem machen muss. Das ist alles schön wegabstrahiert, damit es nicht allzu "exotisch" aussieht.

    Sprich: alles, was nicht zum Standard gehört, darum musst du dich selbst kümmern.



  • Deployment von Qt-Anwendungen unter Linux ist leider eine Wissenschaft für sich. Allerdings ist Qt Bestandteil der LSB (Linux Standard Base) und die notwendigen Bibliotheken somit in der Regel vorinstalliert. Ärger kann auch die Version machen, z.B. ist unter Ubuntu 12.04 Qt4 installiert, Qt5 fehlt aber gänzlich in den Paketquellen. Ubuntu 14.04 kommt stattdessen mit Qt4 und Qt 5.2.1.

    In der Debian-Paketverwaltung werden die Abhängigkeiten in der Datei "control" angegeben, hier ein Beispiel:

    Package: passman
    Version: 1.0.01
    Section: non-free
    Priority: extra
    Architecture: amd64
    Depends: libc6, libgcc1, libstdc++6, libqt5clucene5 (>= 5.2.1), libqt5core5a (>= 5.2.1), libqt5gui5 (>= 5.2.1), libqt5help5 (>= 5.2.1), libqt5network5 (>= 5.2.1), libqt5sql5 (>= 5.2.1), libqt5widgets5 (>= 5.2.1), libqt5xml5 (>= 5.2.1)
    Installed-Size: 1024
    ...

    Bei meinen ersten Gehversuchen hat mir folgende Seite weitergeholfen:
    http://www.tomprogs.at/tutorials/linux/debian-paket-tutorials-01-ein-erstes-paket.xhtml

    Beim statischen linken werden die benötigten Bibliotheken in die ausführbare Datei eingebunden, die dann entsprechend (wesentlich) größer ist. Soweit ich weiß ist statisches linken aber nur mit der kommerziellen Lizenz möglich (und legal sowieso nur mit dieser).

    Falls Du weitere Fragen zur Debian-Paketen hast, kannst Du mich gerne kontaktieren. Mit anderen Paketverwaltungen kann ich Dir (momentan) leider nicht helfen.


Log in to reply