Die Kompilierung schlägt fehl mit "Verschiebung R_X86_64_32 gegen" .rodata.str1.8 "kann nicht verwendet werden, wenn ein freigegebenes Objekt erstellt wird"

85

Ich versuche, diesen Quellcode aus dem Makefile in einem VPS zu kompilieren, aber es funktioniert nicht. Das VPS ist ein 64-Cent-Betriebssystem

Hier ist der vollständige Fehler

# make
gcc -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/amx/*.c
g++ -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/*.cpp
g++ -c -O3 -w -DLINUX -I../SDK/amx/ *.cpp
g++ -O2 -fshort-wchar -shared -o "TCP_V1.so" *.o
/usr/bin/ld: TCP-LINUX_V1.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be     used when making a shared object; recompile with -fPIC
TCP-LINUX_V1.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [all] Error 1

Hier ist mein Makefile:

GPP=g++
GCC=gcc
OUTFILE="TCP_V1.so"

COMPILE_FLAGS=-c -O3 -w -DLINUX -I../SDK/amx/

all:
    $(GCC) $(COMPILE_FLAGS) ../SDK/amx/*.c
    $(GPP) $(COMPILE_FLAGS) ../SDK/*.cpp
    $(GPP) $(COMPILE_FLAGS) *.cpp
    $(GPP) -O2 -fshort-wchar -shared -o $(OUTFILE) *.o

Weiß jemand was los ist?

user1667191
quelle
6
Hast du es versucht recompile with -fPIC?
Joachim Isaksson
Entschuldigung, aber ich bin mir nicht sicher, wie ich das machen soll. Ich kann bei Google nichts über "-fPIC" finden.
user1667191
4
Versuchen Sie etwas wieCOMPILE_FLAGS=-c -O3 -w -DLINUX -fPIC -I../SDK/amx/
Joachim Isaksson
Siehe auch
Ciro Santilli 法轮功 冠状 病 六四 事件 22
9
Wenn Sie Google nach -fPIC durchsuchen, werden Sie sicherlich nichts finden. Entfernen Sie das Minus oder verwenden Sie Anführungszeichen "-fPIC", andernfalls lassen Sie alle Ergebnisse weg, die fPIC enthalten.
d00d

Antworten:

119

Tun Sie, was der Compiler Ihnen sagt, dh kompilieren Sie mit -fPIC. Informationen dazu, was dieses Flag bewirkt und warum Sie es in diesem Fall benötigen, finden Sie unter Codegenerierungsoptionen im GCC-Handbuch.

Kurz gesagt bezieht sich der Begriff positionsunabhängiger Code (PIC) auf den erzeugten Maschinencode, der speicheradressenunabhängig ist, dh keine Annahmen darüber macht, wo er in den RAM geladen wurde. In gemeinsam genutzten Objekten (SO) sollte nur positionsunabhängiger Code enthalten sein, da diese in der Lage sein sollten, ihren Speicherort im RAM dynamisch zu ändern.

Schließlich können Sie auch auf Wikipedia darüber lesen .

Alexander Shukaev
quelle
3
Können Sie erklären, wie Sie mit -fPIC neu kompilieren können?
Beni Bogosel
12
@ Beni Bogosel: Das ist sehr einfach. Sie fügen einfach die -fPICzu allen Compiler-Aufrufen für alle Quelldateien (Übersetzungseinheiten, z. B. *.cppDateien) der Bibliothek hinzu. Die konkrete Vorgehensweise hängt von dem von Ihnen verwendeten Build-System ab. In CMake könnten Sie beispielsweise Probleme verursachen set_target_properties(${LIBRARY_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON). Im Falle dieses Typen (mit einfachem altem Make) müsste er dies tun, COMPILE_FLAGS+=-fPICda er diese Variable verwendet, um den Satz von Kompilierungsflags für alle Quelldateien seiner Bibliothek zu kennzeichnen.
Alexander Shukaev
1
Informationen zum Aktivieren von -fPIC mithilfe von configure: configure --enable-shared finden Sie unter stackoverflow.com/a/850464/440403
camino
50

In meinem Fall trat dieser Fehler auf, weil ein makeBefehl erwartete, gemeinsam genutzte Bibliotheken ( *.soDateien) aus einem Remote-Verzeichnis abzurufen, das durch eine LDFLAGSUmgebungsvariable angegeben wird. Aus Versehen waren dort nur statische Bibliotheken ( *.laoder *.aDateien) verfügbar .

Daher lag mein Problem nicht bei dem Programm, das ich kompilierte, sondern bei den Remote-Bibliotheken, die es abzurufen versuchte. Daher musste ich -fPICder Kompilierung, die durch den Verschiebungsfehler unterbrochen wurde , kein Flag (z. B. ) hinzufügen . Vielmehr habe ich die Remote-Bibliothek neu kompiliert, sodass die freigegebenen Objekte verfügbar waren.

Grundsätzlich handelt es sich um einen nicht gefundenen Fehler in der Verkleidung.

In meinem Fall musste ich einen falsch platzierten --disable-sharedSchalter im configureAufruf für das erforderliche Programm entfernen , da sowohl gemeinsam genutzte als auch statische Bibliotheken standardmäßig erstellt wurden.


Mir ist aufgefallen, dass die meisten Programme beide Arten von Bibliotheken gleichzeitig erstellen, daher ist meine wahrscheinlich ein Eckfall. Im Allgemeinen kann es vorkommen, dass Sie gemeinsam mit den Standardeinstellungen gemeinsam genutzte Bibliotheken aktivieren müssen.

Um Ihre spezielle Situation mit Kompilierungsschaltern und Standardeinstellungen zu untersuchen, würde ich die Zusammenfassung vorlesen, die ./configure --help | lessnormalerweise im Abschnitt Optionale Funktionen angezeigt wird. Ich habe oft festgestellt, dass dieses Lesen zuverlässiger ist als Installationshandbücher, die nicht aktualisiert werden, während sich Abhängigkeitsprogramme weiterentwickeln.

XavierStuvw
quelle
1
Perfekt: "Es war ein Fehler, bei dem die Datei nicht gefunden wurde." In meinem Fall wurde die Abhängigkeit noch nicht installiert.
Litty
+1 In meinem Fall wurde eine neuere Kopie von openssl manuell erstellt und ohne gemeinsam genutzte Bibliotheken installiert. Die Bibliothek, die ich erstellen wollte, wurde bereits mit -fPIC kompiliert. Gibt es eine Möglichkeit, dass der Compiler diesen Fehler erkennt und eine weniger undurchsichtige Fehlermeldung ausgibt, z. B. "Wird voraussichtlich die gemeinsam genutzte Bibliothek libssl.so finden, aber nur die inkompatible statische Bibliothek /usr/local/ssl/lib/libssl.a." ?
Rohan Mahy
1
Vielen Dank. Ich hatte ein make -j und eine parallele Ausführung war für dieses Softwarepaket nicht erlaubt.
MikeBergmann
In meinem Fall habe ich diese Zeile "find_library (NGHTTP2_LIB NAMES libnghttp2.a libnghttp2.so libnghttp2.dylib)". und es nahm nur die .a auf, ich änderte sie später in find_library (NGHTTP2_LIB NAMES libnghttp2.so libnghttp2.a libnghttp2.dylib) "und es fing an zu funktionieren. Mein Anliegen ist, was es früher für mich funktionierte?
Naba Chinde
1
@NabaChinde Ich fürchte, ich habe keine Antwort auf Ihre Frage, auch weil mir Kontextinformationen zu Ihren Ergebnissen fehlen. Ich würde auf jeden Fall empfehlen, eine separate Frage zu stellen, in der Sie Ihre Arbeitssituation und das unerwartete Verhalten erläutern.
XavierStuvw
11

Es geht nicht immer um die Kompilierungsflags, ich habe den gleichen Fehler bei gentoo bei der Verwendung von distcc.

Der Grund ist, dass auf dem distcc-Server ein nicht gehärtetes Profil verwendet wird und auf dem Client das Profil gehärtet ist. Überprüfen Sie diese Diskussion: https://forums.gentoo.org/viewtopic-p-7463994.html

EIIPII
quelle
10

Es wurde mit der -no-pieOption in der Linker-Phase behoben:

g++-8 -L"/home/pedro/workspace/project/lib" -no-pie ...
Pedro H.
quelle
4

Durch einfaches Reinigen des Projekts wurde es für mich gelöst.

Mein Projekt ist eine C ++ - Anwendung (keine gemeinsam genutzte Bibliothek). Ich habe diesen Fehler nach vielen erfolgreichen Builds zufällig erhalten.

Gábor Kiss-Vámosi
quelle
2

Ich hatte das gleiche Problem. Versuchen Sie, mit -fPICflag neu zu kompilieren .

Saurav Chowdhury
quelle
0

Ich erhalte die gleiche Lösung wie @ caminos Kommentar zu https://stackoverflow.com/a/19365454/10593190 und die Antwort von XavierStuvw .

Ich habe es zum Laufen gebracht (für die Installation von ffmpeg), indem ich das Ganze einfach von Anfang an neu installiert habe, wobei alle Instanzen von $ ./configureersetzt wurden $ ./configure --enable-shared(lösche zuerst alle Ordner und Dateien einschließlich der .so-Dateien aus dem vorherigen Versuch).

Anscheinend funktioniert dies, weil https://stackoverflow.com/a/13812368/10593190 .

V Li
quelle