Estoy intentando ejecutar mi primer programa C++ en Solaris. Sólo un sencillo programa Hola Mundo. Cuando intento correr. Recibo el error libstdc++.so.6:open failed:No such file or directory
. Por supuesto, busqué en Google y descubrí que puedo resolver esto configurando la variable de entorno:
export LD_LIBRARY_PATH=/usr/local/lib
Después de volver a iniciar sesión, descubrí que no era una forma permanente de resolverlo. Supongo que esto tiene algo que ver con vincular libstdc++.so.6 durante la compilación. Aquí está el paso que hice desde el principio:
bash-3.2# gcc -c test.cpp
bash-3.2# gcc -o test test.o -lstdc++
bash-3.2# ./test
libstdc++.so.6:open failed:No such file or directory
bash-3.2# ldd test | grep not
libstdc++.so.6 => (file not found)
bash-3.2# /usr/ccs/bin/elfdump test | grep RUNPA
bash-3.2# find /usr -name libstdc++.so.6
/usr/local/lib/libstdc++.so.6
¿Me perdí una bandera o algo así durante la compilación? ¿Cómo creo un enlace suave para que sepa dónde buscar cuando ejecute ese programa?
Esta es la plataforma que estoy usando:
bash-3.2# uname -a
SunOS ms-sparc8 5.8 Generic_108528-13 sun4u sparc SUNW,Sun-Blade-100
bash-3.2# gcc -v
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/3.3.2/specs
Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls --disable-libgcj --enable-languages=c,c++
Thread model: posix
gcc version 3.3.2
Respuesta1
La forma más sencilla de configurar la ruta de búsqueda del vinculador de tiempo de ejecución de Solaris es mediante crle
, pero debe tener mucho cuidado al hacerlo, ya que puede inutilizar fácilmente su sistema si lo rompe. Para agregar /usr/local/bin
a la ruta del vinculador:
# crle -u -l /usr/local/lib
Una vez que haya hecho eso, llame crle
por su cuenta para verificar la nueva ruta de búsqueda.
Una alternativa es compilar la ruta en el propio binario:
$ gcc -Wl,-rpath,/usr/local/lib -o test test.o -lstdc++
Lo anterior es una mejor opción ya que el binario funcionará en otros sistemas sin tener que ajustar la ruta del vinculador.
Respuesta2
El problema es que elSolarisEl cargador no puede encontrar la biblioteca.
Lo mejor que puede hacer es configurar la LD_RUN_PATH
variable de entorno durante la compilación en el directorio dondelibstdc++.so.xxxx(su número de versión) vive. Esto le dice al vinculador que busque ese directorio en tiempo de ejecución.
Tenga en cuenta que
LD_RUN_PATH
no debe confundirse conLD_LIBRARY_PATH
. Este último se analiza en tiempo de ejecución, mientras queLD_RUN_PATH
esencialmente se compila en una ruta de biblioteca en el ejecutable, de modo que no necesita unaLD_LIBRARY_PATH
configuración para encontrar sus bibliotecas.
Si todo lo demás falla, siempre puede ejecutar sus programas desde scripts de shell contenedor que configuran la LD_LIBRARY_PATH
variable de entorno de manera adecuada.
Eso es en esencia,
selecciona elLD_LIBRARY_PATH, si no está incluido en
/usr/local/lib
:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ; export LD_LIBRARY_PATH
gccLos archivos normalmente se instalan en
/usr/lib/gcc/
.
Luego vincule libstdc++.so.6 desde el directorio instalado /usr/lib
ao /usr/local/lib
usando enlaces suaves
sudo ln -s libstdc++.so.6 /usr/lib/<filename>
Respuesta3
Primero, no es necesario usar crle (y a menos que realmente entiendas lo que estás haciendo, aléjate de él; créeme, te bloquearás con errores locos de tiempo de ejecución cuando lo uses mal).
En segundo lugar, no es necesario configurar LD_LIBRARY_PATH, nunca (bueno, en su mayoría), tampoco es necesario vincular simbólicamente ninguna biblioteca de terceros en /usr.
Simplemente haga lo que sugiere mjturner y déle a gcc la ruta de ejecución correcta al compilar.
PD: el código C++ debe compilarse con g++
Enlaces:
http://notes.theorbis.net/2010/01/how-to-screw-up-solaris-with-crle.html http://prefetch.net/articles/linkers.badldlibrary.html
Respuesta4
Si utiliza la interfaz de g++, sabrá cómo vincular correctamente el código C++ con la biblioteca libstdc++. Esto es especialmente cierto en el caso de Solaris.
No importa lo que haga, bajo ninguna circunstancia use LD_RUN_PATH o LD_LIBRARY_PATH porque esas variables están destinadas a los desarrolladores de bibliotecas de objetos compartidos para ayudar con la depuración y no para el enlace final. Su uso interpondrá símbolos de diferentes versiones de bibliotecas de objetos compartidos y puede provocar fallos insidiosos que son extremadamente difíciles de depurar, ya que no se sabrá qué símbolos se están utilizando en tiempo de ejecución debido a dicha interposición.
Enlace siempre a través del front-end de g++. Si necesita pasar información RPATH adicional al editor de enlaces, lo correcto es g++ -Wl,-R/path/to/lib o g++ -m64 -Wl,-R/path/to/lib/64 ( a diferencia de "lib64" en GNU/Linux) dependiendo de si se está compilando 32 o 64 bits, respectivamente. Los compiladores GCC en Solaris son de múltiples arcos.