Relocation R_X86_64_PC32 against undefined symbol can not be used when making a shared object; recompile with -fPIC - c++

I recently upgraded gSOAP from 2.8.7 to 2.8.76. I had to make a few minor code adjustments for the upgrade, but after the upgrade the code won't link on the computer it would before.
I'm trying to use gSOAP to create a shared library on a computer which uses g++ 4.9.2. I've condensed the code down to create a test case that simplifies things a bit to try to identify where the failure is occurring.
gSOAP generates some ebaySoapLib* files when I run:
/usr/local/bin/soapcpp2 -z1 -C -w -x -n -pebaySoapLib -qebaySoapLib -I/usr/local/include/gsoap:/usr/local/share/gsoap:/usr/local/share/gsoap/import ebaySvc.h
The -z1 option is to keep things similar to how they were with gSOAP 2.8.7.
If I run:
g++ -fPIC -c ebaySoapLibClientLib.cpp
g++ -shared -fPIC -o test.so ebaySoapLibClientLib.o
I get the error:
/usr/bin/ld: ebaySoapLibClientLib.o: relocation R_X86_64_PC32 against
undefined symbol `soap_serializeheader' can not be used when making a
shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
I copied over the exact files to another computer running g++ 6.3.0 (not sure that the compiler version is what is mattering or now), and this compiles and links fine.
The file ebaySoapLibClientLib.cpp contains:
#define SOAP_FMAC3 static
#include "ebaySoapLibC.cpp"
#include "ebaySoapLibClient.cpp"
Now, if I remove the line:
#define SOAP_FMAC3 static
then the code compiles fine on both computers.
I'm at a loss for what I need to do differently to make it link OK with the g++ 4.9.2 computer. I could take out the #define so the functions aren't defined static and get it to work, but the question is WHY as gSOAP is putting it in there for a reason, and it links fine on the g++ 6.3.0 with these functions set to static.

You need to get library that supplies soap_serializeheader to be compile ready for shared library, its not ebaySoaLibClientLib.cpp. Use g++ -v to see what libraries g++ is using. Try using shared library instead of static ones.

Related

golang gcc c++ existing static library can not be used when making a PIE object; recompile with -fPIC

I tried to link an existing C++ library to go code. The C++ library only has a static library and a header file, no source code.
I used swigc to generate a libfoo.go and I wrote a simple libb.go to build this library. This worked well on ubuntu 16.04 with gcc-6 earlier.
However, once I upgraded to ubuntu 18, and even with older go1.9 and gcc-6, which used to work, I am hitting the following error:
/usr/bin/ld: ./lib/libfoo.a(parser.o): relocation R_X86_64_32S against symbol `xmlSAX2IgnorableWhitespace' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: ./lib/libfoo.a(tree.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIC
I have downgraded both go compiler and gcc to the version that used to work.
The following is the libb.go that used to work
/*
#cgo CXXFLAGS: -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -w
#cgo CFLAGS: -I${SRCDIR}/include -w
#cgo LDFLAGS: -Wl -rpath,./lib, -L${SRCDIR}/lib -l:libfoo.a -l:libxml2.a
*/
import "C"
What should I do get this fixed? I searched and it seems that I have to recompile that static library, which is mission impossible in my case. I tried to pass the -no-pie parameter to LDFLAGS, that didn't work either.
I also run into this problem these days. Finally, I found that adding below lines
"env CGO_LDFLAGS=-no-pie"
to go build command line could solve this problem. For example,
"env CGO_LDFLAGS=-no-pie go build -o main main.go"

Ubuntu 16.04 Eclipse CPP - error adding symbols: Bad value [duplicate]

I am using the command:
g++ --std=c++11 -fPIC -Iincludes parser.cpp lib/main-parser.o lib/lib.a
To compile a C++ program on Debian 9. But I am getting the below error message:
/usr/bin/ld: lib/lib.a(csdocument.o): relocation R_X86_64_32 against '.rodata' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
I have already seen the thread:
Compilation fails with "relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object"
However, I have tried adding the -fPIC argument however it strangely gives the same error message, along with "recompile with -fPIC"
Any ideas would be appreciated. I have tried compiling this on my University's RedHat systems and it works fine there. I'm thinking it could be a missing dependency, but I've been unable to find any answers.
Thanks in advance
As it seems gcc is trying to produce a position-independent executable ("shared object" is the hint), tell it not to:
g++ --std=c++11 -no-pie -Iincludes parser.cpp lib/main-parser.o lib/lib.a
It seems that g++ produces position-independent executables by default on your system. Other systems would require -pie to do so. Using -no-pie should create a "regular" (position dependent) executable.
(The error is a result of trying to link an object file that was compiled as non-position-independent into an executable that is supposed to be position-independent).
/usr/bin/ld: lib/lib.a(csdocument.o): relocation R_X86_64_32 against '.rodata' \
can not be used when making a shared object; recompile with -fPIC
This linker error is telling you that the object file csdocument.o in the
static library lib/lib.a is not Position Independent Code and hence
cannot be linked with your PIE program. So you need to recompile the source
files of lib/lib.a with -fPIC, then rebuild the static library, then link
it with your PIE program. If you don't have control of the libary sources
then request a PIC build from its supplier.
(Others have questioned why you should need to build a PIE target at all
since it's not a shared library. In Debian 9, GCC produces PIE executables
by default,
whether programs or shared libraries. The same goes for Ubuntu as of 17.04. )
Adding this worked for me.
g++ --std=c++11 -no-pie
I also added the -fPIC to compile flag.

Errors when linking libsodium.a into a Shared Object

I am trying to use the libsodium library in a C++ project and I'm having difficulty with linking the static Libsodium Library into a Shared Object that I've created. This project is being compiled using G++ and is set to use C++11 Standards.
After reading various forum posts about linking a Static Library into a Shared Object, I've tried using the Whole Archive which seems to get me further but still will not link in correctly.
The following is the Command being used to link:
/usr/bin/g++ -shared -fPIC -o ./Debug/libwowcrypt.so #"libwowcrypt.txt" -L. -L../SharedLibraries/Sodium/lib -Wl,--whole-archive -lsodium -Wl,--no-whole-archive
The following error messages are returned from ld:
/usr/bin/ld: ../SharedLibraries/Sodium/lib/libsodium.a(libsodium_la-hmac_hmacsha256.o): relocation R_X86_64_PC32 against symbol `crypto_auth_hmacsha256_init' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
Can anyone advise on the correct linker flags that are needed to incorporate this static library into my shared object?
I ran into the same problem. Assuming you are on Ubuntu < 15.04 (mine is 14.04 LTS), you need to disable PIE
./configure --disable-pie
and then the usual: make / make install etc.
Now you should be able to link the static libsodium.a to your .so. I got this from a recent discussion on github issue i raised here

Finding mangled C++ link error

There are two link errors in this project.
The first, pointed out by #Steve, is the lack of
void *__gxx_personality_v0;
If anyone can explain why a C++ project compiled with clang++3.5 under cygwin would create a reference to this, I would like to understand. Anyway, I defined the symbol as a workaround.
The other problem appears to be references to 32-bit relative addressing in 64-bit. I am looking for a way to tell clang++ to compile 32 bit or 64 bit. I will try on native linux as well, but again, if anyone can explain why this is happening, I would like to understand.
I am thinking it might be a static variable, located down low in the address space, being accessed by something on the stack, but again, clang is generating everything so as far as I can see, this is a bug in the compiler.
clang++ -std=c++11 -O2 -g -I include/ -pthread -c RequestHandler.cc
clang++ -std=c++11 -O2 -g Config.o Logger.o RequestHandler.o FileSys.\
o Buffer.o server.o CspServlet.o -pthread -o server
RequestHandler.o:fake:(.debug_info+0x54bd): relocation truncated to f\
it: R_X86_64_32 against `.debug_ranges'
...
FileSys.o:fake:(.eh_frame$_ZNSt10_HashtableISsSt4pairIKSsP2FLESaIS4_E\
NSt8__detail10_Select1stESt8equal_toISsESt4hashISsENS6_18_Mod_range_h\
ashingENS6_20_Default_ranged_hashENS6_20_Prime_rehash_policyENS6_17_H\
ashtable_traitsILb1ELb0ELb1EEEE21_M_insert_unique_nodeEmmPNS6_10_Hash\
_nodeIS4_Lb1EEE+0x13): undefined reference to `__gxx_personality_v0'
FileSys.o:fake:(.eh_frame$_ZNSt8__detail16_Hashtable_allocISaINS_10_H\
ash_nodeISt4pairIKSsP2FLELb1EEEEE16_M_allocate_nodeIJRKS6_EEEPS7_DpOT\
_+0x13): more undefined references to `__gxx_personality_v0' follow
collect2: error: ld returned 1 exit status
Ok, it turns out that on cygwin, when I installed clang, it doesn't fully use the clang toolchain. clang is compiling, but g++ is linking (I think). Bear in mind all these tools could be aliased to something else, but it's very suspicious.
I built on Unix and it worked. Same makefile.
So the problem is that when I wrote clang, it wasn't using clang to link. And that is weird.

Undefined Reference Error When Linking to Static Library

I am trying to compile a project that depends on the Xerces XML Parser. The project compiles for Windows without any difficulty, but I'm having some trouble compiling it with g++ in Cygwin.
In order to use Xerces, I am trying to compile my code against the static library libxerces-c.a. But when I do so, I get errors that look like this:
/tmp/cc2QGvMh.o:test.cpp:(.text+0x3a): undefined reference to `xercesc_2_8::DOMImplementationRegistry::getDOMImplementation(unsigned short const*)'
I've inspected the static library using ar, and confirmed that it contains the DOMImplementationRegistry.o file that defines the function that I am calling.
ar -t libxerces-c.a
...
DOMImplementationImpl.o
DOMImplementationRegistry.o
DOMLocatorImpl.o
...
I've also extracted the object files from the library, and used 'nm' to make sure that the function I am calling actually exists:
ar -x libxerces-c.a
nm --demangle DOMImplementationRegistry.o
...
00000080 T xercesc_2_8::getDOMImplSrcVectorMutex()
00000300 T xercesc_2_8::DOMImplementationRegistry::getDOMImplementation(unsigned short const*)
000002a0 T xercesc_2_8::DOMImplementationRegistry::addSource(xercesc_2_8::DOMImplementationSource*)
...
Since I can compile everything for Windows but not with g++, I thought that the error could be in the linker order (similar to the problem described in this question). However, even after changing the linker order, I am still getting the same compiler error. I have tried both
g++ -o test.exe test.cpp -Llib -lxerces-c
and
g++ -o test.exe test.cpp lib/libxerces-c.a
Any ideas?
Your project uses method from xercesc_2_6 namespace as pointed by compiler error message but your library offers xercesc_2_8 version. Problem is probably caused by mismatch between headers you use and library object file.
You didn't say the source of the archive. If it isn't compiled with cygwin, it could be a name mangling problem. Compiling the library from source might well fix this.
It could also be that the archive is built incorrectly so that it has internal resolution problems. Try giving the library name twice.
g++ -o test.exe test.cpp lib/libxerces-c.a lib/libxerces-c.a
If this works, the archive is broken and you should look for or build a new one.
Try the linker option --enable-stdcall-fixup (see 'man ld'). It will care for name mangling and calling conventions:
g++ -o test.exe test.o -Wl,--enable-stdcall-fixup -Llib -lxerces-c