Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

how-to

C++ Cross-Platform Dev Cookbook — one-liners, tools, and patterns for game dev, research, and reverse engineering.

Install once. Use everywhere. Copy-paste friendly.


📋 Index

# Topic What Deep Dive
0 Install One-command install per platform tools-install.md
1 CMake CLI one-liners: configure, build, test, pro tricks cmake.md
2 Project Navigation Study any repo fast: blame, history, diff, AI project-navigation.md
3 Git & lazygit Rebase, bisect, stash, cherry-pick, lazygit TUI git-tricks.md
4 Shell Tricks <() process substitution, pipes, parallel, aliases shell-tricks.md
5 Build Speed ccache, Ninja, PCH, unity build-acceleration.md
6 Search ripgrep, fd, fzf, bat search-navigation.md
7 Static Analysis cppcheck, clang-tidy, ast-grep static-analysis.md
8 Debug & Profile GDB/LLDB, threads, reverse debug, crash dumps (all platforms) debugging-profiling.md
9 Network Debug tcpdump, Wireshark, DNS, TLS, why can't it connect network-debugging.md
10 Cross-Compile Zig, Android, iOS cross-compilation.md
11 Packages vcpkg, Conan, FetchContent cmake-package-managers.md
12 Task Runner just — never type cmake again justfile.md
13 Benchmarking hyperfine, Google Benchmark benchmarking.md
14 File Tracking What did that command produce?
15 Mobile Dev ADB, root, Xcode, devicectl, LLDB mobile.md
16 Reverse Engineering Ghidra, r2, x64dbg, WinDbg reverse-engineering.md
17 Binary Tools UPX, hex, PE, shipping binary-tools.md
18 Controls & Input Steam Golden Rules, gamepad controls.md
19 Windows Dev Mode, WSL, Terminal, PowerToys, MSVC, CRT, PDB windows-cpp.md
20 Resources Books, talks, channels resources.md
21 USB-C Gamedev SDL3 gamepad, DP Alt Mode, PD charging, cables, docks usb-c-gamedev.md

0. Install Tools

Scoop preferred on Windows. Full table with every tool: tools-install.md

# 🪟 Windows (scoop — no admin needed, clean install to ~/scoop/)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
scoop install git cmake ninja ccache ripgrep fd bat fzf just llvm zig lazygit

# 🐧 Linux (Ubuntu/Debian)
sudo apt update && sudo apt install -y \
  build-essential cmake ninja-build ccache gdb lldb clang clang-tidy \
  ripgrep fd-find bat fzf strace tcpdump

# 🍎 macOS (get Xcode CLT first for clang + lldb + git)
xcode-select --install
brew install cmake ninja ccache ripgrep fd bat fzf just lazygit

1. CMake

Full CLI cookbook with pro tricks: cmake.md See also: Modern CMake guide, Professional CMake book

# THE daily command — debug + ninja + ccache + compile_commands
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
cmake --build build
ln -sf build/compile_commands.json .         # clangd/clang-tidy/IDE need this at root

# Build one target
cmake --build build --target myapp

# Test
ctest --test-dir build --output-on-failure

# Sanitizers
cmake -B build -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer" -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined"

# Presets (if project has CMakePresets.json)
cmake --list-presets
cmake --preset dev && cmake --build --preset dev && ctest --preset dev

# Study the project — what targets exist?
cmake --build build --target help | sort
# What features/options does it expose?
cmake -B build -LAH | rg -i "feature|enable|option|with"
# Generate dependency graph (needs graphviz)
cmake -B build --graphviz=deps.dot && dot -Tpng deps.dot -o deps.png
# Profile configure speed (CMake 3.28+)
cmake -B build --profiling-output=prof.json --profiling-format=google-trace
# → open prof.json at https://ui.perfetto.dev

# Cross-compile
cmake -B build/linux -DCMAKE_TOOLCHAIN_FILE=zig-toolchain.cmake
cmake -B build/android -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-24
cmake -B build/ios -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64

2. Project Navigation

Just cloned a big repo? Full guide: project-navigation.md Git official docs: git-log, git-blame, git-bisect

Orient yourself in 60 seconds

# What is this project?
scc                                         # language mix + line counts
tree -L 2 --dirsfirst -I 'build|.git|node_modules'
bat README.md

# What does it build?
cmake -B build -G Ninja && cmake --build build --target help | sort

# Who works on it?
git shortlog -sn --all | head -10           # top contributors
git log --oneline -20                       # recent activity

# Hottest files (most changed = most complex, most bugs)
git log --format=format: --name-only --since="6 months ago" | sort | uniq -c | sort -rn | head -15

Understand any file

# Who wrote this and when?
git blame src/engine/renderer.cpp | bat -l gitblame
git log --oneline -10 -- src/engine/renderer.cpp

# When was this function added?
git log -S "initVulkan" --oneline

# What changed in this file recently?
git diff HEAD~10 -- src/engine/renderer.cpp

AI-assisted study

# aider — AI pair programmer in terminal (https://aider.chat)
pip install aider-chat
aider --read-only src/engine/               # study mode: ask questions about code
# > "explain how the rendering pipeline works"
# > "what are the main abstractions and data flow?"

# GitHub Copilot Chat in terminal (https://cli.github.com)
gh copilot suggest "find all functions that allocate without RAII"
gh copilot explain "git rebase -i HEAD~5"

bisect — find the commit that broke it

git bisect start
git bisect bad HEAD                          # current is broken
git bisect good v1.0                         # v1.0 was good
# Test each checkout → git bisect good/bad → repeat until found
git bisect reset

# Automated (if you have a test):
git bisect start HEAD v1.0
git bisect run cmake --build build && ctest --test-dir build

3. Git & lazygit

Full reference with lazygit keybindings: git-tricks.md Tool: lazygit — TUI git client, makes rebase/bisect/cherry-pick visual

# Install: scoop install lazygit / brew install lazygit / sudo apt install lazygit
lazygit                                      # launch TUI — everything is visual

# Interactive rebase (lazygit: go to Commits [3], press 'e' to edit, 's' to squash)
git rebase -i HEAD~5                         # CLI equivalent

# Cherry-pick
git cherry-pick abc1234                      # one commit
git cherry-pick abc1234..def5678             # range

# Stash tricks
git stash push -m "WIP: feature X"          # named stash
git stash push -- src/a.cpp src/b.cpp       # specific files only
git stash push -u -m "with untracked"       # include untracked
git stash list                              # see all stashes
git stash apply stash@{2}                   # apply without dropping

# Reflog — recover anything
git reflog                                  # every HEAD movement ever
git checkout -b recovered-branch abc1234    # recover deleted branch

# Worktrees — work on multiple branches simultaneously
git worktree add ../project-hotfix hotfix-branch
cd ../project-hotfix                        # separate dir, same repo

# Pretty log
git log --oneline --graph --decorate --all -30

💡 Pro tip: lazygit makes interactive rebase 10× faster. Select commit → press e to edit, s to squash, d to drop. Resolve conflicts inline. No CLI editor needed.


4. Shell Tricks

Full reference with process substitution, pipes, aliases: shell-tricks.md

Process substitution <() — the secret weapon

Did you know? <() runs a command and gives you a temp file descriptor. No temp files needed.

# Compare two command outputs
diff <(cmake --build build --target help | sort) <(cmake --build build-rel --target help | sort)

# Compare compile_commands between builds
diff <(jq '.[].file' build/compile_commands.json | sort) <(jq '.[].file' build-rel/compile_commands.json | sort)

# Compare git log of two branches
diff <(git log main --oneline -20) <(git log feature --oneline -20)

# Feed multiple sources to one command
cat <(rg "#include" --type cpp --no-filename) <(rg "#include" --type c --no-filename) | sort -u

# Pipe to multiple commands simultaneously
cmake --build build 2>&1 | tee >(grep -i error > errors.log) >(grep -i warning > warnings.log)

Pipe tricks

# xargs with parallel execution
fd -e cpp | xargs -P 8 -I {} clang-format -i {}

# Pipe to clipboard
rg "pattern" --type cpp | xclip -selection clipboard    # Linux
rg "pattern" --type cpp | pbcopy                         # macOS
rg "pattern" --type cpp | clip                           # Windows

# GNU parallel — process files 8 at a time
fd -e cpp -e hpp | parallel -j8 clang-format -i {}

# Brace expansion — create project structure fast
mkdir -p project/{src/{core,render,audio},include,test,build}
cp main.cpp{,.bak}                           # same as: cp main.cpp main.cpp.bak

fzf-powered workflow

# Install fzf key bindings: ~/.fzf/install
# Now you get:
# Ctrl+R = fuzzy history search with preview
# Ctrl+T = fuzzy file search inline
# Alt+C  = fuzzy cd

# Fuzzy open file with preview
fd -e cpp | fzf --preview 'bat --style=numbers {}' | xargs vim

# Fuzzy git branch checkout
git branch | fzf | xargs git checkout

5. Build Speed

Full reference: build-acceleration.md Compiler cache comparison: ccache vs sccache

# ccache — 5-10× faster rebuilds
ccache -s                                    # stats
ccache -C                                    # clear

# Enable in cmake:
cmake -B build -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache

# Unity builds (CI only!)
cmake -B build -DCMAKE_UNITY_BUILD=ON
Technique Cold build Hot rebuild
+ Ninja ~80% ~70%
+ ccache ~80% ~15%
+ PCH ~60% ~50%
+ Unity ~25% n/a

6. Search

Full reference: search-navigation.md Tools: ripgrep, fd, fzf, bat

# ripgrep — search code
rg "pattern" --type cpp -n -C 3             # with context
rg "TODO|FIXME|HACK" --type cpp             # todos
rg "new\s+\w+" --type cpp                   # raw owning pointers (smart ptr candidates)
rg "^#include" --type cpp --no-filename | sort -u  # all unique includes

# fd — find files
fd -e cpp -e hpp                            # all C++ files
fd --changed-within 1day                    # modified today

# fzf — fuzzy find
fd -e cpp | fzf --preview 'bat {}'          # fuzzy open with preview
git branch | fzf | xargs git checkout       # fuzzy branch switch

# bat — cat with syntax
bat src/main.cpp --diff                     # show git changes in gutter

7. Static Analysis

Full reference: static-analysis.md Tools: cppcheck, clang-tidy, ast-grep

# cppcheck — find bugs without compiling
cppcheck --enable=all --suppress=missingIncludeSystem src/

# clang-tidy (needs compile_commands.json from cmake configure)
clang-tidy -p build src/main.cpp
clang-tidy -p build --fix src/main.cpp      # auto-fix what it can

# clang-format (https://clang.llvm.org/docs/ClangFormat.html)
clang-format -style=llvm -dump-config > .clang-format
clang-format -i src/**/*.cpp src/**/*.hpp   # format all files

# ast-grep — structural search (AST-aware, not text)
sg -p 'new $$$' --lang cpp                  # all raw new
sg -p 'NULL' -r 'nullptr' --lang cpp -i     # replace all NULLs with nullptr

8. Debug & Profile

Full pro reference with thread control, reverse debugging & cross-platform crash dumps: debugging-profiling.md Debuggers: GDB, LLDB, raddebugger, x64dbg Profiler: Tracy, Perfetto, Valgrind

GDB

gdb -tui ./myapp
# b main | r | n | s | c | p var | bt | bt full | watch var | layout split | thread apply all bt

LLDB (preferred on macOS/iOS — ships with Xcode)

lldb ./myapp
# b main | run | next | step | continue | print var | po obj | bt | frame variable | expr myFunc(42)

🧵 Thread isolation — debug one thread, freeze all others

Did you know? You can freeze all threads except one. This is HUGE for multithreaded apps.

# GDB — freeze all threads except current
info threads                                 # list threads
thread 3                                     # switch to thread 3
set scheduler-locking on                     # NOW only YOUR thread steps
n                                            # next — only thread 3 moves
s                                            # step — only thread 3 moves
set scheduler-locking off                    # resume all

# LLDB — same concept
thread list                                  # list threads
thread select 3                              # switch to thread 3
settings set target.process.stop-others true # freeze others during step
next                                         # only thread 3 moves
settings set target.process.stop-others false

⏪ Reverse debugging — step BACKWARDS in time

Did you know? GDB can record execution and replay it backwards. Find "how did we get here?"

# GDB — record & reverse
(gdb) target record-full                     # start recording EVERY instruction
(gdb) continue                                # run forward normally
# ... hit breakpoint or crash ...
(gdb) reverse-step                            # step BACKWARDS
(gdb) reverse-continue                        # run backwards to previous breakpoint
(gdb) reverse-next                            # next line, backwards

💀 Crash dump debugging (all platforms)

Full cross-platform reference: debugging-profiling.md — Crash Dump section

⚠️ Always provide the target binary! Without it, no symbols resolve = raw hex addresses.

# Windows — LLDB (exe as target, dump as core — BOTH required!)
lldb myapp.exe -c crash.dmp
(lldb) bt                                    # backtrace at crash
(lldb) bt all                                # all threads
(lldb) frame variable                        # locals

# Windows — WinDbg for deeper analysis (auto-finds exe from dump)
windbg -z crash.dmp
.sympath+ C:\path\to\pdbs                    # add YOUR PDBs!
!analyze -v                                  # auto-analysis
kb                                           # call stack with params

# Linux — GDB core dump (binary + core — BOTH required!)
gdb ./myapp core.12345
(gdb) bt full                                # backtrace + locals
(gdb) thread apply all bt full               # all threads

# Linux — coredumpctl (systemd — auto-finds binary + core)
coredumpctl list                             # captured cores
coredumpctl gdb <pid>                        # opens GDB with correct binary + core

# Linux — LLDB (binary + core — BOTH required!)
lldb ./myapp -c core.12345
(lldb) bt

# macOS — crash report (binary + report — BOTH required!)
lldb ./MyApp -c MyApp-2024-01-15.ips
(lldb) bt

# Android — tombstone symbolication (unstripped .so path is critical!)
adb logcat | ndk-stack -sym obj/local/arm64-v8a

# iOS — symbolicate crash log (dSYM is critical!)
xcrun symbolicatecrash crash.ips MyApp.app.dSYM > symbolicated.crash
Platform Dump Symbols Binary needed Tool
Windows .dmp .pdb (MANDATORY) .exe (MANDATORY) LLDB, WinDbg, cdb
Linux core unstripped binary / .debug ELF binary GDB, LLDB, coredumpctl
macOS .crash / .ips .dSYM/ (MANDATORY) Mach-O binary LLDB, atos
iOS .ips .dSYM/ (MANDATORY) .app binary symbolicatecrash, LLDB
Android tombstone unstripped .so (MANDATORY) .so files ndk-stack, addr2line, LLDB
cmake -B build -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer" -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined"

Tracy (always-on profiler)

#include <Tracy.hpp>
void heavy() { ZoneScoped; TracyPlot("dt", dt); FrameMark; }
tracy-profiler & ./build/dev/myapp          # GUI connects automatically

Advanced debugging


9. Network Debug

Full reference with tcpdump, Wireshark, DNS, TLS decryption: network-debugging.md Tools: tcpdump, Wireshark, curl, netcat

Why can't my app connect?

# Step 1: Can I reach the host?
ping -c 4 host.com                           # by name
ping -c 4 1.2.3.4                            # by IP (bypasses DNS)

# Step 2: Is DNS working?
dig host.com                                 # DNS lookup (Linux/macOS)
nslookup host.com                            # all platforms

# Step 3: Is the port open?
nc -zv host.com 443 -w 3                     # TCP connect test
# PowerShell:
Test-NetConnection host.com -Port 443

# Step 4: What's the route?
traceroute host.com                          # Linux/macOS
tracert host.com                             # Windows

Packet capture

# tcpdump — capture everything on a port
sudo tcpdump -i any port 8080 -w capture.pcap
# Open capture.pcap in Wireshark

# Filter by host + save
sudo tcpdump -i any -w capture.pcap host api.example.com

# Show only connection attempts (SYN) and refusals (RST)
sudo tcpdump -i any 'tcp[tcpflags] & (tcp-syn|tcp-rst) != 0'

# DNS queries only
sudo tcpdump -i any port 53

TLS decryption in Wireshark

# Set SSLKEYLOGFILE before running your app
export SSLKEYLOGFILE=~/sslkeys.log
curl https://api.example.com                 # or run your app
# In Wireshark: Preferences → Protocols → TLS → set key log file
# Now you see decrypted HTTP content!

curl timing — where is it slow?

curl -o /dev/null -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nFirst byte: %{time_starttransfer}s\nTotal: %{time_total}s\n" https://api.example.com
# If DNS is slow → check /etc/resolv.conf
# If Connect is slow → firewall or routing issue
# If TLS is slow → certificate chain too long
# If First byte is slow → server-side processing

Host spoofing (test against different server)

# /etc/hosts — redirect domain to localhost
sudo sh -c 'echo "127.0.0.1 api.example.com" >> /etc/hosts'
# Or without modifying hosts:
curl --resolve api.example.com:443:127.0.0.1 https://api.example.com

10. Cross-Compile

Full reference: cross-compilation.md Cross-compiler: Zig — one tool, every target Emulator: QEMU — test Linux ARM/ARM64 binaries on any host

# Zig — one-command cross-compile
zig c++ -target x86_64-linux-gnu -O2 main.cpp -o main_linux
zig c++ -target aarch64-linux-gnu -O2 main.cpp -o main_arm
zig c++ -target x86_64-macos-none -O2 main.cpp -o main_mac

# Test with QEMU
qemu-x86_64 ./main_linux
qemu-x86_64 -strace ./main_linux            # trace syscalls

# CMake + Zig toolchain
cmake -B build/linux -DCMAKE_TOOLCHAIN_FILE=zig-toolchain.cmake -G Ninja

11. Packages

Full reference: cmake-package-managers.md Managers: vcpkg, Conan, CPM.cmake

# vcpkg (install: scoop install vcpkg / brew install vcpkg)
cmake -B build -DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake"
vcpkg install fmt spdlog nlohmann-json       # classic mode

# Conan 2 (install: pip install conan)
conan install . --output-folder=build --build=missing
cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake

12. Task Runner

Full reference: justfile.md Tool: just — like Make but without the pain

# justfile
default:
    @just --list

build preset="dev":
    cmake --preset {{preset}}
    cmake --build --preset {{preset}}

test preset="dev":
    ctest --preset {{preset}} --output-on-failure

watch preset="dev":
    watchexec -e cpp,hpp,h,c,cmake,just -- just build {{preset}}

lint:
    cppcheck --enable=all --suppress=missingIncludeSystem src/

format:
    clang-format -i src/**/*.cpp src/**/*.hpp

todos:
    rg "TODO|FIXME|HACK|XXX" --type cpp -n
just build preset=clang
just watch
just todos

13. Benchmarking

Full reference: benchmarking.md Tool: hyperfine — statistical CLI benchmarking

# Basic
hyperfine --warmup 5 --min-runs 20 "./myapp"

# Compare two versions
hyperfine "./old" "./new"

# Parameter sweep
hyperfine -P size 1024 65536 "./myapp --buf {size}"

# Compilation benchmark
hyperfine --prepare 'rm -rf build && cmake -B build -G Ninja' 'cmake --build build'

14. File Tracking

What files did that command/exe actually produce?

Linux/macOS

# strace — trace all file opens/writes (https://strace.io)
strace -f -e trace=open,openat,write -o trace.log ./myapp
strace -f -e trace=openat ./myapp 2>&1 | grep "O_CREAT"   # only new files

# macOS — fs_usage (built-in, comprehensive)
fs_usage -f filesys ./myapp

# Quick before/after snapshot
touch marker && ./myapp && find . -newer marker -type f

Windows

# procmon — GUI file/registry/network tracker ([Sysinternals](https://learn.microsoft.com/en-us/sysinternals/))
procmon /Quiet /Minimized /BackingFile trace.pml /AcceptEula
./myapp.exe
procmon /Terminate
procmon /OpenLog trace.pml /SaveAs trace.csv

# drstrace — CLI syscall tracing
scoop install drmemory
drstrace -- myapp.exe                        # → drstrace.myapp.exe.PID.log

Output tracking table

Command Produces Where
cmake -B build CMakeCache.txt, build.ninja build/
cmake --build build .o, .a, .exe, .so, .dylib build/
clang-tidy --fix Modified .cpp (in-place) source tree
clang-format -i Modified .cpp (in-place) source tree
upx --best app Compressed binary (in-place) same path
strip app Stripped binary (in-place) same path
rgp capture *.rgp GPU trace specified path
tracy-profiler *.tracy capture current dir
doxygen html/, latex/ docs/ or configured

15. Mobile Dev

Full reference: mobile.md Android: ADB docs, Android NDK iOS: devicectl, xcrun

Android

# Install: scoop install adb / brew install android-platform-tools
adb devices -l                              # list devices
adb install -r app.apk                      # install/reinstall
adb logcat -s MyTag *:E                     # filtered errors

# Root (eng/userdebug builds or [Magisk](https://topjohnwu.github.io/Magisk/))
adb root                                    # restart adbd as root
adb shell setenforce 0                      # disable SELinux
adb shell getenforce                        # check: Enforcing/Permissive

# Google APIs image (no Play Services — for clean testing)
sdkmanager "system-images;android-34;google_apis;arm64-v8a"
emulator -avd pixel_test -writable-system -no-snapshot

iOS (macOS only — requires Xcode)

xcrun simctl list devices                   # list simulators
xcrun simctl boot "iPhone 15"               # boot one
xcrun simctl install booted MyApp.app       # install
xcrun simctl io booted screenshot screen.png

# Physical device (Xcode 15+)
xcrun devicectl list devices
xcrun devicectl device install app --device <id> MyApp.app

# Build
xcodebuild -project MyApp.xcodeproj -scheme MyApp -sdk iphonesimulator build

# LLDB remote debug
lldb -n MyApp

16. Reverse Engineering

Full reference: reverse-engineering.md Tools: Ghidra (NSA decompiler), radare2 (RE framework), x64dbg (Windows debugger), WinDbg (kernel debug), IDA

# Quick recon
file myapp                                   # ELF/PE/Mach-O?
checksec --file=myapp                        # ASLR, DEP, PIE, canary?
strings myapp | rg -i "password|secret|key|token"

# Ghidra — decompile to C
ghidra                                       # launch GUI
# F5 = decompile | L = rename | X = cross-refs | G = go to address

# radare2 — CLI RE
r2 -A myapp                                  # open + full analyze
# afl = functions | iz = strings | pdf = disasm | VV = graph | s main = seek to main

# x64dbg — Windows runtime debug
x64dbg myapp.exe
# F2 = breakpoint | F7 = step in | F8 = step over | F9 = run

# WinDbg — kernel debug + crash dumps
windbg -z crash.dmp
# !analyze -v | kb | lm | .sympath srv*https://msdl.microsoft.com/download/symbols

# Binary patching (r2)
oo+                                        # reopen in write mode
wa nop @ 0x401000                            # NOP out instruction

17. Binary Tools

Full reference: binary-tools.md Tools: UPX, pe-bear, ImHex

# Compress
strip myapp.exe && upx --best myapp.exe

# DLL/dylib/so dependencies
depends myapp.exe                            # Windows ([dependencywalker.com](https://www.dependencywalker.com))
ldd myapp                                    # Linux (built-in)
otool -L myapp                               # macOS (built-in)

# PE/ELF inspection
pe-bear myapp.exe                            # Windows PE viewer
readelf -h myapp                             # ELF header
objdump -h myapp.exe                         # PE sections

# Strings audit
strings myapp.exe | rg -i "password|secret|pdb"

# Pre-ship checklist
checksec --file=myapp                        # security flags
strings myapp | rg "\.pdb"                   # debug symbols leaked?
strings myapp | rg -i "password"             # secrets?
depends myapp.exe                            # missing DLLs?

18. Controls & Input

Full reference: controls.md Source: Valve Steam Input docs, ISteamInput API, Steamworks

  1. On-screen icons match device — detect controller type, swap glyphs at runtime
  2. Cursor matches device — visible for mouse, hidden for gamepad
  3. All devices work 100% — test disconnect/reconnect, Steam Remote Play
  4. All inputs navigate menus — d-pad, stick, mouse all traverse UI
  5. Disconnect → pause — single player pause, multiplayer mark disconnected

Bonus: Gamepad + mouse must work simultaneously — #1 cause of Steam Input compatibility issues.

// Steam Input API — get real controller type for correct glyphs
SteamInput()->Init();
SteamInput()->RunFrame();
InputHandle_t ctrl = SteamInput()->GetControllerForGamepadIndex(0);
EInputActionOrigin origin = SteamInput()->GetActionOriginFromXboxOrigin(ctrl, k_EXboxOrigin_A);
const char* glyph = SteamInput()->GetGlyphForActionOrigin(origin);
// Load glyph as texture → future-proof for any new controller

Critical: Camera/aim action type MUST be absolute_mouse in IGA file. Steam Input converts gyro/trackpad/stick → absolute_mouse. Cannot convert back from joystick_move.


19. Windows C++

Full reference: windows-cpp.md — Dev Mode, WSL, Terminal, PowerToys, compilers, CRT, PDB

# Static CRT (no vcruntime.dll dependency)
cmake -B build -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$<CONFIG:Debug>:Debug>"

# PDB in release (crash dumps work — without PDB, crash analysis is impossible)
cmake -B build -DCMAKE_CXX_FLAGS_RELEASE="/Zi" -DCMAKE_EXE_LINKER_FLAGS_RELEASE="/DEBUG /OPT:REF /OPT:ICF"
# Defender exclusion for build dirs (admin — massive speedup)
Add-MpPreference -ExclusionPath "C:\Users\YOU\projects"

# Long paths (admin — fixes deep build tree issues)
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
    -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force

# Enable Developer Mode (admin — unlocks symlinks, WSL, sideloading)
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"

# Install WSL
wsl --install

# Install Windows Terminal (scoop — NOT from Store)
scoop install windows-terminal

# Install PowerToys
scoop install powertoys

# Install coreutils (Unix tools in PowerShell)
scoop install uutils-coreutils
Shortcut Action
Win + X, I Open Terminal fast
Win + X, A Terminal as Admin
Alt + Space PowerToys Run (launcher)
Win + Shift + C Color Picker
Compiler Best for
MSVC (cl) Production, best PDB, Visual Studio integration
Clang-cl Sanitizers, clang-tidy, cross-platform parity
GCC (MSYS2) POSIX APIs, autotools compat

20. Resources

Full reference with all links: resources.md

Must-Read Books

Book Author Focus
Professional CMake Craig Scott CMake definitive guide
C++ Best Practices Jason Turner 45+ actionable rules
Game Engine Architecture Jason Gregory Engine design (Naughty Dog)
Practical Reverse Engineering Dang et al. RE for x86/ARM/Windows
Optimized C++ Kurt Guntheroth Performance patterns

Must-Watch

Channel Focus
C++ Weekly (Jason Turner) 600+ weekly C++ episodes
The Cherno Game engine dev, C++ deep dives
CppCon Annual conference, 300+ talks
LiveOverflow Binary exploitation, RE
GDC Game dev conference talks
GPUOpen AMD GPU tools, Radeon profiling

Essential Online

Resource Link
C++ reference en.cppreference.com
Compiler Explorer godbolt.org
C++ Core Guidelines isocpp.github.io/CppCoreGuidelines
Modern CMake cliutils.gitlab.io/modern-cmake
Steamworks partner.steamgames.com/doc
Ghidra ghidra-sre.org

21. USB-C Gamedev

Full reference: usb-c-gamedev.md Covers: SDL3 gamepad hotplug, DisplayPort Alt Mode, Power Delivery, USB analysis, docks, cables

Install SDL3 (one-liner per platform)

scoop install sdl3                           # 🪟 Windows
brew install sdl3                            # 🍎 macOS
sudo apt install libsdl3-dev                 # 🐧 Ubuntu/Debian
epm install libSDL3-devel                    # 🐧 ALT Linux

CMake + SDL3

find_package(SDL3 REQUIRED)
target_link_libraries(mygame PRIVATE SDL3::SDL3)

Hotplug-safe gamepad (SDL3)

SDL_Gamepad* gp = nullptr;
// In event loop:
case SDL_EVENT_GAMEPAD_ADDED:   gp = SDL_OpenGamepad(event.gdevice.which); break;
case SDL_EVENT_GAMEPAD_REMOVED: SDL_CloseGamepad(gp); gp = nullptr; break;
// Per-frame:
SDL_GetGamepadButton(gp, SDL_GAMEPAD_BUTTON_SOUTH);  // A/Cross
SDL_GetGamepadAxis(gp, SDL_GAMEPAD_AXIS_LEFTX);      // left stick X
SDL_RumbleGamepad(gp, low, high, ms);                 # vibration
SDL_GetPowerInfo(&secs, &pct);                        # battery %

USB device listing

lsusb -tv                                    # 🐧 Linux — full USB tree
system_profiler SPUSBDataType                # 🍎 macOS
Get-PnpDevice -Class USB                     # 🪟 Windows PowerShell

Handheld USB-C specs

Device DP Output PD Charging Cable Needed
Steam Deck DP 1.4 Alt Mode 45W USB 3.2+
ROG Ally DP Alt Mode 100W (need 100W PSU) USB 3.2+
Switch / Switch 2 HDMI via dock 18-20W / 100W Official dock

Tip: USB-C cable that costs $3 is USB 2.0 charge-only. No video, no fast data. Need USB 3.2+ ($15-25) for DP Alt Mode.


⚡ Quick Reference Card

INSTALL:   scoop install ripgrep fd bat fzf just cmake ninja ccache llvm zig lazygit
WIN SETUP: reg add DevMode + wsl --install + scoop install windows-terminal powertoys
TERMINAL:  Win+X,I (fast open) | Win+X,A (admin) | scoop install windows-terminal (not Store)
POWERTOYS: Alt+Space (Run) | Win+Shift+C (Color) | Win+Ctrl+T (Always on Top)
COREUTILS: scoop install uutils-coreutils wget curl jq tree sed grep openssh
BUILD:     cmake -B build -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON && cmake --build build
TARGETS:   cmake --build build --target help | sort
FEATURES:  cmake -B build -LAH | rg -i "feature|enable|option"
GRAPH:     cmake -B build --graphviz=deps.dot && dot -Tpng deps.dot -o deps.png
PROFILE:   cmake -B build --profiling-output=prof.json --profiling-format=google-trace
TRACE:     cmake -B build --trace-expand 2>&1 | tee trace.log
LAZYGIT:   lazygit                          (visual rebase, cherry-pick, bisect)
REBASE:    git rebase -i HEAD~5             (or lazygit: [3] → 'e'/'s'/'d')
BISECT:    git bisect start HEAD v1.0 && git bisect run cmake --build build && ctest
WORKTREE:  git worktree add ../hotfix hotfix-branch
PROC_SUB:  diff <(cmd1 | sort) <(cmd2 | sort)  (compare outputs, no temp files)
PARALLEL:  fd -e cpp | xargs -P 8 -I {} clang-format -i {}
WATCH:     watchexec -e cpp,hpp -- cmake --build build
SEARCH:    rg "pattern" --type cpp -n -C 3
FIND:      fd -e cpp -e hpp
TODOS:     rg "TODO|FIXME|HACK" --type cpp -C 2
BLAME:     git blame src/file.cpp | bat -l gitblame
HISTORY:   git log -S "functionName" --oneline
HOT FILES: git log --format=format: --name-only --since="6 months ago" | sort | uniq -c | sort -rn | head -15
DIFF:      git diff main...HEAD --stat
BENCH:     hyperfine --warmup 5 --min-runs 20 "./myapp"
LINT:      cppcheck --enable=all --suppress=missingIncludeSystem src/
FORMAT:    clang-format -i src/**/*.cpp src/**/*.hpp
PROFILE:   tracy-profiler & ./myapp
DEBUG:     gdb -tui ./myapp  |  lldb ./myapp
THREADS:   set scheduler-locking on         (GDB: freeze all threads except current)
REVERSE:   target record-full → reverse-step (GDB: step BACKWARDS in time)
WIN DUMP:  lldb myapp.exe -c crash.dmp → bt (LLDB: exe + dump + PDB all needed!)
WIN DUMP:  windbg -z crash.dmp → !analyze -v (WinDbg: add .sympath+ for YOUR PDBs)
LNX DUMP:  gdb ./myapp core → bt full       (GDB: binary + core both needed!)
LNX DUMP:  coredumpctl gdb <pid>            (systemd: auto-finds binary + core)
MAC DUMP:  lldb ./MyApp -c App.ips → bt    (LLDB: binary + report both needed!)
IOS DUMP:  xcrun symbolicatecrash crash.ips App.dSYM  (iOS: dSYM MANDATORY)
AND DUMP:  ndk-stack -sym obj/local/arm64-v8a < tombstone  (Android: unstripped .so MANDATORY)
SYMBOLS:   Archive PDB/dSYM/.debug + binary per release — no symbols = raw hex, useless!
NETWORK:   nc -zv host 443 -w 3             (is port open?)
CAPTURE:   sudo tcpdump -i any port 8080 -w cap.pcap
TLS DEBUG: export SSLKEYLOGFILE=~/sslkeys.log → Wireshark decrypts HTTPS
CURL TIME: curl -o /dev/null -w "%{time_total}s\n" https://host
CACHE:     ccache -s
COMPILEDB: cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON && ln -sf build/compile_commands.json .
STRACE:    strace -f -e trace=openat ./myapp  |  drstrace -- myapp.exe
TRACK:     touch marker && ./myapp && find . -newer marker -type f
GPU:       rgp capture --output frames.rgp --app myapp --frame 42
ANDROID:   adb devices -l && adb install -r app.apk && adb logcat -s Tag
IOS:       xcrun simctl boot "iPhone 15" && xcrun simctl install booted App.app
RE:        r2 -A myapp  |  ghidra  |  x64dbg myapp.exe
CHECKSEC:  checksec --file=myapp
SHIP:      strip app && upx --best app && depends app && strings app | rg pdb
STEAM:     SteamInput()->Init() + GetGlyphForActionOrigin() → future-proof glyphs
CROSS:     zig c++ -target x86_64-linux-gnu -O2 main.cpp -o main_linux
LOC:       scc src/
AI STUDY:  aider --read-only src/engine/     (ask questions about code)
SDL3:      scoop install sdl3 | apt install libsdl3-dev | epm install libSDL3-devel
GAMEPAD:   SDL_EVENT_GAMEPAD_ADDED → SDL_OpenGamepad() → SDL_GetGamepadButton/Axis
RUMBLE:    SDL_RumbleGamepad(gp, low, high, ms)
BATTERY:   SDL_GetPowerInfo(&secs, &pct)    → SDL_POWERSTATE_ON_BATTERY / CHARGING
USB LIST:  lsusb -tv | system_profiler SPUSBDataType | Get-PnpDevice -Class USB
USB VID:   0x045e=Xbox 0x054c=Sony 0x057e=Nintendo 0x28de=Valve
DP ALT:    USB-C → dock → HDMI/DP (need USB 3.2+ cable, not $3 charge cable)
PD:        Deck=45W | Ally=100W | Switch=18W | EPR=240W
WSL:       wsl --install → sudo apt install build-essential cmake gdb lldb clang

🗺️ Dev Flow

CLONE REPO ──► scc + tree + bat README ──► git shortlog + log (orient)
                                              │
WRITE CODE ──► lazygit commit ─────────► cppcheck + clang-tidy (analyze)
                    │                            │
                    ▼                            ▼
              gdb / lldb                  sanitizers (ASAN/UBSAN)
              set scheduler-locking on    thread isolation
              target record-full          reverse debugging
                    │                            │
                    └──────────┬─────────────────┘
                               ▼
                          tracy profile (CPU) | RGP profile (GPU)
                               ▼
                          hyperfine bench
                               │
                ┌──────────────┼──────────────┐
                ▼              ▼              ▼
          cross-compile   strace/tcpdump    ship
          Zig/QEMU        (trace files,     checksec + strip + UPX
          ADB deploy      packets,          depends/ldd check
          xcrun deploy    network, TLS)     strings secret scan
                               │            Steam Input (IGA)
                               ▼            Big Picture mode
                          git bisect (find the regression)
                               ▼
                          Ghidra/r2/x64dbg (when you need to go deeper)
                               ▼
                          💀 crash dump analysis (BINARY + SYMBOLS + DUMP)
                          Win: lldb myapp.exe -c crash.dmp / windbg !analyze -v
                          Lnx: gdb ./app core / coredumpctl gdb
                          Mac: lldb ./App -c App.ips / symbolicatecrash
                          And: ndk-stack -sym obj/local/arm64-v8a
                          iOS: xcrun symbolicatecrash + dSYM
                               ▼
                          USB-C: lsusb + SDL3 gamepad test + dock DP output

Companion deep-dives linked inline throughout. Install via scoop, apt, epm, or brew.

About

C++ dev hints, CMake presets, cross-compilation, debugging, profiling — personal cheatsheet for Windows C++ workflows

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors