运行时"符号查找错误"编译和链接后.so

时间:2017-01-25 09:30:45

标签: c++ g++ static-linking

首先,我已经搜索了一下这个问题并且没有设法找到具有相同情况的问题。

我在64位计算机上使用cpp-redis构建一个32位插件作为共享对象。 cpp-redis构建正常,我使用cmake工具链强制32位,在构建期间检查.o文件并确认它们是32位。

我编译并链接了我的基本程序(由一个主要源文件和一个额外的lib组成,用于与我的主机应用程序通信,因为这是一个插件)。

运行将插件加载到主机应用程序后,我受到了欢迎:

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

我很难过,因为我已经使用-L将cpp-redis目录添加到链接器路径,使用-l将库添加到库中,这里是我的comp / link行:

(SDK_DIR是我的主机应用程序sdk,非常小,最小的.c / h文件集)

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

运行良好且没有错误,我用-v运行链接阶段以检查标志是否正常进入并且一切正常。

(为可读性添加了一些换行符)

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 ++以来已经有一段时间......我现在都在谈论Python和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 =静态?

我尝试搜索gcc libs:

$ 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

然而,执行ldconfig搜索会显示名为libgcc.so.1的文件:

$ 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

这可能是原因吗?

谷歌搜索错误会带来一些结果,所以我会继续挖掘......

1 个答案:

答案 0 :(得分:0)

即使您将cpp_redis构建为静态库以使其可与共享库链接,也必须使用-fPIC标志进行编译,即代码必须是可重定位的。在您的情况下,链接器在链接共享库时默默地忽略不兼容的代码。您可以通过使用.so文件运行nm来检查来自cpp_redis的符号是否已解析到插件中。

根据您的更新,您应该将您的插件与-W,--no-undefined而不是cpp_redis相关联。最有可能它会失败,因为来自主程序的符号会丢失。但是你可以检查来自cpp_redis的符号是否被列为缺失。