Opinions on include directories

Hi,
The annoying noob is back and is asking stupid questions again :sweat_smile:
I am currently spending some time to figure out a useful directory structure for my use of headers…

I still would like the everything to be as self cotained as possible, without my directory structure looking crowded… Please tell me which of the three structures you would prefer, or if there is even something better than the structures I am consdering.

Layout 1:

lib1/
├── CMakeLists.txt
├── lib1.cpp
└── lib1.hpp

This would be my prefered option as far as looks, but then my cmake code for this library would need to look something like this:

add_library(lib1 lib1.cpp)
target_include_directories(lib1 PUBLIC .)

I think that this solution is a little bit janky…

Layout 2:
Another version of that that would probably be okay would be the following:

lib1/
├── CMakeLists.txt
├── include
│   └── lib1.hpp
└── lib1.cpp

I don’t know if I could like this layout, but the cmake code would be nicer:

add_library(lib1 lib1.cpp)
target_include_directories(lib1 PUBLIC include)

I think that it will look a little clunky too, but at least header and implementation will still be close together. Which is not true for the next one.

Layout 3:

.
├── CMakeLists.txt
├── include
│   └── lib1
│       └── lib1.hpp
└── src
    └── lib1
        └── lib1.cpp

This is a variation of a layout I was forced to use and that I quickly got sick of… Cmake code would roughly look like this:

add_library(lib1 src/lib1/lib1.cpp)
target_include_directories(lib1 PUBLIC include/lib1)

Here is an example of one of my projects, you can see how I’ve laid out the directories.

One thing to be aware of with include directories is that you only want to hard-code absolute paths when the library is being built – when using the installed package, the directories need to be relative to the root of the package. You can use generator expressions for this:

target_include_directories (lib1 PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
$<INSTALL_INTERFACE:include>)

install (FILES yourHeaders DESTINATION include)

I was omitting the generator expressions for my tiny examples, because they cause me some pain. I seem to always mess them up.
But I will take a look at cour project