Mahlzeit! kann man auf einem aktuellen Debian ein C-Programm so übersetzen, dass es auch auf Rechnern mit alter libc läuft? Tritt das Problem auch bei libX11.so usw. auf? Die offensichtliche Lösung, den alten Kisten endlich ein Update zu gönnen, kommt offensichtlich nicht in Frage (sind nicht meine). Zur Zeit benutze ich zum Übersetzen so einen alten Rechner, aber der ist soo laaangsam...
Containerless Container (vulgo: statisch gelinkt) zu verwenden wäre eine Möglichkeit.
danke, eigentlich naheliegend, aber praktisch ziemlich aussichtslos:
1 | warning: |
2 | Using 'getaddrinfo' in statically linked applications requires at |
3 | runtime the shared libraries from the glibc version used for linking |
Bauform B. schrieb: > danke, eigentlich naheliegend, aber praktisch ziemlich > aussichtslos:warning: > Using 'getaddrinfo' in statically linked applications requires at > runtime the shared libraries from the glibc version used for linking Sehr lustig :-)))) Nach meinem Halbwissen braucht man "getaddrinfo" nur für dynamisch gelinkte Libraries. Für statische schaut der Compiler. Wozu sollte da irgendwer "getaddrinfo" aufrufen? Gruß Klaus (der soundsovielte)
Klaus S. schrieb: > Wozu sollte da irgendwer "getaddrinfo" aufrufen? die da war es, aber wozu werden wir nie erfahren... libX11.a(xim_trans.o): in function `_XimXTransSocketINETConnect'
Bauform B. schrieb: > Die offensichtliche Lösung, den alten Kisten endlich ein Update zu > gönnen, kommt offensichtlich nicht in Frage (sind nicht meine). Zur Zeit > benutze ich zum Übersetzen so einen alten Rechner, aber der ist soo > laaangsam... Dann sperre doch die alte Installation in eine VirtualBox oder KVM-QEMU auf aktueller Hardware. Dann ist es auch schnell. fchk
Bauform B. schrieb: >> Wozu sollte da irgendwer "getaddrinfo" aufrufen? > die da war es, aber wozu werden wir nie erfahren... Ist der Versuch, statisch zu linken, damit endgültig gescheitert? Finde den Versuch dazu hochgradig interessant, weil ich der Meinung bin, daß Linux erst dann desktoptauglich wird, wenn statisches Linken genauso einfach wird wie dynamisches. Meine eigenen Versuche dazu sind jedenfalls alle gescheitert. Gruß Klaus (der soundsovielte)
Wie macht das eigentlich Golang? Denn Golang produziert per default statisch gelinkte Binarys. Ansonsten bliebe nur das ersetzen von getaddrinfo() gegen was eigenes.
Frank K. schrieb: > KVM-QEMU auf aktueller Hardware das hatte ich schon mal aufgegeben, aber da wollte ich das komplette alte System laufen lassen. Rein als "Build-Server" sollte es einfach sein, muss ich nochmal probieren, danke. Klaus S. schrieb: > Ist der Versuch, statisch zu linken, damit endgültig gescheitert? Finde > den Versuch dazu hochgradig interessant, weil ich der Meinung bin, daß > Linux erst dann desktoptauglich wird, wenn statisches Linken genauso > einfach wird wie dynamisches. Speziell für dieses Programm probiere ich nicht weiter. Eine reine Consolen-Anwendung läuft aber. Bei der habe ich nur dem gcc ein -static mit gegeben und die Funktionen aus meiner shared lib direkt dazu gelinkt. Wenn sich -static bewährt, würde ich aus der lib.so natürlich eine lib.a machen. Der nächste Versuch wäre ein GTK-Programm. Das setzt auf X11 auf und dürfte genau wie der erste Versuch daran scheitern. X11 funktioniert ja per Netzwerk. In einer alten rinetd.conf steht ein Kommentar
1 | # hostnamen gehen nicht, wenn rinetd statisch gelinkt ist |
Ich kann mich aber nicht erinnern, ob ich deshalb direkt IP-Adressen benutzt habe oder doch einen dynamisch gelinkten rinetd. Irgendwas war da, so ganz grob ungefähr "zwecks Performance bietet die libc ein paar Netzwerkfunktionen nicht statisch an". Vulganer schrieb: > Wie macht das eigentlich Golang? > Denn Golang produziert per default statisch gelinkte Binarys. Naja, wer eine ganze Sprache neu baut, kann natürlich ein paar Funktionen mitliefern.
Eine Möglichkeit eine komplexe Anwendungen mit vielen Abhängigkeiten statisch zu linken ist der Paketmanager Conan ( https://conan.io/ ). Wenn man in den Optionen für Abhängigkeiten (Gtk+ & Co) "static" angibt, wird statisch gelinkt. Das funktioniert allerdings prinzipbedingt nicht unbeschränkt, manche Dinge wie OpenGL oder Vulkan müssen die jeweiligen Treiber dynamisch laden. Außerdem sind nicht alle Pakete darauf vorbereitet, stelle dich auf eine Menge Fummelei ein. Was m.M.n. die bessere Option ist: Alle benötigten .so's mitliefern. Wenn man conan verwendet kann man sich dort alle benötigten .so's in den Build-Ordner kopieren lassen, dann kopiert man sich noch die libc.so dazu, und fertig ist das komplette Anwendungspaket was so ziemlich überall laufen sollte.
Programmierer schrieb: > Was m.M.n. die bessere Option ist: Alle benötigten .so's mitliefern. Und dann mit LD_LIBRARY_PATH=/home/user/lib/ oder wie? Irgendwie extrem, besonders, was die libc angeht. Das vereinigt die Nachteile von statischem und dynamischem Linken, also eine richtig moderne Lösung ;) Aber irgendwie auch extrem praktisch und bequem. Führe mich nicht in Versuchung...
Bauform B. schrieb: > Aber irgendwie auch extrem praktisch und bequem. Führe mich nicht in > Versuchung... Gobolinux hat genau damit das Problem grundsätzlich zu lösen versucht. Hat aber wohl nicht viel Anklang gefunden, ist wohl zu einfach. Gruß Klaus (der soundsovielte)
Bauform B. schrieb: > Und dann mit LD_LIBRARY_PATH=/home/user/lib/ oder wie? Ja genau. Am besten in ein "start.sh" script wrappen o.ä. Ist aus technischer Sicht nicht gerade sauber, aber eben pragmatisch und funktioniert gut. Da Speicher mittlerweile billig ist tut es auch nicht allzu weh die Bibliotheken ggf. mehrfach auf der Platte zu haben. Bauform B. schrieb: > Führe mich nicht in Versuchung... Naja, irgendwo muss man auch mal ans Ziel kommen. Da die Linux-Community nicht dazu in der Lage ist dafür eine vernünftige Lösung zu finden (außer alles in den Package Manager zu stellen und zu hoffen dass ein Maintainer es am Leben hält, super für proprietäre oder Spezial-Software). Man kann ja die .so's immer noch löschen und hoffen, dass es mit dem System-Libs funktioniert. Die .so's zusammen mit der Anwendung aufzubewahren ist schon eine gute Idee für die Langzeit-Verfügbarkeit. Die Linux-Kernel-APIs hingegen sind sehr stabil. Android macht es letztlich genauso, alle Apps liefern alle ihre Abhängigkeiten in der .apk Datei mit. Man kann keine Libraries einzeln installieren und Android selber bietet einen definierten versionierten Satz an APIs. Das ist zwar auch Speicherverschwendung weil so ziemlich jede App z.B. die AndroidX Library mitliefert, aber es ist sehr erfolgreich; weil es eben super einfach ist Apps zu installieren und es keine Abhängigkeitshölle gibt. So lustige Paket-Konflikt-Situationen wie sie unter den klassischen Distros auftreten können gibt's unter Android nicht.
Du kannst auch eine alte Version deines OS in einem chroot installieren. Bei Debian geht das einwandfrei. Man kann dort dann zum Beispiel ein aktuelles 64bit Debian als OS fahren und im chroot ein altes 32bit.
Schau Dir mal AppImage an. Da werden die Binaries so gebaut, daß sie alle Shared Libraries gepackt mitbringen. Beim Start wird das dann alles ausgepackt und über einen relativen Pfad geladen.
ja, was es alles gibt, danke. Dabei fällt mir ein, früher hat man qemu und ein Image von der alten Platte genommen und fertig war die VM. Wenn das immer noch so läuft, ist das doch konkurenzlos einfach. Angeblich/theoretisch würde das gleiche Image sogar unter Windows funktionieren. Nicht für mich, aber für manche Leute mit Laptop könnte das ein Argument sein.
Bauform B. schrieb: > kann man auf einem aktuellen Debian ein C-Programm so übersetzen, dass > es auch auf Rechnern mit alter libc läuft? Tritt das Problem auch bei > libX11.so usw. auf? Im Prinzip braucht man dafür nur den "--sysroot" Parameter des Compilers und ein System-image. Das System-Image muss man sich selbst irgendwo zusammenbauen, zum Beispiel aus einem Docker-Container mit allem benótigtem Zeug (dev-Packages für libc etc.) herauskopieren und danach die Symlinks von absolute in relative verwandeln (zB mit https://github.com/brandt/symlinks). Wenn das Programm cmake als Build-System verwendet muss man dann nur noch CMAKE_SYSROOT auf den Pfad zum sysimage setzen. Bei autotools dann eben "--sysroot" zu den CFLAGS und LDFLAGS hinzufügen. Problematisch ist dann nur noch der RPATH für transitive Abhängigkeiten: den muss man ggf. via "-Wl,--rpath-link,..." in den LDFLAGS an den Linker weitergeben. Je nach Aufbau der Distro gilt es dann noch Unterschiede in der Ordner-Struktur zu beachten (multilib, multiarch) und Suchpfade entsprechend anzupassen - eventuell muss man sogar den Compiler zum Targetting des anderen Systems neu bauen, weil manche Suchpfade fest eingebacken sind. Also, ja, das ist durchaus möglich, erfordert aber uU einiges an Arbeit und Túftelei, bis es richtig funktioniert: Im Grunde macht man da ein ganz normales cross-compiling von linux zu linux, macht es also im Grunde auch nicht anders, als wenn man sich eine toolchain für "system X" zusammen baut.
Bauform B. schrieb: > kann man auf einem aktuellen Debian ein C-Programm so übersetzen, dass > es auch auf Rechnern mit alter libc läuft? Tritt das Problem auch bei > libX11.so usw. auf? Die Linux-Welt war dafür noch nie vorgesehen, daher lautet die Antwort "nein". Es gibt natürlich Workarounds. Theoretisch könnte man statisch linken, aber glibc hat das noch nie sinnvoll unterstützt. Fällt also aus. Du kannst dein Programm in einer alten Umgebung übersetzen, also chroot, docker, VirtualBox o.ä. Oder du tauschst die libc gegen eine, die statisch linken kann. Beispielsweise kommt dietlibc mit einem passenden Compiler-Wrapper, wo du nur "gcc" gegen "diet gcc" tauschen musst; inwieweit das Buildsystem deiner Anwendung damit klarkommt, lässt sich schlecht sagen. Die dritte Option wäre, dein Zielsystem als embedded device zu betrachten und eine vollwertige Cross-Compile-Umgebung aufzusetzen. Sowas kann buildroot, und es gibt auch einige glibc-Versionen zur Auswahl; da fällt dann ein Cross-Compiler bei raus, der für das Target passende Binaries erzeugt. > Die offensichtliche Lösung, den alten Kisten endlich ein Update zu > gönnen, kommt offensichtlich nicht in Frage (sind nicht meine). Zur Zeit > benutze ich zum Übersetzen so einen alten Rechner, aber der ist soo > laaangsam... Installiere deine alte Software auf einen neuen Rechner (in einer VM), das dürfte die einfachste Lösung sein. Bauform B. schrieb: >> Was m.M.n. die bessere Option ist: Alle benötigten .so's mitliefern. > Und dann mit LD_LIBRARY_PATH=/home/user/lib/ oder wie? Wird dann eklig, wenn manche Teile trotzdem dynamisch bleiben müssen (z.B: die oben genannten OpenGL-Dinge) und dann im Extremfall zwei malloc-Implementationen den gleichen Speicher zu verwalten versuchen. Für die libc - insbesondere die glibc - ist das keine wirklich gute Lösung, im Gegensatz zu eigenen Bibliotheken.
S. R. schrieb: > Bauform B. schrieb: >>> Was m.M.n. die bessere Option ist: Alle benötigten .so's mitliefern. >> Und dann mit LD_LIBRARY_PATH=/home/user/lib/ oder wie? > > Wird dann eklig, wenn manche Teile trotzdem dynamisch bleiben müssen > (z.B: die oben genannten OpenGL-Dinge) und dann im Extremfall zwei > malloc-Implementationen den gleichen Speicher zu verwalten versuchen. > > Für die libc - insbesondere die glibc - ist das keine wirklich gute > Lösung, im Gegensatz zu eigenen Bibliotheken. Richtig. Sämtliches Zeug selbst mitausliefern erhöht nur den eigenen Wartungsaufwand, da man dann sämtliche Updates von verwendeten Paketen immer selbst machen muss, statt die normalen System-Updates der Zieldristribution auszunutzen. Man muss auch gar nicht so feingranular vorgehen und genau die selbe Version/Distro targetten, da die meisten Updates in linux-land rückwärtskompatibel sind. "Hinreichend outdated" genügt also.
Frank K. schrieb: > Bauform B. schrieb: > >> Die offensichtliche Lösung, den alten Kisten endlich ein Update zu >> gönnen, kommt offensichtlich nicht in Frage (sind nicht meine). Zur Zeit >> benutze ich zum Übersetzen so einen alten Rechner, aber der ist soo >> laaangsam... > > Dann sperre doch die alte Installation in eine VirtualBox oder KVM-QEMU > auf aktueller Hardware. Dann ist es auch schnell. Auch Docker ist eine Option. Das nutze ich, um Programme für eine alte CentOS-Version zu compilieren, die ein Kunde einsetzt. Ich habe einfach ein Image der betreffenden Version genommen, darauf basierend alles, was ich zum Bauen brauche hinzugefügt, und dann einen Container erstellt, aus dem heraus direkt auf das Source-Verzeichnis auf dem "Host" zugegriffen werden kann. Da kann ich dann den make-Prozess laufen lassen. Das klingt vielleicht kompliziert, ist es aber gar nicht.
Bauform B. schrieb: > kann man auf einem aktuellen Debian ein C-Programm so übersetzen, dass > es auch auf Rechnern mit alter libc läuft? Nachdem die Bibliotheks-Kompatibilität normalerweise nur "in die andere Richtung" gewährleistet wird, wäre die naheliegende Antwort: Kompilier das Programm auf dem ältesten Debian(-chroot,-container,-vm), das du unterstützen willst. Dann wird es auch auf den neueren Versionen funktionieren. d.H. du hast beim Übersetzen einmalig Mehraufwand, aber alle deine Anwender kriegen ein sofort lauffähiges Binary.
Εrnst B. schrieb: > Kompilier das Programm auf dem ältesten Debian(-chroot,-container,-vm), > das du unterstützen willst. Dann wird es auch auf den neueren Versionen > funktionieren. Das ist auch der Ansatz, den nvidia mit den Binärtreibern fährt. Weiss Nicht schrieb: > Sämtliches Zeug selbst mitausliefern erhöht nur den eigenen > Wartungsaufwand, da man dann sämtliche Updates von verwendeten > Paketen immer selbst machen muss, statt die normalen System- > Updates der Zieldristribution auszunutzen. Das Zielsystem macht offensichtlich schon seit Jahren keine ordentlichen Updates mehr... Programme als Container auszuliefern kommt wieder in Mode. Der Kreis aus den 90ern ist jetzt wieder geschlossen, demnächst wird dann InstallShield wiederauferstehen.
Nach einem langen Wochenende muss ich das erstmal vertagen. Vielen Dank für die vielen Vorschläge, die gehören alle mal näher untersucht. Also, bis später. Die einfachste Möglichkeit, qemu, funktioniert schon mal nicht. qemu-kvm kann anscheinend kein 3dnow und ohne wird es noch langsamer als die alte Hardware. Und virtualbox ist bei Debian wegen Oracles Umgang mit Sicherheitslücken in Ungnade gefallen.
Bauform B. schrieb: > qemu-kvm kann anscheinend kein 3dnow und ohne wird es noch langsamer > als die alte Hardware. Wenn deine Host-CPU kein 3DNow! kann, dann kann die Gast-CPU das auch nicht (stattdessen bekommst du MMX, SSE, SSE2, SSE3 und evtl. SSE4 - einige gab es auch damals schon). Performance-Einbußen solltest du keine haben. Bauform B. schrieb: > Und virtualbox ist bei Debian wegen Oracles Umgang mit > Sicherheitslücken in Ungnade gefallen. Du solltest das alte System ja nicht mit der virtuellen Maschine ersetzen, sondern damit nur die alte Software neu bauen können... C-Compiler nutzen weder MMX noch 3DNow, sie erzeugen nur Code, der das tut. Mit anderen Worten: Hä? Du erzählst komische Dinge.
S. R. schrieb: > Hä je nun, qemu ist besonders attraktiv, wenn man ein vorhandenes Disk Image 1:1 nutzen kann. Wenn das nicht geht, sind alle Lösungen wieder gleich auf. Unter diesen Umständen sollte ich wirklich eher für Updates auf den alten Rechnern sorgen.
Und was hat das mit "Qemu kann kein 3DNow!" zu tun?
Das Disk-Image der alten Rechner funktioniert mit qemu/kvm nicht und ohne kvm ist es viel zu langsam. Wahrscheinlich brauche ich "nur" einen passenden Kernel im Image, aber das ist, wie alle anderen Lösungen, eben viel aufwändiger. Und alles bleibt nur eine Notlösung. Bei der ursprünglichen Frage hatte ich gehofft, dass man dem Linker (dem gcc?) irgendwie sagen könnte "bau das kompatibel zur alten glibc-x.y.z".
Bauform B. schrieb: > Bei der ursprünglichen Frage hatte ich gehofft, dass man dem Linker (dem > gcc?) irgendwie sagen könnte "bau das kompatibel zur alten glibc-x.y.z". Geht rein theoretisch auch, Ungetestet: In der Glibc sind seit längerem die Symbole versioniert, und du kannst gegen eine spezielle Version linken. dazu schaust du in der Fehlermeldung (das was du im Thread-Titel abgeschnitten hast) nach, welche Funktionen in einer zu neuen Version erwartet werden, und packst dann per __asm__(".symver funktionsname,funktionsname@GLIBC_2.x.y"); für jede störende Version einen entsprechenden Hinweis an den Linker dazu. Edit: Evtl. ist das über "-Wl,--version-script ..." einfacher zu erreichen, damit müsstest du auch die glibc-funktionen auf eine ältere Version linken können...
:
Bearbeitet durch User
Εrnst B. schrieb: > .symver Faszinierend! Der Mechanismus funktioniert beim ersten Versuch, obwohl es im Handbuch¹ so aussieht, als ob .symver nur für die Quellen einer lib gedacht ist. Es war nicht einmal Fleißarbeit, weil nur ein einziges fcntl() zu neu war. Also genügte eine Zeile in der Quelle, die fcntl() benutzt. Witzigerweise ist das fcntl(fd, F_SETFD, FD_CLOEXEC) wahrscheinlich sogar überflüssig. "Neuerdings" benutzt man doch open() mit O_CLOEXEC, oder? Jetzt braucht es noch ein wenig testen und Untergrundforschung, im Moment benutzt ein Programm die falsche Konfiguration... 1) http://sourceware.org/binutils/docs/ld/VERSION.html Edit: es scheint auch mit open(,, O_CLOEXEX) zu laufen, aber close-on-exec haben oder nicht gibt hässliche Fehler. Jedenfalls sieht man mal wieder, das richtig fragen viel schwieriger ist als antworten. Vielen Dank!
:
Bearbeitet durch User
Bauform B. schrieb: > kann man auf einem aktuellen Debian ein C-Programm so übersetzen, dass > es auch auf Rechnern mit alter libc läuft? Höchstwahrscheinlich, aber wie Du bereits bemerkt hast, gibt es ein Problem mit dem statischen Linken der Resolver-Bibliothek aus der GNU C Library. Eine Möglichkeit zur Behebung des Problems war bei mir (vor langer, langer Zeit) die Verwendung einer anderen C-Bibliothek -- wenn ich mich recht entsinne, habe ich die Software einfach unter Alpine Linux übersetzt, das die musl-libC verwendet. Eine andere Alternative könnte auch die dietlibc von Felix "Fefe" von Leitner sein. Das ist aber alles sehr lange her, meine Ohren sind trüb und meine Erinnerung ist grauhaarig. ;-) > Tritt das Problem auch bei libX11.so usw. auf? Das käme wohl auf einen Versuch an, schätze ich. HTH, but YMMV.
Es gibt noch eine andere Variante: Man liefert die glibc selbst auch mit. Dazu muss man allerdings auch den dynamischen Linker (ld-linux-x86-64.so.2 oder sowas) manuell aufrufen. Ja, das ist zwar ein .so-File, kann aber als Executable auch direkt ausgeführt werden. Dazu einmal ldd <deinprogramm> machen und alle angezeigten Bibliotheken in ein Verzeichnis kopieren. Dann ein Skript machen, das LD_LIBRARY_PATH auf dieses Verzeichnis setzt und dann eben das kopierte ld-….so aufruft mit dem Executable als Kommandozeilenparameter.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.