estoy tratando de enlazar un módulo C++ utilizando GCC, esencialmente como esto:¿Se ha cambiado el orden de enlace GCC?
gcc -c hello.c
g++ -c world.cpp
gcc -ohello -lstdc++ hello.o world.o
Nota que utilizo -lstdc++
para unir el módulo C++ en, por lo que puedo usar en lugar de gcc
g++
. El problema es que estoy recibiendo el error:
undefined reference to `operator new(unsigned long)'
(Suponiendo que world.cpp
contiene al menos una llamada a new
.)
Este error se fija si pongo -lstdc++
al final de la línea de enlazador , como este:
gcc -ohello hello.o world.o -lstdc++
Soy consciente de que esta pregunta se ha hecho muchas veces aquí, pero tengo un requisito especial. No estoy llamando directamente a GCC. Estoy usando un sistema de compilación para un lenguaje de programación diferente (Mercury) que llama a GCC en mi nombre, y no puedo modificar fácilmente la forma en que llama a GCC (aunque puedo especificar bibliotecas adicionales usando la variable de entorno LDFLAGS). Así que tengo dos requisitos adicionales:
- que no puedo utilizar
g++
vincular (sólogcc
) - es por eso que estoy haciendo el truco-lstdc++
anterior en lugar de simplemente la vinculación cong++
). - No creo que pueda controlar el orden de los comandos del enlazador - Mercury colocará los archivos .o en la línea de comandos después de cualquier biblioteca.
entiendo la razón fundamental por la cual el orden es importante, pero lo que me es desconcertante es ¿por qué esta ruptura ahora? Acabo de actualizar a Ubuntu 11.10/GCC 4.6.1. He estado compilando con éxito este programa durante años utilizando precisamente la técnica anterior (primero poniendo -lstdc++
). Solo ahora ha surgido este error. Un programa no relacionado de mis enlaces contra OpenGL usando -lgl
y eso también se rompió cuando actualicé y tuve que mover -lgl
al final de la línea de comandos. Probablemente voy a descubrir que docenas de mis programas ya no compilan. ¿Por qué cambió esto? ¿Hay algún problema con mi nuevo sistema o es así como es ahora? Tenga en cuenta que estas son bibliotecas compartidas ordinarias, no están vinculadas estáticamente.
¿Hay algo que pueda hacer para que GCC vuelva al modo anterior, donde el orden de las bibliotecas no importa? ¿Hay alguna otra manera en que pueda convencer a GCC para que vincule correctamente el libstdc++
sin moverlo después de los archivos .o
en la línea de comandos?
Entonces, básicamente, esta "regresión" es solo que para toda mi carrera de desarrollo, he estado confiando en el hecho de que "funcionó accidentalmente" y ahora ha dejado de funcionar. Parece un cambio bastante importante: he estado colocando bibliotecas antes de archivos de objetos durante la mayor parte de una década porque no tenía idea de que esto era un problema :(Gracias por el consejo.Parece que el problema no era Mercury poniendo objetos después de las bibliotecas, sino que hay dependencias más complejas dentro de mi comando LDFLAGS. Estoy progresando, así que te daré un tic. Gracias. – mgiuca
Hipótesis no probada: puede haber un cambio en 'ld' que le afecta. El objetivo puede ser evitar cargar las bibliotecas compartidas no utilizadas. Si usa bibliotecas estáticas, solo obtendrá las cosas que necesita. Solía ocurrir que si incluía una biblioteca compartida en la línea del enlace, se cargaba en el tiempo de ejecución, incluso si la biblioteca no proporcionaba ningún símbolo. Solo cargar la biblioteca si satisface al menos un símbolo puede reducir el tiempo de inicio del programa. Pero también significa que si el único símbolo sobresaliente cuando se escanea la biblioteca es 'main()', entonces la biblioteca no se cargará. –
Consulte los comentarios sobre '--as-needed' para la versión 2.20 de' ld' en [NOTICIAS] (http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/ld/NEWS? rev = 1.121 & content-type = text/plain & cvsroot = src & only_with_tag = binutils-binutils-2_22) archivo. Ver también el [manual] (http://sourceware.org/binutils/docs-2.22/ld/Options.html#Options) y el '--copy-dt-needed-entries' y' --no-copy- Opciones de dt-needed-entries'. La anterior "hipótesis no comprobada" está, al menos, algo probada, creo. –