# CMake projects and targets **A project is declared with `project(name)`, and targets are the build artifacts you create** — executables, libraries, or custom outputs. Each target has properties (source files, include paths, linked libraries, compiler flags). In modern CMake, you apply settings to targets, not globally. A project groups related targets: ```cmake cmake_minimum_required(VERSION 3.20) project(MyApp VERSION 1.0) add_executable(myapp main.cpp) add_library(mylib utils.cpp) ``` This creates a project `MyApp` with two targets: the executable `myapp` and a library `mylib`. Target types: - `add_executable(name source.cpp)`: builds an executable - `add_library(name source.cpp)`: builds a library (static by default) - `add_library(name SHARED source.cpp)`: shared library (.so, .dll) - `add_library(name STATIC source.cpp)`: static library (.a, .lib) - `add_library(name INTERFACE)`: header-only library (no build, only interface) - `add_custom_target(name COMMAND ...)`: runs a command (not a traditional build output) Each target owns its properties: source files, include directories, linked libraries, compiler flags. Properties are set with `target_*` commands: ```cmake target_sources(mylib PRIVATE utils.cpp utils.h) target_include_directories(mylib PUBLIC include/) target_link_libraries(mylib PRIVATE somelib) target_compile_options(mylib PRIVATE -Wall) ``` The `PRIVATE`, `PUBLIC`, `INTERFACE` keywords control visibility: - `PRIVATE`: only the target itself uses it - `PUBLIC`: target and anything that links to it use it - `INTERFACE`: only consumers of the target use it (for header-only libraries) Modern CMake means thinking in targets. Don't set global flags with `set(CMAKE_CXX_FLAGS ...)`. Instead, configure each target individually. This makes builds predictable and modular.