Repository navigation
323 lines (291 loc) · 16.6 KB
/
Copy pathcmake-multi-platform.yml
File metadata and controls
323 lines (291 loc) · 16.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
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
name: CMake on multiple platforms
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
workflow_dispatch:
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
fail-fast: false
# Set up a matrix to run the following 3 configurations:
# 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
# 2. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>
# 3. <Linux, Release, latest Clang compiler toolchain on the default runner image, default generator>
#
# To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
build_type: [Release]
c_compiler: [gcc, clang, cl]
include:
- os: windows-latest
c_compiler: cl
cpp_compiler: cl
- os: ubuntu-latest
c_compiler: gcc
cpp_compiler: g++
- os: ubuntu-latest
c_compiler: clang
cpp_compiler: clang++
- os: macos-latest
c_compiler: clang
cpp_compiler: clang++
- os: macos-latest
c_compiler: gcc
cpp_compiler: g++
exclude:
- os: windows-latest
c_compiler: gcc
- os: windows-latest
c_compiler: clang
- os: ubuntu-latest
c_compiler: cl
- os: macos-latest
c_compiler: cl
steps:
- uses: actions/checkout@v4
- name: Set reusable strings
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
id: strings
shell: bash
run: |
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
# OpenSSL for the station crypto selftests (supplicant, station_sm,
# ccmp_framing), which CMakeLists only builds when find_package(OpenSSL)
# succeeds. Every job that runs ctest configures with
# DEVOURER_REQUIRE_STA_CRYPTO_TESTS=ON, so a runner that stops providing
# OpenSSL fails configure instead of silently dropping those cells.
# Linux and macOS install it explicitly (cheap). The MSVC cell does NOT:
# its runner image already ships an OpenSSL that FindOpenSSL picks up,
# and building one through vcpkg would add minutes to every run.
- name: Install dependency libraries (Windows)
id: vars
if: runner.os == 'Windows'
run: |
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg integrate install
.\vcpkg install libusb
echo ("VCPKG_ROOT=" + "$PWD") >> $env:GITHUB_ENV
- name: Install dependency libraries (Linux)
if: runner.os == 'Linux'
run:
sudo apt install libusb-1.0-0-dev libssl-dev
- name: Install dependency libraries (macOS)
if: runner.os == 'macOS'
run: |
brew install libusb openssl@3
echo "OPENSSL_ROOT_DIR=$(brew --prefix openssl@3)" >> "$GITHUB_ENV"
- name: Configure CMake
# DEVOURER_MT7612U=ON: the option defaults OFF, so without it here the
# MediaTek subtree would be compiled by nothing but its own Makefile on
# Linux. Turning it on in the matrix is what makes MSVC and macOS
# first-class for the LIBRARY — the POSIX-only pieces it still has (the
# flock adapter lock) are _WIN32-guarded, and this is what proves it.
# The mt7612uprobe bench tool is NOT portable and is gated on UNIX in
# CMakeLists.txt; it is deliberately outside that claim.
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-DDEVOURER_MT7612U=ON
-DDEVOURER_REQUIRE_STA_CRYPTO_TESTS=ON
-S ${{ github.workspace }}
- name: Build
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}
- name: Test
working-directory: ${{ steps.strings.outputs.build-output-dir }}
# Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest --build-config ${{ matrix.build_type }}
# mingw-w64 (GCC on Windows). NOT covered by the matrix above (that Windows
# cell is MSVC + vcpkg). This is the toolchain the stream-link TX demos'
# binary-stdin fix targets: mingw defines _WIN32 but not _MSC_VER, and it
# gets libusb from pkg-config with VCPKG_ROOT unset. Build-only would miss a
# text-mode stdin regression, so this also runs ctest (the StreamStdinSelftest
# round-trip catches it).
build-mingw:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4
# OpenSSL so the station crypto acceptance cells (supplicant, station_sm,
# ccmp_framing - the KRACK and known-answer tests) build and run here
# too. CMakeLists gates them on find_package(OpenSSL); the configure
# below sets DEVOURER_REQUIRE_STA_CRYPTO_TESTS=ON, so if this package
# ever stops providing it the job fails rather than skipping them.
- name: Set up MSYS2 / mingw-w64
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-gcc
mingw-w64-x86_64-cmake
mingw-w64-x86_64-ninja
mingw-w64-x86_64-libusb
mingw-w64-x86_64-pkgconf
mingw-w64-x86_64-openssl
- name: Configure CMake (mingw, pkg-config libusb, no vcpkg)
# VCPKG_ROOT is unset, so CMakeLists takes the pkg-config path — the
# exact configuration the mingw binary-stdin fix exists for.
run: >
cmake -B build -G Ninja
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_C_COMPILER=gcc
-DCMAKE_CXX_COMPILER=g++
-DDEVOURER_MT7612U=ON
-DDEVOURER_REQUIRE_STA_CRYPTO_TESTS=ON
- name: Build (library + stream demos + self-tests)
# rxdemo / txdemo / precoder use POSIX-only APIs
# (e.g. fork() in examples/tx/main.cpp for the DEVOURER_TX_WITH_RX path) and
# are not mingw targets, so this job can't build the whole tree. It builds
# the stdin-driven stream demos plus the `selftests` aggregate — a target
# that depends on every *Selftest binary (collected automatically in
# CMakeLists.txt), so a newly-added self-test is picked up here without
# touching this file, and a REGISTERED one can never be skipped into a
# ctest "Not Run". What the aggregate cannot see is a test that was never
# registered: the OpenSSL-gated station cells are simply absent when
# OpenSSL is, which is why configure sets
# DEVOURER_REQUIRE_STA_CRYPTO_TESTS=ON above.
run: cmake --build build --target devourer streamtx duplex selftests
- name: Test
working-directory: build
run: ctest --output-on-failure
# Per-chip compile-time selection (CMakeLists DEVOURER_* options). The default
# matrix above already covers all-chips-ON; this job builds each stripped
# config so a missing #if guard (which only fails to link when a chip's
# sources are dropped) is caught, plus the two invalid configs that must
# fail configure with a FATAL_ERROR.
build-configs:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: jaguar1-only
flags: "-DDEVOURER_8814=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: jaguar1+8814
flags: "-DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: 8822b-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: 8821c-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: jaguar2-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: 8822c-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: 8822e-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: jaguar3-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: kestrel-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF"
- name: kestrel-8852b-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: kestrel-8852c-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF"
- name: pcie+8821c-only
flags: "-DDEVOURER_PCIE=ON -DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: pcie+kestrel-8852c-only
flags: "-DDEVOURER_PCIE=ON -DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF"
- name: pcie+all
flags: "-DDEVOURER_PCIE=ON"
# Jaguar1 stays ON because it has to: MT7612U is deliberately not
# counted as chip support, so an MT7612U-only configure is a
# FATAL_ERROR. This proves the subtree is independent of the other
# seven Realtek chips' sources, not of Jaguar1's.
# MediaTek alone, valid now that the option carries a radio backend.
# This is the cell that can catch the subtree depending on a Realtek
# chip's sources - the one below cannot, because it must leave
# Jaguar1 on.
- name: mt7612u-only
flags: "-DDEVOURER_MT7612U=ON -DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: mt7612u+jaguar1
flags: "-DDEVOURER_MT7612U=ON -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_8733B=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
- name: rtl8733b-only
flags: "-DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF -DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF -DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF"
steps:
- uses: actions/checkout@v4
- name: Install dependency libraries
run: sudo apt install libusb-1.0-0-dev libssl-dev
- name: Configure (${{ matrix.name }})
run: cmake -B build -DCMAKE_BUILD_TYPE=Release -DDEVOURER_REQUIRE_STA_CRYPTO_TESTS=ON ${{ matrix.flags }} -S ${{ github.workspace }}
- name: Build (${{ matrix.name }})
run: cmake --build build
- name: Test (${{ matrix.name }})
working-directory: build
run: ctest --output-on-failure
# Sanitized build of the whole tree (library + demos + selftests) with the
# headless suite run under ASan/UBSan. Leak detection is off here: the
# selftests are pure computation and never open a device, so the only
# allocations still live at exit would come from libusb in demo code this
# job never runs — leak triage belongs to the on-hardware runs.
build-sanitizers:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependency libraries
run: sudo apt install libusb-1.0-0-dev libssl-dev
- name: Configure (ASan + UBSan)
# DEVOURER_MT7612U=ON here too: that subtree moved from calloc/free to
# new/delete and its sync primitives are constructed members now, so the
# sanitizers are the cheapest guard against a lifetime regression in it.
run: >
cmake -B build-asan -DCMAKE_BUILD_TYPE=RelWithDebInfo
-DDEVOURER_SANITIZE=address+undefined -DDEVOURER_MT7612U=ON
-DDEVOURER_REQUIRE_STA_CRYPTO_TESTS=ON
-S ${{ github.workspace }}
- name: Build (ASan + UBSan)
run: cmake --build build-asan -j
- name: Test (ASan + UBSan)
working-directory: build-asan
env:
ASAN_OPTIONS: detect_leaks=0
UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1
run: ctest --output-on-failure
# Invalid option combinations must fail at configure time, not silently
# produce a broken binary.
reject-bad-configs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependency libraries
run: sudo apt install libusb-1.0-0-dev
- name: Reject "no chip selected"
run: |
if cmake -B build-none -DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=OFF \
-DDEVOURER_JAGUAR3_8822C=OFF -DDEVOURER_JAGUAR3_8822E=OFF \
-DDEVOURER_JAGUAR2_8822B=OFF -DDEVOURER_JAGUAR2_8821C=OFF \
-DDEVOURER_8733B=OFF \
-DDEVOURER_KESTREL_8852B=OFF -DDEVOURER_KESTREL_8852C=OFF \
-S "${{ github.workspace }}" 2>err.log; then
echo "ERROR: configure should have failed (no chip selected)"; cat err.log; exit 1
fi
grep -q "No chip support selected" err.log
- name: Reject "PCIe without a PCIe-capable chip"
run: |
if cmake -B build-pcie-bad -DDEVOURER_PCIE=ON \
-DDEVOURER_JAGUAR2_8821C=OFF -DDEVOURER_KESTREL_8852C=OFF \
-S "${{ github.workspace }}" 2>err.log; then
echo "ERROR: configure should have failed (PCIe without 8821C or 8852C)"; cat err.log; exit 1
fi
grep -q "DEVOURER_PCIE=ON requires" err.log
- name: Reject "8814 without jaguar1"
run: |
if cmake -B build-bad -DDEVOURER_JAGUAR1=OFF -DDEVOURER_8814=ON \
-S "${{ github.workspace }}" 2>err.log; then
echo "ERROR: configure should have failed (8814 without jaguar1)"; cat err.log; exit 1
fi
grep -q "requires DEVOURER_JAGUAR1" err.log