Programatically generating footprints

I’ve generated a few KiCad footprints using built-in tools, but now I’d like to programmatically generate a few exotic footprints with precise dimensions (interlaced digits, hexagons, etc). I’m fluent in Python and s-expression languages (scheme, Lisp, etc).

Are there a tutorials or any useful starting points that would help with this?

If not, I can reverse engineer existing .kicad_mod files, but have a couple of questions:

  • What is the minimum info required in each .kicad_mod file?
  • What is the tstamp property that adorns pad and fp_line statements? Is it required?

File format documentation is here if you’re looking to DIY footprint generation: Footprint Library File Format | Developer Documentation | KiCad

Would strongly suggest you at least look at the (python) tooling the library team uses to generate many of the official footprints, though: KiCad / KiCad Libraries / KiCad Footprint Generator · GitLab

I’m not sure how good the generator documentation is, but you should be able to look at some of the scripts and figure out what’s going on.

For common package types, usually you can add a new size definition by adding adding some dimensions to a yaml file. For less common packages like you’re talking about you’ll have to do the geometry math yourself, but the generator provides APIs for adding shapes, and it will handle all the footprint properties, file format stuff, etc.

Edit: there’s also another option, which is the footprint wizards built into KiCad. These are python scripts with hooks to be usable in the GUI; you can build your own.

Some starter documentation is here: PCB Editor | 8.0 | English | Documentation | KiCad

There’s not a lot of info in the manual about the guts of the geometry stuff you’d have to implement yourself, but you can look at the wizard scripts that KiCad ships to get an idea. IIRC they’re fairly legible. Here’s one that might be useful: pcbnew/python/plugins/mutualcap_button_wizard.py · master · KiCad / KiCad Source Code / kicad · GitLab

@gkeeth That’s everything I was looking for in an answer (and more) – thanks for all the details and suggestions.