-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbuild_wasm.sh
More file actions
213 lines (175 loc) · 6.31 KB
/
build_wasm.sh
File metadata and controls
213 lines (175 loc) · 6.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#!/bin/bash
# Build Pebble QEMU for WebAssembly using Emscripten (via Docker)
# Uses QEMU 10.1 with native WASM/TCI support + Pebble device model overlay
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
QEMU_SRC="${QEMU_SRC:-/Users/eric/dev/qemu-10.1.0}"
DOCKER_IMAGE="qemu101-wasm-base"
CONTAINER_NAME="build-pebble-wasm"
WEB_DIR="${SCRIPT_DIR}/web"
if [ ! -d "${QEMU_SRC}" ]; then
echo "Error: QEMU 10.1 source not found at ${QEMU_SRC}"
echo "Download from https://download.qemu.org/qemu-10.1.0.tar.xz"
exit 1
fi
# Check Docker image exists
if ! docker image inspect "${DOCKER_IMAGE}" &>/dev/null; then
echo "Error: Docker image '${DOCKER_IMAGE}' not found."
echo "Build it first:"
echo " docker build --progress=plain -t ${DOCKER_IMAGE} - < ${QEMU_SRC}/tests/docker/dockerfiles/emsdk-wasm32-cross.docker"
exit 1
fi
echo "=== Starting WASM build container ==="
# Stop any existing container
docker rm -f "${CONTAINER_NAME}" 2>/dev/null || true
# Start container with both QEMU source and Pebble overlay mounted read-only
docker run --rm --init -d \
--name "${CONTAINER_NAME}" \
-v "${QEMU_SRC}:/qemu-src:ro" \
-v "${SCRIPT_DIR}:/pebble:ro" \
"${DOCKER_IMAGE}" \
sleep infinity
echo "=== Preparing QEMU source with Pebble overlay ==="
# Inside container: copy QEMU source to writable dir and overlay Pebble files
docker exec "${CONTAINER_NAME}" bash -c '
set -ex
# Copy QEMU source to writable location
cp -a /qemu-src /qemu-rw
cd /qemu-rw
# Copy Pebble include files
mkdir -p include/hw/arm
cp /pebble/include/hw/arm/stm32_common.h include/hw/arm/
cp /pebble/include/hw/arm/pebble.h include/hw/arm/
cp /pebble/include/hw/arm/stm32_clktree.h include/hw/arm/
# Copy Pebble hw source files
for dir in arm misc char ssi timer dma display gpio; do
if [ -d "/pebble/hw/${dir}" ]; then
mkdir -p "hw/${dir}"
for f in /pebble/hw/${dir}/*; do
[ -f "$f" ] && cp "$f" "hw/${dir}/" && echo " -> hw/${dir}/$(basename "$f")"
done
fi
done
# Apply source patches
echo " Applying patches..."
for p in /pebble/patches/*.patch; do
[ -f "$p" ] || continue
patch -p1 --forward < "$p" || true
done
# Patch Kconfig
if ! grep -q "CONFIG_PEBBLE" hw/arm/Kconfig; then
echo " Patching hw/arm/Kconfig..."
cat >> hw/arm/Kconfig << KEOF
config PEBBLE
bool
default y
depends on TCG && ARM
imply ARM_V7M
select ARM_V7M
select PFLASH_CFI02
KEOF
fi
# Patch default.mak
if ! grep -q "CONFIG_PEBBLE" configs/devices/arm-softmmu/default.mak; then
echo "CONFIG_PEBBLE=y" >> configs/devices/arm-softmmu/default.mak
fi
# Helper function to patch meson.build files
patch_meson() {
local file="$1"
local marker="$2"
local content="$3"
if ! grep -q "${marker}" "${file}"; then
echo " Patching ${file}..."
printf "\n%s\n" "${content}" >> "${file}"
fi
}
# hw/arm/meson.build — QEMU 10.1 uses arm_common_ss (not arm_ss)
patch_meson hw/arm/meson.build "CONFIG_PEBBLE" \
"arm_common_ss.add(when: '"'"'CONFIG_PEBBLE'"'"', if_true: files(
'"'"'pebble.c'"'"',
'"'"'pebble_robert.c'"'"',
'"'"'pebble_silk.c'"'"',
'"'"'pebble_control.c'"'"',
'"'"'pebble_stm32f4xx_soc.c'"'"',
))"
# hw/misc/meson.build
patch_meson hw/misc/meson.build "stm32_pebble" \
"system_ss.add(when: '"'"'CONFIG_PEBBLE'"'"', if_true: files(
'"'"'stm32_pebble_rcc.c'"'"',
'"'"'stm32_pebble_clktree.c'"'"',
'"'"'stm32_pebble_common.c'"'"',
'"'"'stm32_pebble_exti.c'"'"',
'"'"'stm32_pebble_syscfg.c'"'"',
'"'"'stm32_pebble_adc.c'"'"',
'"'"'stm32_pebble_pwr.c'"'"',
'"'"'stm32_pebble_crc.c'"'"',
'"'"'stm32_pebble_flash.c'"'"',
'"'"'stm32_pebble_dummy.c'"'"',
'"'"'stm32_pebble_i2c.c'"'"',
))"
# hw/timer/meson.build
patch_meson hw/timer/meson.build "stm32_pebble" \
"system_ss.add(when: '"'"'CONFIG_PEBBLE'"'"', if_true: files(
'"'"'stm32_pebble_tim.c'"'"',
'"'"'stm32_pebble_rtc.c'"'"',
))"
# hw/ssi/meson.build
patch_meson hw/ssi/meson.build "stm32_pebble" \
"system_ss.add(when: '"'"'CONFIG_PEBBLE'"'"', if_true: files('"'"'stm32_pebble_spi.c'"'"'))"
# hw/dma/meson.build
patch_meson hw/dma/meson.build "stm32_pebble" \
"system_ss.add(when: '"'"'CONFIG_PEBBLE'"'"', if_true: files('"'"'stm32_pebble_dma.c'"'"'))"
# hw/display/meson.build
patch_meson hw/display/meson.build "pebble_snowy" \
"system_ss.add(when: '"'"'CONFIG_PEBBLE'"'"', if_true: files('"'"'pebble_snowy_display.c'"'"'))"
# hw/gpio/meson.build
patch_meson hw/gpio/meson.build "stm32_pebble" \
"system_ss.add(when: '"'"'CONFIG_PEBBLE'"'"', if_true: files('"'"'stm32_pebble_gpio.c'"'"'))"
# hw/char/meson.build
patch_meson hw/char/meson.build "stm32_pebble_uart" \
"system_ss.add(when: '"'"'CONFIG_PEBBLE'"'"', if_true: files('"'"'stm32_pebble_uart.c'"'"'))"
# === WASM cross-compilation patches ===
python3 /pebble/scripts/patch_wasm.py /qemu-rw
# Clone dtc subproject (needed, source is tarball not git repo)
if [ ! -d subprojects/dtc/libfdt ]; then
echo " Cloning dtc subproject..."
rm -rf subprojects/dtc
git clone --depth 1 https://github.com/dgibson/dtc.git subprojects/dtc
fi
# Install tomli (needed by QEMU 10.1 configure)
pip3 install tomli 2>&1 | tail -1
echo " Pebble overlay complete."
'
echo "=== Configuring and building ==="
docker exec "${CONTAINER_NAME}" bash -c '
set -ex
cd /build
# Configure QEMU for WASM with arm-softmmu + TCI
emconfigure /qemu-rw/configure \
--static \
--target-list=arm-softmmu \
--without-default-features \
--enable-system \
--enable-tcg-interpreter \
--disable-tools \
--disable-docs \
--disable-pie \
--extra-cflags="-DSTM32_UART_NO_BAUD_DELAY -DTCI_INSTRUMENT -flto -msimd128" \
--extra-ldflags="-flto"
# Build — Emscripten outputs .js extension, so target is qemu-system-arm.js
ninja -j$(nproc) qemu-system-arm.js 2>&1
EXIT_CODE=$?
echo "EXIT_CODE=$EXIT_CODE"
echo "=== Done ==="
ls -lh qemu-system-arm.js qemu-system-arm.wasm qemu-system-arm.worker.js 2>/dev/null || echo "Build output files not found"
'
echo ""
echo "=== Copying build artifacts ==="
mkdir -p "${WEB_DIR}"
# Copy WASM build output
docker cp "${CONTAINER_NAME}:/build/qemu-system-arm.js" "${WEB_DIR}/"
docker cp "${CONTAINER_NAME}:/build/qemu-system-arm.wasm" "${WEB_DIR}/"
docker cp "${CONTAINER_NAME}:/build/qemu-system-arm.worker.js" "${WEB_DIR}/"
echo ""
echo "=== WASM build complete ==="
ls -lh "${WEB_DIR}/qemu-system-arm"*