Problem-solving recipes
A step-by-step procedure for every problem type this course teaches — what to do first, what to do next, and how to tell which case you're in.
What are you being asked to do?
What's in front of you right now?
- The build stopped with
error:lines → Fix a build that won't compile. If the first error is inside a template, with pages ofrequired from hereandcandidatenotes → Fix a build that fails inside a template. - It builds, but crashes or gives a wrong answer → Debug a crash or a wrong answer. If someone reported the bug and the code has tests → Fix a reported bug, test first, which uses the debugging recipe inside it.
- You're designing a class that owns something → Make a class copy and move correctly.
- One file has grown and a second program or a test needs its code → Split code into a header, a source file and a CMake library.
- You need data from a text file → Read a text file to the end.
- Your project needs someone else's library → Add a library your project depends on. There are three versions in Chapter 24: FetchContent (§2), then vcpkg (§3), then Conan (§4). Each adds a path to the one before it.
- Other projects need your library → Ship a shared library for other projects to use.
When the build fails
Fix a build that fails inside a template
Use when: the first error: points into a template's body or a library header, and the output runs to pages of required from here, requested here and note: candidate lines
Goal: the one line of your own code that caused the error, and whether to change the type you passed or the call you made
Reading template errors
The same first move, plus finding what T was and which line of yours asked for it.
When it builds but misbehaves
Debug a crash or a wrong answer
Use when: the program builds, but it crashes, prints garbage that changes from run to run, or gives a wrong answer, and reading the code hasn't shown why
Goal: the exact line that goes wrong, found by the tools rather than by guessing, and a fix confirmed on the same input
Sanitizers · extended later in this course
Warnings, then a sanitizer build, then the debugger, always on the same input.
Fix a reported bug, test first
Use when: someone reports a wrong result ("an empty message counts as one word") in code that has, or can have, automated tests
Goal: a fix, plus a regression test that you've seen fail on the old code and pass on the new code
Test-first bug fixing
Wraps the debugging recipe in a test that fails first and stays in the suite.
Writing the code
Libraries in and out
Add a library your project depends on
Use when: your code needs a library from outside the project, such as {fmt} or a JSON parser, and the build should get it by itself, with nothing installed by hand first
Goal: the library's :: target, pinned to one exact version and linked into your own target, building the same way on every machine
FetchContent, building a dependency from source · extended later in this course
With FetchContent, building the library from source inside your own build.
Add a library your project depends on
Use when: your code needs a library from outside the project, and the build should get it by itself, including big libraries you don't want rebuilt in every fresh build folder
Goal: the library's :: target, at a version you chose on purpose, linked into your own target, with CMakeLists.txt never naming the tool that fetched it
vcpkg in manifest mode · extended later in this course
Adds vcpkg, for big libraries or many of them.
Add a library your project depends on
Use when: your code needs a library from outside the project, and the build should get it by itself, whether that means building it from source or downloading a copy someone already built
Goal: the library's :: target, at a version you chose on purpose, linked into your own target, with CMakeLists.txt the same whichever tool fetched it
Conan 2
Adds Conan 2, for prebuilt binaries on many platforms. The most complete version.
Ship a shared library for other projects to use
Use when: you've written a library, and a separate project, built on another day, maybe on another machine, should use it with one find_package line and one target_link_libraries line
Goal: an installed folder, with bin, lib, include and a CMake package, that another project finds by name and links as one :: target, and whose programs still load the library after the folder is moved
install(), export(), and find_package
The other direction. Build, export, install and package your own library so find_package can use it.