La compilación falla con "reubicación R_X86_64_32 contra` .rodata.str1.8 'no se puede usar al hacer un objeto compartido "

84

Estoy tratando de compilar este código fuente desde el archivo MAKE en un VPS, pero no funciona. El VPS es un sistema operativo de 64 Cent

Aquí está el error completo

# 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

Aquí está mi archivo MAKE:

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

Alguien sabe lo que pasa?

usuario1667191
fuente
6
Lo intentaste recompile with -fPIC?
Joachim Isaksson
Lo siento, pero no estoy seguro de cómo hacer esto. No puedo encontrar nada sobre "-fPIC" en Google.
user1667191
4
Pruebe algo comoCOMPILE_FLAGS=-c -O3 -w -DLINUX -fPIC -I../SDK/amx/
Joachim Isaksson
Relacionado: stackoverflow.com/questions/6093547/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
9
Si busca -fPIC en Google, ciertamente no encontrará nada. Elimine el signo menos o utilice comillas "-fPIC"; de lo contrario, omitirá todos los resultados que contengan fPIC.
d00d

Respuestas:

119

Haga lo que le diga el compilador, es decir, vuelva a compilar con -fPIC. Para saber qué hace esta bandera y por qué la necesita en este caso, consulte Opciones de generación de código del manual de GCC.

En resumen, el término código de posición independiente (PIC) se refiere al código de máquina generado que es independiente de la dirección de memoria, es decir, no hace ninguna suposición sobre dónde se cargó en la RAM. Se supone que solo se incluye código independiente de la posición en los objetos compartidos (SO), ya que deberían tener la capacidad de cambiar dinámicamente su ubicación en la RAM.

Finalmente, también puedes leer sobre esto en Wikipedia .

Alexander Shukaev
fuente
3
¿Podría explicar cómo recompilar con -fPIC?
Beni Bogosel
12
@Beni Bogosel: Esto es muy simple. Simplemente agregue el -fPICa todas las invocaciones del compilador para todos los archivos fuente (unidades de traducción, por ejemplo, *.cpparchivos) de la biblioteca. La forma concreta de hacerlo depende del sistema de construcción que utilice. Por ejemplo, en CMake podría emitir set_target_properties(${LIBRARY_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON). En el caso de este tipo (usando Make simple y antiguo), tendría que hacerlo COMPILE_FLAGS+=-fPICya que está usando esta variable para indicar el conjunto de indicadores de compilación para todos los archivos fuente de su biblioteca.
Alexander Shukaev
1
para habilitar -fPIC usando configure: configure --enable-shared, consulte stackoverflow.com/a/850464/440403
camino
49

En mi caso, este error se produjo porque un makecomando esperaba obtener bibliotecas compartidas ( *.soarchivos) de un directorio remoto indicado por una LDFLAGSvariable de entorno. En un error, solo las bibliotecas estáticas estaban disponibles allí ( *.lao *.aarchivos).

Por lo tanto, mi problema no residía en el programa que estaba compilando, sino en las bibliotecas remotas que intentaba recuperar. Por lo tanto, no necesité agregar ningún indicador (digamos -fPIC) a la compilación interrumpida por el error de reubicación. Más bien, volví a compilar la biblioteca remota para que los objetos compartidos estuvieran disponibles.

Básicamente, ha sido un error de archivo no encontrado disfrazado.

En mi caso, tuve que eliminar un --disable-sharedconmutador perdido en la configureinvocación del programa requerido, ya que las bibliotecas compartidas y estáticas se crearon de forma predeterminada.


Me di cuenta de que la mayoría de los programas crean ambos tipos de bibliotecas al mismo tiempo, por lo que el mío es probablemente un caso de esquina. En general, puede darse el caso de que prefiera habilitar las bibliotecas compartidas, según los valores predeterminados.

Para inspeccionar su situación particular con los conmutadores de compilación y los valores predeterminados, leería el resumen que aparece ./configure --help | less, generalmente en la sección Características opcionales. A menudo descubrí que esta lectura es más confiable que las guías de instalación que no se actualizan mientras los programas de dependencia evolucionan.

XavierStuvw
fuente
1
Perfecto, "ha sido un error de archivo no encontrado disfrazado". En mi caso, la dependencia aún no se instaló.
Litty
+1 En mi caso, una copia más nueva de openssl se construyó manualmente y se instaló sin bibliotecas compartidas. La biblioteca que estaba intentando construir ya estaba compilada con -fPIC. ¿Hay alguna forma de que el compilador pueda reconocer este error para dar un mensaje de error menos oscuro, por ejemplo "Se esperaba encontrar la biblioteca compartida libssl.so, pero solo encontró la biblioteca estática incompatible /usr/local/ssl/lib/libssl.a"? ?
Rohan Mahy
1
Gracias. Tenía un make -j y la ejecución paralela no estaba permitida para este paquete de software.
MikeBergmann
En mi caso, tengo esta línea "find_library (NGHTTP2_LIB NAMES libnghttp2.a libnghttp2.so libnghttp2.dylib)". y solo estaba recogiendo el .a, luego lo cambié a find_library (NGHTTP2_LIB NAMES libnghttp2.so libnghttp2.a libnghttp2.dylib) "y comenzó a funcionar. Mi preocupación es, ¿qué solía funcionar antes para mí?
Naba Chinde
1
@NabaChinde Me temo que no tengo una respuesta para su pregunta también porque carezco de información contextual sobre sus resultados. Sin duda, le animo a publicar una pregunta separada en la que explique su situación laboral y el comportamiento inesperado.
XavierStuvw
11

No siempre se trata de las banderas de compilación, tengo el mismo error en gentoo cuando uso distcc.

La razón es que en el servidor distcc se usa un perfil no reforzado y en el cliente el perfil está reforzado. Consulte esta discusión: https://forums.gentoo.org/viewtopic-p-7463994.html

EIIPII
fuente
9

Se corrigió con la -no-pieopción en la etapa del enlazador:

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

Simplemente limpiar el proyecto lo resolvió por mí.

Mi proyecto es una aplicación C ++ (no una biblioteca compartida). Recibí este error al azar después de muchas compilaciones exitosas.

Gábor Kiss-Vámosi
fuente
2

Yo tuve el mismo problema. Intente volver a compilar usando -fPICflag.

Saurav Chowdhury
fuente
0

Recibo la misma solución que el comentario de @ camino en https://stackoverflow.com/a/19365454/10593190 y la respuesta de XavierStuvw .

Lo hice funcionar (para instalar ffmpeg) simplemente reinstalando todo desde el principio con todas las instancias de $ ./configurereemplazado por $ ./configure --enable-shared(primero asegúrese de eliminar todas las carpetas y archivos, incluidos los archivos .so del intento anterior).

Aparentemente, esto funciona porque https://stackoverflow.com/a/13812368/10593190 .

V Li
fuente