Skip to main content
Massively Parallel Procrastination

Fab out

A couple years back, I put a ton of effort into building a tool that would let me create KiCAD fabrication outputs (gerber files, pick and place docs, schematics) from the commandline. What started as a hacky perl script became a 500 megabyte Docker image and a conference talk.

At the time, getting KiCAD to generate Gerber files was...just barely possible through their Python API. But when it came to generating a schematic or a BOM, the simplest, most straightforward option was to spin up a headless X server in a virtual machine and write a bit of code to open the GUI, tab through UI widgets and "click" on the output options.

It was slow and incredibly clunky. But it worked.

Flash forward to last week when the first Release Candidate for KiCAD 8 dropped.

This shell script, largely written for me by an LLM, just does everything my tool used to.

#!/bin/bash

KICAD_CLI_PATH=/Applications/KiCad/KiCad.app/Contents/MacOS/kicad-cli
kicad_cli_path="${KICAD_CLI_PATH:-$HOME/kicad/bin/kicad-cli}"

project_name=$(basename "$PWD")
project_path="$PWD"
output_dir="output"
current_date=$(date '+%Y-%m-%d-%H:%M:%S')
export_name="$project_name-$current_date"
project_output_dir="$output_dir/$export_name"

if [ ! -d "$project_output_dir" ]; then
  mkdir -p "$project_output_dir"
fi

export_description_file="$project_output_dir/export-version-info.txt"
gerbers_output_dir="$project_output_dir/gerbers"
step_output_dir="$project_output_dir/3d"
schematic_output_dir="$project_output_dir/schematic"
pos_output_dir="$project_output_dir/pos"
bom_output_dir="$project_output_dir/bom"
if [ ! -d "$gerbers_output_dir" ]; then
  mkdir "$gerbers_output_dir"
fi
if [ ! -d "$step_output_dir" ]; then
  mkdir "$step_output_dir"
fi
if [ ! -d "$schematic_output_dir" ]; then
  mkdir "$schematic_output_dir"
fi
if [ ! -d "$bom_output_dir" ]; then
  mkdir "$bom_output_dir"
fi
if [ ! -d "$pos_output_dir" ]; then
  mkdir "$pos_output_dir"
fi


echo "exporting git version information"
echo "Git describe output: " >> $export_description_file
git describe >> $export_description_file
echo "Export date and time: ${date}" >> $export_description_file


echo "Exporting gerbers"
"$kicad_cli_path" pcb export gerbers --output="$gerbers_output_dir" "$project_path/$project_name.kicad_pcb"

echo "Export schematic as PDF"
"$kicad_cli_path" sch export pdf --output="$schematic_output_dir/$project_name.pdf" "$project_path/$project_name.kicad_sch"

echo "Export BOM"
"$kicad_cli_path" sch export bom --output="$bom_output_dir/$project_name.csv" "$project_path/$project_name.kicad_sch"

echo "Export position file"
"$kicad_cli_path" pcb export pos --output="$pos_output_dir/$project_name.pos" "$project_path/$project_name.kicad_pcb"

echo "Export 3D model"
"$kicad_cli_path" pcb export step --output="$step_output_dir/$project_name.step" "$project_path/$project_name.kicad_pcb"

echo "Export drill files"
"$kicad_cli_path" pcb export drill --output="$gerbers_output_dir/" "$project_path/$project_name.kicad_pcb"

cd $output_dir
zip -r $export_name.zip $export_name

echo "Created $output_dir/$export_name.zip"