09 — Day-One Setup Script

Below is an actual bash script you run on Day 1 of M1 (July 2026). It works on macOS 15+ with Homebrew, or Ubuntu 26.04 LTS (native or WSL2). It installs everything you need for the 13-month roadmap. Total runtime: ~15-25 minutes depending on your network.

Save this as ~/c-roadmap-setup.sh, chmod +x, and run once.

macOS variant (c-roadmap-setup-macos.sh)

#!/usr/bin/env bash
set -euo pipefail

echo "==> 13-Month C Roadmap: Day 1 setup (macOS)"

# 1. Homebrew (skip if already installed)
if ! command -v brew >/dev/null 2>&1; then
  /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi

# 2. Xcode Command Line Tools (bundles clang, lldb, git, make)
if ! xcode-select -p >/dev/null 2>&1; then
  xcode-select --install
  echo "    Wait for the Xcode CLT installer to finish, then re-run this script."
  exit 0
fi

# 3. Compilers and toolchain
brew install \
  gcc \
  llvm \
  make cmake ninja meson pkg-config bear \
  ccache

# 4. Debug / analysis tools (valgrind not available on Apple Silicon; use ASan)
brew install \
  gdb || true            # gdb is fiddly on macOS; skip on failure

# 5. Docker / VM — OrbStack (recommended)
brew install --cask orbstack

# 6. Shell quality-of-life
brew install \
  tmux ripgrep fd bat fzf jq htop

# 7. Editor — VS Code (skip if you use Neovim)
brew install --cask visual-studio-code || true

# 8. Set up ccache path
CCACHE_LINE='export PATH="/opt/homebrew/opt/ccache/libexec:$PATH"'
grep -qxF "$CCACHE_LINE" ~/.zshrc || echo "$CCACHE_LINE" >> ~/.zshrc
echo 'export CCACHE_MAXSIZE="5G"' >> ~/.zshrc

# 9. Git identity (edit if needed)
git config --global user.name  "$(id -F 2>/dev/null || echo Your Name)"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase true

# 10. First project scaffold
mkdir -p ~/code/c-roadmap/month-01
cd ~/code/c-roadmap/month-01
cat > hello.c <<'EOF'
#include <stdio.h>
int main(void) {
    printf("day 1.\n");
    return 0;
}
EOF
cat > Makefile <<'EOF'
CC = gcc-15
CFLAGS = -std=c17 -Wall -Wextra -Wpedantic -O2 -g -fsanitize=address,undefined
LDFLAGS = -fsanitize=address,undefined
all: hello
hello: hello.c
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
clean:
	rm -f hello
.PHONY: all clean
EOF
make
./hello

echo "==> Setup complete. You should see 'day 1.' printed above."
echo "==> Restart your shell (or 'source ~/.zshrc') to pick up ccache."

Ubuntu 26.04 variant (c-roadmap-setup-ubuntu.sh)

#!/usr/bin/env bash
set -euo pipefail

echo "==> 13-Month C Roadmap: Day 1 setup (Ubuntu 26.04)"

# 1. Base package refresh
sudo apt-get update
sudo apt-get upgrade -y

# 2. Compilers and toolchain
sudo apt-get install -y \
  build-essential \
  gcc g++ \
  clang clangd clang-format clang-tidy clang-tools lldb \
  make cmake ninja-build meson pkg-config bear \
  ccache mold

# 3. Debug / analysis
sudo apt-get install -y \
  gdb valgrind strace ltrace \
  linux-tools-common "linux-tools-$(uname -r)" \
  bpftrace \
  cppcheck

# 4. rr (record-and-replay), if x86_64 with perf counters
if [ "$(uname -m)" = "x86_64" ]; then
  sudo apt-get install -y rr || echo "    rr not available in your apt sources; install from source if needed."
fi

# 5. Shell quality-of-life
sudo apt-get install -y \
  tmux ripgrep fd-find bat fzf jq htop

# 6. Editor (VS Code)
if ! command -v code >/dev/null 2>&1; then
  sudo apt-get install -y wget gpg
  wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /tmp/microsoft.gpg
  sudo install -D -o root -g root -m 644 /tmp/microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg
  echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" | sudo tee /etc/apt/sources.list.d/vscode.list
  sudo apt-get update && sudo apt-get install -y code
fi

# 7. Set up ccache and mold path
CCACHE_LINE='export PATH="/usr/lib/ccache:$PATH"'
grep -qxF "$CCACHE_LINE" ~/.bashrc || echo "$CCACHE_LINE" >> ~/.bashrc
echo 'export CCACHE_MAXSIZE="5G"' >> ~/.bashrc

# 8. Allow unprivileged perf (may prompt for reboot)
echo 'kernel.perf_event_paranoid = 1' | sudo tee /etc/sysctl.d/99-perf.conf
sudo sysctl --system

# 9. Git identity
git config --global user.name  "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase true

# 10. First project scaffold
mkdir -p ~/code/c-roadmap/month-01
cd ~/code/c-roadmap/month-01
cat > hello.c <<'EOF'
#include <stdio.h>
int main(void) {
    printf("day 1.\n");
    return 0;
}
EOF
cat > Makefile <<'EOF'
CC = gcc
CFLAGS = -std=c17 -Wall -Wextra -Wpedantic -O2 -g -fsanitize=address,undefined
LDFLAGS = -fsanitize=address,undefined -fuse-ld=mold
all: hello
hello: hello.c
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
clean:
	rm -f hello
.PHONY: all clean
EOF
make
./hello

echo "==> Setup complete. Restart shell or 'source ~/.bashrc' for ccache."

Post-setup checklist

After running the script, verify each tool:

gcc --version        # 15.x on Ubuntu; use gcc-15 on Mac
clang --version      # 20.x
gdb --version        # Linux only
lldb --version       # both platforms
make --version
cmake --version      # 3.28+
ninja --version
meson --version
ccache --version
mold --version       # Linux
docker --version     # via OrbStack on Mac

If any of these fail, that specific step of the script had an issue; re-run just that section.

VS Code post-setup

  1. Open VS Code.

  2. Install extension: llvm-vs-code-extensions.vscode-clangd.

  3. Disable extension: ms-vscode.cpptools (Microsoft C/C++). They fight; clangd wins.

  4. Reload window.

  5. Open ~/code/c-roadmap/month-01/hello.c — you should see clangd’s inline diagnostics.

Neovim post-setup (if preferred)

brew install neovim     # Mac
sudo apt install neovim # Ubuntu

# Bootstrap kickstart.nvim (single-file starter config)
git clone https://github.com/nvim-lua/kickstart.nvim.git \
  "${XDG_CONFIG_HOME:-$HOME/.config}/nvim"
nvim   # Mason will install clangd on first launch

What most people get wrong about setup scripts

They tweak the script for two weeks and never run it. Rule: run it once, exactly as-is, today. Fix the exact one thing that breaks. Move on to writing C. You will have opinions about your dotfiles later. Not on Day 1.

Return to README.md · Next: 10_hardware_notes.md