diff --git a/kicad b/kicad index ca88773..2759de6 160000 --- a/kicad +++ b/kicad @@ -1 +1 @@ -Subproject commit ca8877324ce78d1bc9cb32bf634f091e0e76fb29 +Subproject commit 2759de60c2acc537781aed6edb9b286f4a755201 diff --git a/scripts/kicad/build-kicad-target.sh b/scripts/kicad/build-kicad-target.sh index b277421..9c1c35e 100755 --- a/scripts/kicad/build-kicad-target.sh +++ b/scripts/kicad/build-kicad-target.sh @@ -87,18 +87,27 @@ case "$APP_NAME" in ;; esac -# Which app's embind bindings to compile + link. Most apps use their own; the -# sym_convert CLI links the eeschema kiface objects, which reference eeschema's -# embind symbols (kicadCollabOnSave et al.) — reuse eeschema's embind object. +# Which app's embind bindings to compile + link. Most apps use their own. +# NOTE sym_convert deliberately does NOT reuse eeschema's embind object even +# though it links the eeschema kiface: the kiface references exactly one embind +# symbol (kicadCollabOnSave), and linking the real bindings TU for it roots the +# whole editor surface from .init_array (~4x binary size — ysync 0009 size +# research). Its own wasm/bindings/sym_convert_embind.cpp provides a no-op hook. case "$APP_NAME" in - sym_convert) EMBIND_APP="eeschema" ;; - # occ_service links the pcbnew kiface objects → pcbnew's embind object, same - # reason (its own embind entry points live in occ_service_main.cpp, compiled - # inside the CMake target). + # occ_service links the pcbnew kiface objects → pcbnew's embind object (its + # own embind entry points live in occ_service_main.cpp, compiled inside the + # CMake target). occ_service) EMBIND_APP="pcbnew" ;; *) EMBIND_APP="$APP_NAME" ;; esac +# Embind linker support (--bind). sym_convert has no bindings at all (see +# above) — dropping --bind keeps the embind JS/native runtime out entirely. +case "$APP_NAME" in + sym_convert) EMBIND_LINK_FLAG="" ;; + *) EMBIND_LINK_FLAG="--bind" ;; +esac + # Which app's WASM stub libraries (scripting/frame placeholders) to link. # sym_convert links the eeschema kiface objects, so it needs eeschema's frame # stub (eeschema_frame_stub.cpp). kicad_editor links pcbnew's kiface objects, which @@ -515,7 +524,7 @@ emcmake cmake "${KICAD_DIR}" \ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ -DCMAKE_CXX_FLAGS="${EXTRA_FLAGS} -Xclang -fno-pch-timestamp -pthread -sUSE_ZLIB=1 -DKICAD_USE_PLATFORM_WASM=1${DIAG_DEFINES} -I${SYSROOT}/include -I${STUBS_DIR} -include ${STUBS_DIR}/char_traits_uint16_workaround.h" \ -DCMAKE_C_FLAGS="${EXTRA_FLAGS} -pthread -sUSE_ZLIB=1 -I${SYSROOT}/include -I${STUBS_DIR}" \ - -DCMAKE_EXE_LINKER_FLAGS="${LINKER_DEBUG_FLAGS} -pthread -sUSE_ZLIB=1 -sASYNCIFY=1 -sDYNCALLS=1 -sASYNCIFY_STACK_SIZE=65536 -sUSE_PTHREADS=1 -sMALLOC=mimalloc -sPTHREAD_POOL_SIZE='${PTHREAD_POOL_EXPR}' -sPTHREAD_POOL_SIZE_STRICT=0 -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=256MB -sMAXIMUM_MEMORY=4GB -sMAX_WEBGL_VERSION=2 ${GL3D_LINK_FLAGS} ${NANOSLEEP_YIELD_LINK} ${MALLINFO_STUB_LINK} -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','UTF8ToString','stringToUTF8','lengthBytesUTF8','dynCall'] -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=['\$dynCall'] --bind -L${SYSROOT}/lib ${STUBS_BUILD}/libgit2_stub.a ${STUBS_BUILD}/libcurl_stub.a${APP_STUB_LINK} ${STUBS_BUILD}/libnng_stub.a ${EMBIND_OBJ}" \ + -DCMAKE_EXE_LINKER_FLAGS="${LINKER_DEBUG_FLAGS} -pthread -sUSE_ZLIB=1 -sASYNCIFY=1 -sDYNCALLS=1 -sASYNCIFY_STACK_SIZE=65536 -sUSE_PTHREADS=1 -sMALLOC=mimalloc -sPTHREAD_POOL_SIZE='${PTHREAD_POOL_EXPR}' -sPTHREAD_POOL_SIZE_STRICT=0 -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=256MB -sMAXIMUM_MEMORY=4GB -sMAX_WEBGL_VERSION=2 ${GL3D_LINK_FLAGS} ${NANOSLEEP_YIELD_LINK} ${MALLINFO_STUB_LINK} -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','UTF8ToString','stringToUTF8','lengthBytesUTF8','dynCall'] -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=['\$dynCall'] ${EMBIND_LINK_FLAG} -L${SYSROOT}/lib ${STUBS_BUILD}/libgit2_stub.a ${STUBS_BUILD}/libcurl_stub.a${APP_STUB_LINK} ${STUBS_BUILD}/libnng_stub.a ${EMBIND_OBJ}" \ -DCMAKE_PREFIX_PATH="${SYSROOT};${WX_BUILD}" \ -DwxWidgets_CONFIG_EXECUTABLE="${WX_BUILD}/wx-config" \ \ diff --git a/wasm/bindings/sym_convert_embind.cpp b/wasm/bindings/sym_convert_embind.cpp new file mode 100644 index 0000000..d9ddb5f --- /dev/null +++ b/wasm/bindings/sym_convert_embind.cpp @@ -0,0 +1,11 @@ +// sym_convert's "embind" object — deliberately embind-free (ysync 0009 size +// research, step (a)). +// +// The eeschema kiface references exactly ONE symbol from the editor's embind +// TU: kicadCollabOnSave (files-io.cpp, called from SCH_EDIT_FRAME::SaveEEFile — +// a path the headless converter never executes). Linking the real +// eeschema_embind.o for that one symbol roots the ENTIRE editor surface from +// .init_array (EMSCRIPTEN_BINDINGS takes the address of every bound function: +// kicadOpenFile → frames/tools/dialogs, collab bridge, presence → GAL), which +// GC cannot remove. This no-op hook satisfies the reference instead. +extern "C" void kicadCollabOnSave( const char* /* aPath */ ) {} diff --git a/wasm/cli/sym_convert_stubs.cpp b/wasm/cli/sym_convert_stubs.cpp new file mode 100644 index 0000000..ab36272 --- /dev/null +++ b/wasm/cli/sym_convert_stubs.cpp @@ -0,0 +1,115 @@ +// sym_convert link-time diet stubs (ysync 0009 size research, steps (b)+(c)). +// +// This TU is listed in add_executable(sym_convert …) BEFORE the kiface object +// library and archives, and the target links with --allow-multiple-definition: +// wasm-ld resolves duplicate strong symbols to the FIRST definition, so these +// override the real out-of-line definitions without touching KiCad sources. +// The losing definitions become unreferenced and post-link GC drops them plus +// everything only they reached. +// +// Safety (verified in 0009-kicad-lint-size-research.md §3): ConvertLibrary uses +// only the symbol-library entry points (EnumerateSymbolLib/SaveLibrary/ +// SaveSymbol); parse never resolves fonts (SetUnresolvedFontName) and the +// writer prints only already-set font names. Every stub below either throws or +// aborts LOUDLY — a violated assumption fails the conversion, never corrupts it. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// ── (b) schematic-file entry points ────────────────────────────────────────── +// Severs the schematic half of both instantiated plugins: ParseSchematic, +// SCHEMATIC/SCH_SCREEN/sheets, SCH_SYMBOL/SCH_LINE/labels/groups vtables (and +// their Plot/font/GUI edges), Fontconfig()->ListFonts and Pgm(). + +SCH_SHEET* SCH_IO_KICAD_SEXPR::LoadSchematicFile( const wxString& aFileName, SCHEMATIC*, + SCH_SHEET*, + const std::map* ) +{ + THROW_IO_ERROR( wxString::Format( + wxS( "sym_convert: schematic loading is compiled out (stub); cannot load '%s'" ), + aFileName ) ); +} + + +void SCH_IO_KICAD_SEXPR::SaveSchematicFile( const wxString& aFileName, SCH_SHEET*, SCHEMATIC*, + const std::map* ) +{ + THROW_IO_ERROR( wxString::Format( + wxS( "sym_convert: schematic saving is compiled out (stub); cannot save '%s'" ), + aFileName ) ); +} + + +SCH_SHEET* SCH_IO_KICAD_LEGACY::LoadSchematicFile( const wxString& aFileName, SCHEMATIC*, + SCH_SHEET*, + const std::map* ) +{ + THROW_IO_ERROR( wxString::Format( + wxS( "sym_convert: schematic loading is compiled out (stub); cannot load '%s'" ), + aFileName ) ); +} + + +void SCH_IO_KICAD_LEGACY::SaveSchematicFile( const wxString& aFileName, SCH_SHEET*, SCHEMATIC*, + const std::map* ) +{ + THROW_IO_ERROR( wxString::Format( + wxS( "sym_convert: schematic saving is compiled out (stub); cannot save '%s'" ), + aFileName ) ); +} + +// ── (e) UI virtuals whose real bodies reference pruned typeinfo/data ───────── +// The kiface prune (cut e) leaves these vtable-pinned bodies referencing +// typeinfo for SCH_NAVIGATE_TOOL / SCH_EDIT_FRAME and SCH_NAVIGATE_TOOL:: +// g_BackLink — DATA symbols, which (unlike functions) cannot become JS imports +// under -sERROR_ON_UNDEFINED_SYMBOLS=0. Overriding the whole virtual here makes +// the real body a discarded duplicate, so its relocations are never processed +// and the KiCad sources stay untouched. All four are user-interaction paths a +// headless converter cannot reach (hypertext clicks, the message panel). + +void SCH_FIELD::DoHypertextAction( EDA_DRAW_FRAME*, const VECTOR2I& ) const +{ +} + + +void SCH_TEXT::DoHypertextAction( EDA_DRAW_FRAME*, const VECTOR2I& ) const +{ +} + + +void SCH_TEXTBOX::DoHypertextAction( EDA_DRAW_FRAME*, const VECTOR2I& ) const +{ +} + + +void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME*, std::vector& ) +{ +} + +// ── (c) font-factory choke point ───────────────────────────────────────────── +// The single route into the font engine: severs STROKE_FONT::LoadFont (and the +// 2.7 MB newstroke glyph data), OUTLINE_FONT (freetype + harfbuzz), fontconfig. +// abort() (not a soft null) so any violated assumption surfaces immediately in +// the qa corpus instead of producing subtly wrong output. + +namespace KIFONT +{ + +FONT* FONT::GetFont( const wxString&, bool, bool, const std::vector*, bool ) +{ + std::fprintf( stderr, + "sym_convert: FATAL: KIFONT::FONT::GetFont called — the font engine is " + "compiled out (ysync 0009 diet stub)\n" ); + std::abort(); +} + +} // namespace KIFONT