.so

2017-01-25 1 views
0

의 컴파일 및 연결 후 런타임에 "심볼 검색 오류"가 발생했습니다. 먼저이 코드를 검색하여 같은 상황에서 질문을 찾을 수 없었습니다..so

저는 64 비트 컴퓨터에서 32 비트 플러그인을 공유 객체로 만들고 cpp-redis을 사용하고 있습니다. cpp-redis가 잘 빌드되었고 cmake toolchain을 사용하여 32 비트를 강제 실행하고 빌드하는 동안 .o 파일을 검사하여 32 비트임을 확인했습니다.

내 기본 프로그램 (하나의 기본 소스 파일과 내 호스트 응용 프로그램과의 대화를위한 별도의 lib로 구성)이 컴파일 및 연결되었습니다. 호스트 응용 프로그램에 플러그인을로드 실행시

는, 나는 맞이하고있다 : 나는 CPP-레디 스 DIR -L과 함께 링커 경로에 추가 한 나는 꽤 난처한 상황에 빠진거야

symbol lookup error: plugins/samp-redis.so: undefined symbol: _ZN9cpp_redis16redis_subscriberC1ERKSt10shared_ptrINS_7network10io_serviceEE 

-l와 라이브러리, 여기 내 완/링크 라인이다 :

오류없이 잘 실행

g++ -fpermissive -fPIC -m32 -std=c++11 -c -O3 -w -D LINUX -I$(SDK_DIR) -I$(SDK_DIR)/amx -I/usr/local/include/cpp_redis (source .cpp files...) 
g++ -v -Wall -O2 -m32 -fshort-wchar -s -shared -L/usr/local/lib/ -lcpp_redis -o $(OUTFILE) *.o 

(SDK_DIR는이 .c/h의 파일을 내 호스트 응용 프로그램 SDK를, 아주 작은 최소한의 집합입니다) 링크 스테이그를 봤어. 플래그를 확인하기 위해 -v를 사용하는 e가 제대로 작동하고 모두 괜찮아 보입니다.

Using built-in specs. 
COLLECT_GCC=g++ 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper 
Target: x86_64-linux-gnu 
Configured with: ../src/configure 
     -v 
     --with-pkgversion='Debian 4.9.2-10' 
     --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs 
     --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ 
     --prefix=/usr 
     --program-suffix=-4.9 
     --enable-shared 
     --enable-linker-build-id 
     --libexecdir=/usr/lib 
     --without-included-gettext 
     --enable-threads=posix 
     --with-gxx-include-dir=/usr/include/c++/4.9 
     --libdir=/usr/lib 
     --enable-nls 
     --with-sysroot=/ 
     --enable-clocale=gnu 
     --enable-libstdcxx-debug 
     --enable-libstdcxx-time=yes 
     --enable-gnu-unique-object 
     --disable-vtable-verify 
     --enable-plugin 
     --with-system-zlib 
     --disable-browser-plugin 
     --enable-java-awt=gtk 
     --enable-gtk-cairo 
     --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre 
     --enable-java-home 
     --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 
     --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 
     --with-arch-directory=amd64 
     --with-ecj-jar=/usr/share/java/eclipse-ecj.jar 
     --enable-objc-gc 
     --enable-multiarch 
     --with-arch-32=i586 
     --with-abi=m64 
     --with-multilib-list=m32,m64,mx32 
     --enable-multilib 
     --with-tune=generic 
     --enable-checking=release 
     --build=x86_64-linux-gnu 
     --host=x86_64-linux-gnu 
     --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 4.9.2 (Debian 4.9.2-10) 
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/ 
    :/usr/lib/gcc/x86_64-linux-gnu/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/ 
    :/usr/lib/gcc/x86_64-linux-gnu/ 
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/32/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/ 
    :/lib/../lib32/ 
    :/usr/lib/../lib32/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../ 
    :/lib/ 
    :/usr/lib/ 
COLLECT_GCC_OPTIONS='-v' '-Wall' '-O2' '-m32' '-fshort-wchar' '-s' '-shared' '-L/usr/local/lib/' '-o' 'samp-redis.so' '-shared-libgcc' '-mtune=generic' '-march=i586' 
/usr/lib/gcc/x86_64-linux-gnu/4.9/collect2 
    -plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so 
    -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper 
    -plugin-opt=-fresolution=/tmp/cc0Lo5po.res 
    -plugin-opt=-pass-through=-lgcc_s 
    -plugin-opt=-pass-through=-lc 
    -plugin-opt=-pass-through=-lgcc_s 
    --sysroot=/ 
    --build-id 
    --eh-frame-hdr 
    -m elf_i386 
    --hash-style=gnu 
    -shared 
    -o samp-redis.so 
    -s /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/32/crtbeginS.o 
    -L/usr/local/lib/ 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/32 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32 
    -L/lib/../lib32 
    -L/usr/lib/../lib32 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. 
    -lcpp_redis amxplugin2.o amxplugin.o main.o 
    -lstdc++ 
    -lm 
    -lgcc_s 
    -lc 
    -lgcc_s /usr/lib/gcc/x86_64-linux-gnu/4.9/32/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/crtn.o 

나는 연결 단계를 오해하거나 정적으로 연결하는 건가요 (가독성을위한 몇 줄 바꿈을 추가)? 내가 C++을한지 오래되었습니다. 저는 요즘 파이썬과 Go에 관한 모든 것입니다!


편집 :이 출력 -W,--no-undefined 결과

컴파일 :

Using built-in specs. 
COLLECT_GCC=g++ 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper 
Target: x86_64-linux-gnu 
Configured with: ../src/configure 
    -v 
    --with-pkgversion='Debian 4.9.2-10' 
    --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs 
    --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ 
    --prefix=/usr 
    --program-suffix=-4.9 
    --enable-shared 
    --enable-linker-build-id 
    --libexecdir=/usr/lib 
    --without-included-gettext 
    --enable-threads=posix 
    --with-gxx-include-dir=/usr/include/c++/4.9 
    --libdir=/usr/lib 
    --enable-nls 
    --with-sysroot=/ 
    --enable-clocale=gnu 
    --enable-libstdcxx-debug 
    --enable-libstdcxx-time=yes 
    --enable-gnu-unique-object 
    --disable-vtable-verify 
    --enable-plugin 
    --with-system-zlib 
    --disable-browser-plugin 
    --enable-java-awt=gtk 
    --enable-gtk-cairo 
    --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre 
    --enable-java-home 
    --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 
    --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 
    --with-arch-directory=amd64 
    --with-ecj-jar=/usr/share/java/eclipse-ecj.jar 
    --enable-objc-gc 
    --enable-multiarch 
    --with-arch-32=i586 
    --with-abi=m64 
    --with-multilib-list=m32,m64,mx32 
    --enable-multilib 
    --with-tune=generic 
    --enable-checking=release 
    --build=x86_64-linux-gnu 
    --host=x86_64-linux-gnu 
    --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 4.9.2 (Debian 4.9.2-10) 
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/ 
    :/usr/lib/gcc/x86_64-linux-gnu/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/ 
    :/usr/lib/gcc/x86_64-linux-gnu/ 
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/32/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/ 
    :/lib/../lib32/ 
    :/usr/lib/../lib32/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/ 
    :/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../ 
    :/lib/ 
    :/usr/lib/ 
COLLECT_GCC_OPTIONS='-v' '-Wall' '-O2' '-m32' '-fshort-wchar' '-s' '-shared' '-L/usr/local/lib/' '-o' 'samp-redis.so' '-shared-libgcc' '-mtune=generic' '-march=i586' 
/usr/lib/gcc/x86_64-linux-gnu/4.9/collect2 
    -plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so 
    -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper 
    -plugin-opt=-fresolution=/tmp/ccOq8qY8.res 
    -plugin-opt=-pass-through=-lgcc_s 
    -plugin-opt=-pass-through=-lc 
    -plugin-opt=-pass-through=-lgcc_s 
    --sysroot=/ 
    --build-id 
    --eh-frame-hdr 
    -m elf_i386 
    --hash-style=gnu 
    -shared 
    -o samp-redis.so 
    -s /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/32/crtbeginS.o 
    -L/usr/local/lib/ 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/32 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32 
    -L/lib/../lib32 
    -L/usr/lib/../lib32 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. 
    -Bstatic 
    --no-undefined 
    -lcpp_redis amxplugin.o amxplugin2.o main.o 
    -lstdc++ 
    -lm 
    -lgcc_s 
    -lc 
    -lgcc_s /usr/lib/gcc/x86_64-linux-gnu/4.9/32/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib32/crtn.o 
/usr/bin/ld: cannot find 
    -lgcc_s 
/usr/bin/ld: cannot find 
    -lgcc_s 
collect2: error: ld returned 1 exit status 
makefile:15: recipe for target 'build' failed 
make: *** [build] Error 1 

분명히 그것은 그 무엇이든 gcc_s를 찾을 수 있습니까? s = 정적?

$ sudo /sbin/ldconfig -p | grep libgcc 
    libgccpp.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libgccpp.so.1 
    libgcc_s.so.1 (libc6,x32) => /usr/libx32/libgcc_s.so.1 
    libgcc_s.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libgcc_s.so.1 
    libgcc_s.so.1 (libc6) => /usr/lib32/libgcc_s.so.1 

이는 이유가 될 수 없습니다 :

$ find /usr/ -name libgcc* 
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc_s.so 
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc_eh.a 
/usr/lib/gcc/x86_64-linux-gnu/4.9/x32/libgcc_s.so 
/usr/lib/gcc/x86_64-linux-gnu/4.9/x32/libgcc_eh.a 
/usr/lib/gcc/x86_64-linux-gnu/4.9/x32/libgcc.a 
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc.a 
/usr/lib/gcc/x86_64-linux-gnu/4.9/32/libgcc_s.so 
/usr/lib/gcc/x86_64-linux-gnu/4.9/32/libgcc_eh.a 
/usr/lib/gcc/x86_64-linux-gnu/4.9/32/libgcc.a 
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc_s_32.so 
/usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc_s_x32.so 
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_s.so 
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_eh.a 
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.a 
/usr/lib/x86_64-linux-gnu/libgccpp.so.1 
/usr/lib/x86_64-linux-gnu/libgccpp.so.1.0.3 

아직 libgcc.so.1라는 이름의 파일을 ldconfig를 검색을 보여줍니다 일 :

나는 GCC libs와 검색을 시도?

내가 파고하겠습니다 때문에 오류를 인터넷 검색을하면 어떤 결과를 불러옵니다 ...

+0

기본적으로 g ++은 공유 라이브러리를 빌드 할 때 확인되지 않은 기호를 가질 수 있으며 런타임시 표시됩니다. 공유 라이브러리를 "-Wl, --no-undefined"로 링크하여 모든 심볼을 명시 적으로 강제로 지정하십시오. 예 : 연결할 추가 라이브러리가 없습니다. – axalis

+0

Btw. 심볼이 cpp_redis 라이브러리에서 오는 것 같습니다. 응용 프로그램이 실행 중일 때 라이브러리가 LD_LIBRARY_PATH (또는 Windows의 PATH에있는 것 같습니다)에 있는지 확인하십시오. 플러그인을 실행하면 cpp_redis 라이브러리를 찾아로드 할 수없는 것일 수 있습니다. – axalis

+0

@axalis 감사합니다! g ++에서 미해결 된 기호를 허용하는 부분은 내가 궁금해했고 설명서에서 찾을 수없는 부분이었습니다. 나중에 링크 문단이 잘 돌아 갔지만 런타임이 잘 돌아 가지 않는 이유에 대해 혼란 스러웠다. – Southclaws

답변

0

당신은 -fPIC 플래그, 즉 컴파일해야이 공유 라이브러리와 연결 가능 수 있으려면 정적 라이브러리로 cpp_redis를 구축하더라도 코드는 재배치 가능해야합니다. 링커는 공유 라이브러리를 링크 할 때 호환되지 않는 코드를 자동으로 무시합니다. .so 파일로 nm을 실행하여 cpp_redis의 기호가 플러그인으로 해석되었는지 확인할 수 있습니다.

업데이트에 따르면 플러그인을 -W,--no-undefined (cpp_redis 아님)과 연결해야합니다. 아마 호스트 프로그램의 심볼이 누락되어 실패 할 것입니다. 그러나 cpp_redis의 기호가 누락 되었는지 여부를 확인할 수 있습니다.

+0

실행 파일로 .so를로드하는 호스트 응용 프로그램을 의미하는 경우이를 제어 할 수 없습니다. – Southclaws

+0

그런 실행 파일은 플러그인과 함께 사용되지 않습니다. 이 특정 문제를 고치더라도 플러그인은 실행 파일 자체에 정의 된 기능이 누락되며 라이브러리는 누락됩니다. – Slava

+0

나는 무엇을 의미하는지 완전히 모르겠다. 호스트 프로그램은 수년간 존재 해왔고 다양한 플러그인을 이용할 수있다. 만약 당신이 내 앱에 cpp-redis 코드를 컴파일 할 수 없다고 말하는 것이라면, 사용자들에게 내 플러그인 권리와 함께 cpp-redis를 설치하라고 지시해야만 할 것 같습니까? – Southclaws