Remove compiler definitions - c++

when compiling shared library which links boost and python libraries I receive error:
/usr/bin/ld: libboost_python.a(from_python.o): relocation R_X86_64_32
against `.rodata.str1.8' can not be used when making a shared object;
recompile with -fPIC libboost_python.a: could not read symbols: Bad
value
I've used verbose mode to look at compiler definitions:
/usr/bin/c++ -fPIC -g -shared -Wl,-soname,libCore.so -o
.../libCore.so Core.cpp.o -lpython2.7 -Wl,-Bstatic -lboost_python
-Wl,-Bdynamic
That's it! I have to remove -Wl, -Bstatic from definitions but how to do that? I'm using cmake build system and here is a part of code which generates that shared library:
set(Core_SRC
Core.cpp
)
add_definitions(-g -fPIC)
add_library(Core SHARED ${Core_SRC})
target_link_libraries(Core
${PYTHON_LIBRARIES}
${Boost_LIBRARIES}
)

The problem is you're trying to build a shared library with libboost_python which appears to have been built in such a way that it can't be linked into a shared library.
There's 3 ways round that.
Don't make your library shared
Build a shared version of the boost_python library
eave the references to boost_python unresolved

Related

Linking problem with an Shared Object in 32-bits

I am trying to migrate and old version of an software and I modernized the code with CLang-Tidy assistance and I am having an strange linking problem that is saying this:
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/32/crtbeginT.o:
direct GOT relocation R_386_GOT32X against
`_ITM_deregisterTMCloneTable' without base register can not be used
when making a shared object
I tried to isolate the problem by commenting some .cpp files in CMakeLists.txt but I still can't determine what is wrong.
Here is my CMakeLists.txt section
add_library(client SHARED
network/client/mistery.cpp
network/client/mclient.cpp
network/client/ellect.cpp
network/client/proctcppacket.cpp
network/client/ping.cpp
network/client/signals.cpp
network/client/remotecontrol.cpp
network/client/data.cpp
network/client/sensor.cpp
network/client/events.cpp
network/client/test.cpp
network/client/misteryThread.cpp
network/client/libNetwork.cpp
)
target_link_libraries(client -lssl -lcrypto -ggdb -lxml2 -lz -ldl -pthread -lstdc++ -static)
set_target_properties(client PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
My shared object must be 32-bits mode.
I noticed that I must compile and link without the -static option in the target_link_libraries. Since I am build a shared object I cannot use this option.
Therefore, the correct implementation of the target_link_libraries is:
target_link_libraries(client -lssl -lcrypto -ggdb -lxml2 -lz -ldl -pthread -lstdc++)

Linking libjpeg library to a shared library, and libjpeg is undefined at runtime

I am trying to use libjpeg in my jni program on Ubuntu. I built my c++ code with g++, with libjpeg added as a library. I tried both linking the shared version and the static version, but both of them cause "undefined symbol: jpeg_std_error" error in Java (while my c++ codes worked fine). I did use "extern "C"" for the libjpeg header.
Here is my build script with static libjpeg.a (libjpeg built as part of libjpeg-turbo and renamed libjpeg151.a):
outputName=$libDir/libMyLib.so
g++ -DNDEBUG -O3 -march=native -mfpmath=sse -Ofast -flto -funroll-loops -fPIC -w -shared -o $outputName \
-I$jdkDir/include -I$jdkDir/include/linux -std=c++11 -pthread \
-L$libDir/SEngineLibraries/libjpegTurbo151Linux -ljpeg151 \
myCode.cpp
and the one with shared version (with libjpeg-turbo deb installed)
outputName=$libDir/libMyLib.so
g++ -DNDEBUG -O3 -march=native -mfpmath=sse -Ofast -flto -funroll-loops -fPIC -w -shared -o $outputName \
-I$jdkDir/include -I$jdkDir/include/linux -std=c++11 -pthread \
-ljpeg \
myCode.cpp
In my Java code, when running to codes using libjpeg, this error pops out:
symbol lookup error: /myDir/lib/libMyLib.so: undefined symbol: jpeg_std_error
Here is something might be suspicious: no matter I include the line referencing libjpeg in the build script or not, the .so library has a constant size.
It is strange that it doesn't work with the static version of the library, because then there should not be an extra linked jpeg lib. Few options which you can try:
specify -Wl,--no-undefined to print error for undefined references in the .so (by default the linker doesn't fail when shared library has unresolved symbols)
try ldd <sharedlib> to see unresolved dependencies
for shared library linking, try adding RPATH: -Wl,-rpath,/path/to/jpeglib_so_dir - this inserts the path to the libjpeg.so inside the shared library so that it can be resolved without being in the ldd path

An executable and a shared library dependent on a same statically linked library

Suppose you're developing a shared library libshared.so.
And you have a static library libstatic.a with some internal classes and functionality you need. You'd like to link it to your .so like this:
g++ -o libshared.so -shared myObj.o -lstatic
Also you have an executable.sh which will use your .so and dynamically open it in the runtime
dlopen("libshared.so", RTLD_NOW)
You know this executable was as well statically linked against libstatic.a (but you're not sure the version of the library is exactly the same as yours).
So the question is:
Is it safe and correct to statically link your libshared.so against libstatic.a when you know the same library is already used in executable.sh?
You should avoid linking a static library into a shared one.
Because a shared library should have position independent code (otherwise, the dynamic linker has to do too much relocation, and you lose the benefits of shared libraries), but a static library usually does not have PIC.
Read Drepper's paper: How to write a shared library
You build your library with
g++ -Wall -O -fPIC mySrc.cc -c -o myObj.pic.o
g++ -o libshared.so -shared myObj.pic.o -lotherlib

"relocation R_X86_64_32S against " linking Error

I'm Trying to Link a static Library to a shared library , I'm Getting the Following error
/usr/bin/ld: ../../../libraries/log4cplus/liblog4cplus.a(fileappender.o): relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC
../../../libraries/log4cplus/liblog4cplus.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
But this worked on a 32bit machine without any such error. I tried adding The -fPIC flags manually to the Makefile that too didn't solve the problem
I tried the -whole-archive flag as suggested here but with no success.
/usr/bin/ld: ../../../libraries/log4cplus/liblog4cplus.a(appenderattachableimpl.o): relocation R_X86_64_32S against `vtable for log4cplus::spi::AppenderAttachable' can not be used when making a shared object; recompile with -fPIC
../../../libraries/log4cplus/liblog4cplus.a(appenderattachableimpl.o): could not read symbols: Bad value
collect2: ld returned 1 exit status
Creation of liblog4cplus.a:
unzip log4cplus-1.1.0.zip
./configure --enable-static=yes --enable-threads=yes
vi Makefile and added -fPIC to CXXFLAGS and CFLAGS
make
Then for Compiling my shared library:
g++ -frtti -w -c -fPIC -I"Include_Directory" myfile.cpp
g++ -shared -fPIC -frtti -I"Include_Directory" -o mysofile.so myfile.o -Wl,--whole-archive "../../../libraries/log4cplus/liblog4cplus.a" -Wl,--no-whole-archive -ldl
Assuming you are generating a shared library, most probably what happens is that the variant of liblog4cplus.a you are using wasn't compiled with -fPIC. In linux, you can confirm this by extracting the object files from the static library and checking their relocations:
ar -x liblog4cplus.a
readelf --relocs fileappender.o | egrep '(GOT|PLT|JU?MP_SLOT)'
If the output is empty, then the static library is not position-independent and cannot be used to generate a shared object.
Since the static library contains object code which was already compiled, providing the -fPIC flag won't help.
You need to get ahold of a version of liblog4cplus.a compiled with -fPIC and use that one instead.
Add -fPIC at the end of CMAKE_CXX_FLAGS and CMAKE_C_FLAG
Example:
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++11 -O3 -fPIC" )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -fPIC" )
This solved my issue.
Relocation R_X86_64_PC32 against undefined symbol , usually happens when LDFLAGS are set with hardening and CFLAGS not .
Maybe just user error:
If you are using -specs=/usr/lib/rpm/redhat/redhat-hardened-ld at link time,
you also need to use -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 at compile time, and as you are compiling and linking at the same time, you need either both, or drop the -specs=/usr/lib/rpm/redhat/redhat-hardened-ld .
Common fixes :
https://bugzilla.redhat.com/show_bug.cgi?id=1304277#c3
https://github.com/rpmfusion/lxdream/blob/master/lxdream-0.9.1-implicit.patch
I've got a similar error when installing FCL that needs CCD lib(libccd) like this:
/usr/bin/ld: /usr/local/lib/libccd.a(ccd.o): relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC
I find that there is two different files named "libccd.a" :
/usr/local/lib/libccd.a
/usr/local/lib/x86_64-linux-gnu/libccd.a
I solved the problem by removing the first file.
I also had similar problems when trying to link static compiled fontconfig and expat into a linux shared object:
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: /3rdparty/fontconfig/lib/linux-x86_64/libfontconfig.a(fccfg.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: /3rdparty/expat/lib/linux-x86_64/libexpat.a(xmlparse.o): relocation R_X86_64_PC32 against symbol `stderr##GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
[...]
This contrary to the fact that I was already passing -fPIC flags though CFLAGS variable, and other compilers/linkers variants (clang/lld) were perfectly working with the same build configuration. It ended up that these dependencies control position-independent code settings through despicable autoconf scripts and need --with-pic switch during build configuration on linux gcc/ld combination, and its lack probably overrides same the setting in CFLAGS. Pass the switch to configure script and the dependencies will be correctly compiled with -fPIC.

C++ Statically linked shared library

I have a shared library used by a another application beyond my control which requires *.so objects. My library makes use of sqlite3 which needs to be statically linked with it (I absolutely need a self-contained binary).
When I try to compile and link my library:
-fpic -flto -pthread -m64
-flto -static -shared
I end up with the following error:
/usr/bin/ld: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
What is recompile with -fPIC related to? My code or CRT?
I have already tried to compile my object with -fPIC with the same result.
Thanks.
EDIT:
The problem does not seem to be related to SQLite3.
I wrote a simple one-line-do-nothing library which compiles and links like this:
g++ -c -fPIC -o bar.o bar.cpp
g++ -shared -o bar.so bar.o
but not like this:
g++ -c -fPIC -o bar.o bar.cpp
g++ -static -shared -o bar.so bar.o
The problem seems to be related to CRT (crtbeginT.o). Am I supposed to recompile GCC --with-pic or anything?
You shouldn't use the -static flag when creating a shared library, it's for creating statically linked executables.
If you only have a static version of the library, you can just link it in using -lsqlite3. But if there's both a dynamic version(.so) and a static version, the linker will prefer the dynamic one.
To instruct the linker to pick the static one, give the linker the -Bstatic flag, and make it switch back to dynamic linking for other stuff (like libc and dynamic runtime support) with -Bdynamic. That is, you use the flags:
-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic
Alternativly, you can just specify the full path of the .a file, e.g. /usr/lib/libsqlite3.a instead of any compiler/linker flags.
With the GNU ld, you can also use -l:libsqlite3.a instead of -lsqlite3. This will force the use of the library file libsqlite3.a instead of libsqlite3.so, which the linker prefers by default.
Remember to make sure the .a file have been compiled with the -fpic flag, otherwise you normally can't embed it in a shared library.
Any code that will somehow make its way into a dynamic library should be relocatable. It means that everything that is linked with your .so, no matter statically or dynamically, should be compiled with -fPIC. Specifically, static sqlite library should also be compiled with -fPIC.
Details of what PIC means are here: http://en.wikipedia.org/wiki/Position-independent_code
I had the same problem. Apparently -static is not the same as -Bstatic. I switched to -Bstatic and everything worked.