vector-of-bool / cmrc

A Resource Compiler in a Single CMake Script
MIT License
672 stars 74 forks source link

linking cmrc with a shared library #17

Open neel opened 4 years ago

neel commented 4 years ago

Linker error when I try to link with cmrc generated library with a SHARED library.

/usr/bin/ld: thelibx-resources.a(lib.cpp.o): relocation R_X86_64_PC32 against symbol `_ZN4cmrc6detail9directoryD1Ev' can not be used when making a shared object; recompile with -fPIC

I want the shared library to be statically linked with the cmrc_add_resource_library generated target thelibx-resources.

add_library(thelibx SHARED ${THE_LIBX_SOURCES})
target_link_libraries(thelibx ${Boost_PROGRAM_OPTIONS_LIBRARY} thelibx-resources)

If I remove that SHARED then everything works fine.

mbr0wn commented 4 years ago

I see the same thing.

mbr0wn commented 4 years ago

It looks like forcing -fPIC will fix this. Here's my changes to CMakeRC.cmake:

     # Generate the actual static library. Each source file is just a single file
     # with a character array compiled in containing the contents of the
     # corresponding resource file.
     add_library(${name} STATIC ${libcpp})
     set_property(TARGET ${name} PROPERTY CMRC_LIBDIR "${libdir}")
     set_property(TARGET ${name} PROPERTY CMRC_NAMESPACE "${ARG_NAMESPACE}")
     target_link_libraries(${name} PUBLIC cmrc::base)
     set_property(TARGET ${name} PROPERTY CMRC_IS_RESOURCE_LIBRARY TRUE)
     set_property(TARGET ${name} PROPERTY POSITION_INDEPENDENT_CODE ON)

Note the last line.

mbr0wn commented 4 years ago

I'm just not quite sure if that's a general solution.

themarpe commented 4 years ago

If your root project is a shared library I think that you should apply the following in your CMakeLists.txt:

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

before adding dependencies, to compile them with -fPIC.

Or maybe try adding a property only to cmrc resource library after cmrc_add_resource_library call.

cmrc_add_resource_library(foo-resources ALIAS foo::rc NAMESPACE foo  ...)
set_property(TARGET foo::rc PROPERTY POSITION_INDEPENDENT_CODE ON)

Let me know how these options work for you - to not need to modify the CMakeRC.cmake file

mbr0wn commented 4 years ago

Thanks @themarpe. You would have to do

set_property(TARGET foo-resources PROPERTY POSITION_INDEPENDENT_CODE ON)

in your example (aliases are not permitted in set_property()), but your comment was spot-on. Thanks!

mbr0wn commented 4 years ago

@neel @themarpe I would suggest closing this issue. This ^^^ is the right answer. It might be worth putting into the docs.