Ubuntu链接器在链接共享库时未解析符号

Ubuntu链接器在链接共享库时未解析符号,ubuntu,gcc,linker,Ubuntu,Gcc,Linker,我正在使用libturbojpeg的一些基本Python绑定,我想在我的一个项目中使用。在Debian(sid)中,一切都能完美工作,但在使用Ubuntu(trusty)构建项目时,链接器显然无法正确解析符号 代码库在这里make _pytj.所以应该可以做到这一点,它可以在Debian上运行(它使用SWIG生成C代码,将其与我的其他自定义代码编译,然后链接)。生成的库\u pytj.so具有所有正确的依赖项 相反,在Ubuntu上生成的库缺少依赖项: $ ldd _pytj.so linux-

我正在使用libturbojpeg的一些基本Python绑定,我想在我的一个项目中使用。在Debian(sid)中,一切都能完美工作,但在使用Ubuntu(trusty)构建项目时,链接器显然无法正确解析符号

代码库在这里<代码>make _pytj.所以应该可以做到这一点,它可以在Debian上运行(它使用SWIG生成C代码,将其与我的其他自定义代码编译,然后链接)。生成的库
\u pytj.so
具有所有正确的依赖项

相反,在Ubuntu上生成的库缺少依赖项:

$ ldd _pytj.so
linux-vdso.so.1 =>  (0x00007fff968e2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f12229d8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1222fe0000)
(它也应该依赖于turbojpeg和Python库)

当然,如果我尝试导入生成的模块,python解释器会抱怨未解析的符号

如果我将
-Wl,-z,defs
添加到链接编译行:

$ gcc -shared -o _pytj.so `python-config --libs` -lturbojpeg _pytj.o  _pytj_wrap.o -Wl,-z,defs 2>&1 | head
_pytj.o: In function `create_tjcontext':
_pytj.c:(.text+0x17): undefined reference to `tjInitCompress'
_pytj.c:(.text+0x23): undefined reference to `tjInitDecompress'
_pytj.o: In function `free_tjcontext':
_pytj.c:(.text+0x4c): undefined reference to `tjDestroy'
_pytj.c:(.text+0x5c): undefined reference to `tjDestroy'
_pytj.o: In function `encode_image':
_pytj.c:(.text+0xf7): undefined reference to `tjCompress2'
_pytj.o: In function `free_encoded_image':
_pytj.c:(.text+0x128): undefined reference to `tjFree'
显然,链接器理解我链接到指定库的请求。正如我所说,Debian sid中的同一命令行工作得非常好

我错过了什么

编辑如果使用另一个命令行(如注释中所建议的),则会出现另一个错误:

$ gcc -shared -o _pytj.so _pytj.o _pytj_wrap.o `python-config --libs` -lturbojpeg -Wl,-z,defs 2>&1 | head
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libturbojpeg.a(libturbojpeg_la-turbojpeg.o): relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libturbojpeg.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status

然而,我的理解是,带有
-l
的库必须在使用它们的对象之前指出。

链接器有时很难做到“恰到好处”。尝试将库放在要链接的对象之后(即,运行
gcc-shared-o_pytj.so_pytj.o_pytj_wrap.o`python config--libs`-lturbojpeg-Wl,-z,defs 2>&1 | head
@slugonamission不起作用,请参见编辑。无论如何,谢谢。错误消息非常清楚,甚至建议采取措施解决此问题:使用-fPIC重新编译libturbojpeg。共享库中的代码必须独立于位置。)ent,因为加载的库的基址事先不知道。@NickZavaritsky但是为什么gcc会忽略原始参数顺序中的库?如果我链接的是一个可执行文件而不是另一个共享库,为什么我可以链接到turbojpeg?@giomasce链接器没有忽略库;观察到的行为是由符号引起的解析算法。基本上,如果命令行上的第N项需要foo,则只搜索后续项以查找foo。但在您的情况下,在请求foo的对象之前提供foo apears的库。可执行文件不需要与位置无关,这就是为什么在构建可执行文件时可以链接您的turbojpeg变体的原因。