奇怪的链接器问题“重定位R_X86_64_32” - 不是典型的-fPIC问题

时间:2014-11-03 00:38:43

标签: gcc dll linker-errors g++4.8

尝试在Ubuntu 14.04(64)上创建胖共享库时,我遇到了一个奇怪的问题。如果您忘记添加-fPIC或链接到错误的体系结构库,则通常会收到错误消息:

/usr/bin/ld: /usr/lib/libproj.a(pj_init.o): relocation R_X86_64_32 against 
`.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/usr/lib/libproj.a: error adding symbols: Bad value

第一个静态库编译如下:

gcc -c -fPIC -m64 NativeDB.c 

之后应该创建一个胖的共享库,使用上面的库以及其他几个(spatialite,proj4,geos,sqlite),如下所示:

gcc -shared -fPIC -m64 -o $@ $(OUT_DIR)/NativeDB.o $(OUT_DIR)/sqlite3.o $(SPATIALITE_DIR)/src/.libs/libspatialite.a $(SOME_OTHER_LIBS) 

将NativeDB.o链接到共享库会引发提到的链接器错误。另请注意,可以在没有NativeDB.o的情况下创建共享库。所以这里变得很奇怪,因为你在上面看到了如何编译NativeDB.o并且没有添加额外的(隐式)链接。

观察:

1)正确编译所有库。我验证了例如libproj包含重定位信息并且是正确的架构(通过objdump -f):

...
pj_initcache.o:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
...

我自己的NativeDB.o文件也是如此。

2)当gcc创建的lib被遗忘时,共享库被创建得很好(当然没有我的库......)。

3)我最好的猜测是,当从包含32位.text段的静态库创建共享库时,问题来自gcc的奇怪之处:<​​/ p>

In archive target/libspatialite-4.2.1-rc0/src/.libs/libspatialite.a:

version.o:     file format elf64-x86-64

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE 
0000000000000001 R_X86_64_32       spatialiteversion
0000000000000011 R_X86_64_32       spatialitetargetcpu
...
RELOCATION RECORDS FOR [.debug_info]:
OFFSET           TYPE              VALUE 
...
0000000000000307 R_X86_64_32       .debug_str+0x0000000000000256
0000000000000313 R_X86_64_64       spatialiteversion
0000000000000331 R_X86_64_32       .debug_str+0x000000000000022d
000000000000033d R_X86_64_64       spatialitetargetcpu

我已经使用一个以前失败的库(libspatialite.a中的version.o)进行了一些实验。瞧 - 它修复了这个库的链接问题:

mv version.o version_org.o
objcopy -O elf64-x86-64 target/libspatialite-4.2.1-rc0/src/.libs/version_org.o version64.o
# delete version.o from archive
ar -d libspatialite.a version.o
# add 64 bit version.o
ar -r libspatialite.a version.o

到目前为止的结论:

对我来说,这似乎是一个gcc编译器。我希望有一个解决方法,我正在尝试做什么。 顺便说一下,相同的代码库(具有相似但不相同的依赖关系)在OS X上使用clang和build作为dynamiclib可以正常工作。它并没有说太多,但代码库可能没有错。

在回答之前请注意:

显而易见的答案是说我应该以另一种方式捆绑我的东西。但由于某些原因,我真的想使用(JNI加载,库大小等)创建一个胖共享库。

如果你能与我分享你对这个的编译器见解并帮助我解决它,我会很高兴的。

更新1

删除了对g ++的引用。该问题以与使用gcc相同的方式发生。我以前考虑过gcc vs g ++问题。

1 个答案:

答案 0 :(得分:0)

使用eclipse构建时遇到了同样的错误: 尝试使用“-shared”(gcc c链接器 - >共享库设置 - >共享)编译可执行构建,导致此错误。删除共享选项后,它解决了此问题。 由于某种原因,当从“可删除”更改为“静态库”构建在eclipse中时,“-shared”仍然存在,这就是为什么它在我的情况下失败了。 “-shared”选项只需要保留库构建。

希望它可以帮助任何人,