4.1 KiB
Gerber Viewer (gerbview) WASM port — design notes
Goal
Bring up KiCad's Gerber Viewer (gerbview, FRAME_GERBER) in the browser to the
"boots, canvas visible, click around" level the other ported apps reached. Scope is
launch-only — loading actual Gerber/drill files is out of scope for now.
Approach
gerbview is its own standalone program + kiface (unlike symbol_editor, which lived
inside the eeschema kiface), so it follows the pl_editor/pcbnew pattern almost
verbatim: gate the native dynamic-kiface logic behind if( EMSCRIPTEN ) and link the
kiface objects statically into the gerbview executable. gerbview.cpp (the
KIFACE_GETTER) is already part of gerbview_kiface_objects, so no source hoisting
was needed (unlike eeschema). There was no #ifdef __EMSCRIPTEN__ frame stub to
remove (gerbview was never gated out, unlike the symbol editor).
Changes (kicad submodule)
kicad/gerbview/CMakeLists.txt— mirror pl_editor's WASM static-link block:- On EMSCRIPTEN, compile
common/single_top.cppwithTOP_FRAME=FRAME_GERBER(noBUILD_KIWAY_DLL); wrap the native minimal exe link inif( NOT EMSCRIPTEN ). - Hoist the kiface deps into
GERBVIEW_KIFACE_LIBRARIES; on EMSCRIPTEN link them directly into thegerbviewexe withLINKER:--allow-multiple-definition. - Gate
gerbview.cppdefs: EMSCRIPTEN →COMPILING_DLL(noBUILD_KIWAY_DLL, soKIFACE_GETTERlinks statically); elseBUILD_KIWAY_DLL;COMPILING_DLL.
- On EMSCRIPTEN, compile
kicad/gerbview/navlib/CMakeLists.txt— add anif( EMSCRIPTEN )branch that buildsgerbview_navlibfrom the WASM stub instead of the real 3Dconnexion plugin (no SpaceMouse driver in the browser). The frame's navlib member usesNL_GERBVIEW_PLUGINunder WASM (#ifndef __linux__; emscripten doesn't define it).#include <wx/choice.h>added to three files that usewxChoice(the Cmp/Net/Attr/DCode aux-toolbar combo boxes) but only had the forward declaration:gerbview/events_called_functions.cpp,gerbview/toolbars_gerber.cpp,gerbview/tools/gerbview_control.cpp. Native builds pullwx/choice.htransitively; the WASM wxWidgets header config does not, so these failed with "member access into incomplete type 'wxChoice'". Include-what-you-use fix — behavior-neutral, upstream-safe. (gerbview_frame.cppalready gets it transitively; the generated_base.cppcarries its own includes — both left untouched to keep the fork minimal.)
Changes (root repo)
wasm/stubs/nl_gerbview_plugin_stub.cpp(NEW) — no-opNL_GERBVIEW_PLUGINctor/dtor +SetCanvas/SetFocus, mirroringnl_pl_editor_plugin_stub.cpp.scripts/kicad/build-gerbview.sh(NEW) — thin wrapper →build-kicad-target.sh gerbview.scripts/kicad/build-kicad-target.sh— addgerbviewto thepcbnew|eeschema)case arm (target = subdir =gerbview); update usage strings.docker/build.sh— addgerbviewto valid apps, dispatch case, and theallloop (now 6 apps).tests/scripts/setup-kicad-wasm.sh—copy_app gerbview.tests/apps/kicad/gerbview.html(NEW) — browser shell (copy of pl_editor.html; title,thisProgram=/usr/bin/gerbview,gerbview.js).tests/kicad/gerbview.spec.ts(NEW) +tests/package.json— launch-only smoke test (wizard, canvas visible, registry populated, ≥1 toolbar, no abort).
Build & verify
./docker/build.sh gerbview # seed fresh-branch cache from main first (see build-quirks memory)
cd tests && npm run setup:kicad && npm run test:gerbview
Expect: the viewer opens — menu bar, top + aux toolbars (with the Cmp/Net/Attr/DCode
combos), left tool toolbar, dark gerber canvas with grid + origin crosshair, and the
Layers/Items manager pane. gerbview.spec.ts passes (2/2, no abort).
Known limitations
- No Gerber/drill files are loaded; the canvas is empty until a file is opened (file loading untested / out of scope).
- Symbol-editor-style drawing tools that require an open document behave per native KiCad (some are inactive with no layers loaded).
- No persistent storage (MEMFS only).