Search code examples
c++cmakeconan

Include header of CMake targets in a object library


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:

  1. How can I include headers of CMake targets provided by find_package() and CONAN_PKG in a OBJECT library target?
  2. 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
    )
    

    Object libraries may be used as the target (first) argument of target_link_libraries to specify dependencies of their sources on other libraries.