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