2.0 What This Teaches
- The three main compilers: g++, clang++, MSVC
- Compiling a single file from the command line
- Useful compiler flags
- CMake as a portable build system
- A minimal
CMakeLists.txtand build workflow - Multi-directory projects:
src/, a static library, andadd_subdirectory
2.1 Choosing a Compiler
| Compiler | Platform | Notes |
|---|---|---|
| g++ | Linux, macOS, Windows (MinGW/MSYS2) | Default on most Linux distros; install with your package manager |
| clang++ | Linux, macOS, Windows | Excellent error messages; default on macOS via Xcode tools |
| MSVC (cl) | Windows only | Ships with Visual Studio; best Windows integration |
2.2 Single-File Compilation
g++ -std=c++17 -Wall -o program main.cpp
clang++ -std=c++17 -Wall -o program main.cpp
2.3 Useful Compiler Flags
| Flag | Meaning |
|---|---|
| -std=c++17 | Enable C++17; use -std=c++20 for C++20 |
| -Wall | Enable the most common warnings |
| -Wextra | Additional warnings beyond -Wall |
| -O0 | No optimization (default; best for debugging) |
| -O2 | Optimize for speed (release builds) |
| -g | Include debug symbols for gdb/lldb |
| -o <name> | Name the output executable |
2.4 CMake Basics
CMakeLists.txt. The same
CMakeLists.txt works on every platform.
cmake.org or via your package manager
(apt install cmake, brew install cmake,
winget install cmake).
2.5 A Minimal CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(hello)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(hello src/hello.cpp)
add_executable names the
output binary and lists its source files. Add more .cpp files to
that list as the project grows.
2.6 Build and Run with CMake
cmake -S . -B build # configure: generate build files in build/
cmake --build build # compile
./build/hello # run (Linux/macOS)
.\build\Debug\hello.exe # run (Windows)
-S . specifies the source directory (where CMakeLists.txt lives).
-B build puts all generated files in a build/
subdirectory, keeping the source tree clean. Run cmake --build build
again after any source change; CMake only recompiles what changed.
2.7 Multi-Directory Project with a Library
target_link_libraries. A typical layout:
myproject/
CMakeLists.txt <-- root: wires everything together
src/
main.cpp
mylib/
CMakeLists.txt <-- library: compiled independently
mylib.h
mylib.cpp
CMakeLists.txt defines the target and exports its include path:# mylib/CMakeLists.txt
add_library(mylib STATIC mylib.cpp)
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
CMakeLists.txt pulls in the subdirectory and links the executable against it:# CMakeLists.txt (root)
cmake_minimum_required(VERSION 3.15)
project(myproject)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(mylib) # process mylib/CMakeLists.txt
add_executable(myproject src/main.cpp)
target_link_libraries(myproject PRIVATE mylib)
// mylib/mylib.h
#pragma once
int add(int a, int b);
int multiply(int a, int b);
// mylib/mylib.cpp
#include "mylib.h"
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
// src/main.cpp
#include <iostream>
#include "mylib.h"
int main() {
std::cout << add(3, 4) << "\n"; // 7
std::cout << multiply(3, 4) << "\n"; // 12
}
add_library(mylib STATIC ...) compiles mylib.cpp into
a static archive (.a / .lib).
target_include_directories(mylib PUBLIC ...) with PUBLIC
means any target that links mylib automatically gets
mylib/ on its include path — main.cpp can
#include "mylib.h" without any extra flags.
PRIVATE on target_link_libraries means the link
dependency stays internal to myproject and is not exported further.
cmake -S . -B build
cmake --build build
./build/myproject
2.8 Exercise
Exercise
- Compile
hello.cppdirectly withg++orclang++and run it. - Create a
CMakeLists.txtfor the same file, build it with CMake, and confirm the output is identical. - Add
-Wall -Wextrato your direct compile command. Introduce a variable that is declared but never used and observe the warning. - Build the
src+myliblayout from section 2.7. Add a third functionsubtractto the library, call it frommain.cpp, and rebuild withcmake --build build. Confirm only the changed files are recompiled.
2.9 Key Terms
| Term | Meaning |
|---|---|
| g++ | GNU C++ compiler; standard on Linux |
| clang++ | LLVM C++ compiler; standard on macOS |
| MSVC | Microsoft Visual C++ compiler; Windows only |
| CMake | Meta-build system that generates platform-specific build files |
| CMakeLists.txt | CMake configuration file describing the project |
| -std=c++17 | Compiler flag selecting the C++17 language standard |
| -Wall | Enable common compiler warnings |
| cmake -S . -B build | Configure step: generate build files in build/ |
| cmake --build build | Build step: compile the project |
| add_subdirectory | Processes a child CMakeLists.txt and adds its targets to the build |
| add_library | Defines a library target; STATIC produces a .a/.lib archive |
| target_link_libraries | Links a target against another; PRIVATE keeps the dep internal |
| target_include_directories | Adds include paths; PUBLIC propagates them to dependents |