110 votes

La compilation échoue avec "le placement R_X86_64_32 contre `.rodata.str1.8' ne peut pas être utilisé lors de la création d'un objet partagé"

Je essaie de compiler ce code source à partir du fichier makefile dans un VPS, mais cela ne fonctionne pas. Le VPS est un CentOS 64 bits

Voici l'erreur complète

# 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 envers `.rodata.str1.8' ne peut pas être utilisée lors de la création d'un objet partagé; recompiler avec -fPIC
TCP-LINUX_V1.o: ne pouvait pas lire les symboles: Mauvaise valeur
collect2: ld a retourné 1 statut de sortie
make: *** [all] Erreur 1

Voici mon fichier 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

Quelqu'un sait ce qui ne va pas?

135voto

Haroogan Points 6159

Faites ce que le compilateur vous demande de faire, c'est-à-dire recompiler avec -fPIC. Pour apprendre ce que fait ce drapeau et pourquoi vous en avez besoin dans ce cas, consultez les Options de génération de code du manuel GCC.

En bref, le terme code indépendant de la position (PIC) fait référence au code machine généré qui est agnostique de l'adresse mémoire, c'est-à-dire qu'il ne fait aucune hypothèse sur l'endroit où il a été chargé en RAM. Seul le code indépendant de la position est censé être inclus dans les objets partagés (SO) car ils doivent avoir la capacité de changer dynamiquement leur emplacement en RAM.

Enfin, vous pouvez également en lire plus à ce sujet sur Wikipedia.

58voto

XavierStuvw Points 527

Dans mon cas, cette erreur s'est produite parce qu'une commande make s'attendait à récupérer des bibliothèques partagées (fichiers *.so) depuis un répertoire distant indiqué par une variable d'environnement LDFLAGS. Par erreur, seules des bibliothèques statiques étaient disponibles là-bas (fichiers *.la ou *.a).

Par conséquent, mon problème ne résidait pas dans le programme que je compilais mais dans les bibliothèques distantes qu'il tentait de récupérer. Ainsi, je n'ai pas eu besoin d'ajouter de drapeau (par exemple, -fPIC) à la compilation interrompue par l'erreur de relocalisation. Plutôt, j'ai recompilé la bibliothèque distante pour que les objets partagés soient disponibles.

En gros, il s'agissait en réalité d'une erreur de fichier non trouvé.

Dans mon cas, j'ai dû supprimer un commutateur --disable-shared mal placé dans l'invocation de configure pour le programme requis, puisque les bibliothèques partagées et statiques étaient toutes deux construites par défaut.


J'ai remarqué que la plupart des programmes construisent les deux types de bibliothèques en même temps, donc le mien est probablement un cas particulier. En général, il peut être nécessaire d'activer les bibliothèques partagées, selon les paramètres par défaut.

Pour inspecter votre situation particulière avec les commutateurs de compilation et les paramètres par défaut, je lirais le résumé qui apparaît avec ./configure --help | less, généralement dans la section Caractéristiques Optionnelles. J'ai souvent constaté que cette lecture est plus fiable que les guides d'installation qui ne sont pas mis à jour pendant l'évolution des programmes de dépendances.

22voto

Pedro H Points 124

Résolu avec l'option -no-pie lors de l'étape de l'édition des liens :

g++-8 -L"/home/pedro/workspace/project/lib" -no-pie ...

11voto

Paweld2 Points 411

Il ne s'agit pas toujours des indicateurs de compilation, j'ai la même erreur sur gentoo lorsque j'utilise distcc.

La raison en est que le serveur distcc utilise un profil non sécurisé et que le client utilise un profil sécurisé. Consultez cette discussion : https://forums.gentoo.org/viewtopic-p-7463994.html

4voto

Simplement en nettoyant le projet, j'ai résolu le problème.

Mon projet est une application C++ (pas une bibliothèque partagée). J'ai rencontré cette erreur de façon aléatoire après de nombreux builds réussis.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X