Estou tentando executar meu primeiro programa C++ no Solaris. Apenas um simples programa Hello World. Quando tento correr. Eu recebo o erro libstdc++.so.6:open failed:No such file or directory
. É claro que pesquisei no Google e descobri que posso resolver isso definindo a variável de ambiente:
export LD_LIBRARY_PATH=/usr/local/lib
Após o relog, descobri que não era uma forma permanente de resolver o problema. Suponho que isso tenha algo a ver com a vinculação de libstdc++.so.6 durante a compilação. Aqui está o passo que fiz desde o início:
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
Perdi um sinalizador ou algo assim durante a compilação? Como faço para criar um softlink para saber onde procurar ao executar esse programa?
Esta é a plataforma que estou 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
Responder1
A maneira mais fácil de definir o caminho de pesquisa do vinculador de tempo de execução do Solaris é usando crle
, mas você precisa ter muito cuidado ao fazer isso, pois você pode facilmente inutilizar seu sistema se quebrá-lo! Para adicionar /usr/local/bin
ao caminho do vinculador:
# crle -u -l /usr/local/lib
Depois de fazer isso, ligue crle
sozinho para verificar o novo caminho de pesquisa.
Uma alternativa é compilar o caminho no próprio binário:
$ gcc -Wl,-rpath,/usr/local/lib -o test test.o -lstdc++
A opção acima é uma opção melhor, pois o binário funcionará em outros sistemas sem a necessidade de ajustar o caminho do vinculador.
Responder2
O problema é que oSolarisO carregador não consegue encontrar a biblioteca.
A melhor coisa a fazer é definir a LD_RUN_PATH
variável de ambiente durante a compilação para o diretório ondelibstdc++.so.xxxx(seu número de versão) vive. Isso diz ao vinculador para pesquisar esse diretório em tempo de execução.
Observe que
LD_RUN_PATH
não deve ser confundido comLD_LIBRARY_PATH
. Este último é analisado em tempo de execução, enquantoLD_RUN_PATH
essencialmente compila em um caminho de biblioteca no executável, de modo que não precisa de umaLD_LIBRARY_PATH
configuração para encontrar suas bibliotecas.
Se tudo mais falhar, você sempre poderá executar seus programas a partir de scripts de shell wrapper que definem a LD_LIBRARY_PATH
variável de ambiente adequadamente.
Isso é uma essência,
colocou oLD_LIBRARY_PATH, se não estiver incluído em
/usr/local/lib
:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ; export LD_LIBRARY_PATH
gccos arquivos normalmente são instalados em
/usr/lib/gcc/
.
Em seguida, vincule libstdc++.so.6 do diretório instalado /usr/lib
ou /usr/local/lib
usando soft-linking
sudo ln -s libstdc++.so.6 /usr/lib/<filename>
Responder3
Primeiro, não há necessidade de usar crle (e a menos que você realmente entenda o que está fazendo, fique longe dele; acredite em mim, você se bloqueará com erros malucos de tempo de execução quando usá-lo errado)
Em segundo lugar, não há necessidade de definir LD_LIBRARY_PATH, nunca (bem, principalmente), também não há necessidade de vincular simbolicamente quaisquer bibliotecas de terceiros em /usr
Basta fazer o que o mjturner sugere e dar ao gcc o caminho de execução correto ao compilar
PS: o código C++ deve ser compilado com g++
Links:
http://notes.theorbis.net/2010/01/how-to-screw-up-solaris-with-crle.html http://prefetch.net/articles/linkers.badldlibrary.html
Responder4
Se você usar o front-end g++, ele saberá como vincular corretamente o código C++ à biblioteca libstdc++. Isto é especialmente verdadeiro para o Solaris.
Não importa o que você faça, em nenhuma circunstância use LD_RUN_PATH ou LD_LIBRARY_PATH porque essas variáveis são destinadas a desenvolvedores de bibliotecas de objetos compartilhados para ajudar na depuração e não para vinculação final. Usá-los irá interpor símbolos de diferentes versões de bibliotecas de objetos compartilhados e pode causar travamentos insidiosos que são extremamente difíceis de depurar, já que não se saberá quais símbolos estão sendo usados em tempo de execução por causa da referida interposição.
Sempre vincule através do front-end do g++. Se você precisar passar informações adicionais de RPATH para o editor de link, a coisa correta a fazer é g++ -Wl,-R/path/to/lib ou g++ -m64 -Wl,-R/path/to/lib/64 ( ao contrário de "lib64" no GNU/Linux), dependendo se alguém está compilando 32 ou 64 bits, respectivamente. Os compiladores GCC no Solaris são multi-arch.