I have the following CMakeLists.txt defining an object library and a shared library depending on the object library, as follows:
add_library(foo OBJECT
foo.cpp
)
add_library(bar SHARED
bar.cpp
$<TARGET_OBJECTS:foo>
)
add_executable(baz baz.cpp)
target_link_libraries(baz
PUBLIC bar
)
I get the following linker error when linking baz
:
/usr/bin/ld: CMakeFiles/foo.dir/foo.cpp.o: relocation R_X86_64_PC32 against symbol `_ZSt4cout@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
This is because foo.cpp
is not build with -fPIC
(bar.cpp
is). This can be solved by adding:
set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE ON)
Is this the right way to fix this issue? I seems to me there should be a cleaner solution for this. I feel CMake can be smarter here and see that the objects from foo
are only used in a context where -fPIC
is required. I am using CMake 3.11.
Some context; in our project, we need to build a single shared library from a lot of sources scattered around in different directories. Right now, we create separate shared libraries for each directory. Most of these libraries depend on Bison sources, which behind the scenes depend on add_custom_command
to be build. This introduces compile time dependencies between the libraries, seriously limiting how much we can parallelize the build (see: https://gitlab.kitware.com/cmake/cmake/issues/15555).
Object libraries per directory which are then used to build the shared library seem to be a nice solution for this problem.