Linking GCC static/shared libraries and threads and -fPIC flag - c++

I'm building a shared library (C++ code using some C++11/14 features) which links to my own static library and uses threads. It all uses CMake. When I link my shared library ("gscore") and it tries to link to my static library ("gslicense"), I get and error regarding a symbol in pthreads. Full text is further down but the short version is this:
'__pthread_key_create' can not be used when making a shared object; recompile with -fPIC
I've tried following the advice and added -fPIC to the compile-time flags for both of my projects. I've verified that -fPIC is part of my compilation flags but the error persists. I'm not sure what I'm missing.
Here is the error.
[ 57%] Linking CXX shared library libgscore.so
/usr/bin/ld: ../gslicense/libgslicense.a(gslicensing.cpp.o): relocation R_X86_64_32 against `__pthread_key_create' can not be used when making a shared object; recompile with -fPIC
../gslicense/libgslicense.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
GSCore/CMakeFiles/gscore.dir/build.make:1014: recipe for target 'GSCore/libgscore.so' failed
make[2]: *** [GSCore/libgscore.so] Error 1
CMakeFiles/Makefile2:173: recipe for target 'GSCore/CMakeFiles/gscore.dir/all' failed
make[1]: *** [GSCore/CMakeFiles/gscore.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
Here is how I added threading to my project in my CMakeLists.txt file
#
# pthread
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(gscore Threads::Threads)
This is all part of a port of a Windows codebase to linux using CMake. I'm extremely familiar with Windows but fumble around in Linux. I've tried searching all the threads I can find on SO but I'm still at a loss.
Any idea what I'm missing?

Related

Connecting 2 libs: can not be used when making a shared object; recompile with -fPIC

I've connected two libraryes.
a) HotStuff https://github.com/hot-stuff/libhotstuff
b) Bls (with relic) https://github.com/Chia-Network/bls-signatures
I had to add a lot of bls flags into the hotstuff cmake:
(On root dir level)
https://gist.github.com/Raycoms/29e58b80fb493d89d1ea4bfe6f953984
(In examples folder)
https://gist.github.com/Raycoms/8e757d0ab0fd61a006db629dbc35e6fc
However, when building this, this results in the following exception:
/usr/bin/ld: _deps/relic-build/lib/librelic_s.a(relic_core.c.o): relocation R_X86_64_TPOFF32 against symbol `core_ctx' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: bls/src/libblstmp.a(elements.cpp.o): warning: relocation against `_ZTVSt9basic_iosIcSt11char_traitsIcEE##GLIBCXX_3.4' in read-only section `.text._ZN3bls4Util6HexStrB5cxx11ERKSt6vectorIhSaIhEE[_ZN3bls4Util6HexStrB5cxx11ERKSt6vectorIhSaIhEE]'
/usr/bin/ld: bls/src/libblstmp.a(elements.cpp.o): relocation R_X86_64_PC32 against symbol `_ZN3bls4Util19secureAllocCallbackE' 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
make[2]: *** [CMakeFiles/hotstuff_shared.dir/build.make:90: libhotstuff.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:350: CMakeFiles/hotstuff_shared.dir/all] Error 2
make: *** [Makefile:133: all] Error 2
Weirdly, compiling and running it in CLion works just fine, but doing it in the commandline results in the above exception which leaves me confused.
Quick update. It works in CLion because executing "make" in the examples folder works well enough to build the app and app-client starters.
However, the overall build doesn't work.
You need to tell cmake that the target producing the librelic_s.a static lib should use position independent code by setting the POSITION_INDEPENDENT_CODE target property:
add_library(relic_s STATIC ...)
set_target_properties(relic_s PRIVATE POSITION_INDEPENDENT_CODE True)
Not sure this can be done without modifying the cmake file of relic...

Error when linking LibRaw to shared object

So, what i'm actually trying to is to build a shared object, that contains a python-includable-module, generated by pybind11. I got it as far as to have no syntax-errors in CLion, but when i try to compile it, it gives the following error:
/usr/bin/ld: //usr/local/lib/libraw.a(utils_libraw.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
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
CMakeFiles/cr3_to_python.dir/build.make:98: recipe for target 'cr3_to_python.cpython-36m-x86_64-linux-gnu.so' failed
make[3]: *** [cr3_to_python.cpython-36m-x86_64-linux-gnu.so] Error 1
CMakeFiles/Makefile2:77: recipe for target 'CMakeFiles/cr3_to_python.dir/all' failed
make[2]: *** [CMakeFiles/cr3_to_python.dir/all] Error 2
CMakeFiles/Makefile2:84: recipe for target 'CMakeFiles/cr3_to_python.dir/rule' failed
make[1]: *** [CMakeFiles/cr3_to_python.dir/rule] Error 2
Makefile:118: recipe for target 'cr3_to_python' failed
make: *** [cr3_to_python] Error 2
When compiling with c++ i get something very similar:
$ c++ -O3 -Wall -shared -std=c++11 -fPIC -I/usr/include/python3.6m/ -I/usr/local/include/opencv4/ $(python3 -m pybind11 --includes) main.cpp -o cr3_to_python$(python3-config --extension-suffix) -lraw
/usr/bin/ld: //usr/local/lib/libraw.a(utils_libraw.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
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
What annoys me the most is the actual error:
/usr/bin/ld: //usr/local/lib/libraw.a(utils_libraw.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
Because i didn't include anything related to stderr (from my point of view) in the code.
main.cpp
CMakeLists.txt
When compiling a shared library on Linux and Macos (and probably other Unixy OSes) all code used in the library needs to be compiled in "position independent mode", this is because the compiler doesn't know where an executable will load your code so has to generate code which can be run from any address.
To generate PIC code you need to pass the -fPIC flag to GCC.
Note that all the code you want to compile into your shared library needs to be compiled in PIC mode, this includes code in static libraries. In your case you need to recompile libraw.a with -fPIC enabled.
Position independent code might be slightly slower but the difference is small so you can probably just compile all your code with -fPIC even if its being used directly in an executable. Apple recommends that all code including executables is position independent. See How much overhead can the -fPIC flag add? for more details about performance.

Shared library on Linux and -fPIC error

I am trying to compile a shared library in Linux using a Makefile created with Cmake, but running make I obtain the following error:
Linking CXX shared library libcpp-lib.so
/usr/bin/ld: /home/davide/Desktop/boost_1_55_0/stage/lib/libboost_system.a(error_code.o): relocation R_X86_64_32 against .rodata.str1.1 can not be used when making a shared object; recompile with -fPIC
/home/davide/Desktop/boost_1_55_0/stage/lib/libboost_system.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make[2]: *** [libcpp-lib.so] Error 1
make[1]: *** [CMakeFiles/cpp-lib.dir/all] Error 2
make: *** [all] Error 2
I provide the following command in the CMakeLists.txt in order to say that I want a shared (.so) library:
add_library(cpp-lib SHARED ${CPP_FILES})
What else do I need to specify in order to avoid the -fPIC error shown above?
Thanks a lot in advance
The boost libraries needs to be compiled using -fPIC:
Please have a look at: How to compile static library with -fPIC from boost.python
Try to add compiler flags by cmake by in your project:
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")

Error linking to Boost filesystem using cmake on cygwin

I'm using cmake 2.8.9, g++ 3.4.4, and Boost 1.50. in Cygwin on Windows 8 64 bit.
Here is the error message I get.
Linking CXX executable RayTracer.exe
CMakeFiles/RayTracer.dir/Ray_Tracer.cpp.o:Ray_Tracer.cpp:(.text+0x89c):
undefined reference to boost::system::generic_category()'
CMakeFiles/RayTracer.dir/Ray_Tracer.cpp.o:Ray_Tracer.cpp:(.text+0x8a6):
undefined reference toboost::system::generic_category()'
CMakeFiles/RayTracer.dir/Ray_Tracer.cpp.o:Ray_Tracer.cpp:(.text+0x8b0):
undefined reference to boost::system::system_category()'
/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../../i686-pc-cygwin/bin/ld:
CMakeFiles/RayTracer.dir/Ray_Tracer.cpp.o: bad reloc address 0xb in
section
.text$_ZN5boost6system14error_categoryD1Ev[boost::system::error_category::~error_category()]'
collect2: ld returned 1 exit status
CMakeFiles/RayTracer.dir/build.make:94: recipe for target
RayTracer.exe' failed make[2]: *** [RayTracer.exe] Error 1
CMakeFiles/Makefile2:64: recipe for target
CMakeFiles/RayTracer.dir/all' failed make[1]: *
[CMakeFiles/RayTracer.dir/all] Error 2 Makefile:75: recipe for target
`all' failed make: * [all] Error 2
From what I've seen, the usual problem is failing to link the boost system library, but I made sure to do that. Here is the relevant portion of my CMakeLists.txt file:
#Edit: cmake can't find the static libraries on cygwin, so I'm setting this to false for now.
SET(Boost_USE_STATIC_LIBS FALSE)
FIND_PACKAGE(Boost 1.50 REQUIRED date_time program_options thread filesystem system unit_test_framework)
IF(${Boost_FOUND})
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ENDIF()
add_executable(RayTracer
Ray_Tracer.cpp
)
target_link_libraries(RayTracer ${Boost_PROGRAM_OPTIONS_LIBRARIES})
And here's the line in my .cpp file that triggers the error:
#include <boost/filesystem.hpp>
Any idea what I'm doing wrong?
You need to tell the linker to link Boost.Filesystem and Boost.System libraries.
You can do:
target_link_libraries(RayTracer
${Boost_PROGRAM_OPTIONS_LIBRARIES}
${Boost_FILESYSTEM_LIBRARIES}
${Boost_SYSTEM_LIBRARIES}
)
or if you just want to link all the libs specified in your find_package(Boost...) call, you can do:
target_link_libraries(RayTracer ${Boost_LIBRARIES})
For further details on the FindBoost CMake module, see the docs or run:
cmake --help-module FindBoost

ld lookup to find library

I'm cross compiling to an arm embedded system and receiving an error that I have questions about. Here is the error:
[ 19%] Built target cxjpeg-6b
Linking CXX shared library /home/botbear/JAUS++-2.110519- src/libraries/jaus++/2.0/lib/libcxutils.so
/home/botbear/openwrt/trunk/staging_dir/toolchain-arm_v6k_gcc-linaro_uClibc- 0.9.32_eabi/lib/gcc/arm-openwrt-linux-uclibcgnueabi/4.5.4/../../../../arm-openwrt-linux- uclibcgnueabi/bin/ld: cannot find -lpng
collect2: ld returned 1 exit status
make[2]: *** [/home/botbear/JAUS++-2.110519-src/libraries/jaus++/2.0/lib/libcxutils.so] Error 1
make[1]: *** [libcxutils/CxUtils/libcxutils/CMakeFiles/cxutils.dir/all] Error 2
make: *** [all] Error 2
As you can see the linker is looking for a static library named 'libpng'. In addition to the libpng lib., the command in the sub-make file using the -l switch to link to the following libraries: -lpng -lz -lX11 -lXtst -lpthread -Wl. All of the libraries (libpng,libz,libX11, etc) are in my host /usr/lib/ directory but my target toolchain does not have the the libraries. My question is if I manually recompile the libraries with my target compiler will that solved my problem? Or I'm going to have find and install packages for each of the libraries for my target platform.
Thanks in advance.
You seem to compile for the target, so you need target libraries. Either compiled by yourself or provided by the toolchain development environment (if you have one). The latter usually saves you some headaches (cross compiling and setting the paths where necessary).
I see you are using openwrt toolchain. Openwrt seems to have libpng as a package. I'd go with that if possible.