Initial project setup for KiCad WebAssembly port
- Add KiCad fork as git submodule - Create project structure (patches, stubs, cmake, scripts, core, docs) - Add knowledge base and implementation plan documentation - Add README with project overview and goals 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
commit
2d7c26feac
7 changed files with 1405 additions and 0 deletions
846
docs/KNOWLEDGE_BASE_FULL.md
Normal file
846
docs/KNOWLEDGE_BASE_FULL.md
Normal file
|
|
@ -0,0 +1,846 @@
|
|||
# KiCad WebAssembly Port - Complete Knowledge Base
|
||||
|
||||
## Table of Contents
|
||||
1. [Architecture Overview](#architecture-overview)
|
||||
2. [Dependencies Deep Dive](#dependencies-deep-dive)
|
||||
3. [Graphics System (GAL)](#graphics-system-gal)
|
||||
4. [File I/O System](#file-io-system)
|
||||
5. [Python Scripting](#python-scripting)
|
||||
6. [Build System](#build-system)
|
||||
7. [Features to Disable](#features-to-disable)
|
||||
8. [Code Extraction Candidates](#code-extraction-candidates)
|
||||
9. [Technical Challenges](#technical-challenges)
|
||||
10. [Design Decisions](#design-decisions)
|
||||
11. [File Reference](#file-reference)
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Main Applications
|
||||
|
||||
| Application | Directory | Purpose |
|
||||
|-------------|-----------|---------|
|
||||
| `kicad` | `kicad/` | Project manager, launcher |
|
||||
| `pcbnew` | `pcbnew/` | PCB layout editor |
|
||||
| `eeschema` | `eeschema/` | Schematic capture |
|
||||
| `gerbview` | `gerbview/` | Gerber file viewer |
|
||||
| `cvpcb` | `cvpcb/` | Component-footprint association |
|
||||
| `bitmap2component` | `bitmap2component/` | Image to footprint converter |
|
||||
| `pcb_calculator` | `pcb_calculator/` | Engineering calculators |
|
||||
| `pagelayout_editor` | `pagelayout_editor/` | Drawing sheet editor |
|
||||
| `kicad-cli` | `kicad/cli/` | Command-line interface |
|
||||
|
||||
### Shared Libraries
|
||||
|
||||
| Library | Location | Purpose |
|
||||
|---------|----------|---------|
|
||||
| `kicommon` | `common/` | Shared UI, I/O, utilities (SHARED lib) |
|
||||
| `kigal` | `common/gal/` | Graphics Abstraction Layer (SHARED lib) |
|
||||
| `kimath` | `libs/kimath/` | Geometry and math (STATIC lib) |
|
||||
| `core` | `libs/core/` | Base utilities (STATIC lib) |
|
||||
| `sexpr` | `libs/sexpr/` | S-expression parser (STATIC lib) |
|
||||
| `kiplatform` | `libs/kiplatform/` | Platform abstraction |
|
||||
|
||||
### Plugin Architecture (KIFACE)
|
||||
|
||||
Each major application is built as both:
|
||||
- Standalone executable
|
||||
- KIFACE module (`.kiface` on Linux/Mac, `.dll` on Windows)
|
||||
|
||||
This allows:
|
||||
- Standalone operation
|
||||
- Project manager integration via dynamic loading
|
||||
|
||||
Key files:
|
||||
- `include/kiway.h` - KIWAY system for inter-module communication
|
||||
- `include/kiway_holder.h` - Mixin for frames that participate in KIWAY
|
||||
- `include/kiway_player.h` - Frame base class (`KIWAY_PLAYER : public wxFrame`)
|
||||
|
||||
### Frame Hierarchy
|
||||
|
||||
```
|
||||
wxFrame
|
||||
└── KIWAY_PLAYER (include/kiway_player.h)
|
||||
└── EDA_BASE_FRAME (include/eda_base_frame.h)
|
||||
├── PCB_BASE_FRAME (pcbnew/)
|
||||
│ └── PCB_EDIT_FRAME
|
||||
├── SCH_BASE_FRAME (eeschema/)
|
||||
│ └── SCH_EDIT_FRAME
|
||||
└── ...other frames
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependencies Deep Dive
|
||||
|
||||
### wxWidgets (GUI Framework)
|
||||
|
||||
**Version**: 3.2.0+
|
||||
**Components used**: `gl aui adv html core net base propgrid xml stc richtext webview`
|
||||
**Location**: Found via `find_package(wxWidgets)` in `CMakeLists.txt:1089`
|
||||
|
||||
KiCad requires GTK3 port on Linux. All GUI code depends on wxWidgets.
|
||||
|
||||
Key wxWidgets classes used:
|
||||
- `wxFrame`, `wxDialog`, `wxPanel` - windows
|
||||
- `wxGLCanvas` - OpenGL context
|
||||
- `wxFileDialog` - file selection
|
||||
- `wxAuiManager` - dockable panes
|
||||
- `wxPropertyGrid` - property editors
|
||||
|
||||
**Wasm strategy**: Keep native initially. Eventually replace with web framework (React/Vue/Svelte).
|
||||
|
||||
### OpenGL / GLEW
|
||||
|
||||
**Purpose**: Hardware-accelerated 2D rendering via GAL
|
||||
**Location**: `common/gal/opengl/`
|
||||
|
||||
Uses OpenGL 2.1+ with shaders. GLEW handles extension loading.
|
||||
|
||||
**Wasm strategy**: Emscripten maps OpenGL ES to WebGL automatically. Need to:
|
||||
- Use OpenGL ES subset
|
||||
- Convert shaders to GLSL ES (remove `#version`, add `precision` qualifiers)
|
||||
|
||||
### Cairo
|
||||
|
||||
**Version**: 1.12+
|
||||
**Purpose**: Software 2D rendering fallback, printing, PDF export
|
||||
**Location**: `common/gal/cairo/`
|
||||
|
||||
**Wasm strategy**: Can compile Cairo with Emscripten. Or skip for MVP (OpenGL-only).
|
||||
|
||||
### OpenCASCADE (OCC/OCCT)
|
||||
|
||||
**Version**: 7.5.0+
|
||||
**Purpose**:
|
||||
- STEP file import/export (mechanical CAD interchange)
|
||||
- 3D model loading for component visualization
|
||||
- Boolean operations on 3D geometry
|
||||
|
||||
**Files using OCC**:
|
||||
- `pcbnew/exporters/step/step_pcb_model.cpp` - STEP export
|
||||
- `pcbnew/exporters/step/exporter_step.cpp` - Export orchestration
|
||||
- `plugins/3d/oce/loadmodel.cpp` - 3D model loading
|
||||
- `plugins/3d/oce/oce.cpp` - Plugin entry point
|
||||
|
||||
**Headers imported** (from `step_pcb_model.cpp`):
|
||||
```cpp
|
||||
#include <IGESCAFControl_Reader.hxx>
|
||||
#include <STEPCAFControl_Reader.hxx>
|
||||
#include <STEPCAFControl_Writer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <XCAFDoc_ShapeTool.hxx>
|
||||
// ... ~30 more OCC headers
|
||||
```
|
||||
|
||||
**Wasm strategy**: Disable for MVP. OCC is huge (~40MB compiled). Alternative: [opencascade.js](https://github.com/nicholaseasmith/opencascade.js) exists but experimental.
|
||||
|
||||
### libcurl
|
||||
|
||||
**Purpose**: HTTP requests for:
|
||||
1. Plugin Content Manager (PCM) - `kicad/pcm/pcm.cpp`
|
||||
2. Update checker - `kicad/update_manager.cpp`
|
||||
3. HTTP component libraries - `common/http_lib/http_lib_connection.cpp`
|
||||
|
||||
**Wrapper**: `common/kicad_curl/kicad_curl_easy.cpp` (~400 lines)
|
||||
|
||||
**Key class**: `KICAD_CURL_EASY`
|
||||
```cpp
|
||||
class KICAD_CURL_EASY {
|
||||
void SetURL(const std::string& url);
|
||||
void Perform();
|
||||
std::string GetBuffer();
|
||||
};
|
||||
```
|
||||
|
||||
**Wasm strategy**: Stub out. Replace with Emscripten Fetch API or JavaScript fetch via embind.
|
||||
|
||||
### libgit2
|
||||
|
||||
**Version**: 1.5+
|
||||
**Purpose**: Built-in version control for projects
|
||||
|
||||
**Files** (`common/git/`):
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `git_clone_handler.cpp` | Clone repositories |
|
||||
| `git_commit_handler.cpp` | Create commits |
|
||||
| `git_push_handler.cpp` | Push to remote |
|
||||
| `git_pull_handler.cpp` | Pull from remote |
|
||||
| `git_branch_handler.cpp` | Branch management |
|
||||
| `git_status_handler.cpp` | Status display |
|
||||
| `git_revert_handler.cpp` | Revert changes |
|
||||
| `kicad_git_common.cpp` | Common utilities |
|
||||
| `kigit_pcb_merge.cpp` | Custom PCB merge driver |
|
||||
|
||||
**UI integration**:
|
||||
- Project tree shows git status icons
|
||||
- Menus for git operations
|
||||
- Conflict resolution dialogs
|
||||
|
||||
**Wasm strategy**: Stub out entirely. Optional feature. Could use isomorphic-git in browser later.
|
||||
|
||||
### ngspice
|
||||
|
||||
**Purpose**: SPICE circuit simulation in eeschema
|
||||
**Location**: `eeschema/sim/`
|
||||
|
||||
**Wasm strategy**: Stub out. Simulation is a separate concern. Could compile ngspice to Wasm later.
|
||||
|
||||
### nanoodbc (ODBC)
|
||||
|
||||
**Purpose**: Database Libraries feature - fetch component data from SQL databases
|
||||
**Location**: `common/database/database_connection.cpp`
|
||||
|
||||
**What it does**: Connects to external databases (MySQL, PostgreSQL, SQLite, SQL Server) to fetch component information instead of using local `.kicad_sym` files.
|
||||
|
||||
**Enterprise feature** - most users don't use this.
|
||||
|
||||
**Wasm strategy**: Stub out. Would need REST API backend in browser.
|
||||
|
||||
### Boost
|
||||
|
||||
**Version**: 1.71.0+
|
||||
**Components**: `locale`, `unit_test_framework`
|
||||
|
||||
`boost::locale` is used by nanoodbc for Unicode handling.
|
||||
|
||||
**Wasm strategy**: Minimize. If we disable database libraries, we may not need boost::locale.
|
||||
|
||||
### Freetype / HarfBuzz / Fontconfig
|
||||
|
||||
**Purpose**: Text rendering with outline fonts
|
||||
**Versions**: Freetype 2.11.1+, HarfBuzz (any), Fontconfig (any)
|
||||
|
||||
**Location**: `common/font/`
|
||||
|
||||
**Wasm strategy**: Compile with Emscripten. These work. May need to bundle fonts or use browser fonts.
|
||||
|
||||
### Protobuf
|
||||
|
||||
**Purpose**: IPC API for external tool integration
|
||||
**Location**: `api/`
|
||||
|
||||
**Wasm strategy**: Can compile Protobuf to Wasm. Or stub out IPC API for MVP.
|
||||
|
||||
---
|
||||
|
||||
## Graphics System (GAL)
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ VIEW (common/view/) │
|
||||
│ Manages what's visible, handles zoom │
|
||||
└─────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ PAINTER (include/gal/painter.h) │
|
||||
│ Converts board objects to draw calls │
|
||||
└─────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ GAL (graphics_abstraction_layer) │
|
||||
│ Abstract interface for drawing │
|
||||
└─────────────────────────────────────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ OPENGL_GAL │ │ CAIRO_GAL │
|
||||
│ (Hardware accel)│ │ (Software/print)│
|
||||
└─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
### GAL Base Class
|
||||
|
||||
**File**: `include/gal/graphics_abstraction_layer.h`
|
||||
|
||||
```cpp
|
||||
namespace KIGFX {
|
||||
class GAL : public GAL_DISPLAY_OPTIONS_OBSERVER {
|
||||
// Primitives
|
||||
virtual void DrawLine(const VECTOR2D& start, const VECTOR2D& end);
|
||||
virtual void DrawCircle(const VECTOR2D& center, double radius);
|
||||
virtual void DrawArc(const VECTOR2D& center, double radius, ...);
|
||||
virtual void DrawRectangle(const VECTOR2D& start, const VECTOR2D& end);
|
||||
virtual void DrawPolygon(const std::deque<VECTOR2D>& points);
|
||||
|
||||
// State
|
||||
virtual void SetFillColor(const COLOR4D& color);
|
||||
virtual void SetStrokeColor(const COLOR4D& color);
|
||||
virtual void SetLineWidth(float width);
|
||||
|
||||
// Transformations
|
||||
virtual void Transform(const MATRIX3x3D& matrix);
|
||||
virtual void Translate(const VECTOR2D& translation);
|
||||
virtual void Scale(const VECTOR2D& scale);
|
||||
virtual void Rotate(double angle);
|
||||
|
||||
// Layers
|
||||
virtual void SetLayerDepth(double depth);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### OpenGL GAL
|
||||
|
||||
**Files**:
|
||||
- `include/gal/opengl/opengl_gal.h`
|
||||
- `common/gal/opengl/opengl_gal.cpp`
|
||||
- `common/gal/opengl/shader.cpp` - GLSL shader management
|
||||
- `common/gal/opengl/vertex_manager.cpp` - Vertex buffer management
|
||||
- `common/gal/opengl/gpu_manager.cpp` - GPU memory management
|
||||
- `common/gal/opengl/cached_container.cpp` - Geometry caching
|
||||
|
||||
**Canvas**: `HIDPI_GL_CANVAS` wraps `wxGLCanvas`
|
||||
|
||||
**Shader files** (`common/gal/shaders/`):
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `kicad_vert.glsl` | Main vertex shader |
|
||||
| `kicad_frag.glsl` | Main fragment shader |
|
||||
| `smaa_base.glsl` | SMAA antialiasing base |
|
||||
| `smaa_pass_1_frag.glsl` | SMAA edge detection |
|
||||
| `smaa_pass_2_frag.glsl` | SMAA blending weights |
|
||||
| `smaa_pass_3_frag.glsl` | SMAA neighborhood blending |
|
||||
|
||||
Shaders are embedded as C strings at build time.
|
||||
|
||||
**For WebGL**: Need to convert shaders:
|
||||
```glsl
|
||||
// Before (desktop GLSL)
|
||||
#version 120
|
||||
varying vec4 color;
|
||||
|
||||
// After (WebGL/GLSL ES)
|
||||
precision mediump float;
|
||||
varying vec4 color;
|
||||
```
|
||||
|
||||
### Cairo GAL
|
||||
|
||||
**Files**:
|
||||
- `include/gal/cairo/cairo_gal.h`
|
||||
- `common/gal/cairo/cairo_gal.cpp`
|
||||
- `common/gal/cairo/cairo_compositor.cpp` - Layer compositing
|
||||
- `common/gal/cairo/cairo_print.cpp` - Printing support
|
||||
|
||||
Used for:
|
||||
- Software rendering fallback
|
||||
- Printing
|
||||
- PDF/SVG export
|
||||
|
||||
### Draw Panel
|
||||
|
||||
**File**: `include/class_draw_panel_gal.h`
|
||||
|
||||
`EDA_DRAW_PANEL_GAL` wraps GAL and handles:
|
||||
- Mouse events
|
||||
- Keyboard events
|
||||
- Tool dispatching
|
||||
- View management
|
||||
|
||||
---
|
||||
|
||||
## File I/O System
|
||||
|
||||
### Architecture
|
||||
|
||||
Plugin-based system with base class `IO_BASE`:
|
||||
|
||||
**File**: `include/io/io_base.h`
|
||||
|
||||
```cpp
|
||||
class IO_BASE {
|
||||
struct IO_FILE_DESC {
|
||||
wxString m_Description;
|
||||
std::vector<std::string> m_FileExtensions;
|
||||
bool m_CanRead;
|
||||
bool m_CanWrite;
|
||||
};
|
||||
|
||||
virtual std::vector<IO_FILE_DESC> GetFileDescriptors();
|
||||
virtual void SetReporter(REPORTER* reporter);
|
||||
virtual void SetProgressReporter(PROGRESS_REPORTER* reporter);
|
||||
};
|
||||
```
|
||||
|
||||
### Format Plugins
|
||||
|
||||
**KiCad Native** (`common/io/kicad/`):
|
||||
- S-expression based format
|
||||
- `.kicad_pcb`, `.kicad_sch`, `.kicad_sym`, `.kicad_mod`
|
||||
|
||||
**Import Plugins** (`common/io/`):
|
||||
| Plugin | Location | Formats |
|
||||
|--------|----------|---------|
|
||||
| Eagle | `common/io/eagle/` | `.brd`, `.sch` |
|
||||
| Altium | `common/io/altium/` | `.PcbDoc`, `.SchDoc` |
|
||||
| CADSTAR | `common/io/cadstar/` | `.cpa`, `.csa` |
|
||||
| EasyEDA | `common/io/easyeda/` | `.json` |
|
||||
| EasyEDA Pro | `common/io/easyedapro/` | `.epro` |
|
||||
|
||||
### S-Expression Parser
|
||||
|
||||
**Location**: `libs/sexpr/`
|
||||
|
||||
KiCad native files use S-expressions:
|
||||
```lisp
|
||||
(kicad_pcb (version 20221018)
|
||||
(generator pcbnew)
|
||||
(layers
|
||||
(0 "F.Cu" signal)
|
||||
(31 "B.Cu" signal))
|
||||
(footprint "Package_SO:SOIC-8"
|
||||
(at 100 100)
|
||||
(pad "1" smd rect (at -1.905 -2.475) (size 0.6 1.5))))
|
||||
```
|
||||
|
||||
Parser is pure C++, good candidate for Wasm.
|
||||
|
||||
### PCB Data Model
|
||||
|
||||
**Key classes** (in `pcbnew/`):
|
||||
|
||||
| Class | File | Purpose |
|
||||
|-------|------|---------|
|
||||
| `BOARD` | `board.h` | Top-level PCB container |
|
||||
| `FOOTPRINT` | `footprint.h` | Component footprint |
|
||||
| `PAD` | `pad.h` | Footprint pad |
|
||||
| `PCB_TRACK` | `pcb_track.h` | Trace segment |
|
||||
| `PCB_VIA` | `pcb_track.h` | Via |
|
||||
| `ZONE` | `zone.h` | Copper pour |
|
||||
| `PCB_SHAPE` | `pcb_shape.h` | Graphical shape |
|
||||
| `PCB_TEXT` | `pcb_text.h` | Text |
|
||||
|
||||
**Hierarchy**:
|
||||
```
|
||||
BOARD
|
||||
├── FOOTPRINT[]
|
||||
│ ├── PAD[]
|
||||
│ ├── PCB_SHAPE[]
|
||||
│ └── PCB_TEXT[]
|
||||
├── PCB_TRACK[]
|
||||
├── PCB_VIA[]
|
||||
├── ZONE[]
|
||||
├── PCB_SHAPE[]
|
||||
└── PCB_TEXT[]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Python Scripting
|
||||
|
||||
### SWIG Bindings
|
||||
|
||||
**Location**: `scripting/`, `common/swig/`, `pcbnew/python/swig/`
|
||||
|
||||
**Interface files** (`.i`):
|
||||
| File | Lines | Purpose |
|
||||
|------|-------|---------|
|
||||
| `kicadplugins.i` | 695 | Plugin framework |
|
||||
| `wx.i` | 348 | wxWidgets types |
|
||||
| `board.i` | 201 | BOARD class |
|
||||
| `board_item.i` | 222 | Base item class |
|
||||
| `footprint.i` | 200 | FOOTPRINT class |
|
||||
| `pad.i` | 128 | PAD class |
|
||||
| `pcbnew.i` | 148 | Main pcbnew module |
|
||||
| Others | ~1600 | Various classes |
|
||||
| **Total** | ~3500 | |
|
||||
|
||||
### How SWIG Works
|
||||
|
||||
1. SWIG reads `.i` interface files
|
||||
2. Generates C++ wrapper code for CPython
|
||||
3. Wrapper compiled to shared library (`_pcbnew.so`)
|
||||
4. Python imports the module
|
||||
|
||||
```python
|
||||
import pcbnew
|
||||
board = pcbnew.GetBoard()
|
||||
for track in board.GetTracks():
|
||||
print(track.GetStart(), track.GetEnd())
|
||||
```
|
||||
|
||||
### Plugin Types
|
||||
|
||||
| Type | Purpose | Interface |
|
||||
|------|---------|-----------|
|
||||
| FootprintWizard | Generate footprints programmatically | `FootprintWizardPlugin` |
|
||||
| ActionPlugin | Custom toolbar actions | `ActionPlugin` |
|
||||
| FilePlugin | Custom file formats | `FilePlugin` |
|
||||
|
||||
### Wasm Strategy
|
||||
|
||||
SWIG generates CPython-specific code. Options for Wasm:
|
||||
|
||||
1. **Emscripten embind**: Rewrite bindings (~3500 lines to port)
|
||||
```cpp
|
||||
#include <emscripten/bind.h>
|
||||
EMSCRIPTEN_BINDINGS(pcbnew) {
|
||||
class_<BOARD>("Board")
|
||||
.function("GetTracks", &BOARD::Tracks);
|
||||
}
|
||||
```
|
||||
|
||||
2. **Pyodide**: If we want Python in browser, use Pyodide with custom FFI
|
||||
|
||||
3. **Skip for MVP**: Python scripting is optional for basic editing
|
||||
|
||||
---
|
||||
|
||||
## Build System
|
||||
|
||||
### Main CMakeLists.txt Structure
|
||||
|
||||
```
|
||||
CMakeLists.txt
|
||||
├── Project setup (lines 1-100)
|
||||
├── Options (lines 110-290)
|
||||
│ ├── KICAD_SPICE_QA
|
||||
│ ├── KICAD_USE_SENTRY
|
||||
│ ├── KICAD_BUILD_I18N
|
||||
│ ├── KICAD_BUILD_QA_TESTS
|
||||
│ ├── KICAD_SCRIPTING_WXPYTHON
|
||||
│ ├── KICAD_UPDATE_CHECK
|
||||
│ └── ... more options
|
||||
├── Compiler setup (lines 300-800)
|
||||
├── Dependencies (lines 800-1200)
|
||||
│ ├── find_package(ZLIB)
|
||||
│ ├── find_package(CURL) # Line 825 - REQUIRED
|
||||
│ ├── find_package(libgit2) # Line 842 - REQUIRED
|
||||
│ ├── find_package(ngspice) # Line 877 - REQUIRED
|
||||
│ ├── find_package(OCC) # Line 880 - FATAL if not found
|
||||
│ └── ... more deps
|
||||
├── wxWidgets setup (lines 1080-1140)
|
||||
└── Subdirectories (lines 1250+)
|
||||
```
|
||||
|
||||
### Common Library Build
|
||||
|
||||
**File**: `common/CMakeLists.txt`
|
||||
|
||||
```cmake
|
||||
# KICOMMON_SRCS includes:
|
||||
# - git/*.cpp (lines 75-95)
|
||||
# - kicad_curl/*.cpp (lines 140-141)
|
||||
# - database/*.cpp
|
||||
# - All UI code
|
||||
|
||||
target_link_libraries(kicommon
|
||||
CURL::libcurl # Line 325
|
||||
${LIBGIT2_LIBRARIES} # Line 330
|
||||
# ...
|
||||
)
|
||||
```
|
||||
|
||||
### Adding CMake Options for Optional Deps
|
||||
|
||||
Need to add after line 107:
|
||||
```cmake
|
||||
option( KICAD_USE_CURL "Enable network features" ON )
|
||||
option( KICAD_USE_GIT "Enable git integration" ON )
|
||||
option( KICAD_USE_OCC "Enable STEP/3D via OpenCASCADE" ON )
|
||||
option( KICAD_USE_NGSPICE "Enable SPICE simulation" ON )
|
||||
option( KICAD_USE_DATABASE "Enable database libraries" ON )
|
||||
```
|
||||
|
||||
Then wrap find_package calls:
|
||||
```cmake
|
||||
if( KICAD_USE_CURL )
|
||||
find_package( CURL REQUIRED )
|
||||
add_compile_definitions( KICAD_USE_CURL )
|
||||
else()
|
||||
add_library( CURL::libcurl INTERFACE IMPORTED )
|
||||
endif()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Features to Disable
|
||||
|
||||
### Git Integration
|
||||
|
||||
**Files to stub** (`common/git/`):
|
||||
- `git_add_to_index_handler.cpp`
|
||||
- `git_branch_handler.cpp`
|
||||
- `git_clone_handler.cpp`
|
||||
- `git_commit_handler.cpp`
|
||||
- `git_config_handler.cpp`
|
||||
- `git_compare_handler.cpp`
|
||||
- `git_init_handler.cpp`
|
||||
- `git_pull_handler.cpp`
|
||||
- `git_push_handler.cpp`
|
||||
- `git_remove_from_index_handler.cpp`
|
||||
- `git_remove_vcs_handler.cpp`
|
||||
- `git_resolve_conflict_handler.cpp`
|
||||
- `git_revert_handler.cpp`
|
||||
- `git_status_handler.cpp`
|
||||
- `git_switch_branch_handler.cpp`
|
||||
- `git_sync_handler.cpp`
|
||||
- `kicad_git_common.cpp`
|
||||
- `git_backend.cpp`
|
||||
- `libgit_backend.cpp`
|
||||
- `project_git_utils.cpp`
|
||||
|
||||
**Stub header needed**: `stubs/include/git2.h`
|
||||
|
||||
### Network Features (curl)
|
||||
|
||||
**Files to stub** (`common/kicad_curl/`):
|
||||
- `kicad_curl.cpp`
|
||||
- `kicad_curl_easy.cpp`
|
||||
|
||||
**Files to stub** (`common/http_lib/`):
|
||||
- `http_lib_connection.cpp`
|
||||
|
||||
**Files affected** (`kicad/`):
|
||||
- `pcm/pcm.cpp` - Plugin Content Manager
|
||||
- `pcm/pcm_task_manager.cpp`
|
||||
- `update_manager.cpp`
|
||||
|
||||
**Stub header needed**: `stubs/include/curl/curl.h`
|
||||
|
||||
### OpenCASCADE (STEP/3D)
|
||||
|
||||
**Files to exclude**:
|
||||
- `pcbnew/exporters/step/*.cpp`
|
||||
- `plugins/3d/oce/*.cpp`
|
||||
|
||||
**Approach**: Don't build these targets rather than stubbing.
|
||||
|
||||
### SPICE Simulation
|
||||
|
||||
**Files affected**: `eeschema/sim/`
|
||||
|
||||
**Approach**: Disable simulator UI, don't build sim targets.
|
||||
|
||||
### Database Libraries
|
||||
|
||||
**Files to stub** (`common/database/`):
|
||||
- `database_connection.cpp`
|
||||
- `database_cache.cpp`
|
||||
|
||||
---
|
||||
|
||||
## Code Extraction Candidates
|
||||
|
||||
### Tier 1: Pure Computation (No Dependencies)
|
||||
|
||||
| Component | Location | Lines (approx) | Notes |
|
||||
|-----------|----------|----------------|-------|
|
||||
| Math library | `libs/kimath/src/` | ~5000 | Vectors, matrices, geometry |
|
||||
| Core utilities | `libs/core/src/` | ~2000 | String utils, exceptions |
|
||||
| S-expr parser | `libs/sexpr/` | ~1500 | Pure parsing |
|
||||
|
||||
### Tier 2: File I/O (Minimal Dependencies)
|
||||
|
||||
| Component | Location | Notes |
|
||||
|-----------|----------|-------|
|
||||
| KiCad PCB parser | `common/io/kicad/` | Needs kimath, sexpr |
|
||||
| Board data model | `pcbnew/*.cpp` | Core classes only |
|
||||
| Schematic parser | `common/io/eeschema/` | Needs kimath |
|
||||
|
||||
### Tier 3: Algorithms (May Need Adaptation)
|
||||
|
||||
| Component | Location | Notes |
|
||||
|-----------|----------|-------|
|
||||
| DRC engine | `pcbnew/drc/` | May use threading |
|
||||
| Router | `pcbnew/router/` | Push & Shove |
|
||||
| ERC | `eeschema/erc/` | Electrical checks |
|
||||
| Connectivity | `pcbnew/connectivity/` | Net analysis |
|
||||
|
||||
---
|
||||
|
||||
## Technical Challenges
|
||||
|
||||
### Threading
|
||||
|
||||
**Current usage**:
|
||||
- DRC runs checks in parallel
|
||||
- Router uses threading for optimization
|
||||
- Background jobs system
|
||||
|
||||
**Wasm limitation**: Single-threaded by default.
|
||||
|
||||
**Solutions**:
|
||||
1. **Web Workers**: Spawn separate Wasm instances
|
||||
2. **Wasm threads** (experimental): SharedArrayBuffer + pthreads
|
||||
3. **Sequential fallback**: Slower but works
|
||||
|
||||
**Decision**: Use Web Workers. Design for async message-passing.
|
||||
|
||||
### Memory Management
|
||||
|
||||
**Challenge**: Need to share board state between native GUI and Wasm core.
|
||||
|
||||
**Options**:
|
||||
1. **Serialize/deserialize**: Simple, proof of concept
|
||||
2. **Shared memory**: Complex, requires careful synchronization
|
||||
3. **Authoritative Wasm copy**: GUI requests views
|
||||
|
||||
**Decision**: Serialize/deserialize. Proof of concept, simplicity over performance.
|
||||
|
||||
### File Access
|
||||
|
||||
**Native**: Direct filesystem, `wxFileDialog`
|
||||
|
||||
**Browser**: No filesystem access without user interaction
|
||||
|
||||
**Solutions**:
|
||||
- Emscripten virtual filesystem (MEMFS, IDBFS)
|
||||
- File System Access API (Chrome)
|
||||
- IndexedDB for persistence
|
||||
- Drag & drop / file picker
|
||||
|
||||
### Clipboard
|
||||
|
||||
**Native**: `wxClipboard`, platform integration
|
||||
|
||||
**Browser**: Async Clipboard API (permissions required)
|
||||
|
||||
### Fonts
|
||||
|
||||
**Native**: System fonts via Fontconfig
|
||||
|
||||
**Browser**: Bundle fonts or use CSS fonts
|
||||
|
||||
---
|
||||
|
||||
## Design Decisions
|
||||
|
||||
### Memory Management
|
||||
|
||||
**Decision**: Serialize/deserialize on every operation
|
||||
|
||||
**Rationale**:
|
||||
- Proof of concept phase
|
||||
- Simplicity over performance
|
||||
- Clean interface between GUI and core
|
||||
- Easy to debug
|
||||
- Browser-friendly (no shared memory complexity)
|
||||
|
||||
**Implementation**:
|
||||
```cpp
|
||||
// GUI → Wasm: Send operation + serialized state
|
||||
std::string boardJson = SerializeBoard(board);
|
||||
wasmCore.ApplyOperation(boardJson, operation);
|
||||
std::string newBoardJson = wasmCore.GetBoardState();
|
||||
board = DeserializeBoard(newBoardJson);
|
||||
```
|
||||
|
||||
### Threading Model
|
||||
|
||||
**Decision**: Web Workers
|
||||
|
||||
**Rationale**:
|
||||
- Target is browser
|
||||
- Clean message-passing interface
|
||||
- Each worker is isolated Wasm instance
|
||||
- No shared memory complexity
|
||||
|
||||
**Implementation**:
|
||||
```javascript
|
||||
// Main thread
|
||||
const worker = new Worker('kicad-core-worker.js');
|
||||
worker.postMessage({ type: 'runDRC', board: boardData });
|
||||
worker.onmessage = (e) => { handleDRCResults(e.data); };
|
||||
|
||||
// Worker
|
||||
importScripts('kicad_core.js');
|
||||
onmessage = async (e) => {
|
||||
const core = await KicadCore();
|
||||
if (e.data.type === 'runDRC') {
|
||||
const results = core.runDRC(e.data.board);
|
||||
postMessage(results);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Incremental Updates
|
||||
|
||||
**Decision**: Re-serialize entire board (for now)
|
||||
|
||||
**Rationale**:
|
||||
- Simple implementation
|
||||
- Board files are typically <10MB
|
||||
- Performance acceptable for proof of concept
|
||||
- Can optimize later with deltas if needed
|
||||
|
||||
---
|
||||
|
||||
## File Reference
|
||||
|
||||
### Core Headers
|
||||
|
||||
| Purpose | File |
|
||||
|---------|------|
|
||||
| GAL interface | `include/gal/graphics_abstraction_layer.h` |
|
||||
| OpenGL GAL | `include/gal/opengl/opengl_gal.h` |
|
||||
| Cairo GAL | `include/gal/cairo/cairo_gal.h` |
|
||||
| Draw panel | `include/class_draw_panel_gal.h` |
|
||||
| Base frame | `include/eda_base_frame.h` |
|
||||
| KIWAY | `include/kiway.h` |
|
||||
| KIWAY holder | `include/kiway_holder.h` |
|
||||
| I/O base | `include/io/io_base.h` |
|
||||
| Board | `pcbnew/board.h` |
|
||||
| Footprint | `pcbnew/footprint.h` |
|
||||
| Track | `pcbnew/pcb_track.h` |
|
||||
|
||||
### Build Files
|
||||
|
||||
| Purpose | File |
|
||||
|---------|------|
|
||||
| Main build | `CMakeLists.txt` |
|
||||
| Common lib | `common/CMakeLists.txt` |
|
||||
| GAL lib | `common/gal/CMakeLists.txt` |
|
||||
| PCBnew | `pcbnew/CMakeLists.txt` |
|
||||
| Eeschema | `eeschema/CMakeLists.txt` |
|
||||
| 3D viewer | `3d-viewer/CMakeLists.txt` |
|
||||
|
||||
### SWIG Bindings
|
||||
|
||||
| Purpose | File |
|
||||
|---------|------|
|
||||
| Main entry | `scripting/kicadplugins.i` |
|
||||
| Common | `common/swig/kicad.i` |
|
||||
| wxWidgets | `common/swig/wx.i` |
|
||||
| Math | `common/swig/math.i` |
|
||||
| Shapes | `common/swig/shape.i` |
|
||||
| Board | `pcbnew/python/swig/board.i` |
|
||||
| PCBnew main | `pcbnew/python/swig/pcbnew.i` |
|
||||
|
||||
### Git Integration
|
||||
|
||||
| Purpose | File |
|
||||
|---------|------|
|
||||
| Common class | `common/git/kicad_git_common.cpp` |
|
||||
| Clone | `common/git/git_clone_handler.cpp` |
|
||||
| Commit | `common/git/git_commit_handler.cpp` |
|
||||
| Push | `common/git/git_push_handler.cpp` |
|
||||
| Pull | `common/git/git_pull_handler.cpp` |
|
||||
| Status | `common/git/git_status_handler.cpp` |
|
||||
| PCB merge | `pcbnew/git/kigit_pcb_merge.cpp` |
|
||||
|
||||
### Curl/Network
|
||||
|
||||
| Purpose | File |
|
||||
|---------|------|
|
||||
| Curl wrapper | `common/kicad_curl/kicad_curl_easy.cpp` |
|
||||
| Curl init | `common/kicad_curl/kicad_curl.cpp` |
|
||||
| HTTP lib | `common/http_lib/http_lib_connection.cpp` |
|
||||
| PCM | `kicad/pcm/pcm.cpp` |
|
||||
| Updates | `kicad/update_manager.cpp` |
|
||||
|
||||
### OpenCASCADE/STEP
|
||||
|
||||
| Purpose | File |
|
||||
|---------|------|
|
||||
| STEP model | `pcbnew/exporters/step/step_pcb_model.cpp` |
|
||||
| STEP export | `pcbnew/exporters/step/exporter_step.cpp` |
|
||||
| OCC plugin | `plugins/3d/oce/oce.cpp` |
|
||||
| Model loader | `plugins/3d/oce/loadmodel.cpp` |
|
||||
Loading…
Reference in a new issue