-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
265 lines (238 loc) · 10.6 KB
/
Copy pathwasm.yml
File metadata and controls
265 lines (238 loc) · 10.6 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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
name: Wasm
on:
pull_request:
types: [synchronize, opened]
push:
branches:
- main
env:
DEBIAN_FRONTEND: noninteractive
OPENCV_VERSION: 5.0.0
# Must match the Emscripten version bundled with the .NET wasm SDK below (currently
# Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk), since OpenCvSharpExtern.a built here gets
# statically linked by that SDK's own emcc/wasm-ld later - mixing Emscripten versions across
# that link boundary is unsupported and has already caused one silent bug (#2039, a wasm-opt
# feature-flag mismatch) plus a suspected second one (a setjmp/longjmp hang; see #2043).
EM_VERSION: 3.1.56
EM_CACHE_FOLDER: 'emsdk-cache'
# Bump this whenever the OpenCV cmake flags below change, to bust the OpenCV build cache.
OPENCV_CACHE_VERSION: 3
jobs:
build:
name: Wasm
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 1
persist-credentials: false
submodules: recursive
- name: Resolve OpenCV revisions
id: opencv-revisions
run: |
echo "opencv=$(git rev-parse HEAD:opencv)" >> "${GITHUB_OUTPUT}"
echo "opencv_contrib=$(git rev-parse HEAD:opencv_contrib)" >> "${GITHUB_OUTPUT}"
- name: Install dependencies
run: |
current_path=$(pwd)
sudo apt-get update -y
sudo apt-get install -y --no-install-recommends \
apt-transport-https \
software-properties-common \
wget \
unzip \
ca-certificates \
g++ \
make \
cmake \
libtbb-dev \
libatlas-base-dev \
libgtk-3-dev \
libavcodec-dev \
libavformat-dev \
libswscale-dev \
libdc1394-dev \
libxine2-dev \
libv4l-dev \
libtheora-dev \
libvorbis-dev \
libxvidcore-dev \
libopencore-amrnb-dev \
libopencore-amrwb-dev \
x264 \
libtesseract-dev
- name: Restore OpenCV cache
id: opencv-cache
uses: actions/cache/restore@v6
with:
path: |
${{ github.workspace }}/opencv_wasm/include
${{ github.workspace }}/opencv_wasm/lib
${{ github.workspace }}/opencv_wasm/libopencv.o
key: opencv-${{ steps.opencv-revisions.outputs.opencv }}-${{ steps.opencv-revisions.outputs.opencv_contrib }}-wasm-${{ env.EM_VERSION }}-v${{ env.OPENCV_CACHE_VERSION }}
- name: Setup Emscripten cache
id: cache-system-libraries
uses: actions/cache@v6
with:
path: ${{env.EM_CACHE_FOLDER}}
key: ${{env.EM_VERSION}}-${{ runner.os }}
- uses: mymindstorm/setup-emsdk@v16
with:
version: ${{env.EM_VERSION}}
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
- name: Build OpenCV
if: steps.opencv-cache.outputs.cache-hit != 'true'
run: |
emcmake cmake \
-S opencv \
-B opencv/build \
-DCMAKE_BUILD_TYPE=Release \
-DOPENCV_EXTRA_MODULES_PATH=${GITHUB_WORKSPACE}/opencv_contrib/modules \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_CXX11=ON -DBUILD_TESTS=OFF \
-DBUILD_PERF_TESTS=OFF \
-DBUILD_DOCS=OFF \
-DBUILD_EXAMPLES=OFF \
-DBUILD_JAVA=OFF \
-DBUILD_opencv_java_bindings_generator=OFF \
-DBUILD_opencv_python_bindings_generator=OFF \
-DBUILD_opencv_python_tests=OFF \
-DBUILD_opencv_ts=OFF \
-DBUILD_opencv_js=OFF \
-DBUILD_opencv_js_bindings_generator=OFF \
-DBUILD_opencv_apps=OFF \
-DBUILD_opencv_barcode=OFF \
-DBUILD_opencv_bioinspired=OFF \
-DBUILD_opencv_ccalib=OFF \
-DBUILD_opencv_datasets=OFF \
-DBUILD_opencv_dnn_objdetect=OFF \
-DBUILD_opencv_dpm=OFF \
-DBUILD_opencv_fuzzy=OFF \
-DBUILD_opencv_gapi=OFF \
-DBUILD_opencv_intensity_transform=OFF \
-DBUILD_opencv_mcc=OFF \
-DBUILD_opencv_objc_bindings_generator=OFF \
-DBUILD_opencv_rapid=OFF \
-DBUILD_opencv_reg=OFF \
-DBUILD_opencv_stereo=ON \
-DBUILD_opencv_structured_light=OFF \
-DBUILD_opencv_surface_matching=OFF \
-DBUILD_opencv_wechat_qrcode=ON \
-DBUILD_opencv_videostab=OFF \
-DWITH_GSTREAMER=OFF \
-DWITH_EIGEN=OFF \
-DWITH_ADE=OFF \
-DOPENCV_ENABLE_NONFREE=ON \
-DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/opencv_wasm \
-DCMAKE_C_FLAGS='-s WASM=1' -DCMAKE_CXX_FLAGS='-s WASM=1' \
-DWITH_ITT=OFF \
-DWITH_JPEG=ON \
-DWITH_TIFF=ON \
-DWITH_PNG=ON \
-DWITH_IPP=OFF \
-DWITH_LAPACK=OFF \
-DWITH_OPENCL=OFF \
-DWITH_PTHREADS_PF=OFF \
-DCV_ENABLE_INTRINSICS=OFF \
-DBUILD_opencv_dnn=ON
cmake --build opencv/build --parallel $(nproc)
cmake --install opencv/build
em++ -r -o ${GITHUB_WORKSPACE}/opencv_wasm/libopencv.o \
-Wl,--whole-archive ${GITHUB_WORKSPACE}/opencv_wasm/lib/*.a \
${GITHUB_WORKSPACE}/opencv_wasm/lib/opencv5/3rdparty/*.a
ls
- name: Save OpenCV cache
if: steps.opencv-cache.outputs.cache-hit != 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: actions/cache/save@v6
with:
path: |
${{ github.workspace }}/opencv_wasm/include
${{ github.workspace }}/opencv_wasm/lib
${{ github.workspace }}/opencv_wasm/libopencv.o
key: opencv-${{ steps.opencv-revisions.outputs.opencv }}-${{ steps.opencv-revisions.outputs.opencv_contrib }}-wasm-${{ env.EM_VERSION }}-v${{ env.OPENCV_CACHE_VERSION }}
- name: Build OpenCvSharpExtern
run: |
ls ${GITHUB_WORKSPACE}/opencv_wasm
echo "-----"
emcmake cmake -S src -B src/build -DCMAKE_BUILD_TYPE=Release -DOpenCV_DIR=${GITHUB_WORKSPACE}/opencv_wasm/lib/cmake/opencv5 -DWASM_LIB=${GITHUB_WORKSPACE}/opencv_wasm/libopencv.o
cmake --build src/build --parallel $(nproc)
ls src/build/OpenCvSharpExtern
cp src/build/OpenCvSharpExtern/libOpenCvSharpExtern.a ${GITHUB_WORKSPACE}/packaging/nuget/OpenCvSharpExtern.a
# Also stage it where OpenCvSharp5.runtime.wasm.props expects it (relative to the props
# file's own location), so test/OpenCvSharp.Tests.Wasm can import that same .props and
# link against this build directly, without a NuGet pack/restore round-trip.
mkdir -p ${GITHUB_WORKSPACE}/runtimes/browser-wasm/4.0.23
cp src/build/OpenCvSharpExtern/libOpenCvSharpExtern.a ${GITHUB_WORKSPACE}/runtimes/browser-wasm/4.0.23/OpenCvSharpExtern.a
- name: Install .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: '10.0.x'
- name: Install wasm-tools workload
run: dotnet workload install wasm-tools
- name: Verify EM_VERSION matches the .NET wasm SDK's bundled Emscripten
run: |
pack_dir=$(ls -d /usr/share/dotnet/packs/Microsoft.NET.Runtime.Emscripten.*.Sdk.* 2>/dev/null | head -1)
if [ -z "$pack_dir" ]; then
echo "::error::Could not find an installed Microsoft.NET.Runtime.Emscripten.*.Sdk pack under /usr/share/dotnet/packs - can't verify EM_VERSION."
exit 1
fi
installed=$(basename "$pack_dir" | sed -E 's/Microsoft\.NET\.Runtime\.Emscripten\.([0-9]+\.[0-9]+\.[0-9]+)\.Sdk.*/\1/')
echo "wasm.yml EM_VERSION: ${EM_VERSION}"
echo ".NET wasm SDK's bundled Emscripten: ${installed}"
if [ "$installed" != "$EM_VERSION" ]; then
echo "::error::EM_VERSION (${EM_VERSION}) no longer matches the .NET wasm SDK's bundled Emscripten (${installed})."\
"OpenCvSharpExtern.a was built with the wrong toolchain version relative to the one that will"\
"statically link it later - update EM_VERSION in wasm.yml to ${installed}. See #2043 for what"\
"this class of mismatch already broke once (a setjmp/longjmp hang)."
exit 1
fi
- name: Create NuGet package
env:
BETA: "-beta"
run: |
yyyymmdd=`date '+%Y%m%d'`
echo $yyyymmdd
version="${OPENCV_VERSION}.${yyyymmdd}${BETA}"
echo "Package version: $version"
dotnet pack ${GITHUB_WORKSPACE}/packaging/nuget/OpenCvSharp5.runtime.wasm.csproj -o ${GITHUB_WORKSPACE}/artifacts_wasm -p:Version=$version
ls ${GITHUB_WORKSPACE}/artifacts_wasm
- uses: actions/upload-artifact@v7
with:
name: artifacts_wasm
path: artifacts_wasm
- name: Check OpenCvSharpExtern package contents
run: |
nupkg=$(ls ${GITHUB_WORKSPACE}/artifacts_wasm/*.nupkg)
echo "Inspecting $nupkg"
unzip -l "$nupkg"
# #2039 regression guard: the native lib must ship WITHOUT the "lib" prefix, since
# NativeFileReference derives the P/Invoke module name from the file's %(Filename).
unzip -p "$nupkg" runtimes/browser-wasm/4.0.23/OpenCvSharpExtern.a > /dev/null
unzip -p "$nupkg" build/net8.0/OpenCvSharp5.runtime.wasm.props > /dev/null
- name: Publish wasm E2E consumer test
run: |
dotnet publish ${GITHUB_WORKSPACE}/test/OpenCvSharp.Tests.Wasm/OpenCvSharp.Tests.Wasm.csproj -c Release -o ${GITHUB_WORKSPACE}/artifacts_wasm_e2e
- name: Run wasm E2E consumer test
run: |
set -e
npx --yes http-server ${GITHUB_WORKSPACE}/artifacts_wasm_e2e/wwwroot -p 8080 --silent &
SERVER_PID=$!
for i in $(seq 1 30); do
if curl -sf http://127.0.0.1:8080/index.html -o /dev/null; then
break
fi
sleep 1
done
if ! curl -sf http://127.0.0.1:8080/index.html -o /dev/null; then
echo "ERROR: http-server did not become ready on port 8080 within 30s"
kill $SERVER_PID || true
exit 1
fi
mkdir -p ${RUNNER_TEMP}/wasm-e2e
cp ${GITHUB_WORKSPACE}/test/OpenCvSharp.Tests.Wasm/run-e2e.mjs ${RUNNER_TEMP}/wasm-e2e/run-e2e.mjs
cd ${RUNNER_TEMP}/wasm-e2e
npm init -y > /dev/null 2>&1
npm install playwright > /dev/null 2>&1
npx playwright install --with-deps chromium
node run-e2e.mjs http://127.0.0.1:8080
kill $SERVER_PID || true