Altes QT-Programm statisch linken
Altes QT-Programm statisch linken
Ich möchte ein altes, aber mir sehr nützliches Programm selbst kompilieren und statisch verlinken.
Es geht um kaptain.
kaptain basiert auf QT4, das jetzt gänzlich aus debian bullseye herausgeflogen ist. Ich kann es nicht mehr starten.
Leider sind meine Kenntnisse in C und QT minimalst, sonst würde ich es lieber auf QT5 portieren.
Kann mir jemand sagen, wie ich kaptain als standalone-Binary statisch kompilieren und linken kann? Auf diese Weise würde es QT4 selbst mitbringen. Meine Erfahrung mit selbst kompilieren ist leider gering.
Als Build-Umgebung würde ich einen Docker Container mit Debian Jessie oder stretch nehmen.
Es geht um kaptain.
kaptain basiert auf QT4, das jetzt gänzlich aus debian bullseye herausgeflogen ist. Ich kann es nicht mehr starten.
Leider sind meine Kenntnisse in C und QT minimalst, sonst würde ich es lieber auf QT5 portieren.
Kann mir jemand sagen, wie ich kaptain als standalone-Binary statisch kompilieren und linken kann? Auf diese Weise würde es QT4 selbst mitbringen. Meine Erfahrung mit selbst kompilieren ist leider gering.
Als Build-Umgebung würde ich einen Docker Container mit Debian Jessie oder stretch nehmen.
Die Vernunft kann einem schon leidtun. Sie verliert eigentlich immer.
Re: Altes QT-Programm statisch linken
Beim Kompilieren des Programms muß man wenig bis gar nichts beachten. Da wird nur c/c++-Code in Maschinencode umgesetzt. Das eigentliche Problem ist das Linken, das die Dateien, in denen der Maschinencode steckt (*.o) mit Bibliotheken (z.B. libc und Qt-Libs) zu einem Executable zusammenkopiert wird. Sind die Bibliotheken statisch (erkennbar an der Dateiendung .a), wird auch das Programm ein statisch gelinnktes Programm. Sind die Bibliotheken dynamisch (erkennbar an der Dateiendung .so), wird auch das Programm ein dynamisch gelinktes Programm. Ist eine Mischung vorhanden, werden nur die .so-Dateien dynamisch gelinkt und der Rest statisch.MartinV hat geschrieben:18.02.2020 22:02:55Kann mir jemand sagen, wie ich kaptain als standalone-Binary statisch kompilieren und linken kann?
In deinem Fall würde es reichen, die Qt4-Bibliotheken als statische Bibliotheken zu erstellen. Dazu mußt du aber den Qt4-Code selbst kompilieren. Im Moment bin ich mir aber nichtmal mehr sicher, ob das Erstellen von statischen Qt-Libs überhaupt noch vorgesehen ist, ich habe da was dunkel n Erinnerung, daß das in der Vergangenheit zu Problemen geführt hat und heute nicht mehr vom Qt-Buildprozeß unterstützt wird.
-
- Beiträge: 3799
- Registriert: 26.02.2009 14:35:56
Re: Altes QT-Programm statisch linken
ein weiteres Problem könnte auftauchen, wenn die Anwendung mit dlopen und Konsorten arbeitet. Das geht nur mit .so-Bibliotheken und kann grundsätzlich nicht statisch gelinkt werden. Eventuell die QT4-Bibliotheken besorgen, in einen extra Ordner packen und den vor Programmstart aus der shell mit export LD_LIBRARY_PATH=.... entsprechend vorverketten.
Entspricht im MVS in der JCL dem //JOBLIB DD DSN=deine.biblio.thek.
Dazu könnten dann auch noch andere älterere Libs notwendig werden, - die dann halt auch dorthin packen. Mit etwas Glück muss dann Kaptain noch nicht mal neu kompiliert werden.
Auf die Art betreibe ich heute noch den xmms, der ja bekanntlich mit GTK 1.6 oder so rennt. Ist halt vom Klang her der beste Player - insbesondere mit dem eq-xmms-Plugin, dass für alles und nicht nur für mp3 funktioniert.
Entspricht im MVS in der JCL dem //JOBLIB DD DSN=deine.biblio.thek.
Dazu könnten dann auch noch andere älterere Libs notwendig werden, - die dann halt auch dorthin packen. Mit etwas Glück muss dann Kaptain noch nicht mal neu kompiliert werden.
Auf die Art betreibe ich heute noch den xmms, der ja bekanntlich mit GTK 1.6 oder so rennt. Ist halt vom Klang her der beste Player - insbesondere mit dem eq-xmms-Plugin, dass für alles und nicht nur für mp3 funktioniert.
Re: Altes QT-Programm statisch linken
Ahh, jetzt, wo du es sagst. Qt verwendet intern dlopen , um eigene shared Objects zu öffnen. Das Styling und Druckfunktionalitäten stecken schon seit langem in .so-Dateien, die mit dlopen geladen werden. Das was auch der Grund, warum man Qt nicht mehr in statisch Bibliotheken bauen kann.pferdefreund hat geschrieben:19.02.2020 08:29:42ein weiteres Problem könnte auftauchen, wenn die Anwendung mit dlopen und Konsorten arbeitet.
Re: Altes QT-Programm statisch linken
Eigentlich müsste man QT4 statisch linken können. PS: wenn dlopen dies verhindert, dann geht's wohl doch nicht immer
Ich hatte mal ein QT4.8-Programm für debian 7 (kam noch mit QT4.6) gebaut. (Es handelte sich um das Programm RespeQt, Hilfe bekam ich auf dem AtariAge-Forum. Bei Interesse bitte googlen, ich will hier nicht auf ein anderes Forum verlinken).
Eine andere Möglichkeit ist, ein AppImage aus einer laufenden Installation heraus zu erstellen. Das, so fand ich, war weniger aufwändig. Dass das eigentliche Programm wesentlich größer war, spielte keine Rolle, da man gar nichts kompilieren muss.
Ich hatte mal ein QT4.8-Programm für debian 7 (kam noch mit QT4.6) gebaut. (Es handelte sich um das Programm RespeQt, Hilfe bekam ich auf dem AtariAge-Forum. Bei Interesse bitte googlen, ich will hier nicht auf ein anderes Forum verlinken).
Eine andere Möglichkeit ist, ein AppImage aus einer laufenden Installation heraus zu erstellen. Das, so fand ich, war weniger aufwändig. Dass das eigentliche Programm wesentlich größer war, spielte keine Rolle, da man gar nichts kompilieren muss.
-
- Beiträge: 3799
- Registriert: 26.02.2009 14:35:56
Re: Altes QT-Programm statisch linken
Ich würde mir die QT-Debs runterladen, irgendwo hinstellen und das Original alte Programm damit probieren (vorher den LD_LIBRARY_PATH entsprechend anpassen) und schauen was noch fehlt oder passiert. MIt etwas Glück ist der Käse dann schon zum Bahnhof gerollt.
Re: Altes QT-Programm statisch linken
Eine schmutzige Lösung:
Soviele alte Libs als Abhängigkeit hat das Programm gar nicht. Im Archiv bzw. im Repo sind die ja noch vorhanden, die würde ich einzeln herunterladen und manuell in das richtige Verzeichnis kopieren. Überschrieben werden kann nichts mehr, und das Programm läuft auch.
Ist etwas Arbeit, aber das Kompilieren ist sicher aufwändiger. Dann noch eine kurze Notiz mit den Libs, wenn man die mal wieder entfernen will, damit hat man auch noch die Übersicht.
Soviele alte Libs als Abhängigkeit hat das Programm gar nicht. Im Archiv bzw. im Repo sind die ja noch vorhanden, die würde ich einzeln herunterladen und manuell in das richtige Verzeichnis kopieren. Überschrieben werden kann nichts mehr, und das Programm läuft auch.
Ist etwas Arbeit, aber das Kompilieren ist sicher aufwändiger. Dann noch eine kurze Notiz mit den Libs, wenn man die mal wieder entfernen will, damit hat man auch noch die Übersicht.
-
- Beiträge: 3799
- Registriert: 26.02.2009 14:35:56
Re: Altes QT-Programm statisch linken
Na ja, ich würde alles komplett - nicht nur die Libs in einen extra-Ordner packen, und auch dort das Startscript mit den LD_LIBRARY_PATH... reinpacken. Dann bin ich sicher, dass ein apt-get autoremove mir die Libs nicht wieder entsorgt - und wenn ich update, wird ein eigener Ordner ja vom System selbst nie angefasst. Im Notfall kann ich sogar den ganzen Ordner auf eine andere Maschine kopieren (so gleiche Architektur) und solange die LIBC6 und andere noch passen, rennt das problemlos weiterhin.
Re: Altes QT-Programm statisch linken
Danke für Eure Tips!
Ein erster Erfolg!
Auffallend ist libpng12, das nicht Teil von QT zu sein scheint.
Von jeder lib gibt es mehrere Varianten. Sollte nicht eine davon genügen? (Edit: Doppelte libs auf die so.4 Version zu reduzieren geht.)
Das statisch linken probiere ich auch, in einem Container habe ich Qt4 als static kompilieren können. Mal schauen, wie ich jetzt kaptain damit verlinke.
Statisch gelinkt ist mir immer noch die bevorzugte Lösung, da ich kaptain mit meinen eigenen Programmen anbieten will.
Ein erster Erfolg!
Ich habe gemäß den Fehlermeldungen nach und nach die Bibliotheken kopiert und den Ordner mit LD_LIBRARY_PATH angegeben. Funktioniert! Die Liste der Bibliotheken:pferdefreund hat geschrieben:19.02.2020 14:12:57Ich würde mir die QT-Debs runterladen, irgendwo hinstellen und das Original alte Programm damit probieren (vorher den LD_LIBRARY_PATH entsprechend anpassen) und schauen was noch fehlt oder passiert. MIt etwas Glück ist der Käse dann schon zum Bahnhof gerollt.
Code: Alles auswählen
libpng12.so.0 libQtCore.so.4.8 libQtNetwork.so.4.8.6
libpng12.so.0.50.0 libQtCore.so.4.8.6 libQtSql.so.4
libQt3Support.so.4 libQtGui.so.4 libQtSql.so.4.8
libQt3Support.so.4.8 libQtGui.so.4.8 libQtSql.so.4.8.6
libQt3Support.so.4.8.6 libQtGui.so.4.8.6 libQtXml.so.4
libqt3supportwidgets.so libQtNetwork.so.4 libQtXml.so.4.8
libQtCore.so.4 libQtNetwork.so.4.8 libQtXml.so.4.8.6
Von jeder lib gibt es mehrere Varianten. Sollte nicht eine davon genügen? (Edit: Doppelte libs auf die so.4 Version zu reduzieren geht.)
Das statisch linken probiere ich auch, in einem Container habe ich Qt4 als static kompilieren können. Mal schauen, wie ich jetzt kaptain damit verlinke.
Statisch gelinkt ist mir immer noch die bevorzugte Lösung, da ich kaptain mit meinen eigenen Programmen anbieten will.
Die Vernunft kann einem schon leidtun. Sie verliert eigentlich immer.
Re: Altes QT-Programm statisch linken
libpng ist nicht Bestandteil von Qt, das ist eine ganz normale Bibliothek, die aber von Qt benutzt wird (Icons, Symbols...) und daher davon abhängig ist.MartinV hat geschrieben:21.02.2020 13:23:56Auffallend ist libpng12, das nicht Teil von QT zu sein scheint.
libpng12 hat allerdings Sicherheitslücken, die aktiv ausgenutzt werden. Man sollte diese veraltete Version nicht mehr verwenden.
Bitte die libpng-Problematik beachten. Du solltest versuchen, deine Qt4 gegen eine neuere libpnpg bauen.Statisch gelinkt ist mir immer noch die bevorzugte Lösung, da ich kaptain mit meinen eigenen Programmen anbieten will.
Re: Altes QT-Programm statisch linken
Danke für den Hinweis!MSfree hat geschrieben:21.02.2020 13:39:12Bitte die libpng-Problematik beachten. Du solltest versuchen, deine Qt4 gegen eine neuere libpnpg bauen.
Statt mit Debian Jessie baue ich jetzt auf Debian buster. Dort gibt es libpng16.
Nach ein paar Stolpersteinen lief die Kompilierung von QT4 durch.
Beim Kompilieren mit make von kaptain bekomme ich jetzt eine Fehlermeldung:
Code: Alles auswählen
communication.h:4:10: fatal error: qsocketnotifier.h: No such file or directory
Code: Alles auswählen
# find / | grep -i qsocket
/usr/local/Trolltech/Qt-4.8.7/include/QtCore/QSocketNotifier
/usr/local/Trolltech/Qt-4.8.7/include/QtCore/qsocketnotifier.h
/usr/local/Trolltech/Qt-4.8.7/include/Qt/qsocketnotifier.h
/qt4/qt/src/corelib/kernel/qsocketnotifier.cpp
/qt4/qt/src/corelib/kernel/qsocketnotifier.h
/qt4/qt/src/corelib/.moc/release-static/moc_qsocketnotifier.cpp
/qt4/qt/src/corelib/.obj/release-static/qsocketnotifier.o
/qt4/qt/src/corelib/.obj/release-static/moc_qsocketnotifier.o
/qt4/qt/tests/auto/q3socket/tst_qsocket.cpp
/qt4/qt/tests/auto/qsocketnotifier
/qt4/qt/tests/auto/qsocketnotifier/.gitignore
/qt4/qt/tests/auto/qsocketnotifier/qsocketnotifier.pro
/qt4/qt/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp
/qt4/qt/include/QtCore/QSocketNotifier
/qt4/qt/include/QtCore/qsocketnotifier.h
/qt4/qt/include/Qt/qsocketnotifier.h
Die Vernunft kann einem schon leidtun. Sie verliert eigentlich immer.
Re: Altes QT-Programm statisch linken
Ein weiterer Erfolg: Ich habe kaptain mit den Qt4-Bibliotheken statisch gelinkt!
Ich habe leider nicht herausgefunden, wie ich auf das Qt-Verzeichnis richtig verweise, so daß die header-Dateien gefunden werden. Experimente mit Variable CPATH gaben nur andere Folgefehler.
Stattdessen habe ich erfolgreich gepfuscht: Ich habe die Sourcedateien von kaptain in das Qt-Source-Verzeichnis brutal hineinkopiert und make dort gestartet. Damit lief es durch.
Das ist das schöne an Containern: Ich kann nach Belieben im Container-System herumpfuschem, ohne mein Hauptsystem zu beschädigen.
Einen Schönheitsfehler gibt es noch: Statt als "Executeable" wird es als "Shared object" gesehen. Warum das so ist und wie ich das richtig machen kann, weiß ich nicht. Kann mich jemand aufklären?
Das originale kaptain ergibt:
Mein selbstgebautes kaptain:
Ein neues .deb-paket, basierend auf dem Original, habe ich auch schon gebastelt und erfolgreich installieren können.
Ich habe leider nicht herausgefunden, wie ich auf das Qt-Verzeichnis richtig verweise, so daß die header-Dateien gefunden werden. Experimente mit Variable CPATH gaben nur andere Folgefehler.
Stattdessen habe ich erfolgreich gepfuscht: Ich habe die Sourcedateien von kaptain in das Qt-Source-Verzeichnis brutal hineinkopiert und make dort gestartet. Damit lief es durch.
Das ist das schöne an Containern: Ich kann nach Belieben im Container-System herumpfuschem, ohne mein Hauptsystem zu beschädigen.
Einen Schönheitsfehler gibt es noch: Statt als "Executeable" wird es als "Shared object" gesehen. Warum das so ist und wie ich das richtig machen kann, weiß ich nicht. Kann mich jemand aufklären?
Das originale kaptain ergibt:
Code: Alles auswählen
$ file kaptain
kaptain: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=acfb8e32e64ea3f56c32c52cb5ff49798c067ff8, stripped
Code: Alles auswählen
$ file kaptain
kaptain: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=11063ff39a3aaa9d32a8f73855317894af5163aa, not stripped
Die Vernunft kann einem schon leidtun. Sie verliert eigentlich immer.
Re: Altes QT-Programm statisch linken
Mit diesem Dockerfile baue ich kaptain mit statisch gelinkten Qt4-libs und erzeuge ein neues .deb Paket:
Mein kaptain repository: https://github.com/mviereck/kaptain
Code: Alles auswählen
# Build kaptain with statically linked Qt4 libraries.
# Generates /deb/kaptain_0.73-3-staticqt4_amd64_debian.deb
# Allows to install kaptain on systems without Qt4 libraries.
FROM debian:buster
RUN echo deb-src http://deb.debian.org/debian buster main >> /etc/apt/sources.list && \
sed -i "s/main/main contrib non-free/g" /etc/apt/sources.list
# Dependencies
RUN apt-get update && \
apt-get install -y git-core nano wget tar bison flex qt4-qmake && \
apt-get build-dep -y qt4-qmake
# Build static libs of Qt4
RUN git clone https://github.com/qt/qt.git
WORKDIR /qt
RUN echo yes | ./configure \
-prefix /usr \
-release -static -opensource \
-qt3support \
-nomake tools -nomake tests -nomake examples \
-no-multimedia -no-audio-backend -no-phonon -no-phonon-backend \
-no-svg -no-webkit -no-javascript-jit -no-script -no-scripttools \
-no-declarative -no-declarative-debug -no-openssl -no-cups -no-dbus \
-no-accessibility
RUN make
RUN make install
# Build kaptain
WORKDIR /
RUN wget https://github.com/mviereck/kaptain/raw/master/kaptain-0.73.tgz && \
tar -xzf kaptain-0.73.tgz
WORKDIR /kaptain-0.73
ENV QT_SELECT=qt4
RUN qmake kaptain.pro && \
make
# Generate new .deb package based on Debian jessie kaptain package
RUN mkdir -p /deb/kaptain
WORKDIR /deb
RUN wget http://ftp.debian.org/debian/pool/main/k/kaptain/kaptain_0.73-2_amd64.deb && \
dpkg-deb -R kaptain_0.73-2_amd64.deb /deb/kaptain
RUN cp /kaptain-0.73/kaptain /deb/kaptain/usr/bin/kaptain && \
sed -i 's%^Maintainer:.*$%Maintainer: Martin Viereck (not a Debian maintainer. www.github.com/mviereck/kaptain)% ; \
s%^Installed-Size:.*$%Installed-Size: 15472% ; \
s%^Version:.*$%Version: 1:0.73-3% ; \
s%^Depends:.*$%Depends: libc6 (>= 2.14), libgcc1 (>= 1:4.1.1), libpng16-16(>=1.6.28), libstdc++6 (>= 4.9)% ; \
' /deb/kaptain/DEBIAN/control && \
echo " This unofficial build contains statically linked Qt4 libs." >> /deb/kaptain/DEBIAN/control
RUN dpkg-deb -b /deb/kaptain kaptain_0.73-3-staticqt4_amd64_debian.deb
Das Problem habe ich jetzt etwas anders gelöst: Qt wird jetzt mit "configure -prefix /usr" gebaut, um eine systemweite Installation bei "make install" zu bekommen. So kann ich auf das schmutzige Hineinkopieren von kaptain in den Qt-Ordner verzichtenIch habe leider nicht herausgefunden, wie ich auf das Qt-Verzeichnis richtig verweise, so daß die header-Dateien gefunden werden. Experimente mit Variable CPATH gaben nur andere Folgefehler.
Stattdessen habe ich erfolgreich gepfuscht: Ich habe die Sourcedateien von kaptain in das Qt-Source-Verzeichnis brutal hineinkopiert und make dort gestartet. Damit lief es durch.
Dafür habe ich keine Lösung gefunden.Einen Schönheitsfehler gibt es noch: Statt als "Executeable" wird es als "Shared object" gesehen. Warum das so ist und wie ich das richtig machen kann, weiß ich nicht. Kann mich jemand aufklären?
Die Vernunft kann einem schon leidtun. Sie verliert eigentlich immer.