libpthread.so.0: erro ao adicionar símbolos: DSO ausente na linha de comando


205

Ao compilar o openvswitch-1.5.0, encontrei o seguinte erro de compilação:

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith
     -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init  -g -O2 -export-dynamic ***-lpthread***  -o utilities/ovs-dpctl utilities/ovs-dpctl.o lib/libopenvswitch.a
 /home/jyyoo/src/dpdk/build/lib/librte_eal.a
 /home/jyyoo/src/dpdk/build/lib/libethdev.a
 /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a
 /home/jyyoo/src/dpdk/build/lib/librte_hash.a
 /home/jyyoo/src/dpdk/build/lib/librte_lpm.a
 /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a
 /home/jyyoo/src/dpdk/build/lib/librte_ring.a
 /home/jyyoo/src/dpdk/build/lib/librte_mempool.a
 /home/jyyoo/src/dpdk/build/lib/librte_malloc.a -lrt -lm 
     /usr/bin/ld: /home/jyyoo/src/dpdk/build/lib/librte_eal.a(eal.o): undefined reference
     to symbol 'pthread_create@@GLIBC_2.2.5'
     /lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from 
     command line

Se eu tentar ver os símbolos de libpthread, parece ótimo.

$ readelf -s /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create
   199: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 pthread_create@@GLIBC_2.2.5
   173: 0000000000008220  2814 FUNC    LOCAL  DEFAULT   13 __pthread_create_2_1
   462: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 pthread_create@@GLIBC_2.2

Você poderia dar dicas ou sugestões?



Link_libraries (pthread)
Alex Punnen

# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf: Erro: Não foi possível localizar '/lib/x86_64-linux-gnu/libncurses.so'. Mensagem de erro do sistema: Muitos níveis de links simbólicos
Ashish Karpe 17/17

Possível duplicado de DSO faltando linha de comando
luator

4
Droga, eu fiz gccnãog++
Pós Auto

Respostas:


164

Você deve mencionar a biblioteca na linha de comando após a compilação dos arquivos de objeto:

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init \
     -g -O2 -export-dynamic -o utilities/ovs-dpctl utilities/ovs-dpctl.o \
     lib/libopenvswitch.a \
     /home/jyyoo/src/dpdk/build/lib/librte_eal.a /home/jyyoo/src/dpdk/build/lib/libethdev.a /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a /home/jyyoo/src/dpdk/build/lib/librte_hash.a /home/jyyoo/src/dpdk/build/lib/librte_lpm.a /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a /home/jyyoo/src/dpdk/build/lib/librte_ring.a /home/jyyoo/src/dpdk/build/lib/librte_mempool.a /home/jyyoo/src/dpdk/build/lib/librte_malloc.a \
     -lrt -lm -lpthread 

Explicação: o link depende da ordem dos módulos. Os símbolos são solicitados primeiro e depois vinculados a partir de uma biblioteca que os possui. Portanto, você deve especificar os módulos que usam as bibliotecas primeiro e as bibliotecas depois deles. Como isso:

gcc x.o y.o z.o -la -lb -lc

Além disso, caso haja uma dependência circular, você deve especificar a mesma biblioteca na linha de comando várias vezes. Portanto, caso libbprecise de um símbolo libce libcprecise de um símbolo libb, a linha de comando deve ser:

gcc x.o y.o z.o -la -lb -lc -lb

24
Eu acho que você pode fazer -Wl,--start-group -la -lb- -lc -Wl,--end-grouppor dependências circulares.
Z28_Bernon

2
Observe que isso também se aplica aos arquivos de origem - eles devem ser listados antes das bibliotecas. Você pode pensar nos arquivos de objeto resultantes substituindo os arquivos de origem na linha de comando e aplicar a mesma ordem acima.
Jspencer

Onde você deve adicionar -lpthread ao usar o make para criar o aplicativo?
Codezombie 8/08/16

50

A mensagem de erro depende da versão da distribuição / compilador:

Ubuntu Saucy:

/usr/bin/ld: /mnt/root/ffmpeg-2.1.1//libavformat/libavformat.a(http.o): undefined reference to symbol 'inflateInit2_'
/lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line

Ubuntu Raring: (mais informativo)

/usr/bin/ld: note: 'uncompress' is defined in DSO /lib/x86_64-linux-gnu/libz.so.1 so try adding it to the linker command line

Solução: pode estar faltando uma biblioteca em suas etapas de compilação, durante o estágio de vinculação. No meu caso, adicionei '-lz' aos sinalizadores makefile / GCC.

Background: DSO é um objeto compartilhado dinâmico ou uma biblioteca compartilhada.


1
Eu usei essa solução criando outro projeto que estava dando o mesmo erro adicionando -lz ao LDFLAGS e funcionou perfeitamente. Obrigado!
precisa

O erro ainda permanece para mim: / usr / bin / ld: gaSim.o: referência indefinida ao símbolo 'pthread_create @@ GLIBC_2.1' /lib/i386-linux-gnu/libpthread.so.0: erro ao adicionar símbolos: DSO ausente da linha de comando
Aerox

Em parte resolvido adicionando '-lpthread', mas agora ele me mostra: gaSim.c :(. Text + 0x11d6): referência indefinida a `glewInit '
Aerox

@Aerox: for glewInit, you need-lGLEW
mchiasson

19

fundo

o DSO missing from command line mensagem será exibida quando o vinculador não encontrar o símbolo necessário em sua pesquisa normal, mas o símbolo estiver disponível em uma das dependências de uma biblioteca dinâmica especificada diretamente.

No passado, o vinculador considerava símbolos em dependências de idiomas especificados como disponíveis. Mas isso mudou em alguma versão posterior e agora o vinculador impõe uma visão mais rigorosa do que está disponível. A mensagem, portanto, pretende ajudar nessa transição.

O que fazer?

Se você é o mantenedor do software

Você deve resolver esse problema, certificando-se de que todas as bibliotecas necessárias para satisfazer os símbolos necessários sejam especificadas diretamente na linha de comando do vinculador. Lembre-se também de que a ordem geralmente importa.

Se você está apenas tentando compilar o software

Como solução alternativa, é possível voltar à visualização mais permissiva de quais símbolos estão disponíveis usando a opção -Wl,--copy-dt-needed-entries .

As maneiras comuns de injetar isso em uma compilação são exportar LDFLAGS antes da execução configureou algo semelhante:

export LDFLAGS="-Wl,--copy-dt-needed-entries"

Às vezes, passar LDFLAGS="-Wl,--copy-dt-needed-entries"diretamente para maketambém pode funcionar.


A versão 7.4.0 do gcc (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) não reconheceu esse sinalizador.
UserX

1
Não é uma opção do gcc, então você está perdendo o -Wl,bit ou tem um vinculador que não suporta essas opções. Qual vinculador você está usando? Esta resposta assume o vinculador binutils clássico (ld.bfd). O vinculador binutils gold (ld.gold) documenta --copy-dt-needed-entriescomo "Não suportado". Portanto, se você possui isso (ou qualquer outro vinculador que não suporte essa opção) como padrão, pode ser necessário seguir a seção para mantenedores ou alternar para o ld clássico para vinculação. Eu acho que você pode usar -fuse-ld=ld.bfdpara isso.
textshell

14

Encontrei outro caso e, portanto, acho que está tudo errado.

Isto é o que eu tinha:

/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: eggtrayicon.o: undefined reference to symbol 'XFlush'
/usr/lib64/libX11.so.6: error adding symbols: DSO missing from command line

O problema é que a linha de comando NÃO contém -lX11 - embora o libX11.so deva ser adicionado como uma dependência, porque também havia bibliotecas GTK e GNOME nos argumentos.

Portanto, a única explicação para mim é que essa mensagem pode ter sido destinada a ajudá-lo , mas não foi corretamente. Provavelmente isso foi simples: a biblioteca que fornece o símbolo não foi adicionada à linha de comando.

Observe três regras importantes relacionadas à ligação no POSIX:

  • As bibliotecas dinâmicas têm dependências definidas, portanto, apenas as bibliotecas da dependência superior devem ser fornecidas em qualquer ordem (embora após as bibliotecas estáticas)
  • As bibliotecas estáticas têm apenas símbolos indefinidos - cabe a você conhecer suas dependências e fornecer todas elas na linha de comando
  • A ordem nas bibliotecas estáticas é sempre: primeiro solicitante , o provedor segue . Caso contrário, você receberá uma mensagem de símbolo indefinida, como quando se esqueceu de adicionar a biblioteca à linha de comando
  • Quando você especifica a biblioteca com -l<name>, você nunca sabe se será lib<name>.soou não lib<name>.a. A biblioteca dinâmica é preferida, se encontrada, e as bibliotecas estáticas podem ser aplicadas apenas pela opção do compilador - isso é tudo. E se você tiver algum problema como acima, depende se você possui bibliotecas estáticas ou dinâmicas
  • Bem, às vezes as dependências podem estar ausentes nas bibliotecas dinâmicas: D

Não se destina apenas a ajudá-lo, é necessário que o vinculador resolva os nomes em questão. O erro é completamente válido. Se o compilador decidisse deixar isso passar, você obteria um segfault por acessar algo que não existe no tempo de execução binário.
Kevr

1
Para adicionar, é possível que em plataformas diferentes, a fonte seja compilada de maneira diferente; o que está vinculado em um sistema pode não estar vinculado em outro. Geralmente não é esse o caso, mas é 100% plausível.
Kevr

O problema não é que não é válido, mas não é exatamente útil encontrar a causa do problema.
Ethouris 9/01/19

7

Eu descobri que tinha o mesmo erro. Eu estava compilando um código com lapack e blas. Quando mudei a ordem em que as duas bibliotecas foram chamadas, o erro desapareceu.

"LAPACK_LIB = -llapack -lblas" funcionou onde "LAPACK_LIB = -lblas -llapack" deu o erro descrito acima.


9
Eu recebo esse erro em um projeto definido pelo cmake ... então existe um bug no Cmake que coloca a ordem do vinculador errada?
peter Karasev

respondendo a @peterkarasev: tente usar find_package(Threads)etarget_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
activedecay

7

Eu também encontrei o mesmo problema. Não sei porque, apenas adiciono-lpthread opção ao compilador e tudo ok.

Velho:

$ g++ -rdynamic -m64 -fPIE -pie  -o /tmp/node/out/Release/mksnapshot ...*.o *.a -ldl -lrt

obteve o seguinte erro. Se eu anexar a -lpthreadopção ao comando acima, então OK.

/usr/bin/ld: /tmp/node/out/Release/obj.host/v8_libbase/deps/v8/src/base/platform/condition-variable.o: undefined reference to symbol 'pthread_condattr_setclock@@GLIBC_2.3.3'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

Isso funcionou para mim; Eu tive que adicionar um segundo "redundante" -lpthread ao comando g ++ no makefile que faz o link. (Ele já apareceu uma vez na lista LIBS no makefile.) Também adicionei "-L / lib / x86_64-linux-gnu" à definição LDFLAGS no makefile.
UserX

2

O que descobri é que, às vezes, a biblioteca que o vinculador reclama não é a que está causando o problema. Possivelmente, há uma maneira inteligente de descobrir onde está o problema, mas é isso que eu faço:

  • Comente todas as bibliotecas vinculadas no comando link.
  • Limpe todos os arquivos .o, .so etc. (Normalmente, limpar é suficiente, mas você pode executar um achado recursivo + rm, ou algo semelhante).
  • Remova o comentário das bibliotecas no comando link, uma de cada vez, e reorganize a ordem conforme necessário.

@ Peter Karasev: Eu me deparei com o mesmo problema com um projeto cmake do gcc 4.8.2 no CentOS7. A ordem das bibliotecas na seção "target_link_libraries" é importante. Eu acho que o cmake apenas passa a lista para o vinculador como está, ou seja, ele não tenta e trabalha na ordem correta. Isso é razoável - quando você pensa sobre isso, não pode saber qual é a ordem correta até que o vínculo seja concluído com êxito.



1

O mesmo problema aconteceu comigo quando uso distccpara criar meu projeto c ++; Finalmente eu resolvi isso com export CXX="distcc g++".


1

Se você estiver usando cmake e pthreads, tente adicionar as seguintes linhas

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})

0

O mesmo aconteceu comigo quando eu estava instalando o benchmark HPCC (inclui HPL e alguns outros benchmarks). Eu adicionei -lmaos sinalizadores do compilador no meu script de compilação e, em seguida, ele foi compilado com êxito.


3
Isso não responde a essa pergunta específica nem fornece uma resposta geral para uma família de problemas semelhantes. Esta é uma resposta altamente localizada para outra pergunta inteiramente .
Hermann Döppes

0

Se usar g++, certifique-se de que você não está executando gccvez


3
Por quê? Você poderia elaborar um pouco?
Ivan Ivković

@ IvanIvković bem, gcc é o compilador C, g ++ é o compilador C ++. Enquanto C ++ pode compilar C, gcc não pode compilar C ++.
Jean-Marc Zimmer

0

Tente adicionar -pthreadno final da lista da biblioteca no Makefile .

Funcionou para mim.


0

Se você estiver usando o CMake, existem algumas maneiras de resolvê-lo:

Solução 1: A mais elegante

add_executable(...)
target_include_directories(...)
target_link_libraries(target_name pthread)

Solução 2: usando o CMakefind_package

find_package(Threads REQUIRED) # this will generate the flag for CMAKE_THREAD_LIBS_INIT

add_executable(...)
target_include_directories(...)
target_link_libraries(target_name ${CMAKE_THREAD_LIBS_INIT})

Solução 3: Alterar sinalizadores do CMake

# e.g. with C++ 17, change to other version if you need
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pthread")
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.