# External Library Size Measurement (Task #76) ## Goal Measure true demo code size by stubbing external library dependencies. **Motivation:** STRIP_ALL builds (~5MB) include wgpu_native (~3.5MB), GLFW (~500KB), miniaudio. Need to isolate demo code size for 64KB target tracking. ## Strategy Two-part approach: ### 1. Audio: Use miniaudio's Null Backend miniaudio has built-in `ma_backend_null` that excludes platform audio drivers: ```cmake target_compile_definitions(demo64k PRIVATE MA_ENABLE_ONLY_SPECIFIC_BACKENDS MA_ENABLE_NULL ) ``` **Savings:** ~100-200KB (excludes CoreAudio/WASAPI/ALSA/etc.) **Benefit:** Audio synthesis still runs, but no driver overhead ### 2. GPU/Platform: Stub Our Own Abstractions Instead of stubbing ~300 external functions, stub our ~10 platform/gpu wrappers: **`src/platform/stub_types.h` (STRIP_EXTERNAL_LIBS only):** ```cpp // Minimal WebGPU opaque types typedef void* WGPUInstance; typedef void* WGPUAdapter; typedef void* WGPUDevice; typedef void* WGPUBuffer; typedef void* WGPUTexture; // ... all types as void* struct WGPUBufferDescriptor {}; struct WGPUTextureDescriptor {}; // ... all descriptor structs empty ``` **`src/platform/stub_platform.cc`:** ```cpp #if defined(STRIP_EXTERNAL_LIBS) #include "stub_types.h" PlatformState platform_init(bool, int w, int h) { return {w, h, nullptr, nullptr}; } void platform_poll_events() {} bool platform_should_close() { return false; } void platform_shutdown() {} void platform_present() {} double platform_get_time() { return 0.0; } #endif ``` **`src/gpu/stub_gpu.cc`:** ```cpp #if defined(STRIP_EXTERNAL_LIBS) WGPUDevice gpu_create_device() { return nullptr; } WGPUBuffer gpu_create_buffer(const WGPUBufferDescriptor*) { return nullptr; } // ... stub ~20 gpu wrapper functions #endif ``` **Benefits:** - Stub our API (~30 functions) vs external APIs (~300 functions) - Opaque pointers only (no real struct definitions needed) - Don't link wgpu_native or GLFW at all - Actually measures demo code, not stub code ## Build System Integration **CMakeLists.txt:** ```cmake if(DEMO_STRIP_EXTERNAL_LIBS) # Audio: Use null backend target_compile_definitions(demo64k PRIVATE MA_ENABLE_ONLY_SPECIFIC_BACKENDS MA_ENABLE_NULL ) # GPU/Platform: Use stubs target_compile_definitions(demo64k PRIVATE STRIP_EXTERNAL_LIBS) target_sources(demo64k PRIVATE src/platform/stub_platform.cc src/gpu/stub_gpu.cc ) # Don't link external libs # (only math/pthread from system) # Size measurement flags set(CMAKE_C_FLAGS "-Os") set(CMAKE_CXX_FLAGS "-Os") endif() ``` **Build:** ```bash cmake -S . -B build_size -DDEMO_STRIP_EXTERNAL_LIBS=ON cmake --build build_size -j4 strip build_size/demo64k ls -lh build_size/demo64k # True demo size ``` ## Expected Results ``` STRIP_ALL build: 5.1 MB ├── wgpu_native: 3.5 MB ├── GLFW: 0.5 MB ├── miniaudio (full): 0.3 MB ├── System libs: 0.3 MB └── Demo code: 0.5 MB STRIP_EXTERNAL_LIBS: 0.5 MB └── Demo code only: 0.5 MB (100%) ``` Binary compiles but does NOT run (all I/O stubbed). ## Implementation Plan ### Phase 1: Stub Type Definitions (1 hour) Create `src/platform/stub_types.h`: - Define all WebGPU types as `typedef void*` - Define all descriptor structs as empty `struct {}` - Include guards for `STRIP_EXTERNAL_LIBS` ### Phase 2: Platform Stubs (1 hour) Create `src/platform/stub_platform.cc`: - Implement ~10 platform functions as no-ops - Return dummy PlatformState with reasonable dimensions - Compile only when `STRIP_EXTERNAL_LIBS` defined ### Phase 3: GPU Stubs (1 hour) Create `src/gpu/stub_gpu.cc`: - Implement ~20 gpu wrapper functions as no-ops - All pointer returns = nullptr - All void functions = empty body ### Phase 4: Build Integration (1 hour) Update `CMakeLists.txt`: - Add `DEMO_STRIP_EXTERNAL_LIBS` option - Enable ma_backend_null defines - Add stub source files conditionally - Remove external library linking ### Phase 5: Validation (1 hour) ```bash cmake -S . -B build_size -DDEMO_STRIP_EXTERNAL_LIBS=ON cmake --build build_size -j4 strip build_size/demo64k size build_size/demo64k ``` **Estimated time: 5 hours** ## Use Cases **Weekly size tracking:** ```bash ./scripts/measure_size.sh # Demo=512KB, External=4.5MB ``` **Subsystem attribution:** - GPU effects: 150KB - 3D rendering: 120KB - Audio synthesis: 100KB - Asset system: 80KB **CI size monitoring:** ```yaml - run: cmake -B build_size -DDEMO_STRIP_EXTERNAL_LIBS=ON - run: size build_size/demo64k | tee size_report.txt ``` ## Success Criteria 1. Binary compiles with `STRIP_EXTERNAL_LIBS=ON` 2. Size < 1MB (confirms external lib isolation) 3. Repeatable builds 4. Tracks size changes over time ## Related Files **New:** - `src/platform/stub_types.h` - WebGPU opaque types - `src/platform/stub_platform.cc` - Platform stubs (~10 functions) - `src/gpu/stub_gpu.cc` - GPU stubs (~20 functions) - `scripts/measure_size.sh` - Size measurement script **Modified:** - `CMakeLists.txt` - Add STRIP_EXTERNAL_LIBS mode