pcbjam/tests/apps/Makefile.wasm
Viktor Vaczi 7629ab978d test(e2e): fix wx suite — header deps, port pinning, drop legacy-GL tests, wx+pthread worker fix
Suite went 64 failed → 291 passed / 0 failed:
- Makefile.wasm: compile with -MMD -MP and include .d files — stale objects
  relinked against a newer wx lib crashed apps at startup with "function
  signature mismatch" after any header/vtable change
- playwright(.coroutine).config.ts: pin the server port for the whole run
  (resolvePort from playwright-kicad.config.ts); the 60s freshness window made
  workers restarted after a failure rotate to a dead port (ERR_CONNECTION_REFUSED
  cascade across ~50 tests)
- drop legacy-GL testing: KiCad renders via WebGL GAL (gal-webgl.spec.ts);
  remove minimal_test's OpenGL tab/GLTestCanvas, opengl.spec.ts, GL z-order
  describes, -sLEGACY_GL_EMULATION + gl_immediate_shim.js from the test build,
  and the orphaned GL baselines
- coroutine-pthread repro apps join the `all` target (make clean used to delete
  them while all never rebuilt them); clean no longer eats checked-in JS like
  worker_dom_stub.js
- bump wxwidgets: guard module-eval document access so wx+pthread apps
  (threadpool tests) survive Web Worker eval

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 13:40:00 +02:00

704 lines
31 KiB
Text

# Makefile for wxWidgets WASM test apps
# Uses the local wxWidgets build
#
# Usage:
# make -f Makefile.wasm # Optimized release build
# make -f Makefile.wasm DEBUG=1 # Debug build with DWARF symbols and source maps
WXCONFIG = ../../build-wasm/wxwidgets-universal/wx-config
TOOLS_ROOT = ../../wxwidgets/build/wasm
KICAD_ROOT = ../../kicad
CXX = em++
WX_CXXFLAGS := $(shell $(WXCONFIG) --cxxflags)
# Libraries for non-GL apps (standalone tests don't need GL)
WX_LDFLAGS_NOGL := $(shell $(WXCONFIG) --libs base,core,aui)
# Libraries for HTML apps (htmlwin_test needs html)
WX_LDFLAGS_HTML := $(shell $(WXCONFIG) --libs base,core,html)
# Libraries for STC apps (stc_test needs stc)
WX_LDFLAGS_STC := $(shell $(WXCONFIG) --libs base,core,stc)
# Libraries for PropGrid apps (propgrid_test needs propgrid)
WX_LDFLAGS_PROPGRID := $(shell $(WXCONFIG) --libs base,core,propgrid)
# Libraries for AUI apps (auinotebook needs aui)
WX_LDFLAGS_AUI := $(shell $(WXCONFIG) --libs base,core,aui)
# Libraries for ADV apps (wizard, calendar need adv)
WX_LDFLAGS_ADV := $(shell $(WXCONFIG) --libs base,core,adv)
# Libraries for XML apps (xml_test needs xml)
WX_LDFLAGS_XML := $(shell $(WXCONFIG) --libs base,core,xml)
# Debug or Release build
ifdef DEBUG
# Debug: DWARF info, source maps, minimal optimization
CXXFLAGS = -g -O0 $(WX_CXXFLAGS)
DEBUG_LDFLAGS = -g -gsource-map
else
# Release: optimized
CXXFLAGS = -O2 $(WX_CXXFLAGS)
DEBUG_LDFLAGS =
endif
# Track header dependencies: without this, objects compiled against old wx headers
# get silently relinked into a newer library, and any vtable layout change then
# crashes apps at startup with "RuntimeError: function signature mismatch".
CXXFLAGS += -MMD -MP
# Base Emscripten flags (for all apps)
# ASYNCIFY enables blocking modal dialogs (ShowModal waits for user)
# ASYNCIFY_IMPORTS tells Emscripten which imported JS functions can unwind the stack
# - startModal: for modal dialogs
# - js_writeTextToClipboard, js_readTextFromClipboard, js_clipboardHasText, js_clearClipboard: for clipboard
# - js_enumerateFonts: for font enumeration via Local Font Access API
BASE_LDFLAGS = -sALLOW_MEMORY_GROWTH -sERROR_ON_UNDEFINED_SYMBOLS=0 \
-s "EXPORTED_RUNTIME_METHODS=['HEAPU8','HEAP8','HEAP32','ccall']" \
-sASYNCIFY=1 \
-sASYNCIFY_STACK_SIZE=8192 \
-sASYNCIFY_IMPORTS=['startModal','js_writeTextToClipboard','js_readTextFromClipboard','js_clipboardHasText','js_clearClipboard','js_enumerateFonts']
# LDFLAGS for non-GL apps (standalone tests)
LDFLAGS_NOGL = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) $(WX_LDFLAGS_NOGL)
# LDFLAGS for HTML apps (htmlwin_test)
LDFLAGS_HTML = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) $(WX_LDFLAGS_HTML)
# LDFLAGS for STC apps (stc_test)
LDFLAGS_STC = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) $(WX_LDFLAGS_STC)
# LDFLAGS for PropGrid apps (propgrid_test)
LDFLAGS_PROPGRID = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) $(WX_LDFLAGS_PROPGRID)
# LDFLAGS for AUI apps (auinotebook)
LDFLAGS_AUI = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) $(WX_LDFLAGS_AUI)
# LDFLAGS for ADV apps (wizard, calendar)
LDFLAGS_ADV = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) $(WX_LDFLAGS_ADV)
# LDFLAGS for XML apps (xml_test)
LDFLAGS_XML = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) $(WX_LDFLAGS_XML)
# LDFLAGS for pthread test - uses dynamic PTHREAD_POOL_SIZE to match hardware_concurrency
# This fixes the KiCad deadlock: pre-warm enough workers for all threads
LDFLAGS_PTHREAD = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) -pthread \
-sPTHREAD_POOL_SIZE='navigator.hardwareConcurrency' \
-sPTHREAD_POOL_SIZE_STRICT=0 \
$(WX_LDFLAGS_NOGL)
# Coroutine harness flags - mirror KiCad's fiber-related runtime needs
COROUTINE_BASE_LDFLAGS = -sALLOW_MEMORY_GROWTH -sERROR_ON_UNDEFINED_SYMBOLS=0 \
-s "EXPORTED_RUNTIME_METHODS=['HEAPU8','HEAP8','HEAP32','ccall']" \
-sASYNCIFY=1 \
-sASYNCIFY_STACK_SIZE=65536 \
-sASYNCIFY_IMPORTS=['startModal','js_writeTextToClipboard','js_readTextFromClipboard','js_clipboardHasText','js_clearClipboard','js_enumerateFonts','emscripten_fiber_swap']
LDFLAGS_COROUTINE = $(DEBUG_LDFLAGS) $(COROUTINE_BASE_LDFLAGS) $(WX_LDFLAGS_NOGL)
JS = $(TOOLS_ROOT)/wx.js
HTML = $(TOOLS_ROOT)/template.html
# wxWidgets library directory - used as dependency to rebuild when libs change
WX_LIB_DIR = ../../build-wasm/wxwidgets-universal/lib
# Key library that changes when wxWidgets is rebuilt
WX_CORE_LIB = $(WX_LIB_DIR)/libwx_wasmunivu_core-3.2-emscripten.a
# Standalone directories
S = standalone
# Pull in the dependency files generated by -MMD
-include $(wildcard *.d) $(wildcard $(S)/*/*.d)
all: minimal_test.html \
$(S)/menu/menu_test.html \
$(S)/clipboard/clipboard_test.html \
$(S)/filedialog/filedialog_test.html \
$(S)/layout/layout_test.html \
$(S)/aui/aui_test.html \
$(S)/toolbar/toolbar_test.html \
$(S)/grid/grid_test.html \
$(S)/dialog/dialog_test.html \
$(S)/timer/timer_test.html \
$(S)/tree/tree_test.html \
$(S)/dataview/dataview_test.html \
$(S)/htmlwin/htmlwin_test.html \
$(S)/stc/stc_test.html \
$(S)/print/print_test.html \
$(S)/dnd/dnd_test.html \
$(S)/propgrid/propgrid_test.html \
$(S)/pickers/pickers_test.html \
$(S)/collapsible/collapsible_test.html \
$(S)/listctrl/listctrl_test.html \
$(S)/infobar/infobar_test.html \
$(S)/dataviewvirtual/dataviewvirtual_test.html \
$(S)/auinotebook/auinotebook_test.html \
$(S)/wizard/wizard_test.html \
$(S)/gridedit/gridedit_test.html \
$(S)/calendar/calendar_test.html \
$(S)/gridrenderers/gridrenderers_test.html \
$(S)/printpreview/printpreview_test.html \
$(S)/bitmapbuttons/bitmapbuttons_test.html \
$(S)/specialized/specialized_test.html \
$(S)/validators/validators_test.html \
$(S)/ownerdrawn/ownerdrawn_test.html \
$(S)/popup/popup_test.html \
$(S)/xml/xml_test.html \
$(S)/wasmedge/wasmedge_test.html \
$(S)/fontenum/fontenum_test.html \
$(S)/textdecor/textdecor_test.html \
$(S)/bitmask/bitmask_test.html \
$(S)/regions/regions_test.html \
$(S)/maximize/maximize_test.html \
$(S)/earlysize/earlysize_test.html \
$(S)/threadpool/threadpool_test.html \
$(S)/logerror/logerror_test.html \
$(S)/retinascale/retinascale_test.html \
$(S)/coroutine/coroutine_test.html \
$(S)/coroutine-nested/nested_test.html \
$(S)/coroutine-pthread/coroutine_test_wxpt.html \
$(S)/coroutine-pthread/embind_repro.html \
$(S)/coroutine-pthread/gl_repro.html \
$(S)/coroutine-pthread/gl_repro_pt.html \
$(S)/coroutine-pthread/main_repro.html \
$(S)/coroutine-pthread/mainloop_repro.html \
$(S)/coroutine-pthread/nested_repro_ex.html \
$(S)/coroutine-pthread/vcall_repro.html
# Main test app
minimal_test.o: minimal_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
minimal_test.html: minimal_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Menu test (no GL)
$(S)/menu/menu_test.o: $(S)/menu/menu_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/menu/menu_test.html: $(S)/menu/menu_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Clipboard test (no GL)
$(S)/clipboard/clipboard_test.o: $(S)/clipboard/clipboard_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/clipboard/clipboard_test.html: $(S)/clipboard/clipboard_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# FileDialog test (no GL)
$(S)/filedialog/filedialog_test.o: $(S)/filedialog/filedialog_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/filedialog/filedialog_test.html: $(S)/filedialog/filedialog_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Layout test (no GL)
$(S)/layout/layout_test.o: $(S)/layout/layout_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/layout/layout_test.html: $(S)/layout/layout_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# AUI test (no GL)
$(S)/aui/aui_test.o: $(S)/aui/aui_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/aui/aui_test.html: $(S)/aui/aui_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Toolbar test (no GL)
$(S)/toolbar/toolbar_test.o: $(S)/toolbar/toolbar_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/toolbar/toolbar_test.html: $(S)/toolbar/toolbar_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Grid test (no GL)
$(S)/grid/grid_test.o: $(S)/grid/grid_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/grid/grid_test.html: $(S)/grid/grid_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Dialog test (no GL)
$(S)/dialog/dialog_test.o: $(S)/dialog/dialog_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/dialog/dialog_test.html: $(S)/dialog/dialog_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Timer test (no GL)
$(S)/timer/timer_test.o: $(S)/timer/timer_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/timer/timer_test.html: $(S)/timer/timer_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Tree test (no GL)
$(S)/tree/tree_test.o: $(S)/tree/tree_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/tree/tree_test.html: $(S)/tree/tree_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# DataView test (no GL)
$(S)/dataview/dataview_test.o: $(S)/dataview/dataview_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/dataview/dataview_test.html: $(S)/dataview/dataview_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# HtmlWindow test (needs HTML library)
$(S)/htmlwin/htmlwin_test.o: $(S)/htmlwin/htmlwin_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/htmlwin/htmlwin_test.html: $(S)/htmlwin/htmlwin_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_HTML) --pre-js $(JS) --shell-file $(HTML) -o $@
# StyledTextCtrl test (needs STC library)
$(S)/stc/stc_test.o: $(S)/stc/stc_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/stc/stc_test.html: $(S)/stc/stc_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_STC) --pre-js $(JS) --shell-file $(HTML) -o $@
# Print test (no GL)
$(S)/print/print_test.o: $(S)/print/print_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/print/print_test.html: $(S)/print/print_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# DragDrop test (no GL)
$(S)/dnd/dnd_test.o: $(S)/dnd/dnd_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/dnd/dnd_test.html: $(S)/dnd/dnd_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# PropertyGrid test (needs propgrid library)
$(S)/propgrid/propgrid_test.o: $(S)/propgrid/propgrid_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/propgrid/propgrid_test.html: $(S)/propgrid/propgrid_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_PROPGRID) --pre-js $(JS) --shell-file $(HTML) -o $@
# Pickers test (colour/font pickers, no GL)
$(S)/pickers/pickers_test.o: $(S)/pickers/pickers_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/pickers/pickers_test.html: $(S)/pickers/pickers_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Collapsible pane test (no GL)
$(S)/collapsible/collapsible_test.o: $(S)/collapsible/collapsible_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/collapsible/collapsible_test.html: $(S)/collapsible/collapsible_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# ListCtrl virtual mode test (no GL)
$(S)/listctrl/listctrl_test.o: $(S)/listctrl/listctrl_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/listctrl/listctrl_test.html: $(S)/listctrl/listctrl_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# InfoBar test (no GL)
$(S)/infobar/infobar_test.o: $(S)/infobar/infobar_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/infobar/infobar_test.html: $(S)/infobar/infobar_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# DataViewCtrl Virtual Mode test (no GL, uses base dataview)
$(S)/dataviewvirtual/dataviewvirtual_test.o: $(S)/dataviewvirtual/dataviewvirtual_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/dataviewvirtual/dataviewvirtual_test.html: $(S)/dataviewvirtual/dataviewvirtual_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# AuiNotebook test (needs aui)
$(S)/auinotebook/auinotebook_test.o: $(S)/auinotebook/auinotebook_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/auinotebook/auinotebook_test.html: $(S)/auinotebook/auinotebook_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_AUI) --pre-js $(JS) --shell-file $(HTML) -o $@
# Wizard test (needs adv)
$(S)/wizard/wizard_test.o: $(S)/wizard/wizard_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/wizard/wizard_test.html: $(S)/wizard/wizard_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_ADV) --pre-js $(JS) --shell-file $(HTML) -o $@
# Grid Edit test (cell editing, no GL)
$(S)/gridedit/gridedit_test.o: $(S)/gridedit/gridedit_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/gridedit/gridedit_test.html: $(S)/gridedit/gridedit_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Calendar test (needs adv)
$(S)/calendar/calendar_test.o: $(S)/calendar/calendar_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/calendar/calendar_test.html: $(S)/calendar/calendar_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_ADV) --pre-js $(JS) --shell-file $(HTML) -o $@
# Grid Renderers test (no GL)
$(S)/gridrenderers/gridrenderers_test.o: $(S)/gridrenderers/gridrenderers_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/gridrenderers/gridrenderers_test.html: $(S)/gridrenderers/gridrenderers_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Print Preview test (no GL)
$(S)/printpreview/printpreview_test.o: $(S)/printpreview/printpreview_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/printpreview/printpreview_test.html: $(S)/printpreview/printpreview_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Bitmap Buttons test (no GL)
$(S)/bitmapbuttons/bitmapbuttons_test.o: $(S)/bitmapbuttons/bitmapbuttons_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/bitmapbuttons/bitmapbuttons_test.html: $(S)/bitmapbuttons/bitmapbuttons_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Specialized Controls test (needs adv for treebook)
$(S)/specialized/specialized_test.o: $(S)/specialized/specialized_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/specialized/specialized_test.html: $(S)/specialized/specialized_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_ADV) --pre-js $(JS) --shell-file $(HTML) -o $@
# Validators test (no GL)
$(S)/validators/validators_test.o: $(S)/validators/validators_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/validators/validators_test.html: $(S)/validators/validators_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Owner-drawn ComboBox test (no GL)
$(S)/ownerdrawn/ownerdrawn_test.o: $(S)/ownerdrawn/ownerdrawn_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/ownerdrawn/ownerdrawn_test.html: $(S)/ownerdrawn/ownerdrawn_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Popup Window test (no GL)
$(S)/popup/popup_test.o: $(S)/popup/popup_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/popup/popup_test.html: $(S)/popup/popup_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# XML Document test (needs xml library)
$(S)/xml/xml_test.o: $(S)/xml/xml_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/xml/xml_test.html: $(S)/xml/xml_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_XML) --pre-js $(JS) --shell-file $(HTML) -o $@
# WASM Edge Cases test (no GL)
$(S)/wasmedge/wasmedge_test.o: $(S)/wasmedge/wasmedge_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/wasmedge/wasmedge_test.html: $(S)/wasmedge/wasmedge_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Font Enumeration test (no GL)
$(S)/fontenum/fontenum_test.o: $(S)/fontenum/fontenum_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/fontenum/fontenum_test.html: $(S)/fontenum/fontenum_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Text Decorations test (no GL)
$(S)/textdecor/textdecor_test.o: $(S)/textdecor/textdecor_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/textdecor/textdecor_test.html: $(S)/textdecor/textdecor_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Bitmask test (no GL)
$(S)/bitmask/bitmask_test.o: $(S)/bitmask/bitmask_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/bitmask/bitmask_test.html: $(S)/bitmask/bitmask_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Regions test (no GL)
$(S)/regions/regions_test.o: $(S)/regions/regions_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/regions/regions_test.html: $(S)/regions/regions_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Maximize test (no GL) - reproduces KiCad startup maximize issue
$(S)/maximize/maximize_test.o: $(S)/maximize/maximize_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/maximize/maximize_test.html: $(S)/maximize/maximize_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Early size test (no GL) - tests GetClientSize() before Show()
$(S)/earlysize/earlysize_test.o: $(S)/earlysize/earlysize_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/earlysize/earlysize_test.html: $(S)/earlysize/earlysize_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Thread Pool test (pthread) - reproduces KiCad deadlock when hardware_concurrency() > PTHREAD_POOL_SIZE
$(S)/threadpool/threadpool_test.o: $(S)/threadpool/threadpool_test.cpp
$(CXX) -c $(CXXFLAGS) -pthread $< -o $@
$(S)/threadpool/threadpool_test.html: $(S)/threadpool/threadpool_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_PTHREAD) --pre-js $(JS) --shell-file $(HTML) -o $@
# Log Error test (no GL) - reproduces KiCad's kiface error dialog
$(S)/logerror/logerror_test.o: $(S)/logerror/logerror_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/logerror/logerror_test.html: $(S)/logerror/logerror_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Coroutine stress harness - mirrors KiCad coroutine semantics against real libcontext
$(S)/coroutine/coroutine_test.o: $(S)/coroutine/coroutine_test.cpp $(S)/coroutine/kicad_coroutine_harness.h
$(CXX) -c $(CXXFLAGS) -I$(KICAD_ROOT)/thirdparty/libcontext $< -o $@
$(S)/coroutine/libcontext.o: $(KICAD_ROOT)/thirdparty/libcontext/libcontext.cpp $(KICAD_ROOT)/thirdparty/libcontext/libcontext.h
$(CXX) -c $(CXXFLAGS) -I$(KICAD_ROOT)/thirdparty/libcontext $< -o $@
$(S)/coroutine/coroutine_test.html: $(S)/coroutine/coroutine_test.o $(S)/coroutine/libcontext.o $(WX_CORE_LIB)
$(CXX) $^ $(LDFLAGS_COROUTINE) --pre-js $(JS) --shell-file $(HTML) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
# Nested coroutine+modal interaction harness - reproduces Asyncify rewind corruption
# when fiber swaps happen inside a wxDialog::ShowModal event loop (Issue #9153).
$(S)/coroutine-nested/nested_test.o: $(S)/coroutine-nested/nested_test.cpp $(S)/coroutine/kicad_coroutine_harness.h
$(CXX) -c $(CXXFLAGS) -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-nested/nested_test.html: $(S)/coroutine-nested/nested_test.o $(S)/coroutine/libcontext.o $(WX_CORE_LIB)
$(CXX) $^ $(LDFLAGS_COROUTINE) --pre-js $(JS) --shell-file $(HTML) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
# Convenience targets
menu: $(S)/menu/menu_test.html
clipboard: $(S)/clipboard/clipboard_test.html
filedialog: $(S)/filedialog/filedialog_test.html
layout: $(S)/layout/layout_test.html
aui: $(S)/aui/aui_test.html
toolbar: $(S)/toolbar/toolbar_test.html
grid: $(S)/grid/grid_test.html
dialog: $(S)/dialog/dialog_test.html
timer: $(S)/timer/timer_test.html
tree: $(S)/tree/tree_test.html
dataview: $(S)/dataview/dataview_test.html
htmlwin: $(S)/htmlwin/htmlwin_test.html
stc: $(S)/stc/stc_test.html
print: $(S)/print/print_test.html
dnd: $(S)/dnd/dnd_test.html
propgrid: $(S)/propgrid/propgrid_test.html
pickers: $(S)/pickers/pickers_test.html
collapsible: $(S)/collapsible/collapsible_test.html
listctrl: $(S)/listctrl/listctrl_test.html
infobar: $(S)/infobar/infobar_test.html
dataviewvirtual: $(S)/dataviewvirtual/dataviewvirtual_test.html
auinotebook: $(S)/auinotebook/auinotebook_test.html
wizard: $(S)/wizard/wizard_test.html
gridedit: $(S)/gridedit/gridedit_test.html
calendar: $(S)/calendar/calendar_test.html
gridrenderers: $(S)/gridrenderers/gridrenderers_test.html
printpreview: $(S)/printpreview/printpreview_test.html
bitmapbuttons: $(S)/bitmapbuttons/bitmapbuttons_test.html
specialized: $(S)/specialized/specialized_test.html
validators: $(S)/validators/validators_test.html
ownerdrawn: $(S)/ownerdrawn/ownerdrawn_test.html
popup: $(S)/popup/popup_test.html
xml: $(S)/xml/xml_test.html
wasmedge: $(S)/wasmedge/wasmedge_test.html
fontenum: $(S)/fontenum/fontenum_test.html
textdecor: $(S)/textdecor/textdecor_test.html
bitmask: $(S)/bitmask/bitmask_test.html
regions: $(S)/regions/regions_test.html
maximize: $(S)/maximize/maximize_test.html
earlysize: $(S)/earlysize/earlysize_test.html
threadpool: $(S)/threadpool/threadpool_test.html
logerror: $(S)/logerror/logerror_test.html
# Retina/HiDPI scaling test
$(S)/retinascale/retinascale_test.o: $(S)/retinascale/retinascale_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/retinascale/retinascale_test.html: $(S)/retinascale/retinascale_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
retinascale: $(S)/retinascale/retinascale_test.html
coroutine: $(S)/coroutine/coroutine_test.html
coroutine-nested: $(S)/coroutine-nested/nested_test.html
# Only delete generated app files (*_test*, *_repro*) — a bare $(S)/*/*.js would
# also delete checked-in sources like coroutine-pthread/worker_dom_stub.js.
clean:
rm -f minimal_test.o minimal_test.d minimal_test.html minimal_test.js minimal_test.wasm minimal_test.wasm.map
rm -f $(S)/*/*.o $(S)/*/*.d $(S)/*/*.wasm.map
rm -f $(S)/*/*_test*.html $(S)/*/*_test*.js $(S)/*/*_test*.wasm
rm -f $(S)/*/*_repro*.html $(S)/*/*_repro*.js $(S)/*/*_repro*.wasm
.PHONY: all clean menu clipboard filedialog layout aui toolbar grid dialog timer tree dataview htmlwin stc print dnd propgrid pickers collapsible listctrl infobar dataviewvirtual auinotebook wizard gridedit calendar gridrenderers printpreview bitmapbuttons specialized validators ownerdrawn popup xml wasmedge fontenum textdecor bitmask regions maximize earlysize threadpool logerror retinascale coroutine coroutine-nested
# === Coroutine pthread variant — reproduces the KiCad Asyncify-fiber x pthreads crash ===
# Same modal-free harness as `coroutine`, but compiled/linked with pthreads to match
# KiCad's runtime (-pthread + PTHREAD_POOL_SIZE). The single-threaded `coroutine` build
# passes in system Chrome; KiCad (pthreads) crashes. This isolates that difference.
LDFLAGS_COROUTINE_PTHREAD = $(DEBUG_LDFLAGS) $(COROUTINE_BASE_LDFLAGS) -pthread \
-sPTHREAD_POOL_SIZE='navigator.hardwareConcurrency' -sPTHREAD_POOL_SIZE_STRICT=0 \
$(WX_LDFLAGS_NOGL)
$(S)/coroutine-pthread/coroutine_test_pt.o: $(S)/coroutine/coroutine_test.cpp $(S)/coroutine/kicad_coroutine_harness.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-pthread/libcontext_pt.o: $(KICAD_ROOT)/thirdparty/libcontext/libcontext.cpp $(KICAD_ROOT)/thirdparty/libcontext/libcontext.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -I$(KICAD_ROOT)/thirdparty/libcontext $< -o $@
$(S)/coroutine-pthread/coroutine_test.html: $(S)/coroutine-pthread/coroutine_test_pt.o $(S)/coroutine-pthread/libcontext_pt.o $(WX_CORE_LIB)
$(CXX) $^ $(LDFLAGS_COROUTINE_PTHREAD) --pre-js $(JS) --shell-file $(HTML) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread: $(S)/coroutine-pthread/coroutine_test.html
.PHONY: coroutine-pthread
# === No-wx pthread main() reproduction: fiber pattern in main + pthreads, no wxWidgets ===
LDFLAGS_COROUTINE_PTHREAD_NOWX = $(DEBUG_LDFLAGS) -sALLOW_MEMORY_GROWTH -sERROR_ON_UNDEFINED_SYMBOLS=0 \
-sASYNCIFY=1 -sASYNCIFY_STACK_SIZE=65536 -sASYNCIFY_IMPORTS=['emscripten_fiber_swap'] \
-sDYNCALLS=1 -pthread -sPTHREAD_POOL_SIZE='navigator.hardwareConcurrency' \
-sPTHREAD_POOL_SIZE_STRICT=0 -sEXPORTED_RUNTIME_METHODS=['ccall']
$(S)/coroutine-pthread/main_repro.o: $(S)/coroutine-pthread/main_repro.cpp $(S)/coroutine/kicad_coroutine_harness.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-pthread/main_repro.html: $(S)/coroutine-pthread/main_repro.o $(S)/coroutine-pthread/libcontext_pt.o
$(CXX) $^ $(LDFLAGS_COROUTINE_PTHREAD_NOWX) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread-main: $(S)/coroutine-pthread/main_repro.html
.PHONY: coroutine-pthread-main
# Nested JS<->wasm dynCall-boundary reproduction (no wx + pthreads)
$(S)/coroutine-pthread/nested_repro.o: $(S)/coroutine-pthread/nested_repro.cpp $(S)/coroutine/kicad_coroutine_harness.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-pthread/nested_repro.html: $(S)/coroutine-pthread/nested_repro.o $(S)/coroutine-pthread/libcontext_pt.o
$(CXX) $^ $(LDFLAGS_COROUTINE_PTHREAD_NOWX) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread-nested: $(S)/coroutine-pthread/nested_repro.html
.PHONY: coroutine-pthread-nested
# Nested invoke_/dynCall reproduction WITH exceptions (invoke_* boundaries, asyncify-unwindable)
LDFLAGS_COROUTINE_INVOKE = $(DEBUG_LDFLAGS) -sALLOW_MEMORY_GROWTH -sERROR_ON_UNDEFINED_SYMBOLS=0 \
-sASYNCIFY=1 -sASYNCIFY_STACK_SIZE=65536 \
-sASYNCIFY_IMPORTS=['invoke_vi','invoke_v','invoke_ii','invoke_iii','emscripten_fiber_swap'] \
-sDYNCALLS=1 -fexceptions -pthread -sPTHREAD_POOL_SIZE='navigator.hardwareConcurrency' \
-sPTHREAD_POOL_SIZE_STRICT=0 -sEXPORTED_RUNTIME_METHODS=['ccall']
$(S)/coroutine-pthread/nested_repro_ex.o: $(S)/coroutine-pthread/nested_repro.cpp $(S)/coroutine/kicad_coroutine_harness.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -fexceptions -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-pthread/libcontext_ex.o: $(KICAD_ROOT)/thirdparty/libcontext/libcontext.cpp $(KICAD_ROOT)/thirdparty/libcontext/libcontext.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -fexceptions -I$(KICAD_ROOT)/thirdparty/libcontext $< -o $@
$(S)/coroutine-pthread/nested_repro_ex.html: $(S)/coroutine-pthread/nested_repro_ex.o $(S)/coroutine-pthread/libcontext_ex.o
$(CXX) $^ $(LDFLAGS_COROUTINE_INVOKE) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread-nested-ex: $(S)/coroutine-pthread/nested_repro_ex.html
.PHONY: coroutine-pthread-nested-ex
# wx event loop + pthreads (KiCad's 13-scenario harness) with a worker DOM stub so the
# pthread workers don't crash on wx's module-eval document access.
$(S)/coroutine-pthread/coroutine_test_wxpt.html: $(S)/coroutine-pthread/coroutine_test_pt.o $(S)/coroutine-pthread/libcontext_pt.o $(WX_CORE_LIB)
$(CXX) $^ $(LDFLAGS_COROUTINE_PTHREAD) --pre-js $(S)/coroutine-pthread/worker_dom_stub.js --pre-js $(JS) --shell-file $(HTML) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread-wx: $(S)/coroutine-pthread/coroutine_test_wxpt.html
.PHONY: coroutine-pthread-wx
# embind reproduction: coroutine activated via an embind (--bind) call
LDFLAGS_COROUTINE_EMBIND = $(LDFLAGS_COROUTINE_INVOKE) --bind
$(S)/coroutine-pthread/embind_repro.o: $(S)/coroutine-pthread/embind_repro.cpp $(S)/coroutine/kicad_coroutine_harness.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -fexceptions -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-pthread/embind_repro.html: $(S)/coroutine-pthread/embind_repro.o $(S)/coroutine-pthread/libcontext_ex.o
$(CXX) $^ $(LDFLAGS_COROUTINE_EMBIND) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread-embind: $(S)/coroutine-pthread/embind_repro.html
.PHONY: coroutine-pthread-embind
# Main-loop (rAF) activation reproduction: coroutine activated inside emscripten_set_main_loop
$(S)/coroutine-pthread/mainloop_repro.o: $(S)/coroutine-pthread/mainloop_repro.cpp $(S)/coroutine/kicad_coroutine_harness.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-pthread/mainloop_repro.html: $(S)/coroutine-pthread/mainloop_repro.o $(S)/coroutine-pthread/libcontext_pt.o
$(CXX) $^ $(LDFLAGS_COROUTINE_PTHREAD_NOWX) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread-mainloop: $(S)/coroutine-pthread/mainloop_repro.html
.PHONY: coroutine-pthread-mainloop
# WebGL2 + coroutine reproduction (no wx, no pthreads, default shell with #canvas)
LDFLAGS_COROUTINE_GL = $(DEBUG_LDFLAGS) -sALLOW_MEMORY_GROWTH -sERROR_ON_UNDEFINED_SYMBOLS=0 \
-sASYNCIFY=1 -sASYNCIFY_STACK_SIZE=65536 -sASYNCIFY_IMPORTS=['emscripten_fiber_swap'] \
-sDYNCALLS=1 -sMAX_WEBGL_VERSION=2 -sMIN_WEBGL_VERSION=2 -sEXPORTED_RUNTIME_METHODS=['ccall']
$(S)/coroutine-pthread/gl_repro.o: $(S)/coroutine-pthread/gl_repro.cpp $(S)/coroutine/kicad_coroutine_harness.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-pthread/gl_repro.html: $(S)/coroutine-pthread/gl_repro.o $(S)/coroutine/libcontext.o
$(CXX) $^ $(LDFLAGS_COROUTINE_GL) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread-gl: $(S)/coroutine-pthread/gl_repro.html
.PHONY: coroutine-pthread-gl
# WebGL2 + coroutine + PTHREADS (the last untested combo: KiCad uses GL + pthreads together)
LDFLAGS_COROUTINE_GL_PTHREAD = $(LDFLAGS_COROUTINE_GL) -pthread \
-sPTHREAD_POOL_SIZE='navigator.hardwareConcurrency' -sPTHREAD_POOL_SIZE_STRICT=0
$(S)/coroutine-pthread/gl_repro_pt.o: $(S)/coroutine-pthread/gl_repro.cpp $(S)/coroutine/kicad_coroutine_harness.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-pthread/gl_repro_pt.html: $(S)/coroutine-pthread/gl_repro_pt.o $(S)/coroutine-pthread/libcontext_pt.o
$(CXX) $^ $(LDFLAGS_COROUTINE_GL_PTHREAD) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread-gl-pt: $(S)/coroutine-pthread/gl_repro_pt.html
.PHONY: coroutine-pthread-gl-pt
$(S)/coroutine-pthread/vcall_repro.o: $(S)/coroutine-pthread/vcall_repro.cpp $(S)/coroutine/kicad_coroutine_harness.h
@mkdir -p $(S)/coroutine-pthread
$(CXX) -c $(CXXFLAGS) -pthread -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
$(S)/coroutine-pthread/vcall_repro.html: $(S)/coroutine-pthread/vcall_repro.o $(S)/coroutine-pthread/libcontext_pt.o
$(CXX) $^ $(LDFLAGS_COROUTINE_PTHREAD_NOWX) -o $@
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
coroutine-pthread-vcall: $(S)/coroutine-pthread/vcall_repro.html
.PHONY: coroutine-pthread-vcall