Gcc “奇数链接器问题”;重新定位R_X86_64_32,以防不是典型的fPIC问题

Gcc “奇数链接器问题”;重新定位R_X86_64_32,以防不是典型的fPIC问题,gcc,dll,linker-errors,g++4.8,Gcc,Dll,Linker Errors,G++4.8,在Ubuntu 14.04(64)上创建fat共享库时,我遇到了一个奇怪的问题。如果忘记添加-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

在Ubuntu 14.04(64)上创建fat共享库时,我遇到了一个奇怪的问题。如果忘记添加-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)创建一个fat共享库,如下所示:

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

意见:

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

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

2) 如果不使用gcc创建的库,那么共享库就可以很好地创建(当然没有我的库…)

3) 我最好的猜测是,当从包含32位的静态库创建共享库时,gcc的一个奇怪之处导致了这个问题。文本部分:

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
迄今为止的结论:

对我来说,这似乎是一件怪事。我希望有一个变通的办法来解决我正在尝试做的事情。 顺便说一下,相同的代码库(具有相似但不相同的依赖项)在OSX上使用clang和build as dynamiclib可以很好地工作。这说明不了什么,但代码库可能没有错

回答前请注意:

显而易见的答案是,我应该用另一种方式打包我的东西。但出于特定的原因,我确实希望使用(JNI加载、库大小等)创建一个fat共享库

如果你能与我分享你对这个问题的编译器见解并帮助我解决它,我将非常高兴

更新1


删除了对g++的引用。仅使用gcc时,问题以相同的方式出现。我以前考虑过gcc与g++的问题。

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


希望它能帮助任何人,

在这行
gcc-shared-fPIC**.m64**-o$@$(OUT\u DIR)/NativeDB.o$(OUT\u DIR)/sqlite3.o$(SPATIALITE\u DIR)/src/.libs/libspatialite.a$(其他库)
您使用
.m64
。你是说
-m64
?谢谢,修好了。那是个打字错误。实际的build命令没有这个错误。我在另一个库(MPFR)中发现了这个错误,它们可能提供了一个线索<代码>10。当我构建MPFR时,我收到一个错误,要求我使用-fPIC重新编译。。还有一个关于Darwin(OS/X)和Linux的不同之处的说明。重新编译其他库不是一个选项。但这暗示Linux下的“fat共享库”支持是不好的。
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
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