diff --git a/.gitignore b/.gitignore index aec1a34..79615c0 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ wxwidgets-clean/ /tests/apps/standalone/*/*.wasm /tests/apps/kicad/*.js /tests/apps/kicad/*.wasm +/tests/apps/kicad/*.tar.gz !tests/apps/kicad/pcbnew.html /temp/ *.log diff --git a/docker/build.sh b/docker/build.sh index 65574f9..fe6464a 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -21,10 +21,15 @@ fi docker compose -f docker/docker-compose.yml up -d # Sync source code to container volume (fixes macOS Docker timestamp issues) -# This ensures timestamps are consistent within the container filesystem +# rsync -a preserves host timestamps, but make needs container timestamps to +# correctly detect changes against cached object files. We touch transferred +# files to set their mtime to container's current time. echo "Syncing source code to container..." docker compose -f docker/docker-compose.yml exec kicad-wasm-builder \ - rsync -a --delete --exclude='build-wasm' --exclude='output' /workspace-host/ /workspace/ + bash -c 'rsync -ai --delete --exclude="build-wasm" --exclude="output" /workspace-host/ /workspace/ | \ + grep "^>f" | \ + sed "s/^[^ ]* //" | \ + while read f; do touch "/workspace/$f" 2>/dev/null; done' # Run build command (without asyncify - handled on host due to memory requirements) docker compose -f docker/docker-compose.yml exec kicad-wasm-builder \ @@ -34,7 +39,10 @@ docker compose -f docker/docker-compose.yml exec kicad-wasm-builder \ # Note: pcbnew.wasm.debug.wasm contains DWARF debug info (generated with -gseparate-dwarf) echo "Copying build output to ./output/..." docker compose -f docker/docker-compose.yml exec kicad-wasm-builder \ - bash -c "mkdir -p /workspace/output && cp /workspace/build-wasm/kicad-pcbnew/pcbnew/pcbnew.{js,wasm,wasm.debug.wasm,wasm.map,worker.js} /workspace/output/ 2>/dev/null || cp /workspace/build-wasm/kicad-pcbnew/pcbnew/pcbnew.{js,wasm} /workspace/output/" + bash -c "mkdir -p /workspace/output && \ + cp /workspace/build-wasm/kicad-pcbnew/pcbnew/pcbnew.{js,wasm,wasm.debug.wasm,wasm.map,worker.js} /workspace/output/ 2>/dev/null || \ + cp /workspace/build-wasm/kicad-pcbnew/pcbnew/pcbnew.{js,wasm} /workspace/output/; \ + cp /workspace/build-wasm/kicad-pcbnew/resources/images.tar.gz /workspace/output/ 2>/dev/null || true" # Inject dynCall shims into pcbnew.js # This fixes "dynCall_* is not defined" errors in Emscripten 4.x diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index c4b2d05..f8f4c40 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -7,12 +7,16 @@ source /emsdk/emsdk_env.sh 2>/dev/null # Sync source from host to workspace volume # This fixes macOS Docker timestamp issues with bind mounts # (autoconf sanity checks fail when timestamps appear inconsistent) +# Touch transferred files to set container timestamps for correct make detection if [[ -d /workspace-host ]]; then echo "Syncing source code to container volume..." - rsync -a --delete \ + rsync -ai --delete \ --exclude='build-wasm' \ --exclude='output' \ - /workspace-host/ /workspace/ + /workspace-host/ /workspace/ | \ + grep "^>f" | \ + sed "s/^[^ ]* //" | \ + while read f; do touch "/workspace/$f" 2>/dev/null; done echo "Sync complete." fi diff --git a/kicad b/kicad index 2532a46..279f2f1 160000 --- a/kicad +++ b/kicad @@ -1 +1 @@ -Subproject commit 2532a4682eb4a6a862d8bdf7baf700f58c4cc5fe +Subproject commit 279f2f1a84dc07a831496334a12373d5454f1d38 diff --git a/scripts/kicad/build-pcbnew.sh b/scripts/kicad/build-pcbnew.sh index 4b8c583..aa69fee 100755 --- a/scripts/kicad/build-pcbnew.sh +++ b/scripts/kicad/build-pcbnew.sh @@ -306,6 +306,11 @@ fi log_info "Building pcbnew..." emmake make -j${JOBS} pcbnew +# Step 8.1: Build bitmap resources (images.tar.gz) +# This creates the icon archive that KiCad loads at runtime +log_info "Building bitmap resources..." +emmake make bitmap_archive_build + # Step 9: Create stamp file create_stamp "${KICAD_STAMP}" log_info "KiCad PCBnew build complete!" diff --git a/tests/apps/kicad/pcbnew.html b/tests/apps/kicad/pcbnew.html index f1004f0..c3ea906 100644 --- a/tests/apps/kicad/pcbnew.html +++ b/tests/apps/kicad/pcbnew.html @@ -105,9 +105,43 @@ document.getElementById('status').style.display = 'none'; }; + // Pre-fetched resource data (fetched before pcbnew.js loads) + var resourceData = null; + + // Start fetching images.tar.gz immediately (runs in parallel with WASM loading) + fetch('images.tar.gz') + .then(function(response) { + if (!response.ok) throw new Error('HTTP ' + response.status); + return response.arrayBuffer(); + }) + .then(function(buffer) { + resourceData = new Uint8Array(buffer); + console.log('[KICAD] Prefetched images.tar.gz (' + resourceData.length + ' bytes)'); + }) + .catch(function(err) { + console.warn('[KICAD] Could not prefetch images.tar.gz:', err.message); + }); + + // Write pre-fetched resources to FS (called in preRun after FS is available) + var writeResources = function() { + // Create directory structure matching KiCad's compiled-in KICAD_DATA path + // This path is baked in during CMake configuration + var resourcePath = '/workspace/build-wasm/sysroot/share/kicad/resources'; + FS.mkdirTree(resourcePath); + + // Write pre-fetched data if available + if (resourceData) { + FS.writeFile(resourcePath + '/images.tar.gz', resourceData); + console.log('[KICAD] Wrote images.tar.gz to ' + resourcePath); + } else { + console.warn('[KICAD] images.tar.gz not ready yet (WASM loaded faster than fetch)'); + } + }; + var Module = { thisProgram: '/usr/bin/pcbnew', // Fake absolute path for argv[0] (KiCad DEBUG check) - preRun: [createCanvas], + + preRun: [createCanvas, writeResources], postRun: [], print: function(text) { diff --git a/tests/scripts/setup-kicad-wasm.sh b/tests/scripts/setup-kicad-wasm.sh index b87ab98..06179bf 100755 --- a/tests/scripts/setup-kicad-wasm.sh +++ b/tests/scripts/setup-kicad-wasm.sh @@ -22,6 +22,8 @@ if [ -f "$OUTPUT_DIR/pcbnew.js" ] && [ -f "$OUTPUT_DIR/pcbnew.wasm" ]; then cp "$OUTPUT_DIR/pcbnew.wasm.map" "$KICAD_TEST/" 2>/dev/null || true # Worker file for pthreads (optional) cp "$OUTPUT_DIR/pcbnew.worker.js" "$KICAD_TEST/" 2>/dev/null || true + # Bitmap resources for KiCad icons (optional) + cp "$OUTPUT_DIR/images.tar.gz" "$KICAD_TEST/" 2>/dev/null || true else echo "Output directory not found, copying from Docker build..." docker compose -f "$PROJECT_ROOT/docker/docker-compose.yml" cp \ @@ -34,6 +36,9 @@ else # Worker file for pthreads (optional) docker compose -f "$PROJECT_ROOT/docker/docker-compose.yml" cp \ kicad-wasm-builder:/workspace/build-wasm/kicad-pcbnew/pcbnew/pcbnew.worker.js "$KICAD_TEST/" 2>/dev/null || true + # Bitmap resources for KiCad icons (optional) + docker compose -f "$PROJECT_ROOT/docker/docker-compose.yml" cp \ + kicad-wasm-builder:/workspace/build-wasm/kicad-pcbnew/resources/images.tar.gz "$KICAD_TEST/" 2>/dev/null || true fi # wxWidgets WASM JavaScript glue code (defines JS functions called from WASM)