feat(schematic): eeschema WASM build + e2e harness
This commit is contained in:
parent
31ff88ee9e
commit
730147d690
19 changed files with 3945 additions and 414 deletions
|
|
@ -3,14 +3,16 @@
|
|||
# We provide stub values so CMake configuration succeeds
|
||||
|
||||
if(EMSCRIPTEN OR NOT KICAD_SPICE)
|
||||
message(STATUS "ngspice not available for WASM build (SPICE disabled)")
|
||||
message(STATUS "ngspice not available for WASM build (using header stub)")
|
||||
|
||||
# Set variables to indicate ngspice is "found" but disabled
|
||||
set(ngspice_FOUND TRUE)
|
||||
set(NGSPICE_FOUND TRUE)
|
||||
|
||||
# Provide empty values
|
||||
set(NGSPICE_INCLUDE_DIR "")
|
||||
# Point at our header-only stub at wasm/stubs/ngspice/sharedspice.h so
|
||||
# eeschema's sim/ngspice.{h,cpp} can compile. The library link line stays
|
||||
# empty — the simulator frame is never instantiated in WASM.
|
||||
set(NGSPICE_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/../stubs")
|
||||
set(NGSPICE_LIBRARY "")
|
||||
set(NGSPICE_LIBRARIES "")
|
||||
|
||||
|
|
|
|||
111
wasm/stubs/char_traits_uint16_workaround.h
Normal file
111
wasm/stubs/char_traits_uint16_workaround.h
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* libc++ workaround: provide std::char_traits<unsigned short> for WASM builds.
|
||||
*
|
||||
* KiCad's third-party Altium parser uses
|
||||
* typedef std::basic_string<uint16_t> utf16string;
|
||||
* (kicad/thirdparty/compoundfilereader/compoundfilereader.h:264).
|
||||
*
|
||||
* Modern libc++ (the version bundled with current Emscripten) pulls
|
||||
* <__format/parser_std_format_spec.h> via <vector>, which triggers implicit
|
||||
* instantiation of char_traits<unsigned short>. The standard only specializes
|
||||
* char_traits for char / wchar_t / char8_t / char16_t / char32_t, so the
|
||||
* uint16_t (== unsigned short) usage now fails to compile.
|
||||
*
|
||||
* We force-include this header into every translation unit via the build
|
||||
* script's CMAKE_CXX_FLAGS so the specialization is visible before any code
|
||||
* that needs it. Specializing std::char_traits for non-standard types is
|
||||
* technically undefined per the standard but is the established workaround
|
||||
* historically supported by libc++/libstdc++.
|
||||
*/
|
||||
|
||||
#ifndef KICAD_WASM_CHAR_TRAITS_UINT16_WORKAROUND_H
|
||||
#define KICAD_WASM_CHAR_TRAITS_UINT16_WORKAROUND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <cwchar>
|
||||
#include <ios>
|
||||
|
||||
namespace std {
|
||||
|
||||
template<>
|
||||
struct char_traits<unsigned short>
|
||||
{
|
||||
using char_type = unsigned short;
|
||||
using int_type = int;
|
||||
using off_type = streamoff;
|
||||
using pos_type = fpos<mbstate_t>;
|
||||
using state_type = mbstate_t;
|
||||
|
||||
static constexpr void assign( char_type& a, const char_type& b ) noexcept { a = b; }
|
||||
static constexpr bool eq( char_type a, char_type b ) noexcept { return a == b; }
|
||||
static constexpr bool lt( char_type a, char_type b ) noexcept { return a < b; }
|
||||
|
||||
static int compare( const char_type* s1, const char_type* s2, size_t n )
|
||||
{
|
||||
for( size_t i = 0; i < n; ++i )
|
||||
{
|
||||
if( s1[i] < s2[i] ) return -1;
|
||||
if( s1[i] > s2[i] ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t length( const char_type* s )
|
||||
{
|
||||
size_t i = 0;
|
||||
while( s[i] != 0 ) ++i;
|
||||
return i;
|
||||
}
|
||||
|
||||
static const char_type* find( const char_type* s, size_t n, const char_type& a )
|
||||
{
|
||||
for( size_t i = 0; i < n; ++i )
|
||||
if( s[i] == a ) return s + i;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static char_type* move( char_type* s1, const char_type* s2, size_t n )
|
||||
{
|
||||
return static_cast<char_type*>( memmove( s1, s2, n * sizeof( char_type ) ) );
|
||||
}
|
||||
|
||||
static char_type* copy( char_type* s1, const char_type* s2, size_t n )
|
||||
{
|
||||
return static_cast<char_type*>( memcpy( s1, s2, n * sizeof( char_type ) ) );
|
||||
}
|
||||
|
||||
static char_type* assign( char_type* s, size_t n, char_type a )
|
||||
{
|
||||
for( size_t i = 0; i < n; ++i ) s[i] = a;
|
||||
return s;
|
||||
}
|
||||
|
||||
static constexpr int_type not_eof( int_type c ) noexcept
|
||||
{
|
||||
return c == eof() ? static_cast<int_type>( 0 ) : c;
|
||||
}
|
||||
|
||||
static constexpr char_type to_char_type( int_type c ) noexcept
|
||||
{
|
||||
return static_cast<char_type>( c );
|
||||
}
|
||||
|
||||
static constexpr int_type to_int_type( char_type c ) noexcept
|
||||
{
|
||||
return static_cast<int_type>( c );
|
||||
}
|
||||
|
||||
static constexpr bool eq_int_type( int_type a, int_type b ) noexcept { return a == b; }
|
||||
static constexpr int_type eof() noexcept { return static_cast<int_type>( -1 ); }
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // __EMSCRIPTEN__
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // KICAD_WASM_CHAR_TRAITS_UINT16_WORKAROUND_H
|
||||
15
wasm/stubs/eeschema_frame_stub.cpp
Normal file
15
wasm/stubs/eeschema_frame_stub.cpp
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Eeschema frame stubs for KiCad WASM build.
|
||||
*
|
||||
* Mirror of pcb_frame_stub.cpp. Populate as linker errors surface during the
|
||||
* first eeschema-wasm build. Methods that need to be stubbed are typically:
|
||||
* - Scripting helpers (LoadSchematic / SaveSchematic) when KICAD_SCRIPTING=OFF
|
||||
* - Action-plugin glue (no plugins in WASM)
|
||||
* - Filesystem-watcher hooks when wxUSE_FSWATCHER=0
|
||||
*
|
||||
* Leave this file empty until the linker complains; the build script skips
|
||||
* compiling it when it has zero bytes.
|
||||
*/
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#endif
|
||||
28
wasm/stubs/eeschema_ngspice_data_stubs.cpp
Normal file
28
wasm/stubs/eeschema_ngspice_data_stubs.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Empty replacements for the four largest ngspice model data initializers.
|
||||
*
|
||||
* Each of sim_model_ngspice_data_{bsim4,b3soi,b4soi,hsim}.cpp defines a
|
||||
* single function (addBSIM4/addB3SOI/addB4SOI/addHSIM) that pushes hundreds
|
||||
* of entries into NGSPICE_MODEL_INFO_MAP::modelInfos[...]. Once compiled to
|
||||
* WASM these functions exceed the V8/SpiderMonkey limit on locals per
|
||||
* function ("too many locals"), so Firefox refuses to instantiate the
|
||||
* resulting module.
|
||||
*
|
||||
* The simulator UI is never reachable in the WASM build (FRAME_SIMULATOR
|
||||
* fails to instantiate via the ngspice header stub at
|
||||
* wasm/stubs/ngspice/sharedspice.h), so leaving these tables empty is safe.
|
||||
*
|
||||
* eeschema/CMakeLists.txt excludes the original four sources from
|
||||
* EESCHEMA_SIM_SRCS for EMSCRIPTEN and adds this file instead.
|
||||
*/
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
||||
#include <sim/sim_model_ngspice.h>
|
||||
|
||||
void NGSPICE_MODEL_INFO_MAP::addBSIM4() {}
|
||||
void NGSPICE_MODEL_INFO_MAP::addB3SOI() {}
|
||||
void NGSPICE_MODEL_INFO_MAP::addB4SOI() {}
|
||||
void NGSPICE_MODEL_INFO_MAP::addHSIM() {}
|
||||
|
||||
#endif // __EMSCRIPTEN__
|
||||
55
wasm/stubs/ngspice/sharedspice.h
Normal file
55
wasm/stubs/ngspice/sharedspice.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Minimal stub of ngspice's sharedspice.h for KiCad WASM builds.
|
||||
*
|
||||
* Only the type names referenced by kicad/eeschema/sim/ngspice.{h,cpp} need
|
||||
* to exist. The eeschema sim layer compiles but the simulator frame is never
|
||||
* instantiated in WASM (FRAME_SIMULATOR's try/catch in IFACE::CreateKiWindow
|
||||
* catches the init failure and returns nullptr).
|
||||
*
|
||||
* We intentionally do NOT define NGSPICE_PACKAGE_VERSION so that ngspice.h's
|
||||
* fallback `typedef bool NG_BOOL;` (line 46) provides the boolean type.
|
||||
*/
|
||||
|
||||
#ifndef KICAD_WASM_NGSPICE_SHAREDSPICE_STUB_H
|
||||
#define KICAD_WASM_NGSPICE_SHAREDSPICE_STUB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ngcomplex {
|
||||
double cx_real;
|
||||
double cx_imag;
|
||||
} ngcomplex_t;
|
||||
|
||||
struct vector_info {
|
||||
char* v_name;
|
||||
int v_type;
|
||||
short v_flags;
|
||||
double* v_realdata;
|
||||
ngcomplex_t* v_compdata;
|
||||
int v_length;
|
||||
};
|
||||
|
||||
typedef struct vector_info* pvector_info;
|
||||
|
||||
/* Opaque payload types for callbacks we never wire up (SendData/SendInitData). */
|
||||
typedef struct vecvaluesall* pvecvaluesall;
|
||||
typedef struct vecinfoall* pvecinfoall;
|
||||
|
||||
/*
|
||||
* Function types (not pointers). ngspice.h references them as `SendChar*` etc.,
|
||||
* so the trailing star in the typedef site makes the pointer.
|
||||
*/
|
||||
typedef int (SendChar)(char*, int, void*);
|
||||
typedef int (SendStat)(char*, int, void*);
|
||||
typedef int (ControlledExit)(int, bool, bool, int, void*);
|
||||
typedef int (SendData)(pvecvaluesall, int, int, void*);
|
||||
typedef int (SendInitData)(pvecinfoall, int, void*);
|
||||
typedef int (BGThreadRunning)(bool, int, void*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KICAD_WASM_NGSPICE_SHAREDSPICE_STUB_H */
|
||||
Loading…
Reference in a new issue