0

The directory structure for my header-only library is as follows:

proj/
    include/
        proj/
            file1.h
            file2.h
    CMakeLists.txt

Basically I would like to be able to do the following inside file1.h (and therefore anywhere within the project):

#include "file2.h"

But have to do the following in any external project:

#include "proj/file2.h"

Currently, my naive implementation of this is in CMakeLists.txt:

add_library( proj INTERFACE )
target_include_directories( proj INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include )
target_include_directories( proj INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include/proj )

To allow both internal and external files do be able to do both. This is not restrictive enough, however, and what I am looking for is something that would work equivalently to this:

add_library( proj INTERFACE )
target_include_directories( proj INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include )
target_include_directories( proj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/proj )

But this obviously results in a CMake error because:

target_include_directories may only set INTERFACE properties on INTERFACE targets

Is it possible to do what I am trying to do? Thank you in advance for your help.

  • 1
    CMake doesn't differentiate users of the library: all INTERFACE properties of the library are propagated to anyone which links with that library. When access library's *interface* headers, it is better to use **same include paths** both inside the project and outside of it. This preference is applicable even for normal (not-header-only) libraries, when you actually can differentiate users by setting PRIVATE and INTERFACE properties. – Tsyvarev Apr 16 '21 at 07:57
  • 2
    The #include statements are not resolved until the c++ file(s) using this library are compiled, so this is when the configured paths must be known. This means that all the include paths of an INTERFACE library must be non-private for the compilation to work. – olm Apr 16 '21 at 08:52
  • Thank you for you answers, they both make sense to me. @Tsyvarev, what is the reasoning behind this preference even for not-header-only libraries? – Sebastian Wieczorek Apr 19 '21 at 01:26
  • The reasoning behind a single way for using some interface (the header file in your case) is a simpler support and a lesser chance of making errors. – Tsyvarev Apr 19 '21 at 07:33

0 Answers0