Wie baue ich meine Linux C ++ App, um eine Verbindung zu einer alten Version von libc herzustellen?

8

Ich habe eine App auf Ubuntu 12.04 erstellt und habe versucht, sie auf einem Embedded-System auszuführen. Ich habe apt-cache show libc6 auf meinem Dev-Rechner ausgeführt, der (neben anderen Dingen)

anzeigt %Vor%

Die Version von libc6, die auf dem eingebetteten Gerät existiert, ist 2.8.90. Im Verzeichnis \lib auf dem Gerät habe ich 2 Bibliotheken

%Vor%

Wenn ich meine Anwendung auf das eingebettete Gerät kopiere, erhalte ich folgende Fehler

%Vor%

Ich weiß, dass ich, wenn möglich, wenn ich die Anwendung auf meiner Entwicklungsmaschine baue, erzwinge, dass er auf dieselbe Version von libc6 verweist, wie sie auf dem eingebetteten Gerät existiert. Das Problem, das ich habe, ist, dass ich einfach nicht weiß, wie das geht. Alle Antworten, die ich gefunden habe, sind im Moment bedeutungslos für mich. Gibt es eine Option, die ich an g ++ übergeben muss, um dies mit der Version 2.8.90 zu verknüpfen?

In meiner Verzweiflung denke ich, ist es möglich, die libc auf meiner dev-Maschine auf das eingebettete Gerät anstelle von dem, was dort ist, zu kopieren und hoffe auf das Beste ??? Ich kann einfach keine Online-Dokumentation finden, die in einfachen Worten erklärt, wie man das überhaupt macht, also wäre jeder Rat wirklich willkommen, wenn ich mir hier die Haare raufe.

    
mathematician1975 09.07.2012, 14:57
quelle

3 Antworten

1

Das ist grundsätzlich falsch. Während Sie möglicherweise in der Lage sind, einen Weg zum Verknüpfen in der alten libc zu hacken, besteht das Problem in Ihrer Umgebung.

Wenn Sie Anwendungen für ein eingebettetes System entwickeln. Sie tun dies auf einem Host. Im Allgemeinen befinden sich Host und eingebettetes Gerät nicht in derselben Architektur. Zum Beispiel ist Ihr Host normalerweise ein Desktop / Laptop, der auf einem x86 läuft, und das eingebettete System könnte sich auf einem ARM befinden. Wenn Sie auf der gleichen Architektur wie Ihr eingebettetes Gerät sind, ist das ein reiner Zufall. Die Einrichtung der Standardübungsumgebung sollte noch folgen:

  • Der Host-Computer sollte über eine Toolchain-Konfiguration verfügen, um Anwendungen auf die eingebettete Architektur zu übertragen
  • Der Hostcomputer sollte eine Kopie des vollständigen rootfs haben, das Ihr eingebettetes Gerät enthält. Dies wird alle Bibliotheken enthalten, die Ihre Cross-Tools zum Kompilieren von Anwendungen für das eingebettete System verwenden

Wenn Sie es so eingerichtet haben. Die Entwicklung wird einfach sein. Sie werden in der Lage sein, einfache, saubere make-Dateien einzurichten, um Ihre Anwendungen zu erstellen und dann einfach scp der Binärdateien in das eingebettete System zu übernehmen und auszuführen.

    
linsek 09.07.2012, 18:25
quelle
9

OK, hier ist eine etwas längere Erklärung, aber gehen Sie vorsichtig vor. Ich empfehle weiterhin dringend, dass Sie eine chroot-Umgebung einrichten, die mit der auf dem eingebetteten Gerät verfügbaren übereinstimmt und diese während der letzten Phase des Build-Prozesses verwendet.

Sie sollten verstehen, wie dynamisch verknüpfte ELF-Executables geladen und ausgeführt werden. Es gibt etwas, das der Laufzeit-Link-Editor (RTLD) genannt wird, der auch als dynamischer Linker bekannt ist, der dafür sorgt, dass alle benötigten dynamisch verbundenen Bibliotheken geladen werden, Umlagerungen korrigiert werden und so weiter. Der Name des dynamischen Linkers lautet /lib/ld-linux.so.2 auf 32-Bit-Linux-Systemen mit glibc2 und /lib64/ld-linux-x86-64.so.2 auf 64-Bit-Linux-Systemen mit %Code%. Der dynamische Linker ist sehr eng mit der glibc2 -Bibliothek gekoppelt und kann normalerweise nur die passende Version dieser Bibliothek verarbeiten. Auch der Pfad dorthin ist hardcoded durch den Linker in die ausführbare Datei geschrieben (normalerweise glibc2 , implizit vom Compiler zum Linken aufgerufen). Sie können die Gültigkeit der letzten Anweisung leicht überprüfen, indem Sie einfach ld ausführen - der Laufzeit-Link-Editor zeigt den vollständigen Pfad:

%Vor%

Um eine dynamisch verknüpfte ausführbare Datei zu erzeugen, die eine Version von ldd some_elf_executable verwendet, die sich von der auf dem System installierten Version unterscheidet, sollten Sie Ihren Code mit den folgenden Optionen mit% co_de verknüpfen %:

  • glibc2 - Dieser Befehl weist den dynamischen Linker an, zuerst ld zu suchen, wenn er versucht, Bibliotheksabhängigkeiten aufzulösen. -rpath=/path/to/newer/libs sollte mit dem Pfad übereinstimmen, auf dem Sie die neuere Version /path/to/newer/libs auf dem integrierten Gerät
  • kopiert haben
  • /path/to/newer/libs - Diese Option weist den Linker (nicht den dynamischen Linker) an, glibc2 zu verwenden, wenn Abhängigkeiten zwischen gemeinsam genutzten Bibliotheken während der Verbindungszeit aufgelöst werden - dies sollte in Ihrem Fall normalerweise nicht notwendig sein.
  • -rpath-link=/path/to/newer/libs - dieser überschreibt den Pfad zur RTLD, die in die ausführbare Datei eingebettet wird

Die Möglichkeit, diese Optionen für /path/to/newer/libs bereitzustellen, erfolgt normalerweise über die Option --dynamic-linker=/path/to/newer/libs/ld-linux.so.2 von GCC.

%Vor%

wird zu:

%Vor%

(Beachten Sie, dass ld durch -Wl ersetzt wird)

%Vor%

wird zu:

%Vor%

Sie sollten = von Ihrem Entwicklungssystem in , auf dem eingebetteten Gerät kopieren. Sie sollten auch /lib/ld-linux.so.2 , die mathematische Bibliothek /path/to/newer/libs/ und alle anderen Bibliotheken kopieren, die von der ausführbaren Datei verwendet werden oder indirekt geladen werden können. Beachten Sie, dass libc.so.6 und libm.so.6 tatsächlich symbolische Links zu den echten Bibliotheken sind, die Namen wie libc.so.6 haben. Sie sollten diese Bibliotheksdateien kopieren und die entsprechenden symbolischen Links erstellen, um alle glücklich zu machen.

    
Hristo Iliev 09.07.2012 16:57
quelle
1

Vielleicht haben Sie etwas Glück beim Kompilieren mit dem LSB SDK ( Ссылка ), das die verfügbaren Symbole einschränkt die ausführbare Datei.

    
Douglas Leeder 09.07.2012 15:16
quelle

Tags und Links