尝试在 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 的一个奇怪之处:
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 并构建为 dynamiclib 可以正常工作。它并没有说明太多,但代码库可能没有错。
回答前请注意:
显而易见的答案是说我应该以另一种方式捆绑我的东西。但是由于给定的原因,我真的想使用(JNI 加载、库大小等)创建一个单一的胖共享库。
如果您能与我分享您对此编译器的见解并帮助我解决它,我会很高兴。
更新 1
删除了对 g++ 的引用。仅使用 gcc 会以相同的方式发生此问题。我之前考虑过 gcc 与 g++ 的问题。