问题
I have an odd problem when trying to create a fat shared library on Ubuntu 14.04 (64). The error messages are what you typically get if you forgot to add -fPIC or link to a wrong architecture library:
/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
The first static library is compiled like this:
gcc -c -fPIC -m64 NativeDB.c
After that a single fat shared library should be created, using above library as well as a few others (spatialite, proj4, geos, sqlite) like so:
gcc -shared -fPIC -m64 -o $@ $(OUT_DIR)/NativeDB.o $(OUT_DIR)/sqlite3.o $(SPATIALITE_DIR)/src/.libs/libspatialite.a $(SOME_OTHER_LIBS)
Linking NativeDB.o to the shared library throws mentioned linker error. Note also that the shared library can be created without NativeDB.o. So here it's getting strange, because you see above how NativeDB.o is compiled and adds no additional (implicit) linkage.
Observations:
1) All libraries are compiled properly. I verified for example that libproj contains relocation info and is the right architecture (via objdump -f):
...
pj_initcache.o: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
...
This is also the case for my own NativeDB.o file.
2) When the gcc created lib is left away, the shared library is created fine (though of course without my library...).
3) My best guess is that the issue comes from an oddity from gcc when creating a shared library from static libraries that contain 32 bit .text sections:
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
I have made some experiments with one previously failing library (version.o within libspatialite.a). And voila - it fixed the linkage issue for this library:
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
Conclusions so far:
It seems like an gcc compiler oddity to me. I hope there is a workaround for what I'm trying to do. By the way, the same code base (with similar but not same dependencies) works fine on OS X using clang and build as dynamiclib. It doesn't tell much, but that the code base is likely not at fault.
Please note before you answer:
The obvious answer would be to say that I should bundle my stuff in another way. But for given reasons, I really want to create a single fat shared library using (JNI loading, library size etc).
I'd be glad if you could share with me your compiler insights on this one and help me solve it.
UPDATE 1
Removed references to g++. The issue occurs in the same way solely using gcc. I previously considered a gcc vs g++ issue.
回答1:
I got the same error when building with eclipse: Trying to compile executable build with "-shared" (gcc c linker->shared library settings->Shared), resulted with this error. When the shared option is removed it solved this issue. From some reason when changing from excutable to "Static library" build in eclipse the "-shared" still remains, that's why it failed in my case. The "-shared" option need to remain only for library build.
Hope it helps anyone,
来源:https://stackoverflow.com/questions/26706214/odd-linker-issue-relocation-r-x86-64-32-against-not-a-typical-fpic-issue