add_subdirectory

add_subdirectory tells CMake to enter another folder, read its CMakeLists.txt, and treat everything defined there as part of the same build.

1add_subdirectory(tests)

When CMake processes this line, it immediately steps into the tests/ directory, loads tests/CMakeLists.txt, and executes it just as if its contents were written in the main file.

Any targets created inside that subdirectory, such as executables or libraries defined with add_executable or add_library, become part of the same overall project. These targets can be built with make, linked against other targets, and discovered and run by ctest.

The big picture in modern CMake is that everything revolves around targets. A target represents a concrete buildable unit, such as an executable or a library, and CMake manages dependencies and relationships between these targets automatically.

target_include_directories

target_include_directories controls where the compiler looks for header files when it encounters an #include directive.

For example, when the compiler sees an include like the following, it needs to know which directories to search in order to find the corresponding header files.

1#include "order_book.hpp"
2#include <boost/asio.hpp>

The compiler first checks the directory of the current source file. If the header is not found there, it then searches through the include directories provided by target_include_directories.

The general syntax of this command is shown below. The visibility keyword determines how the include directories are applied to the target and any targets that depend on it.

1target_include_directories(<target>
2    PRIVATE | PUBLIC | INTERFACE
3    <dir1> <dir2> ...
4)

Using PRIVATE means the include directories are only used when compiling this target. PUBLIC applies the directories to this target and anything that links against it, while INTERFACE applies them only to dependent targets.

In the example below, the Boost include directory is added so the compiler can find Boost headers such as boost/asio.hpp .

1set(BOOST_INCLUDEDIR "/usr/local/opt/boost/include")
2
3add_executable(
4  mini_trader
5  src/main.cpp
6  src/order_book.cpp
7  src/tcp_server.cpp
8)
9
10# Important: all source files must be listed so they are compiled and linked
11target_include_directories(
12  mini_trader
13  PRIVATE ${Boost_INCLUDE_DIRS}
14)