build sudoku from scratch: lesson 0 — set up VS Code + C++ toolchain (Mac & Windows)
Lesson 0 of the build-a-sudoku academic series. Install VS Code + a C++20 toolchain (Apple Clang on Mac / MSVC on Windows) + CMake + Git so the multi-root workspace opens, configures and builds. Cover Mac+Windows paths in parallel — every later lesson assumes both work.

The first time I tried to just write a C++ program outside of a school IDE, I burned an entire weekend on one error message. The compiler swore it had never heard of std::cout. Three browser tabs later, I realised the actual problem was not the code at all — the compiler itself was a leftover stub from a forgotten Xcode update. I had been building against air.
That weekend cost me a project I never finished, and it is also exactly why this series opens with a setup lesson instead of with #include <iostream>. Sudoku is small enough to fit in your head and real enough to teach you how a polished C++20 toolchain behaves — but only if the toolchain is awake before you write the first line. Lesson 0 has nothing to do with Sudoku rules. It is about turning your laptop into a machine that can ship a small C++ binary on demand, on Mac or on Windows, without flinching.
1. Goals
What does "my laptop can build C++20" actually mean in terms you can check in under two minutes? By the end of this lesson, you'll have a laptop that can clone this repository, configure it with CMake, build it with either Apple Clang on Mac or MSVC on Windows, and run the resulting binary to print a placeholder grid. Concretely, every checkbox below should be true:
- VS Code is installed and the recommended extensions (C/C++, CMake Tools, clangd) accepted.
- A C++20 toolchain is on
PATH. On Mac that meansclang++ --versionanswers from Apple Clang. On Windows it meanscl.exeis reachable from a Visual Studio Developer prompt. cmake --versionreports 3.20 or newer.git --versionreports any recent release.- The multi-root workspace file
sudoku.code-workspaceopens cleanly in VS Code. cmake -S . -B buildsucceeds andcmake --build buildproduces asudoku(orsudoku.exe) binary that runs.
If any one of those is missing, don't move on to Lesson 1. Every later lesson assumes this foundation is in place, and chasing a build failure across three lessons is much harder than fixing it here.
2. File tree
Most tutorials open with a sprawling folder skeleton you'll spend the rest of the lesson backfilling — we are going to do the opposite, and you'll thank yourself by Lesson 2. Here's the repository layout at the end of this lesson. Six top-level files plus a small .vscode/ directory — intentionally tiny, because the goal is to feel comfortable with each line before the project grows.
build-sudoku-from-scratch/
├── .gitignore
├── .vscode/
│ ├── extensions.json
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
├── CMakeLists.txt
├── README.md
├── src/
│ └── main.cpp
└── sudoku.code-workspace
3. Content to learn
You don't need to memorise every term in this section on the first read — skim it, run the commands in section 4, then come back to the parts your fingers are still uncertain about. This section is about concepts, not commands. Read it slowly even if you've written C++ before, because the choice between Apple Clang and MSVC will shape error messages and debugger ergonomics for every later lesson in the series.
A C++ toolchain is the bundle of programs that turns source files into a binary: a preprocessor, a compiler, an assembler, and a linker. On Mac the canonical bundle is Apple Clang, which ships inside Xcode Command Line Tools. On Windows the canonical bundle is MSVC, which ships inside Visual Studio Build Tools or the full Visual Studio Community installer. Both are free for personal use, and both support C++20 fully on releases from 2022 onward.
CMake is not a build system. It is a build-system generator. You write CMakeLists.txt; CMake reads it and emits either Ninja files, Makefiles, or Visual Studio solutions depending on your platform. Choosing CMake over a raw Makefile or a vcxproj is what makes the same source tree compile on Mac and Windows without forking the project. The trade-off is a small DSL to learn, in exchange for portability that pays back from Lesson 1 onward.
Why C++20 specifically? The standard brings concepts, ranges, consteval, and std::span. Later lessons use std::span in the solver, ranges in the renderer, and consteval for compile-time grid invariants. C++17 would work for most of the game, but the solver code is noticeably uglier without ranges, so the cost of requiring a moderately recent toolchain is small and the readability win is large.
Multi-root workspace is a VS Code feature that lets one window own several folders that may sit anywhere on disk. We use only one folder today, but the .code-workspace file is forward-compatible with a later lesson where we split the solver into its own subdirectory. Opening the project via the workspace file rather than via Open Folder is what lets CMake Tools find the right sourceDirectory and buildDirectory from day one.
Finally, compile_commands.json is the bridge between your editor and your compiler. CMake emits it when CMAKE_EXPORT_COMPILE_COMMANDS=ON, and clangd or IntelliSense reads it to learn which flags your project compiles under. Without it, hover-tooltips will lie about which header an identifier came from, and that lie compounds as the project grows.
4. How to do it
Commit (start): e0e9b91 Commit (end-of-lesson): 75e8e38
Lesson 0 – Install VS Code, a C++20 toolchain, CMake, and Git
Steps below assume a fresh laptop. Skip any sub-step that's already done. End-to-end, the first run takes roughly 20 to 40 minutes, mostly download wait.
Step 1 – Install Git.
- Mac: open Terminal and run
xcode-select --install. That installs Git plus the rest of the Command Line Tools. If you already have a recent Xcode, it's already done. - Windows: download the installer from https://git-scm.com/download/win and accept the defaults. When asked, pick "Use Git from the Windows Command Prompt".
Step 2 – Install the C++ toolchain.
- Mac: the same Command Line Tools package from Step 1 already ships Apple Clang. Confirm with
clang++ --version. You want Apple Clang 15 or newer, which announces full C++20 support. - Windows: install Visual Studio 2022 Community from https://visualstudio.microsoft.com/downloads/ and tick the "Desktop development with C++" workload. Don't install only the Build Tools unless you know what you're doing. The full workload bundle gives you
cl.exe, the Windows SDK, and an optional CMake in one shot.
Step 3 – Install CMake.
- Mac:
brew install cmake. If you don't yet have Homebrew, install it first from https://brew.sh/. Homebrew normally ships a fresher CMake than the one bundled with Xcode. - Windows: if you ticked the "Desktop development with C++" workload in Step 2, CMake is already on disk. Otherwise grab the x64 installer from https://cmake.org/download/ and tick "Add CMake to the system PATH" during installation.
Step 4 – Install VS Code.
Grab the installer from https://code.visualstudio.com/. On first launch, let it install the three recommended extensions when prompted: ms-vscode.cpptools, ms-vscode.cmake-tools, and llvm-vs-code-extensions.vscode-clangd. The clangd extension is optional on Windows, where IntelliSense alone is fine, but on Mac it produces noticeably faster hover-tooltips against Apple Clang.
Step 5 – Clone the repository.
git clone https://github.com/vytharion/build-sudoku-from-scratch.git
cd build-sudoku-from-scratch
Step 6 – Open the workspace.
Open VS Code, then File → Open Workspace from File… and pick sudoku.code-workspace. Accept the prompt to install the recommended extensions if you skipped it earlier. The CMake Tools status bar should display a kit selector. Pick "Clang" on Mac or "Visual Studio Community 2022 Release - amd64" on Windows.
Step 7 – Configure and build.
From the integrated terminal:
cmake -S . -B build
cmake --build build
CMake will create a build/ directory, write Ninja or MSBuild files into it, and emit compile_commands.json at the repository root.
Step 8 – Run the binary.
# Mac
./build/sudoku
# Windows (from a Developer PowerShell)
./build/Debug/sudoku.exe
You should see a banner of dots and the line C++ standard: 202002. If the number is 201703 instead, your compiler ignored the C++20 flag. Usually that's because an older Apple Clang is shadowing the new one on PATH. Re-run Step 2 before continuing.
5. Key learning
Three habits worth carrying out of this lesson:
-
Treat the toolchain as a project artefact. A build that works on Mac but not Windows is a bug, not a quirk. CMake is the standard answer because it's the smallest abstraction that survives both Apple Clang and MSVC. About 80% of the cross-platform pain in this series gets paid here, in Lesson 0, in exchange for almost frictionless later lessons.
-
Pin the standard early.
set(CMAKE_CXX_STANDARD 20)plusset(CMAKE_CXX_STANDARD_REQUIRED ON)plusset(CMAKE_CXX_EXTENSIONS OFF)is one three-line incantation that guarantees identical language behaviour everywhere. Skipping theREQUIREDflag means CMake silently falls back to an older standard if the compiler refuses C++20. That's exactly the failure mode you want to forbid. -
Emit
compile_commands.jsonfrom day one. clangd, IntelliSense, code-review bots, and CI linters all read it. Addingset(CMAKE_EXPORT_COMPILE_COMMANDS ON)to a new project costs nothing and pays back the first time you hover a symbol and the tooltip is actually accurate.
A fourth, softer habit: keep "I'm editing code" separate from "I'm setting up the environment". Hours spent on Lesson 0 are an investment that compounds, not a tax on the fun part. The investment is biggest on a fresh laptop and smallest when you reproduce the same setup on a second machine — where you should be able to repeat the entire flow in under 10 minutes.
6. How to verify
Run these commands in the integrated terminal. Each one corresponds to a specific failure mode. If any reports something different from the expected value, fix that step before moving on.
git --version # any 2.x release
cmake --version # >= 3.20
clang++ --version # Mac: Apple clang 15+
cl.exe # Windows: 19.30+ (inside Developer prompt)
cmake -S . -B build # configures with zero red lines
cmake --build build # builds with zero red lines
./build/sudoku # prints banner and 202002
Inside VS Code, open src/main.cpp and hover the word cout. The tooltip should pop up within about a second and reference <iostream>. If it shows "Loading…" forever, clangd hasn't picked up compile_commands.json, usually because the file is missing or because the clangd extension hasn't finished its first index. Force a re-index with View → Command Palette → clangd: Restart language server.
7. Common errors / pitfalls
The table below collects the failures that show up most often in this lesson across both platforms. Every "Fix" column is short on purpose: each one is a 30-second action, not a research project.
| # | Symptom | Likely cause | Fix |
|---|---|---|---|
| 1 | clang++: command not found on Mac | Command Line Tools not installed or partly uninstalled | Re-run xcode-select --install |
| 2 | cl is not recognised on Windows | Running from regular PowerShell, not Developer PowerShell | Open "Developer PowerShell for VS 2022" from Start menu |
| 3 | C++ standard: 201703 instead of 202002 | Old Apple Clang on PATH shadowing the new one | which clang++, then remove the stale entry or fix PATH order |
| 4 | CMake configure fails with "No CMAKE_CXX_COMPILER" | First run before any toolchain is installed | Complete Step 2, then re-run cmake -S . -B build |
| 5 | VS Code asks "Which CMake kit?" every reload | Kit not pinned in workspace settings | Select the kit, then CMake: Set Active Kit and accept "save in workspace" |
| 6 | clangd shows red squiggles on std::cout | compile_commands.json missing at repo root | Run cmake -S . -B build once, then clangd: Restart language server |
| 7 | Build is "successful" but no binary exists | Multi-config generator on Windows put it under build/Debug/ | Look in build/Debug/sudoku.exe, not build/sudoku.exe |
| 8 | .DS_Store files keep appearing in git status | Mac Finder leaving metadata | Already gitignored; ignore them or run find . -name .DS_Store -delete |
8. Room for self-study
The setup we built is intentionally minimalist. If you finish the exercises quickly and want to go deeper, try one of these threads:
- Read the CMake tutorial at https://cmake.org/cmake/help/latest/guide/tutorial/index.html through "Step 4". It explains generator expressions, which you'll see when we add the solver subdirectory.
- Compare the same
main.cppcompiled with-O0versus-O2on Mac (or/Odversus/O2on Windows). Disassemble each withobjdump -dordumpbin /disasm. The binary-size delta is small here, but the contrast in generated instructions is instructive. - Set up a second build directory named
build-debugconfigured with-DCMAKE_BUILD_TYPE=Debugand switch between them. Reasoning about why separate directories exist clears up several CMake confusions later in the series. - Read cppreference on
__cplusplusat https://en.cppreference.com/w/cpp/preprocessor/replace to understand how each language standard maps to a number. - Try cloning the repository on a third machine — a Raspberry Pi, a cloud shell, anything with a recent Clang — and confirm the same
cmake -S . -B build && cmake --build buildinvocation just works. That's the payoff of choosing CMake over a hand-rolled Makefile or a Visual Studio solution.
9. End-of-lesson exercises
- Add a
--versionflag tosrc/main.cppthat printssudoku 0.1.0and exits with code 0 when present, without altering the banner behaviour when absent. Make the flag case-insensitive so--Versionalso works. - Modify
CMakeLists.txtso configuration aborts with a clearmessage(FATAL_ERROR ...)if the host compiler doesn't support C++20. Trigger it intentionally by forcingCMAKE_CXX_STANDARD 17on a feature that needs C++20 and confirm the error fires. - Add a second executable target called
sudoku-banner-onlythat compiles a smaller source file containing only the banner (without the__cplusplusprint). Keep the originalsudokutarget intact and confirm both build undercmake --build build. - Add a
.clang-formatfile at the repository root usingBasedOnStyle: GoogleandIndentWidth: 4. Formatsrc/main.cppand commit any whitespace diff separately from your code changes so the formatting commit is easy to revert. - (challenge) Add a CMake option
SUDOKU_ENABLE_WARNINGS_AS_ERRORSthat defaults toOFF. WhenON, it should append-Werrorfor Apple Clang/GCC and/WXfor MSVC. Verify by deliberately writing an unused variable inmain.cppand confirming the build fails under-DSUDOKU_ENABLE_WARNINGS_AS_ERRORS=ONbut still passes when the option isOFF.
10. Exercise answer key
Repository
Full source at https://github.com/vytharion/build-sudoku-from-scratch. Each lesson lands as one commit on main, so you can git checkout <sha> to land on the exact state any lesson describes.
→ Next: 01-grid-data-structure – Modelling the 9×9 grid in C++20