当我试图在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 之后,应该创建一个fat共享库,使用上面的库以及其他一些库(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创建的库时,共享库创建得很好(当然没有我的库...)。
3)我最好的猜测是,当从包含32位.text节的静态库创建共享库时,这个问题来自于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到目前为止的结论:
对我来说,这就像是一个奇怪的gcc编译器。我希望对于我正在尝试做的事情有一个变通的方法。顺便说一句,相同的代码库(具有相似但不相同的依赖项)使用clang和build as dynamiclib在OS上工作得很好。它不能说明太多问题,但代码库可能不会出错。
在回答之前,请注意:
显而易见的答案是,我应该用另一种方式捆绑我的东西。但是由于特定的原因,我真的想使用(JNI加载,库大小等)来创建一个fat共享库。
如果你能与我分享你对这个问题的编译器见解,并帮助我解决这个问题,我会很高兴。
更新1
删除了对g++的引用。这个问题也是以同样的方式出现的,只使用了gcc。我之前考虑过一个关于gcc和g++的问题。
发布于 2015-04-16 20:31:03
在使用eclipse编译时,我遇到了同样的错误:尝试使用"-shared“编译可执行编译(gcc c链接器->共享库设置->共享),结果是这个错误。当共享选项被删除时,它解决了这个问题。由于某种原因,当在eclipse中从可执行文件更改为“静态库”构建时,"-shared“仍然存在,这就是我的例子失败的原因。只有在构建存储库时才需要保留"-shared“选项。
希望它能帮助任何人,
https://stackoverflow.com/questions/26706214
复制相似问题