Issue
Scenario:
I'm porting an applications build system to CMake. Dependencies are already installed on the system or will be handled via conan.
Lets say the project is structured as following:
- include/
- BigFoo/
- *.hpp
- src/
- BigFoo/
- *.cpp
- main.cpp
- *.qml
- test/
- BigFoo/
- *Test.cpp
My goal is to reuse the compilation output (*.o) of BigFoo in the main application and the unit tests. I don't want an internal library (*.a or *.so) for BigFoo.
BigFoo is using Qt5 and Boost components from the target system. It also uses components provided as conan packages.
Current approach:
- Build BigFoo as static library => handle dependencies via target_link_library()
- Build main.cpp and *.qml => link with BigFoo
- Build BigFoo/*Test.cpp => link with BigFoo
Desired approach:
- Build BigFoo as object library => include dependency headers
- Build main.cpp, *.qml with BigFoo_Object => link dependencies
- Build BigFoo/*Test.cpp with BigFoo_Object => link dependencies
Problem of the desired approach:
I could not include dependency headers of several components (Boost::XYZ Qt5::XYZ CONAN_PKG::XYZ etc) via target_include_directories() when building an OBJECT library.
add_library(Core OBJECT)
# I want to do something like this:
target_include_directories(Core PUBLIC
Qt5::Core
Qt5::Qml
Qt5::Quick
Qt5::Scxml
CONAN_PKG::XYZ
CONAN_PKG::XYZ
)
The result is CMake (of course) adds header include paths like the following...
-I../../../Application/Qt5::Qml
And fails later because it cannot dismantle Qt include statements.
When building a static lib the header include was handled by target_link_libraries(), I'm now a bit confussed how to do this on a OBJECT library where I do not link anything.
My Questions:
- How can I include headers of CMake targets provided by find_package() and CONAN_PKG in a OBJECT library target?
- Is there is a better/nicer way of reusing BigFoo so i don't have duplicated compilation?
PS: I'm using cmake 3.13
Solution
I know that this seems nonsense, because object libraries aren't linked at all. But that is only one of the awkwardness of the CMake object libraries. This is what you probably need:
add_library(Core OBJECT)
target_link_libraries(Core PUBLIC
Qt5::Core
Qt5::Qml
Qt5::Quick
Qt5::Scxml
CONAN_PKG::XYZ
CONAN_PKG::XYZ
)
Answered By - Former contributor