Relying on relative includes (quoted) or explicit include directory flags

Say you have a simple library like.

/ lib
/-- foo.h
/-- foo.cpp

with a CMakeLists.txt like

add_library(lib)

target_sources(lib
   PRIVATE
      foo.cpp
      foo.h
)

target_include_directories(lib
   PUBLIC # or INTERFACE?
      .
)

Is it best practice or recommended to use PUBLIC or INTERFACE for the current directory include ? Assuming foo.cpp did a #include "foo.h" the quotes ("") will let the compiler search the current directory. So I don’t believe PUBLIC would be required to build the library. And in that sense INTERFACE could be used, assuming users of lib were to use foo.h. Any pitfalls to avoid here?

Perhaps if this lib used an include and src directory setup, this question wouldn’t arise. Because then in order for foo.cpp to find foo.h, we’d either have to relatively step back a directory, aka #include "../include/foo.h (which feels like a smell), or specify the include directory as PUBLIC. However, in this case, would we want to explicitly list the src directory as PRIVATE or rely on the fact that relative includes just work and omit src from target_include_directories entirely, supposing we had more .h/.cpp files in src.

I usually use PUBLIC, but I also use the ${CMAKE_CURRENT_SOURCE_DIR} variable instead of . (which can change meanings depending on what is reading it; CMake does some work for relative paths here, but I can never remember and instead just prefer to use absolute paths).

If you want to separate out headers, something like:

/lib/include/foo.h
/lib/src/foo.cpp
/lib/src/foo_private.h

could work.

1 Like