libpthread.so.0: sembol ekleme hatası: DSO komut satırında eksik


205

Openvswitch-1.5.0'ı derlerken, aşağıdaki derleme hatasıyla karşılaştım:

 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

Eğer sembollerini görmeye çalışırsam libpthreadiyi görünüyor.

$ 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

Herhangi bir ipucu veya işaret verebilir misiniz?



link_libraries (pthread)
Alex Punnen

# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf: Hata: '/lib/x86_64-linux-gnu/libncurses.so' bulunamadı. Sistem hata mesajı: Çok fazla sayıda sembolik bağlantı
Ashish Karpe


4
Lanet olsun, ben yaptım gccdeğilg++
Mesaj Öz

Yanıtlar:


165

Derlenen nesne dosyalarının ardından komut satırında kütüphaneden bahsetmelisiniz :

 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 

Açıklama: bağlantı, modüllerin sırasına bağlıdır. Semboller önce istenir ve daha sonra bunlara sahip bir kütüphaneden bağlanır. Bu yüzden önce kütüphaneleri, sonra da kütüphaneleri kullanan modülleri belirtmelisiniz. Bunun gibi:

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

Ayrıca, dairesel bir bağımlılık olması durumunda, aynı kitaplığı komut satırında birkaç kez belirtmeniz gerekir. Dolayısıyla, libbsimgeden sembol gerekiyorsa libcve libcsimgeden sembol gerekiyorsa libb, komut satırı şöyle olmalıdır:

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

24
-Wl,--start-group -la -lb- -lc -Wl,--end-groupDairesel bağımlılıklar için yapabileceğinizi düşünüyorum .
Z bozon

2
Bunun kaynak dosyalar için de geçerli olduğunu unutmayın - bunlar kitaplıklardan önce listelenmelidir. Elde edilen nesne dosyalarını komut satırında yer alan kaynak dosyaları düşünebilir ve yukarıdakiyle aynı sırayı uygulayabilirsiniz.
jspencer

Bir uygulama oluşturmak için make kullanılırken -lpthread eklenmelidir?
codezombie

50

Hata mesajı dağıtım / derleyici sürümüne bağlıdır:

Ubuntu Şımarık:

/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: (daha bilgilendirici)

/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

Çözüm: Bağlama aşamasında derleme adımlarınızda bir kütüphane eksik olabilir. Benim durumumda, makefile / GCC bayraklarına '-lz' ekledim.

Arka plan: DSO, dinamik bir paylaşılan nesne veya paylaşılan bir kitaplıktır.


1
Bu çözümü LDFLAGS'a -lz ekleyerek aynı hatayı veren başka bir proje oluşturmak için kullandım ve mükemmel çalıştı. Teşekkürler!
Mark Ellul

Hata hala benim için kalıyor: / usr / bin / ld: gaSim.o: 'pthread_create @@ GLIBC_2.1' / lib/i386-linux-gnu/libpthread.so.0 sembolüne tanımsız başvuru: DSO komut satırında eksik
Aerox

Kısmen '-lpthread' ekleyerek çözüldü, ama şimdi bana gösteriyor: gaSim.c :(. Text + 0x11d6): 8:53'te `` glewInit ''
Aerox

1
@Aerox: için glewInit, ihtiyacınız-lGLEW
mchiasson

19

Arka fon

DSO missing from command lineNormal arama ama sembol bir doğrudan belirtilen dinamik kütüphane bağımlılıkları birinde kullanılabilir ile bağlayıcı gerekli sembol bulamazsa zaman mesajı görüntülenecektir.

Geçmişte bağlayıcı, belirtilen dillerin bağımlılıklarındaki sembolleri kullanılabilir olarak değerlendiriyordu. Ancak bu daha sonraki bazı sürümlerde değişti ve şimdi bağlayıcı mevcut olanların daha katı bir görünümünü uygulamaktadır. Bu nedenle mesajın bu geçişe yardımcı olması amaçlanmıştır.

Ne yapalım?

Yazılımın bakıcısıysanız

Gerekli sorunları karşılamak için gereken tüm kitaplıkların doğrudan linker komut satırında belirtildiğinden emin olarak bu sorunu çözmelisiniz. Ayrıca, siparişin genellikle önemli olduğunu unutmayın.

Sadece yazılımı derlemeye çalışıyorsanız

Çözüm olarak, seçeneği kullanarak hangi sembollerin kullanılabilir olduğuna dair daha izinli görünüme geri dönmek mümkündür -Wl,--copy-dt-needed-entries.

Bunu bir yapıya enjekte etmenin yaygın yolları LDFLAGS'ı çalıştırmadan configureveya buna benzer bir şeyden önce dışa aktarmaktır :

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

Bazen LDFLAGS="-Wl,--copy-dt-needed-entries"doğrudan geçmek makede işe yarayabilir.


gcc sürüm 7.4.0 (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) bu bayrağı tanımadı.
UserX

1
Bu bir gcc seçeneği değil, bu yüzden ya -Wl,biraz eksik ya da bu seçenekleri desteklemeyen bir bağlayıcınız var. Hangi bağlayıcıyı kullanıyorsunuz? Bu yanıt, klasik binutils bağlayıcısını (ld.bfd) varsayar. Binutils gold linker (ld.gold) --copy-dt-needed-entries"Desteklenmiyor" olarak belgelenir . Dolayısıyla, varsayılan olarak (veya bu seçeneği desteklemeyen başka bir bağlayıcıya) sahipseniz, koruyucular için bölümü izlemeniz veya bağlantı için klasik ld'ye geçmeniz gerekebilir. Bunun -fuse-ld=ld.bfdiçin kullanabileceğinizi düşünüyorum .
textshell

14

Başka bir dava buldum ve bu yüzden hepinizin yanlış olduğunu düşünüyorum.

Ben vardı:

/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

Sorun, komut satırı DID NOT içermiyor -lX11- libX11.so bağımlılık olarak eklenmelidir, ancak bağımsız değişkenlerde GTK ve GNOME kitaplıkları da vardı.

Yani, benim için tek açıklama, bu mesajın size yardımcı olması amaçlanmış olabilir , ancak düzgün bir şekilde yapmadı. Bu muhtemelen basitti: sembolü sağlayan kütüphane komut satırına eklenmedi.

POSIX'te bağlantı ile ilgili üç önemli kurala dikkat edin:

  • Dinamik kitaplıklar bağımlılıkları tanımlamıştır, bu nedenle yalnızca üst bağımlılıktan olan kitaplıklar hangi sırada olursa olsun sağlanmalıdır (statik kitaplıklardan sonra olsa da)
  • Statik kütüphanelerin tanımsız sembolleri vardır - bağımlılıklarını bilmek ve hepsini komut satırına sağlamak size kalmış
  • Statik kitaplıklardaki sıra her zaman: önce istekte bulunan , sağlayıcı bunu takip eder . Aksi takdirde, kütüphaneyi komut satırına eklemeyi unuttuğunuzda olduğu gibi tanımlanmamış sembol mesajı alırsınız
  • Birlikte kütüphane belirlediğinizde -l<name>, bunu alıp almayacağını da asla bilemezsiniz lib<name>.soya lib<name>.a. Dinamik kütüphane bulunursa tercih edilir ve statik kütüphaneler yalnızca derleyici seçeneği ile uygulanabilir - hepsi bu. Ve yukarıdaki gibi herhangi bir sorununuz varsa, statik veya dinamik kütüphanelerinizin olup olmadığına bağlıdır.
  • Dinamik kütüphanelerde bazen bağımlılıklar eksik olabilir: D

Sadece size yardımcı olmakla kalmaz, bağlayıcı tarafından söz konusu isimleri çözmesi gerekir. Hata tamamen geçerlidir. Derleyici buna izin vermeye karar verirse, ikili çalışma zamanında olmayan bir şeye erişmek için bir segfault elde edersiniz.
kevr

1
Eklemek için, farklı platformlarda, kaynağın farklı şekilde derlenmesi mümkündür; bir sisteme bağlı olan başka bir sisteme bağlı olmayabilir. Bu genellikle böyle değildir, ancak% 100 mantıklıdır.
kevr

Sorun, geçerli olmadığı değil, sorunun nedenini bulmak için tam olarak yararlı olmadığıdır.
Ethouris

7

Aynı hataya sahip olduğumu fark ettim. Hem lapack hem de blas ile bir kod derliyordum. İki kütüphanenin çağrılma sırasını değiştirdiğimde hata ortadan kalktı.

"LAPACK_LIB = -llapack -lblas" çalıştı, burada "LAPACK_LIB = -lblas -llapack" yukarıda açıklanan hatayı verdi.


9
Cmake tanımlı bir projede bu hatayı alıyorum ... yani Cmake'de linker sırasını yanlış koyan bir hata var mı?
peter karasev

@peterkarasev adlı kişiye yanıt olarak: kullanmayı deneyin find_package(Threads)vetarget_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
activedecay

7

Aynı problemle de karşılaştım. Neden bilmiyorum, ben sadece -lpthreadderleyici seçeneği ve her şey tamam ekleyin .

Eski:

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

aşağıdaki hatayı aldım. -lpthreadYukarıdaki komuta seçenek eklerseniz Tamam'ı tıklayın.

/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

Bu benim için çalıştı; Ben bağlantı yapan makefile g ++ komutuna ikinci bir "artık" -lpthread eklemek zorunda kaldı. (Zaten bir kez makefile LIBS listesinde göründü.) Ben de makefile LDFLAGS tanımına "-L / lib / x86_64-linux-gnu" ekledi.
UserX

2

Ne buldum bazen linker şikayet şikayet kütüphanesi soruna neden olan değil. Muhtemelen sorunun nerede olduğunu anlamanın akıllı bir yolu var ama yaptığım şey bu:

  • Link komutundaki tüm bağlı kütüphaneleri yorumlayın.
  • Tüm .o, .so's vs temizlemek (Genellikle temiz yapmak yeterlidir, ancak yinelemeli bir bulma + rm veya benzer bir şey çalıştırmak isteyebilirsiniz).
  • Link komutundaki kütüphaneleri birer birer açın ve siparişi gerektiği gibi yeniden düzenleyin.

@peter karasev: CentOS7'deki bir gcc 4.8.2 cmake projesiyle aynı problemle karşılaştım. "Target_link_libraries" bölümündeki kitaplıkların sırası önemlidir. Sanırım cmake sadece listeyi olduğu gibi linker'e aktarır, yani doğru sırayı denemeye çalışmaz. Bu makul - bunu düşündüğünüzde, bağlantı başarıyla tamamlanana kadar doğru siparişin ne olduğunu bilemezsiniz.



1

Aynı sorun distccbenim c ++ projemi yapmak için kullandığımda oldu; Sonunda çözdüm export CXX="distcc g++".


1

cmake ve pthreads kullanıyorsanız, aşağıdaki satırları eklemeyi deneyin

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})

0

Aynı şey, HPCC karşılaştırmasını (HPL ve diğer birkaç ölçütü de içerir) yüklerken başıma geldi. -lmDerleme komut dosyama derleme bayraklarına ekledim ve sonra başarıyla derlendi.


3
Bu ne bu özel soruyu cevaplar ne de benzer sorunlara sahip bir aileye genel bir cevap vermez. Bu tamamen başka bir soru için son derece yerelleştirilmiş bir cevaptır .
Hermann Döppes

0

Kullanıyorsanız g++, gccbunun yerine çalışmadığınızdan emin olun


3
Neden? Biraz ayrıntı verebilir misiniz?
Ivan Ivković

@ IvanIvković iyi, gcc C derleyicisi, g ++ C ++ derleyicisi. C ++ C derleyebilirken, gcc C ++ derleyemez.
Jean-Marc Zimmer

0

Makefile'deki-pthread kütüphane listesinin sonuna eklemeyi deneyin .

Benim için çalıştı.


0

CMake kullanıyorsanız, bunu çözmenin bazı yolları vardır:

Çözüm 1: En Zarif çözüm

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

Çözüm 2: CMake'i Kullanmafind_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})

Çözüm 3: CMake bayraklarını değiştirin

# 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")
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.