Shared library on Linux and -fPIC error - c++

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")

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...

Cmake undefined reference to symbol 'dlsym##GLIBC_2.2.5 even though I link with -ldl

I'm getting undefined reference to dlsym##GLIBC_2.2.5 even after linking it before and after the libraries. However in the linking output it appears that it's linking just before, but linking before all libraries should work, I guess.
/bin/g++-9 CMakeFiles/http_downloader.dir/http_downloader_cli.cpp.o CMakeFiles/http_downloader.dir/SimpleOpenVPNSocket.cpp.o -o http_downloader -lpthread /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/liblz4.so -ldl downloader/libhttp_downloader_cli.a downloader/libhttp_downloader_lib.a ../../libopenvpn/libopenvpn_lib.a ../../_smoltcp_cpp_interface/libsmoltcp_cpp.a ../../_libtins/lib/libtins.a -ldl /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread /usr/lib/x86_64-linux-gnu/liblz4.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so ../../../../smoltcp_cpp_interface/target/debug/libsmoltcp_cpp_interface_rust.a /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so
/usr/bin/ld: ../../../../smoltcp_cpp_interface/target/debug/libsmoltcp_cpp_interface_rust.a(std-6640d3868fa846e8.std.1mk5kra7-cgu.0.rcgu.o): undefined reference to symbol 'dlsym##GLIBC_2.2.5'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libdl.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [src/examples/http_downloader/CMakeFiles/http_downloader.dir/build.make:113: src/examples/http_downloader/http_downloader] Error 1
make[2]: Leaving directory '/workspaces/libopenvpnclient/build'
make[1]: *** [CMakeFiles/Makefile2:519: src/examples/http_downloader/CMakeFiles/http_downloader.dir/all] Error 2
make[1]: Leaving directory '/workspaces/libopenvpnclient/build'
make: *** [Makefile:130: all] Error 2
This is how I'm linking it in CMake:
add_executable(http_downloader http_downloader_cli.cpp SimpleOpenVPNSocket.cpp)
add_core_dependencies(http_downloader)
target_include_directories(http_downloader PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/downloader/include)
add_dependencies(http_downloader http_downloader_cli http_downloader_lib openvpn_lib smoltcp_cpp tins)
set_property(TARGET http_downloader PROPERTY CXX_STANDARD 17)
target_link_libraries(http_downloader dl http_downloader_cli http_downloader_lib openvpn_lib smoltcp_cpp tins dl)
As you can see I've put dl before and after everything just to make sure.
If I understand correctly, .a libs do not have dependencies, they only have missing symbols and we have to fill them. Seems like I'm doing that by linking with -ldl
Would you inspect carefully the actual command line used for linking, you will find that after libsmoltcp_cpp_interface_rust.a, which has missed symbol, there is no -ldl parameter.
It seems that in your case smoltcp_cpp is an IMPORTED library target, which has libsmoltcp_cpp_interface_rust.a as a link dependency (not as IMPORTED_LOCATION property or so).
While CMake preserves order of the libraries, linked into a single binary (an or another library), order between dependencies of these libraries is not defined.
You need to add -ldl as a link dependency for the smoltcp_cpp target itself:
target_link_libraries(smoltcp_cpp INTERFACE -ldl)
However, this will work only if libsmoltcp_cpp_interface_rust.a is a direct link dependency for smoltcp_cpp target, that is specified as
target_link_libraries(smoltcp_cpp INTERFACE libsmoltcp_cpp_interface_rust.a)
In case of indirect dependencies, like
target_link_libraries(smoltcp_cpp INTERFACE <intermediate-target>)
target_link_libraries(<intermediate-target> INTERFACE libsmoltcp_cpp_interface_rust.a)
you need to add -ldl as a dependency for that <intermediate-target>.
Ideally, every IMPORTED target should be self-contained, so you may safely link with that target without knowing its internals.

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.

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

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?

Building error, cmake, can not be used when making a shared object; recompile with -fPIC

When I build a project with cmake, I got following error. Though I tried to add compiling flag -fPIC by add_definition() in the CMakeLists.txt, this error persists. Can anyone help? I am a new guy to cmake. Any suggestions will be highly appreciated.
/usr/bin/ld: /act/mvapich2-1.9/gcc-4.7.2/lib/libmpich.a(mvapich_malloc.o): relocation R_X86_64_32S against `.bss' can not be used when making a shared object; recompile with -fPIC
/act/mvapich2-1.9/gcc-4.7.2/lib/libmpich.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
make[2]: *** [src/libstracker.so] Error 1
make[2]: Leaving directory `/home/xxxx/success/AutomaDeD-master'
make[1]: *** [src/CMakeFiles/stracker.dir/all] Error 2
make[1]: Leaving directory `/home/xxxx/success/AutomaDeD-master'
make: *** [all] Error 2
add_definitions is is intended to add preprocessor definitions, not a flag
-fPIC is present by default in the linker flags for a shared library build with GCC, see Modules/Compiler/GNU.cmake. You can see all flags by running make VERBOSE=1.
As for the error itself, see this answer.