# CMake

Nivå: intermediate | Målgrupp: C/C++ programmerare | Förkunskaper: Kunna skriva och kompilera C/C++ applikationer
https://www.ribomation.se/programmerings-kurser/cmake/

CMake har seglat upp som det mest populära byggnations-verktyget för C/C++ applikationer och bibliotek.
Skälet är att CMake egentligen är en generator för byggnations-verktyg såsom Make, Ninja, MSVSC++, Xcode
med flera, vilket skapar flexibilitet avseende både verktyg och editorer.

CMake är ett av de mest populära byggnations-verktyget för C/C++ applikationer.
Det är enkelt att hantera komplexa byggnationer med många bibliotek.

Bibliotek som länkas till en applikation kan vara i många former, såsom
archive (`.a`), shared-object (`.so`) och header-only.
Förutom att vara en del av aktuellt projekt, så kan bibliotek länkas från redan installerade
eller laddas ned automatiskt från en git repo eller webb-server.

Den här kursen lär dig allt du behöver veta för att snabbt komma igång med att skriva egna
CMake script för byggnation av C++ och C applikationer. Kursen är uppdaterad för CMake version 3.28
och innehåller ett nyskrivet kapitel om presets.

- Configure CMake for C/C++ projects
- Configure build of executables
- Configure build of static libraries
- Configure build of shared libraries
- Link external libraries
- Download automatically and link remote libraries
- Generate source code
- Generate API documentation with doxygen
- Execute various tools as part of the build
- How to perform cross-compilation
- Understand how to utilize presets

#### Background
- Why CMake was created
- Properties of CMake
- Compilers
- Build tools
- Build tool generators

### Application Build

#### Compilation & Linkage
- Using GCC
- Pre-processor
- Front-End compilation
- AST and RTL
- Back-end compilation
- Assembler
- Linker
- Loader
- Useful compiler flags
- Linking libraries
- Creating static libraries
- Creating shared libraries
- Executing with shared libraries

#### Archives
- What is an archive
- Creating a static archive file (`*.a`)
- Naming conventions of archive files
- Creating a dynamically linked archive file (`*.so`)

#### Brief about Makefiles
- What is make
- Structure of a Makefile
- Targets
- Actions
- Dependencies
- Rules
- Ninja instead of Make

### CMake Fundamentals

#### Installation of CMake
- Installation via a package manager
- Installation on Windows
- Installation via TAR.GZ archive
- Compiling from sources
- CMake executables
- CMake command-line help
- CMake documentation

#### CMake Syntax
- Structure of CMakeLists.txt
- CMake stages
- Comments
- Command syntax
- Text strings
- Quoted vs. unquotes strings
- Value lists
- Variables
- Conditional blocks
- Looping blocks
- CMake scopes
- Subdirectories and includes
- CMake GUI

#### Control Structures
- Conditional blocks
- Operators
- Loops
- Generator expressions
- Functions

### Executables

#### Building Executables
- Creating a CMake project
- Build steps and commands
- Programming language
- Language standard
- Compiler options
- Linking standard libraries

#### Build Variants
- Debug vs. Release build
- C++ vs. C sources
- GCC vs. CLang compiler
- Make vs. Ninja builder
- Linux vs. Windows build

### Libraries

#### Building Libraries
- Building a static library
- Where to find the *.a file
- Propagating header files to an executable

#### Building Header-Only Libraries
- Defining a header-only library

#### Building Dynamic Libraries
- Building a shared library
- Where to find the *.so file

#### Other Library Types
- Defining an object library
- Using an imported library

#### Linking External Libraries
- What is an external library
- Finding libraries
- Configuration variables

#### Linking Remote Libraries
- What is a remote library
- Downloading and linking a remote library
- Understanding FetchContent
- Fetching a GIT library
- Fetching a TAR.GZ file

### Tests & Docs

#### Configuring and Running Tests
- How cmake perceives a test
- Using CTest
- Configuring a simple test
- Configuring a test based on a header-only testing framework (Catch2)
- Configuring a test based on a linked testing framework (Google Test)
- Fetching and using a remote test framework

#### Generating API documentation using `doxygen`
- What is `doxygen`
- Invoking doxygen from CMake
- Configure tool properties
- How to generate fancy docs with custom CSS, tree-view and images

### Writing CMake Scripts

#### Running External Programs
- Custom targets
- Running the generated executable
- Running arbitrary scripts and programs
- Generating API documentation using doxygen

#### Working with Files
- Finding things in the file system
- Extracting path components
- The versatile `file()` command
- Copy a set of files to a directory
- Writing files
- Reading files
- HTTP(S) operations, i.e., GET and PUT

#### Generating Sources
- Copying files
- Variable substitution
- Managing application version
- Assembling build info

#### Recursive CMake
- How to structure a large C/C++ project
- Top-level CMakeLists.txt
- Dependencies
- Subsystems
- Tests

#### Cross-Compilation
- What is cross-compilation
- Toolchain identifier
- What is `sysroot`
- What is a multi-lib
- Using CMake for cross-compilation
- Toolchain file
- How to build applications for several toolchains (_i.e._, platforms)

#### Presets
- What are CMake presets
- Understanding the preset JSON format
- Top-level JSON properties
- Common structure of all presets objects
- Configure `configurePresents`
- Configure `buildPresents`
- Preset macros
- Preset inheritance
- Preset conditions
