libpthread.so.0 : 기호 추가 오류 : 명령 줄에 DSO가 없습니다.


205

openvswitch-1.5.0을 컴파일 할 때 다음 컴파일 오류가 발생했습니다.

 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

의 기호를 보려고하면 libpthread괜찮아 보입니다.

$ 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

힌트 나 조언을 줄 수 있습니까?



link_libraries (pthread)
Alex Punnen

# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf : 오류 : '/lib/x86_64-linux-gnu/libncurses.so'를 찾을 수 없습니다. 시스템 오류 메시지 : 너무 많은 수준의 기호 링크
Ashish Karpe


4
Goddamnit, 나는하지 gcc않았다g++
Post Self

답변:


163

오브젝트 파일이 컴파일 된 명령 행에서 라이브러리를 언급해야합니다 .

 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 

설명 : 연결은 모듈 순서에 따라 다릅니다. 먼저 심볼을 요청한 다음 심볼이있는 라이브러리에서 심볼을 연결합니다. 따라서 라이브러리를 먼저 사용하고 그 뒤에 라이브러리를 사용하는 모듈을 지정해야합니다. 이처럼 :

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

또한 순환 종속성이있는 경우 명령 행에서 동일한 라이브러리를 여러 번 지정해야합니다. 그래서 경우 libb에서 기호를 필요로 libc하고 libc에서 기호 필요 libb, 명령 줄이되어야한다 :

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

23
-Wl,--start-group -la -lb- -lc -Wl,--end-group순환 의존성을 위해 할 수 있다고 생각합니다 .
Z boson

2
이것은 소스 파일에도 적용됩니다. 라이브러리 앞에 나열해야합니다. 명령 행에서 소스 파일을 대체하는 결과 오브젝트 파일을 생각하고 위와 동일한 순서를 적용 할 수 있습니다.
jspencer

make를 사용하여 애플리케이션을 빌드 할 때 -lpthread를 어디에 추가해야합니까?
codezombie

50

오류 메시지는 배포 / 컴파일러 버전에 따라 다릅니다.

우분투 소스 :

/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

우분투 Raring : (보다 유익한)

/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

솔루션 : 연결 단계에서 컴파일 단계에서 라이브러리가 누락되었을 수 있습니다. 필자의 경우 makefile / GCC 플래그에 '-lz'를 추가했습니다.

배경 : DSO는 동적 공유 객체 또는 공유 라이브러리입니다.


1
이 솔루션을 사용하여 LDFLAGS에 -lz를 추가하여 동일한 오류를 발생시키는 다른 프로젝트를 작성했으며 완벽하게 작동했습니다. 감사!
Mark Ellul

/ usr / bin / ld : gaSim.o : 'pthread_create @@ GLIBC_2.1'심볼에 대한 정의되지 않은 참조 /lib/i386-linux-gnu/libpthread.so.0 : 심볼 추가 오류 : DSO 커맨드 라인에서 누락
Aerox

부분적으로 '-lpthread'를 추가하면 해결되었지만 이제는 다음과 같이 표시됩니다. gaSim.c :(. text + 0x11d6) :`glewInit '에 대한 정의되지 않은 참조
Aerox

@Aerox : glewInit필요합니다-lGLEW
mchiasson

19

배경

DSO missing from command line정상 검색입니다하지만 기호가 직접 지정된 동적 라이브러리의 종속성 중 하나에서 사용할 수와 링커가 필요한 기호를 찾을 수없는 경우 메시지가 표시됩니다.

과거에는 링커에서 지정된 언어의 종속성이있는 기호를 사용할 수있는 것으로 간주했습니다. 그러나 일부 이후 버전에서 변경되었으며 이제 링커는 사용 가능한 항목에 대해보다 엄격한보기를 시행합니다. 따라서 메시지는 그러한 전환에 도움을주기위한 것입니다.

무엇을해야합니까?

소프트웨어 관리자 인 경우

필요한 심볼을 충족시키는 데 필요한 모든 라이브러리가 링커 명령 줄에 직접 지정되어 있는지 확인하여이 문제를 해결해야합니다. 또한 순서는 종종 중요하다는 것을 명심하십시오.

소프트웨어를 컴파일하려는 경우

이 문제를 해결하려면 옵션을 사용하여 사용 가능한 기호에 대한보다 허용적인보기로 다시 전환 할 수 있습니다 -Wl,--copy-dt-needed-entries.

이것을 빌드에 삽입하는 일반적인 방법은 다음 configure과 같이 실행하기 전에 LDFLAGS를 내보내는 것입니다.

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

때로는 LDFLAGS="-Wl,--copy-dt-needed-entries"직접 make전달해도 효과가 있습니다.


gcc 버전 7.4.0 (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1)이이 플래그를 인식하지 못했습니다.
UserX

1
gcc 옵션이 아니므로 -Wl,비트 가 누락되었거나이 옵션을 지원하지 않는 링커가 있습니다. 어떤 링커를 사용하고 있습니까? 이 답변은 고전적인 binutils 링커 (ld.bfd)를 가정합니다. binutils 골드 링커 (ld.gold) 문서 --copy-dt-needed-entries는 "지원되지 않음"으로 표시됩니다. 따라서 기본적 으로이 옵션 (또는이 옵션을 지원하지 않는 다른 링커)이있는 경우 유지 관리 자 섹션을 따르거나 링크를 위해 클래식 ld로 전환해야 할 수도 있습니다. 나는 당신이 그것을 사용할 수 있다고 생각합니다 -fuse-ld=ld.bfd.
textshell

14

나는 또 다른 사건을 발견했기 때문에 당신이 모두 틀린 것입니다.

이것이 내가 가진 것입니다 :

/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

문제는 명령 행에 DID가 포함되어 -lX11있지 않다는 것입니다. 비록 libX11.so는 인수에 GTK와 GNOME 라이브러리도 있기 때문에 의존성으로 추가되어야합니다.

따라서 저에게 유일한 설명은이 메시지가 귀하돕기 위한 것일 수도 있지만 제대로 수행되지 않았다는 것입니다. 이것은 아마도 간단했을 것입니다. 심볼을 제공하는 라이브러리는 명령 행에 추가되지 않았습니다.

POSIX의 연계에 관한 세 가지 중요한 규칙에 유의하십시오.

  • 동적 라이브러리는 종속성을 정의 했으므로 최상위 라이브러리의 라이브러리 만 (정적 라이브러리 이후에도) 순서에 상관없이 제공해야합니다.
  • 정적 라이브러리에는 정의되지 않은 기호가 있습니다. 종속성을 파악하고 명령 줄에 모든 것을 제공하는 것은 사용자의 책임입니다.
  • 정적 라이브러리 의 순서 는 항상 : requester first , provider 다음에 있습니다. 그렇지 않으면 명령 줄에 라이브러리를 추가하는 것을 잊었을 때와 같이 정의되지 않은 기호 메시지가 나타납니다.
  • 로 라이브러리를 지정하면을 사용 -l<name>할지 lib<name>.so또는을 알 수 없습니다 lib<name>.a. 동적 라이브러리가 발견되면 선호되며 정적 라이브러리는 컴파일러 옵션으로 만 시행 할 수 있습니다. 그게 전부입니다. 그리고 위와 같은 문제가 있는지 여부는 정적 라이브러리인지 동적 라이브러리인지에 따라 다릅니다.
  • 글쎄, 때로는 동적 라이브러리에서 종속성이 부족할 수 있습니다.

링커는 문제를 해결하기위한 것일뿐 아니라 해당 이름을 확인해야합니다. 오류가 완전히 유효합니다. 컴파일러가 그것을 통과하기로 결정했다면 바이너리 런타임에없는 것에 액세스하기위한 segfault를 얻습니다.
kevr

1
또한 다른 플랫폼에서는 소스가 다르게 컴파일 될 수 있습니다. 한 시스템에 연결된 것이 다른 시스템에 연결되어 있지 않을 수 있습니다. 일반적으로 그렇지는 않지만 100 % 그럴듯합니다.
kevr

문제는 유효하지 않다는 것이 아니라 문제의 원인을 찾는 것이 도움이되지 않는다는 것입니다.
Ethouris

7

나는 같은 오류가 있음을 발견했다. lapack과 blas로 코드를 컴파일하고있었습니다. 두 라이브러리가 호출 된 순서를 전환하면 오류가 사라졌습니다.

"LAPACK_LIB = -llapack -lblas"는 "LAPACK_LIB = -lblas -llapack"에서 위에서 설명한 오류가 발생한 곳에서 작동했습니다.


9
cmake 정의 프로젝트 에서이 오류가 발생합니다 ... Clink에 링커 순서를 잘못하는 버그가 있습니까?
peter karasev

@peterkarasev에 회신 : 사용 시도 find_package(Threads)target_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
activedecay

7

나도 같은 문제가 발생했습니다. 이유를 모르겠습니다 -lpthread. 컴파일러 에 옵션을 추가 하고 모든 것을 확인했습니다.

낡은:

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

다음과 같은 오류가 발생했습니다. -lpthread위의 명령에 옵션을 추가하면 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

이것은 나를 위해 일했다. 링크를 만드는 makefile의 g ++ 명령에 두 번째 "중복"-lpthread를 추가해야했습니다. (이미 makefile의 LIBS 목록에 이미 한 번 나타났습니다.) 또한 makefile의 LDFLAGS 정의에 "-L / lib / x86_64-linux-gnu"를 추가했습니다.
UserX 2016 년

2

내가 찾은 것은 때로는 링커가 불평하는 라이브러리가 문제를 일으키는 라이브러리가 아니라는 것입니다. 아마도 문제가있는 곳을 해결하는 영리한 방법이 있지만 이것이 내가하는 일입니다.

  • link 명령에서 링크 된 모든 라이브러리를 주석 처리하십시오.
  • 모든 .o, .so 등을 정리하십시오 (보통 깨끗하게 충분하지만 재귀 찾기 + rm 또는 이와 유사한 것을 실행하고 싶을 수도 있습니다).
  • link 명령에서 라이브러리를 한 번에 하나씩 주석 해제하고 필요에 따라 순서를 다시 정렬하십시오.

@ peter karasev : CentOS7에서 gcc 4.8.2 cmake 프로젝트와 동일한 문제가 발생했습니다. "target_link_libraries"섹션의 라이브러리 순서가 중요합니다. cmake는 목록을 그대로 링커에 전달합니다. 즉, 올바른 순서를 시도하지 않습니다. 이것은 합리적입니다. 생각할 때 cmake는 연결이 성공적으로 완료 될 때까지 올바른 순서가 무엇인지 알 수 없습니다.



1

distccC ++ 프로젝트를 만들 때도 같은 문제가 발생했습니다 . 마침내 나는 그것을 해결했다 export CXX="distcc g++".


1

cmake 및 사용 된 pthread를 사용하는 경우 다음 행을 추가하십시오.

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})

0

HPCC 벤치 마크 (HPL 및 기타 몇 가지 벤치 마크 포함)를 설치할 때와 같은 일이 일어났습니다. -lm빌드 스크립트에서 컴파일러 플래그에 추가 한 후 성공적으로 컴파일되었습니다.


3
이것은이 특정 질문에 대답하거나 비슷한 문제의 가족에 대한 일반적인 대답을 제공하지 않습니다. 이것은 다른 질문에 대한 고도로 지역화 된 답변입니다 .
Hermann Döppes

0

를 사용하는 경우 대신 g++실행 중이 아닌지 확인하십시오.gcc


3
왜? 좀 더 자세히 설명해 주시겠습니까?
Ivan Ivković

@ IvanIvković 글쎄, gcc는 C 컴파일러이고, g ++는 C ++ 컴파일러이다. C ++는 C를 컴파일 할 수 있지만 gcc는 C ++를 컴파일 할 수 없습니다.
Jean-Marc Zimmer

0

Makefile-pthread 의 라이브러리 목록 끝에 추가하십시오 .

그것은 나를 위해 일했다.


0

CMake를 사용하는 경우이를 해결할 수있는 몇 가지 방법이 있습니다.

해결책 1 : 가장 우아한 것

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

해결 방법 2 : CMake 사용find_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})

해결 방법 3 : 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")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.