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

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

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



답변

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

 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


답변

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

우분투 소스 :

/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는 동적 공유 객체 또는 공유 라이브러리입니다.


답변

배경

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전달해도 효과가 있습니다.


답변

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

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

/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. 동적 라이브러리가 발견되면 선호되며 정적 라이브러리는 컴파일러 옵션으로 만 시행 할 수 있습니다. 그게 전부입니다. 그리고 위와 같은 문제가 있는지 여부는 정적 라이브러리인지 동적 라이브러리인지에 따라 다릅니다.
  • 글쎄, 때로는 동적 라이브러리에서 종속성이 부족할 수 있습니다.

답변

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

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


답변

나도 같은 문제가 발생했습니다. 이유를 모르겠습니다 -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


답변

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

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

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