一键导入
setup-dev
Dev environment setup: build tools, PostgreSQL, submodules, worktrees. Always import on EnterWorktree/ExitWorktree.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Dev environment setup: build tools, PostgreSQL, submodules, worktrees. Always import on EnterWorktree/ExitWorktree.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Versioning, branch, and release policy (semantic versioning, branch-per-minor, tag-per-patch). MUST consult when: deciding a version number, cutting a release, creating a version tag, opening a release/patch branch, or backporting a bug fix.
Code style, include order, docs update rules, and submodule policy. MUST consult when: writing or modifying C/C++ files (include order matters), adding/removing/changing ducklake.* SQL functions or procedures (keep their inline comments in pg_ducklake--*.sql current), editing third_party/ code, or reviewing code for style.
Commit message conventions (Conventional Commits). Consult before every git commit.
| name | setup-dev |
| description | Dev environment setup: build tools, PostgreSQL, submodules, worktrees. Always import on EnterWorktree/ExitWorktree. |
| user-invocable | true |
Interactive playbook -- follow steps in order, detect current state, skip what is
already done, and present options to the user via AskUserQuestion.
~/.ccache, shared across all worktrees.git worktree add on each submodule's git repo
to share the same object store across worktrees.Run these checks silently to understand what is already set up:
command -v ccache # compiler cache
ls pg-*/bin/pg_config 2>/dev/null # local PG installs in workdir
ls ~/.dev/pg-*/configure 2>/dev/null # PG source worktrees
ls "$(git rev-parse --show-toplevel)"/duckdb/Makefile 2>/dev/null # duckdb submodule initialized?
git worktree list # current worktree situation
Skip any step below that is already satisfied.
command -v ccache && ccache --version
Present options via AskUserQuestion:
| Option | macOS | Linux (apt) |
|---|---|---|
| brew/apt | brew install ccache | sudo apt install ccache |
| Skip | Continue without cache (slow builds) |
Also check for platform build tools:
xcode-select -p (if missing: xcode-select --install)dpkg -l build-essential (if missing: sudo apt install build-essential bison flex)Check the user's shell profile:
grep CMAKE_C_COMPILER_LAUNCHER ~/.zshrc ~/.bashrc 2>/dev/null
If not configured, tell the user to add this block to ~/.zshrc or ~/.bashrc:
if command -v ccache >/dev/null; then
export CC="ccache cc"
export CXX="ccache c++"
export CMAKE_C_COMPILER_LAUNCHER=ccache
export CMAKE_CXX_COMPILER_LAUNCHER=ccache
fi
Why: duckdb and ducklake use cmake and ignore CC=ccache cc. Without
CMAKE_C_COMPILER_LAUNCHER, these heavy builds (~1GB source) recompile
from scratch in every worktree.
Note: if sccache is already installed (e.g. via Homebrew), cmake may
pick it up automatically. That works fine -- just use sccache --show-stats
instead of ccache -s to verify cache hits.
Always build from source, per-worktree. Uses a shared bare repo so multiple PG versions share one clone, and ccache makes rebuilds fast.
Ask the user which versions to install (usually the oldest and newest supported, e.g. 14 and 18).
Shared PG source lives at ~/.dev/pg-src (bare repo, ~200MB):
git clone --bare https://github.com/postgres/postgres.git ~/.dev/pg-src
For each needed version, fetch the branch and create a source worktree:
git -C ~/.dev/pg-src fetch --depth=1 origin refs/heads/REL_<VER>_STABLE:refs/heads/REL_<VER>_STABLE
git -C ~/.dev/pg-src worktree add ~/.dev/pg-<VER> REL_<VER>_STABLE
WT=$(git rev-parse --show-toplevel)
NCPU=$(nproc 2>/dev/null || sysctl -n hw.ncpu)
for VER in 14 18; do
pushd ~/.dev/pg-$VER
./configure --prefix="$WT/pg-$VER" \
--without-icu --without-readline --without-libxml
make -j"$NCPU" && make install
popd
done
PG_CONFIG will be: $(pwd)/pg-<VER>/bin/pg_config
Add pg-*/ to .git/info/exclude to keep git status clean:
exclude_file=$(git rev-parse --git-dir)/info/exclude
grep -qF 'pg-*/' "$exclude_file" 2>/dev/null || echo 'pg-*/' >> "$exclude_file"
Time: ~15-20 min per version on first run, ~1-2 min on reruns (ccache).
pg_ducklake lives in the libpgduckdb monorepo: the libpgddb kernel is
plain in-repo source at libpgduckdb/ (repo root) -- nothing to
initialize. The DuckDB source is a submodule at the repo root,
duckdb/. Initialize it:
git -C "$(git rev-parse --show-toplevel)" submodule update --init --depth=1 duckdb
Time: 5-10 min on first run (duckdb is large even with shallow clone).
third_party/ducklake is a git submodule pinned to a community
duckdb/ducklake commit. Our divergence from community lives as an ordered
series of patch files third_party/ducklake-NNN-<desc>.patch, applied onto the
pristine checkout at build time (apply-once, stamp-guarded -- see the
DUCKLAKE_STAMP rule in Makefile). The build inits the submodule
non-recursively (its inner duckdb / extension-ci-tools submodules are only
for ducklake's own CI and are not needed) and applies the patches in numeric
order; make clean drops the stamp so the next build re-applies from a clean
reset. The submodule working tree is therefore intentionally left dirty
(patched); the gitlink stays at the pinned community commit.
To inspect our customization, read the ducklake-NNN-*.patch files. To bump the
community base: repoint the submodule gitlink, regenerate/rebase the patches
against the new commit, and re-verify (make ... && make check-regression).
git worktree add on a submodule gitdir silently overwrites
core.worktree to point at the new worktree instead of the main one.
Stale worktree entries also break submodule foreach --recursive.
Two hooks in .claude/settings.json handle this automatically:
EnterWorktree (.claude/hooks/worktree-setup.sh):
repairs broken gitdirs, then creates submodule worktrees with
core.worktree preservation.ExitWorktree (.claude/hooks/worktree-cleanup.sh):
removes submodule worktree entries pointing to the current worktree,
then repairs any core.worktree that got corrupted. Only runs when
action is "remove".If the main worktree's submodules are not initialized, the setup hook
has nothing to iterate. Fall back to
git submodule update --init --recursive --depth=1 in the main
worktree first (slow, downloads from remote).
The PG source worktrees at ~/.dev/pg-<VER> already have compiled
object files from the initial build. Reconfigure with the new prefix
and rebuild. make clean is required because PG bakes the
--prefix path into binaries as rpaths — without it, old objects
with the previous worktree's rpath get reused and executables fail
at runtime with "Library not loaded".
WT=$(git rev-parse --show-toplevel)
NCPU=$(nproc 2>/dev/null || sysctl -n hw.ncpu)
for VER in 14 18; do
pushd ~/.dev/pg-$VER
make clean
./configure --prefix="$WT/pg-$VER" \
--without-icu --without-readline --without-libxml
make -j"$NCPU" && make install
popd
done
Time: ~2-5 min per version (ccache hits on recompilation).
PG_CONFIG=<path_to_pg_config> make install
PG_CONFIG=<path_to_pg_config> make installcheck
Time: first build takes 15-30 min (duckdb cmake build dominates). Subsequent builds with ccache take 1-5 min.
A successful make install ends with PGXS installing pg_ducklake.so
and the SQL files into the PG extension directory.
ccache not hitting -- ccache -s shows zero hits. Verify:
echo $CC contains ccacheecho $CMAKE_C_COMPILER_LAUNCHER is ccacheccache in compiler commandWrong submodule commit -- reset to what the branch expects:
git -C "$(git rev-parse --show-toplevel)" submodule update duckdb pg_ducklake/third_party/ducklake
PG configure fails -- missing build deps:
xcode-select --install && brew install bison flexsudo apt install build-essential bison flex libreadline-dev zlib1g-devpg-*/ in git status -- re-run Step 3's exclude command.