This is merely a convention, but you are advised to follow it, especially if you are working in a large project.
Let’s say you have a foo library.
You have the following files:
This is what your layout should look like:
fooproject
|__ libfoo
| CMakeLists.txt
|__ foo
| |__ foo.hpp
|__ src
| |__ foo.cpp
| |__ foo_private.hpp
| |__ foo_private.cpp
|__ test
|__ CMakeLists.txt
|__ foo_test.cpp
Here’s what the CMakeLists.txt should look like
Please note that the location of the CMake list file matters.
You will note that:
#include <foo/...>
This way, we are sure that the code we use can be re-distributed when the headers are installed, and that the path to find the headers while in the source tree does not differ from the paths to find the installed headers. This works because:
qi_install_header(foo/foo.hpp SUBFOLDER foo)
With the proposed layout, you have something like:
foooproject
|__ libfoo
| |__ foo
| | |__ foo.hpp
| libbar
| |__ bar
| |__ bar.hpp
|__ foobar
|__ foobar.cpp
You may want to get rid of the useless redundancy foo/foo, bar/bar, and do this instead:
fooproject
|__ foo
| |__ foo.hpp
| bar
| |__ bar.hpp
foobar
|__ foobar.cpp
But, let’s assume you have
qi_use_lib(foobar foo)
instead of
qi_use_lib(foobar foo bar)
In the first layout, you will have an error during compile time, looking like:
bar/bar.hpp : no such file or directory
(because the include directory that has been staged for foo is different from the include directory that has been staged for bar) But, using the second layout, you will have an error during link time, looking like:
undefined reference to `bar_func'
(because the include directory that was staged was always the same: lib)
Note
For large libraries, also consider using submodles. The documentation can be found here