-
Notifications
You must be signed in to change notification settings - Fork 0
355 lines (307 loc) · 13.3 KB
/
Copy pathlinux.yml
File metadata and controls
355 lines (307 loc) · 13.3 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
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
name: Linux Build
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
# Compilers come from the runner images only. Pinning the OS pins the compiler
# set, which keeps an upstream repository change from breaking a required gate.
#
# The lower bounds do not line up across compilers. GCC is verified from 13 on
# ubuntu-24.04, but Clang starts at 20 on ubuntu-26.04: older Clang releases
# cannot build this library's C++23 usage against the libstdc++ they are paired
# with on ubuntu-24.04. Both are verified up to what ubuntu-26.04 provides.
jobs:
build-ubuntu-gcc:
name: Ubuntu GCC ${{ matrix.toolchain.gcc }} (${{ matrix.build_type }})
runs-on: ${{ matrix.toolchain.os }}
strategy:
fail-fast: false
matrix:
build_type: [Debug, Release]
toolchain:
- { os: ubuntu-24.04, gcc: 13 }
- { os: ubuntu-26.04, gcc: 15 }
steps:
- uses: actions/checkout@v7
- name: Report toolchain versions
run: |
gcc-${{ matrix.toolchain.gcc }} --version
cmake --version
- name: Configure CMake
run: |
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DCMAKE_C_COMPILER=gcc-${{ matrix.toolchain.gcc }} \
-DCMAKE_CXX_COMPILER=g++-${{ matrix.toolchain.gcc }}
- name: Build
run: cmake --build build --config ${{ matrix.build_type }} -j"$(nproc)"
- name: Test
run: ./build/test/dross_test --gtest_color=yes
build-ubuntu-clang:
name: Ubuntu Clang ${{ matrix.toolchain.clang }} (${{ matrix.build_type }})
runs-on: ${{ matrix.toolchain.os }}
strategy:
fail-fast: false
matrix:
build_type: [Debug, Release]
toolchain:
- { os: ubuntu-26.04, clang: 20 }
- { os: ubuntu-26.04, clang: 22 }
steps:
- uses: actions/checkout@v7
# The standard library is left to the image here, so the only record of
# which one a run used is this log. Clang selects the newest GCC
# installation it finds rather than the distribution's default alias, so
# that record cannot be derived from the image name either. Reported, not
# asserted on: these two jobs exist to build against whatever the image
# provides, so a change of release is news, not a failure.
#
# The driver's output is captured before it is filtered. Whenever the
# marker cannot be reported — the driver failed, or it stopped printing
# that line — the captured output goes to the log rather than being
# dropped, so the log never claims the driver said nothing when it said
# something else. Reading the capture directly also leaves no pipeline
# whose exit status would hinge on whether pipefail is set, which this
# step does not set. No branch fails the step.
- name: Report toolchain versions
run: |
clang-${{ matrix.toolchain.clang }} --version
if ! probe=$(clang++-${{ matrix.toolchain.clang }} -std=c++23 \
-E -x c++ -v /dev/null 2>&1); then
printf '%s\n' "$probe"
echo "(the driver exited non-zero; no GCC installation selection recorded)"
elif ! grep -m1 'Selected GCC installation:' <<< "$probe"; then
printf '%s\n' "$probe"
echo "(the driver reported no GCC installation selection)"
fi
cmake --version
# No -stdlib override: the default standard library is what most Clang
# users on Linux build against.
- name: Configure CMake
run: |
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DCMAKE_C_COMPILER=clang-${{ matrix.toolchain.clang }} \
-DCMAKE_CXX_COMPILER=clang++-${{ matrix.toolchain.clang }}
- name: Build
run: cmake --build build --config ${{ matrix.build_type }} -j"$(nproc)"
- name: Test
run: ./build/test/dross_test --gtest_color=yes
# The jobs above cover only the libstdc++ that comes with the runner image
# (15 on ubuntu-26.04), but the declared range promises the older releases a
# consumer may still be sitting on. Which libstdc++ Clang uses is an axis of
# its own — it does not follow from the Clang version the way it does for
# GCC — so the rest of the range is pinned here instead of being left to
# best effort. The pairing is what needs the evidence: these releases predate
# both Clang versions, and -Werror is public, so a diagnostic or a header
# difference on this axis reaches consumers.
#
# Like libc++ below, these headers come from the distribution's own
# repository (universe), so no external source enters a required gate.
build-ubuntu-clang-libstdcxx:
name: Ubuntu Clang ${{ matrix.clang }} libstdc++ ${{ matrix.libstdcxx }} (${{ matrix.build_type }})
runs-on: ubuntu-26.04
strategy:
fail-fast: false
matrix:
build_type: [Debug, Release]
clang: [20, 22]
# 15 is the runner default, already covered by the jobs above.
libstdcxx: [13, 14]
env:
# x86_64-linux-gnu is hardcoded: ubuntu-26.04 is an x86-64 runner today,
# so that is the only triple whose GCC installation this job has to name.
GCC_INSTALL_DIR: /usr/lib/gcc/x86_64-linux-gnu/${{ matrix.libstdcxx }}
LIBSTDCXX_HEADERS: /usr/include/c++/${{ matrix.libstdcxx }}
steps:
- uses: actions/checkout@v7
- name: Install libstdc++ ${{ matrix.libstdcxx }}
run: |
sudo apt-get update
sudo apt-get install -y libstdc++-${{ matrix.libstdcxx }}-dev
- name: Report toolchain versions
run: |
clang-${{ matrix.clang }} --version
cmake --version
# This job's name claims a specific libstdc++, and a green build is not
# evidence for that claim: were --gcc-install-dir to resolve to another
# release than the one pinned, the build would still succeed, just not
# against what the name says. So the include search path is read back and
# its entries are canonicalised in order until one of them falls under
# /usr/include/c++. That one is where the standard library headers come
# from, and it is the only entry compared against the pinned release.
#
# The directory check and the search path check do not subsume each other:
# the directory comes from libgcc-N-dev while the headers come from
# libstdc++-N-dev, so the directory can exist with no headers behind it —
# in which case Clang drops the standard library entries entirely and the
# comparison below reports that rather than a wrong version.
#
# What this does not cover is the flag going missing from the configure
# step below: this check would still pass, and the build would quietly fall
# back to the runner default.
- name: Verify the pinned libstdc++ is the one Clang selects
run: |
set -euo pipefail
if [ ! -d "$GCC_INSTALL_DIR" ]; then
echo "$GCC_INSTALL_DIR does not exist: installing libstdc++-${{ matrix.libstdcxx }}-dev did not bring in the GCC installation this job pins." >&2
exit 1
fi
# The driver's own output is the only diagnosis available when it
# refuses the pinned directory — a GCC installation it will not accept
# exists as far as the check above is concerned — so print it rather
# than letting the failed assignment end the step in silence.
if ! search=$(clang++-${{ matrix.clang }} -std=c++23 \
"--gcc-install-dir=$GCC_INSTALL_DIR" -E -x c++ -v /dev/null 2>&1); then
echo "The driver failed with --gcc-install-dir=$GCC_INSTALL_DIR; its output follows." >&2
printf '%s\n' "$search" >&2
exit 1
fi
entries=$(printf '%s\n' "$search" | awk '
/search starts here:/ { inside = 1; next }
/End of search list/ { inside = 0 }
inside && NF { sub(/^[ \t]+/, ""); print }')
if [ -z "$entries" ]; then
echo "No include search path in the driver output below; the marker Clang prints may have changed." >&2
printf '%s\n' "$search" >&2
exit 1
fi
printf '%s\n' "$entries"
# Clang prints these relative to the GCC installation, as
# .../13/../../../../include/c++/13, so they are canonicalised before
# being compared.
selected=
while read -r entry; do
resolved=$(readlink -m "$entry")
case "$resolved" in
/usr/include/c++/*)
selected=$resolved
break
;;
esac
done <<< "$entries"
if [ "$selected" != "$LIBSTDCXX_HEADERS" ]; then
echo "Expected $LIBSTDCXX_HEADERS to come first, found ${selected:-no standard library headers at all}." >&2
exit 1
fi
echo "$selected comes first in the include search path, as pinned."
# --gcc-install-dir has to reach the link as well as the compile: it
# selects the GCC installation the driver takes its startup files and its
# libstdc++ from. CMAKE_CXX_FLAGS alone already carries it to both link
# lines — the build file CMake writes puts it on the shared library's and
# on the test executable's — but that is CMake filling in language flags
# for its own reasons, not a promise about linking. Naming the linker
# variables states the requirement instead of resting on it. The libc++
# jobs below set CMAKE_EXE_LINKER_FLAGS as well; they set no
# CMAKE_SHARED_LINKER_FLAGS.
- name: Configure CMake
run: |
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DCMAKE_C_COMPILER=clang-${{ matrix.clang }} \
-DCMAKE_CXX_COMPILER=clang++-${{ matrix.clang }} \
-DCMAKE_CXX_FLAGS="--gcc-install-dir=$GCC_INSTALL_DIR" \
-DCMAKE_EXE_LINKER_FLAGS="--gcc-install-dir=$GCC_INSTALL_DIR" \
-DCMAKE_SHARED_LINKER_FLAGS="--gcc-install-dir=$GCC_INSTALL_DIR"
- name: Build
run: cmake --build build --config ${{ matrix.build_type }} -j"$(nproc)"
- name: Test
run: ./build/test/dross_test --gtest_color=yes
# The requirements say either standard library works across the whole Clang
# range, so libc++ is verified at both ends rather than left to best effort.
# Covering only the lower bound would leave the upper end of the declared
# range unverified against libc++ header changes and newly added warnings —
# and -Werror is public, so those reach consumers.
#
# libc++ is not part of the runner image, but it comes from the
# distribution's own repository, so no external source enters a required gate.
build-ubuntu-clang-libcxx:
name: Ubuntu Clang ${{ matrix.clang }} libc++ (${{ matrix.build_type }})
runs-on: ubuntu-26.04
strategy:
fail-fast: false
matrix:
build_type: [Debug, Release]
clang: [20, 22]
steps:
- uses: actions/checkout@v7
- name: Install libc++
run: |
sudo apt-get update
sudo apt-get install -y \
libc++-${{ matrix.clang }}-dev libc++abi-${{ matrix.clang }}-dev
- name: Report toolchain versions
run: |
clang-${{ matrix.clang }} --version
cmake --version
- name: Configure CMake
run: |
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DCMAKE_C_COMPILER=clang-${{ matrix.clang }} \
-DCMAKE_CXX_COMPILER=clang++-${{ matrix.clang }} \
-DCMAKE_CXX_FLAGS="-stdlib=libc++" \
-DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++"
- name: Build
run: cmake --build build --config ${{ matrix.build_type }} -j"$(nproc)"
- name: Test
run: ./build/test/dross_test --gtest_color=yes
build-static-library:
name: Static Library Build
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- name: Configure CMake (Static)
run: |
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF
- name: Build
run: cmake --build build -j"$(nproc)"
- name: Test
run: ./build/test/dross_test --gtest_color=yes
install-test:
name: Installation Test
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- name: Report toolchain versions
run: |
cmake --version
pkg-config --version
- name: Build and Install
run: |
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j"$(nproc)"
sudo cmake --install build
- name: Test find_package
run: |
mkdir test-client && cd test-client
cat > CMakeLists.txt << 'EOF'
cmake_minimum_required(VERSION 3.20)
project(test_client CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(dross REQUIRED)
add_executable(test_client main.cpp)
target_link_libraries(test_client PRIVATE dross::dross)
EOF
cat > main.cpp << 'EOF'
#include <dross/dross.h>
#include <iostream>
int main() {
dross::number n{"42"};
std::cout << "Test passed: " << static_cast<std::string>(n) << std::endl;
return 0;
}
EOF
cmake -S . -B build
cmake --build build
./build/test_client
- name: Test pkg-config
run: |
pkg-config --exists dross
pkg-config --modversion dross
pkg-config --cflags dross
pkg-config --libs dross