vxx2 / .github / workflows / linux_ci.yml
575 lines · 538 sloc · 27.01 KB · c0624b274a458fe3e487d89ae9554c2e8c25bdb6
Raw
1name: CI Linux
2
3on:
4 workflow_dispatch:
5 push:
6 branches:
7 - master
8 paths-ignore:
9 - '**.md'
10 - '**.yml'
11 - '!**/linux_ci.yml'
12 - 'cmd/tools/**'
13 - '!cmd/tools/builders/**.v'
14 pull_request:
15 paths-ignore:
16 - '**.md'
17 - '**.yml'
18 - '!**/linux_ci.yml'
19 - 'cmd/tools/**'
20 - '!cmd/tools/builders/**.v'
21
22concurrency:
23 group: linux-${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.sha || github.ref }}
24 cancel-in-progress: true
25
26jobs:
27 tcc-linux:
28 runs-on: ubuntu-24.04
29 timeout-minutes: 121
30 env:
31 VFLAGS: -cc tcc -no-retry-compilation
32 VTEST_SHOW_LONGEST_BY_RUNTIME: 3
33 VTEST_SHOW_LONGEST_BY_COMPTIME: 3
34 VTEST_SHOW_LONGEST_BY_TOTALTIME: 3
35 steps:
36 - uses: actions/checkout@v7
37 - uses: ./.github/actions/cache-apt-packages-action
38 - name: Build v
39 run: make -j4 && ./v symlink
40 - name: Build v with -prealloc
41 run: v run ci/linux_ci.vsh build_v_with_prealloc
42 - name: All code is formatted
43 run: v run ci/linux_ci.vsh all_code_is_formatted_tcc
44 - name: Install dependencies for examples and tools
45 run: v run ci/linux_ci.vsh install_dependencies_for_examples_and_tools_tcc
46 - name: Test v->c
47 run: v run ci/linux_ci.vsh test_v_to_c_tcc
48 - name: v self compilation
49 run: v run ci/linux_ci.vsh v_self_compilation_tcc
50 - name: v doctor
51 run: v run ci/linux_ci.vsh v_doctor_tcc
52 - name: Verify `v test` works
53 run: v run ci/linux_ci.vsh verify_v_test_works_tcc
54 - name: Test pure V math module
55 run: v run ci/linux_ci.vsh test_pure_v_math_module_tcc
56 - name: Test inline assembly on linux
57 run: v run ci/linux_ci.vsh test_inline_assembly
58 - name: Self tests
59 run: v run ci/linux_ci.vsh self_tests_tcc
60 - name: Build examples
61 run: v run ci/linux_ci.vsh build_examples_tcc
62 - name: Run the submodule example, using a relative path
63 run: v run ci/linux_ci.vsh run_submodule_example_tcc
64 - name: Build v tools
65 run: v run ci/linux_ci.vsh build_tools_tcc
66 - name: Build v binaries
67 run: v run ci/linux_ci.vsh build_vbinaries_tcc
68 - name: Build benches
69 run: v run ci/linux_ci.vsh build_benches_tcc
70 - name: Run a VSH script
71 run: v run ci/linux_ci.vsh run_vsh_script_tcc
72 - name: Test v tutorials
73 run: v run ci/linux_ci.vsh test_v_tutorials_tcc
74 - name: Build cmd/tools/fast
75 run: v run ci/linux_ci.vsh build_fast_tcc
76 - name: V self compilation with -usecache
77 run: v run ci/linux_ci.vsh v_self_compilation_usecache_tcc
78 - name: Test password input
79 run: v run ci/linux_ci.vsh test_password_input_tcc
80 - name: Test readline
81 run: v run ci/linux_ci.vsh test_readline_tcc
82 - name: Test leak detector
83 run: v run ci/linux_ci.vsh test_leak_detector_tcc
84 - name: Test leak detector not being active for normal compile
85 run: v run ci/linux_ci.vsh test_leak_detector_not_active_tcc
86
87 gcc-linux:
88 runs-on: ubuntu-24.04
89 timeout-minutes: 121
90 env:
91 VTEST_SHOW_LONGEST_BY_RUNTIME: 3
92 VTEST_SHOW_LONGEST_BY_COMPTIME: 3
93 VTEST_SHOW_LONGEST_BY_TOTALTIME: 3
94 steps:
95 - uses: actions/checkout@v7
96 - uses: ./.github/actions/cache-apt-packages-action
97 - name: Build V
98 run: make -j4 && ./v symlink
99 - name: backend x64 regressions
100 if: ${{ false }} # Temporarily disabled.
101 run: |
102 set -e
103
104 VJOBS=1 ./v test \
105 vlib/v2_toberemoved/abi \
106 vlib/v2_toberemoved/gen/x64/x64_abi_test.v \
107 vlib/v2_toberemoved/gen/x64/x64_backend_diagnostics_test.v \
108 vlib/v2_toberemoved/gen/x64/x64_object_format_test.v \
109 vlib/v2_toberemoved/gen/x64/x64_pe_linker_test.v \
110 vlib/v2_toberemoved/ssa/tree_sumtype_lowering_test.v
111 VJOBS=1 ./v test -run-only test_module_qualified_alias_array_field_index_has_alias_element_type,test_module_storage_legacy_direct_import_nested_module_selector_uses_declared_leaf_module,test_module_storage_flat_direct_import_nested_module_selector_uses_declared_leaf_module vlib/v2_toberemoved/ssa/module_storage_test.v
112 VJOBS=1 ./v test -run-only test_x64_linux_math_log_20_stdout_exact_bytes,test_x64_linux_generic_sumtype_direct_wrap_stdout_exact_bytes,test_x64_linux_generic_sumtype_repeated_base_specialization_stdout_exact_bytes,test_x64_linux_generic_sumtype_receiver_size_stdout_exact_bytes,test_x64_linux_generic_sumtype_insert_size_stdout_exact_bytes,test_x64_linux_struct_float_fields_stdout_exact_bytes,test_x64_linux_union_f64_bits_stdout_exact_bytes,test_x64_linux_f64_str_interpolation_stdout_exact_bytes,test_x64_linux_f64_for_interpolation_stdout_exact_bytes,test_x64_linux_formatted_int_interpolation_stdout_exact_bytes,test_x64_linux_formatted_int_width_100_interpolation_stdout_exact_bytes,test_x64_linux_formatted_f64_interpolation_stdout_exact_bytes,test_x64_linux_formatted_string_return_lifetime_stdout_exact_bytes,test_x64_linux_spectral_reduced_formatted_stdout_exact_bytes,test_x64_linux_bits_len32_stdout_exact_bytes,test_x64_linux_rand_u32n_interface_result_stdout_exact_bytes,test_x64_linux_rand_intn_range_interface_result_stdout_exact_bytes,test_x64_linux_textscanner_embedded_parser_stdout_exact_bytes,test_x64_linux_struct_positional_side_effect_stdout_exact_bytes,test_x64_linux_struct_named_side_effect_stdout_exact_bytes,test_x64_linux_unrelated_same_shape_struct_stdout_exact_bytes,test_x64_linux_named_init_embedded_value_stdout_exact_bytes,test_x64_linux_get_raw_line_example_stdin_stdout_exact_bytes,test_x64_linux_mini_calculator_example_stdin_stdout_exact_bytes,test_x64_linux_mini_calculator_recursive_descent_example_stdin_stdout_exact_bytes,test_x64_linux_external_c_flag_source_uses_hosted_link_with_compile_flags vlib/v2_toberemoved/gen/x64/x64_runtime_smoke_test.v
113 VJOBS=1 ./v test -run-only test_non_generic_concrete_sumtype_return_wraps_variant,test_option_concrete_sumtype_return_wraps_variant,test_generic_sumtype_declared_param_order_is_preserved_for_crossed_variants,test_worker_clone_sees_sumtype_decl_variant_cache,test_sumtype_decl_variant_cache_records_concrete_generic_variants_only,test_generic_sumtype_match_uses_full_specialization_when_generic_base_repeats,test_flat_direct_generic_sumtype_match_uses_full_specialization_when_generic_base_repeats,test_generic_sumtype_match_smartcast_scans_full_specialization_body,test_flat_direct_generic_sumtype_match_smartcast_scans_full_specialization_body,test_nested_module_concrete_generic_sumtype_base_does_not_fall_back_to_local_tree,test_leaf_module_concrete_generic_sumtype_base_fallback_beats_parent_module_tree vlib/v2_toberemoved/transformer/monomorphize_test.v
114 ./v test vlib/v2_toberemoved/builder/native_test.v vlib/v2_toberemoved/builder/target_os_test.v
115 ./v test vlib/v2_toberemoved/ssa/optimize
116 V2_VERIFY_STRICT=1 ./v test vlib/v2_toberemoved/ssa/optimize
117
118 - name: backend x64 examples
119 if: ${{ false }} # Temporarily disabled.
120 run: |
121 set -e
122
123 tmp="$(mktemp -d)"
124 trap 'rm -rf "$tmp"' EXIT
125
126 check_empty_stderr() {
127 label="$1"
128 stderr="$2"
129 if [ -s "$stderr" ]; then
130 echo "::error::$label wrote to stderr"
131 cat "$stderr"
132 return 1
133 fi
134 }
135
136 check_stdout() {
137 label="$1"
138 expected="$2"
139 actual="$3"
140 if ! cmp -s "$expected" "$actual"; then
141 echo "::error::$label stdout mismatch"
142 echo "expected:"
143 cat "$expected"
144 echo "actual:"
145 cat "$actual"
146 return 1
147 fi
148 }
149
150 run_native_x64_example() {
151 source="$1"
152 name="$2"
153 expected="$3"
154 shift 3
155
156 ./v -v2 -no-parallel -b x64 "$source" -o "$tmp/$name"
157 "$tmp/$name" "$@" > "$tmp/$name.out" 2> "$tmp/$name.err"
158 check_empty_stderr "$name" "$tmp/$name.err"
159 check_stdout "$name" "$expected" "$tmp/$name.out"
160 }
161
162 run_native_x64_example_with_stdin() {
163 source="$1"
164 name="$2"
165 input="$3"
166 expected="$4"
167 shift 4
168
169 ./v -v2 -no-parallel -b x64 "$source" -o "$tmp/$name"
170 "$tmp/$name" "$@" < "$input" > "$tmp/$name.out" 2> "$tmp/$name.err"
171 check_empty_stderr "$name" "$tmp/$name.err"
172 check_stdout "$name" "$expected" "$tmp/$name.out"
173 }
174
175 run_native_x64_example_capture() {
176 source="$1"
177 name="$2"
178 shift 2
179
180 ./v -v2 -no-parallel -b x64 "$source" -o "$tmp/$name"
181 "$tmp/$name" "$@" > "$tmp/$name.out" 2> "$tmp/$name.err"
182 check_empty_stderr "$name" "$tmp/$name.err"
183 }
184
185 check_random_ips_stdout() {
186 label="$1"
187 actual="$2"
188 python3 - "$label" "$actual" <<'PY'
189 import sys
190
191 label = sys.argv[1]
192 path = sys.argv[2]
193 lines = open(path, "r", encoding="utf-8").read().splitlines()
194 if len(lines) != 10:
195 raise SystemExit(f"{label}: expected 10 lines, got {len(lines)}")
196 rows = []
197 for line in lines:
198 parts = line.split(".")
199 if len(parts) != 4:
200 raise SystemExit(f"{label}: invalid IPv4 shape: {line!r}")
201 row = []
202 for part in parts:
203 if not part.isdigit():
204 raise SystemExit(f"{label}: non-numeric octet in {line!r}")
205 value = int(part)
206 if value < 0 or value > 254:
207 raise SystemExit(f"{label}: octet out of range in {line!r}")
208 row.append(value)
209 rows.append(tuple(row))
210 if len(set(rows)) < 3:
211 raise SystemExit(f"{label}: output has too little row diversity")
212 if all(row[1] == 0 for row in rows) and all(row[3] == 0 for row in rows):
213 raise SystemExit(f"{label}: suspicious old x.0.x.0 pattern")
214 PY
215 }
216
217 check_rule110_stdout() {
218 label="$1"
219 actual="$2"
220 width="$3"
221 python3 - "$label" "$actual" "$width" <<'PY'
222 import sys
223
224 label = sys.argv[1]
225 path = sys.argv[2]
226 width = int(sys.argv[3])
227 lines = open(path, "r", encoding="utf-8").read().splitlines()
228 title = "Rule 110 V Implementation"
229 title_lines = [idx for idx, line in enumerate(lines) if title in line]
230 if not title_lines:
231 raise SystemExit(f"{label}: missing title")
232 idx = title_lines[0]
233 generations = lines[idx + 1:]
234 if generations and generations[0] == "":
235 generations = generations[1:]
236 if len(generations) != width:
237 raise SystemExit(f"{label}: expected {width} generation lines, got {len(generations)}")
238 for line in generations:
239 if len(line) != width:
240 raise SystemExit(f"{label}: generation line has width {len(line)}, expected {width}: {line!r}")
241 if any(ch not in " *" for ch in line):
242 raise SystemExit(f"{label}: invalid generation chars: {line!r}")
243 if not any("*" in line for line in generations):
244 raise SystemExit(f"{label}: expected at least one live cell")
245 if len(set(generations)) < 3:
246 raise SystemExit(f"{label}: expected at least 3 distinct generation lines")
247 PY
248 }
249
250 write_v_run_expected() {
251 source="$1"
252 expected="$2"
253 shift 2
254 stderr="$tmp/$(basename "$expected").stderr"
255 ./v run "$source" "$@" > "$expected" 2> "$stderr"
256 check_empty_stderr "v run $source $*" "$stderr"
257 }
258
259 write_v_run_expected_with_stdin() {
260 source="$1"
261 input="$2"
262 expected="$3"
263 shift 3
264 stderr="$tmp/$(basename "$expected").stderr"
265 ./v run "$source" "$@" < "$input" > "$expected" 2> "$stderr"
266 check_empty_stderr "v run $source $*" "$stderr"
267 }
268
269 write_fizz_buzz_expected() {
270 i=1
271 while [ "$i" -le 100 ]; do
272 if [ $((i % 15)) -eq 0 ]; then
273 echo FizzBuzz
274 elif [ $((i % 3)) -eq 0 ]; then
275 echo Fizz
276 elif [ $((i % 5)) -eq 0 ]; then
277 echo Buzz
278 else
279 echo "$i"
280 fi
281 i=$((i + 1))
282 done
283 }
284
285 write_hanoi_expected() {
286 python3 - <<'PY'
287 def hanoi(n, a, b, c):
288 if n == 1:
289 print(f"Disc 1 from {a} to {c}...")
290 else:
291 hanoi(n - 1, a, c, b)
292 print(f"Disc {n} from {a} to {c}...")
293 hanoi(n - 1, b, a, c)
294
295 hanoi(7, "A", "B", "C")
296 PY
297 }
298
299 write_sudoku_expected() {
300 python3 - <<'PY'
301 import sys
302
303 puzzle = [
304 [0, 3, 0, 0, 7, 0, 0, 0, 0],
305 [0, 0, 0, 1, 3, 5, 0, 0, 0],
306 [0, 0, 1, 0, 0, 0, 0, 5, 0],
307 [1, 0, 0, 0, 6, 0, 0, 0, 3],
308 [4, 0, 0, 8, 0, 3, 0, 0, 1],
309 [7, 0, 0, 0, 2, 0, 0, 0, 6],
310 [0, 0, 0, 0, 0, 0, 2, 1, 0],
311 [0, 0, 0, 4, 1, 2, 0, 0, 5],
312 [0, 0, 0, 0, 0, 0, 0, 7, 4],
313 ]
314 solution = [
315 [2, 3, 5, 6, 7, 8, 1, 4, 9],
316 [9, 4, 7, 1, 3, 5, 8, 6, 2],
317 [6, 8, 1, 2, 4, 9, 3, 5, 7],
318 [1, 2, 8, 7, 6, 4, 5, 9, 3],
319 [4, 5, 6, 8, 9, 3, 7, 2, 1],
320 [7, 9, 3, 5, 2, 1, 4, 8, 6],
321 [3, 6, 4, 9, 5, 7, 2, 1, 8],
322 [8, 7, 9, 4, 1, 2, 6, 3, 5],
323 [5, 1, 2, 3, 8, 6, 9, 7, 4],
324 ]
325
326 def append_grid(lines, label, grid):
327 lines.append(label)
328 for i, row in enumerate(grid):
329 if i % 3 == 0 and i != 0:
330 lines.append("- - - - - - - - - - - -")
331 line = ""
332 for j, value in enumerate(row):
333 if j % 3 == 0 and j != 0:
334 line += " | "
335 line += f"{value} "
336 lines.append(line)
337
338 lines = []
339 append_grid(lines, "Sudoku Puzzle:", puzzle)
340 lines.append("Solving...")
341 append_grid(lines, "Solution:", solution)
342 out = ("\n".join(lines) + "\n").encode()
343 if len(out) != 582:
344 raise SystemExit(f"sudoku stdout oracle shape changed: {len(out)} bytes")
345 sys.stdout.buffer.write(out)
346 PY
347 }
348
349 write_tree_of_nodes_expected() {
350 cat <<'EOF'
351 tree structure:
352 Node{
353 value: 10
354 left: Tree(Node{
355 value: 30
356 left: Tree(Empty{})
357 right: Tree(Empty{})
358 })
359 right: Tree(Node{
360 value: 20
361 left: Tree(Empty{})
362 right: Tree(Empty{})
363 })
364 }
365 tree size: 3
366 EOF
367 }
368
369 write_js_hello_world_expected() {
370 printf 'Hello from V.js (0)\nHello from V.js (1)\nHello from V.js (2)\n'
371 }
372
373 write_vascii_expected() {
374 python3 - <<'PY'
375 from pathlib import Path
376 import sys
377
378 source = Path("examples/vascii.v").read_text(encoding="utf-8")
379 start_marker = "println('"
380 end_marker = "')"
381 if source.count(start_marker) != 1:
382 raise SystemExit("vascii stdout oracle expects one single-quoted println literal")
383 start = source.index(start_marker) + len(start_marker)
384 end = source.rindex(end_marker)
385 if source[end + len(end_marker):].strip() != "}":
386 raise SystemExit("vascii stdout oracle expects the println literal to be the final main statement")
387
388 out = bytearray()
389 literal = source[start:end]
390 i = 0
391 while i < len(literal):
392 ch = literal[i]
393 if ch == "\\":
394 i += 1
395 if i >= len(literal):
396 raise SystemExit("unterminated escape in vascii literal")
397 escaped = literal[i]
398 if escaped == "n":
399 out.append(10)
400 elif escaped == "t":
401 out.append(9)
402 elif escaped == "r":
403 out.append(13)
404 elif escaped == "\\":
405 out.append(92)
406 elif escaped == "'":
407 out.append(39)
408 elif escaped == '"':
409 out.append(34)
410 else:
411 out.extend(escaped.encode("utf-8"))
412 else:
413 out.extend(ch.encode("utf-8"))
414 i += 1
415 out.append(10)
416 sys.stdout.buffer.write(out)
417 PY
418 }
419
420 write_rune_expected() {
421 printf '\360\237\230\200\n@\n'
422 }
423
424 printf 'Hello, World!\n' > "$tmp/hello_world.expected"
425 write_fizz_buzz_expected > "$tmp/fizz_buzz.expected"
426 write_hanoi_expected > "$tmp/hanoi.expected"
427 write_sudoku_expected > "$tmp/sudoku.expected"
428 printf 'HELLO WORLD\nHELLO WORLD\nHELLO WORLD\n' > "$tmp/function_types.expected"
429 printf '5\n3\n' > "$tmp/submodule.expected"
430 printf '1\n1\n2\n3\n5\n8\n13\n21\n34\n55\n89\n' > "$tmp/fibonacci_10.expected"
431 printf '120\n' > "$tmp/dump_factorial.expected"
432 write_v_run_expected examples/primes.v "$tmp/primes_20.expected" 20
433 write_tree_of_nodes_expected > "$tmp/tree_of_nodes.expected"
434 write_js_hello_world_expected > "$tmp/js_hello_world.expected"
435 write_vascii_expected > "$tmp/vascii.expected"
436 write_rune_expected > "$tmp/rune.expected"
437 write_v_run_expected examples/graphs/bfs.v "$tmp/bfs.expected"
438 write_v_run_expected examples/graphs/bfs3.v "$tmp/bfs3.expected"
439 write_v_run_expected examples/graphs/dfs.v "$tmp/dfs.expected"
440 write_v_run_expected examples/graphs/dijkstra.v "$tmp/dijkstra.expected"
441 write_v_run_expected examples/graphs/topological_sorting_greedy.v "$tmp/topological_sorting_greedy.expected"
442 write_v_run_expected examples/graphs/topological_sorting_dfs.v "$tmp/topological_sorting_dfs.expected"
443 write_v_run_expected examples/graphs/dfs2.v "$tmp/dfs2.expected"
444 write_v_run_expected examples/graphs/minimal_spann_tree_prim.v "$tmp/minimal_spann_tree_prim.expected"
445 write_v_run_expected examples/graphs/bellman-ford.v "$tmp/bellman_ford.expected"
446 write_v_run_expected examples/binary_search_tree.v "$tmp/binary_search_tree.expected"
447 printf 'wrong format\nempty input\n' > "$tmp/errors.expected"
448 write_v_run_expected examples/custom_error.v "$tmp/custom_error.expected"
449 write_v_run_expected examples/spectral.v "$tmp/spectral_10.expected" 10
450 printf 'length of random array is 1000\nbefore quick sort whether array is sorted: false\nafter quick sort whether array is sorted: true\n' > "$tmp/quick_sort.expected"
451 printf 'hello\nworld\n' > "$tmp/get_raw_line.in"
452 write_v_run_expected_with_stdin examples/get_raw_line.v "$tmp/get_raw_line.in" "$tmp/get_raw_line.expected"
453 printf '3+4*2\nexit\n' > "$tmp/mini_calculator.in"
454 write_v_run_expected_with_stdin examples/mini_calculator.v "$tmp/mini_calculator.in" "$tmp/mini_calculator.expected"
455 printf '3+4*2\nexit\n' > "$tmp/mini_calculator_recursive_descent.in"
456 write_v_run_expected_with_stdin examples/mini_calculator_recursive_descent.v "$tmp/mini_calculator_recursive_descent.in" "$tmp/mini_calculator_recursive_descent.expected"
457
458 run_native_x64_example examples/hello_world.v hello_world "$tmp/hello_world.expected"
459 run_native_x64_example examples/fizz_buzz.v fizz_buzz "$tmp/fizz_buzz.expected"
460 run_native_x64_example examples/hanoi.v hanoi "$tmp/hanoi.expected"
461 run_native_x64_example examples/sudoku.v sudoku "$tmp/sudoku.expected"
462 run_native_x64_example examples/function_types.v function_types "$tmp/function_types.expected"
463 run_native_x64_example examples/submodule/main.v submodule "$tmp/submodule.expected"
464 run_native_x64_example examples/fibonacci.v fibonacci "$tmp/fibonacci_10.expected" 10
465 run_native_x64_example examples/dump_factorial.v dump_factorial "$tmp/dump_factorial.expected"
466 run_native_x64_example examples/primes.v primes "$tmp/primes_20.expected" 20
467 run_native_x64_example examples/tree_of_nodes.v tree_of_nodes "$tmp/tree_of_nodes.expected"
468 run_native_x64_example examples/js_hello_world.v js_hello_world "$tmp/js_hello_world.expected"
469 run_native_x64_example examples/vascii.v vascii "$tmp/vascii.expected"
470 run_native_x64_example examples/rune.v rune "$tmp/rune.expected"
471 run_native_x64_example examples/graphs/bfs.v bfs "$tmp/bfs.expected"
472 run_native_x64_example examples/graphs/bfs3.v bfs3 "$tmp/bfs3.expected"
473 run_native_x64_example examples/graphs/dfs.v dfs "$tmp/dfs.expected"
474 run_native_x64_example examples/graphs/dijkstra.v dijkstra "$tmp/dijkstra.expected"
475 run_native_x64_example examples/graphs/topological_sorting_greedy.v topological_sorting_greedy "$tmp/topological_sorting_greedy.expected"
476 run_native_x64_example examples/graphs/topological_sorting_dfs.v topological_sorting_dfs "$tmp/topological_sorting_dfs.expected"
477 run_native_x64_example examples/graphs/dfs2.v dfs2 "$tmp/dfs2.expected"
478 run_native_x64_example examples/graphs/minimal_spann_tree_prim.v minimal_spann_tree_prim "$tmp/minimal_spann_tree_prim.expected"
479 run_native_x64_example examples/graphs/bellman-ford.v bellman_ford "$tmp/bellman_ford.expected"
480 run_native_x64_example examples/binary_search_tree.v binary_search_tree "$tmp/binary_search_tree.expected"
481 run_native_x64_example examples/errors.v errors "$tmp/errors.expected"
482 run_native_x64_example examples/custom_error.v custom_error "$tmp/custom_error.expected"
483 run_native_x64_example examples/spectral.v spectral "$tmp/spectral_10.expected" 10
484 run_native_x64_example examples/quick_sort.v quick_sort "$tmp/quick_sort.expected"
485 run_native_x64_example_with_stdin examples/get_raw_line.v get_raw_line "$tmp/get_raw_line.in" "$tmp/get_raw_line.expected"
486 run_native_x64_example_with_stdin examples/mini_calculator.v mini_calculator "$tmp/mini_calculator.in" "$tmp/mini_calculator.expected"
487 run_native_x64_example_with_stdin examples/mini_calculator_recursive_descent.v mini_calculator_recursive_descent "$tmp/mini_calculator_recursive_descent.in" "$tmp/mini_calculator_recursive_descent.expected"
488 run_native_x64_example_capture examples/random_ips.v random_ips
489 check_random_ips_stdout random_ips "$tmp/random_ips.out"
490 run_native_x64_example_capture examples/rule110.v rule110 31
491 check_rule110_stdout rule110 "$tmp/rule110.out" 31
492 - name: All code is formatted
493 run: v run ci/linux_ci.vsh all_code_is_formatted_gcc
494 - name: Install dependencies for examples and tools
495 run: v run ci/linux_ci.vsh install_dependencies_for_examples_and_tools_gcc
496 - name: Recompile V with -cstrict and gcc
497 run: v run ci/linux_ci.vsh recompile_v_with_cstrict_gcc
498 - name: Valgrind v.c
499 run: v run ci/linux_ci.vsh valgrind_v_c_gcc
500 - name: Run sanitizers
501 run: v run ci/linux_ci.vsh run_sanitizers_gcc
502 - name: v self compilation
503 run: v run ci/linux_ci.vsh v_self_compilation_gcc
504 - name: v self compilation with -usecache
505 run: v run ci/linux_ci.vsh v_self_compilation_usecache_gcc
506 - name: Verify `v test` works
507 run: v run ci/linux_ci.vsh verify_v_test_works_gcc
508 - name: Test pure V math module
509 run: v run ci/linux_ci.vsh test_pure_v_math_module_gcc
510 - name: Self tests
511 run: v run ci/linux_ci.vsh self_tests_gcc
512 - name: Self tests (-prod)
513 run: v run ci/linux_ci.vsh self_tests_prod_gcc
514 - name: Self tests (-cstrict)
515 run: v run ci/linux_ci.vsh self_tests_cstrict_gcc
516 - name: Build examples
517 run: v run ci/linux_ci.vsh build_examples_gcc
518 - name: Build tetris with -autofree
519 run: v run ci/linux_ci.vsh build_tetris_autofree_gcc
520 - name: Build blog tutorial with -autofree
521 run: v run ci/linux_ci.vsh build_blog_autofree_gcc
522 - name: Build option_test.c.v with -autofree
523 run: v run ci/linux_ci.vsh build_option_test_autofree_gcc
524 - name: V self compilation with -parallel-cc
525 run: v run ci/linux_ci.vsh v_self_compilation_parallel_cc_gcc
526 - name: Build modules
527 run: v run ci/linux_ci.vsh build_modules_gcc
528 - name: compile vdoctor.v with -prod
529 run: v run ci/linux_ci.vsh compile_vdoctor_prod_gcc
530 - name: compile vup.v with -prod
531 run: v run ci/linux_ci.vsh compile_vup_prod_gcc
532
533 clang-linux:
534 runs-on: ubuntu-24.04
535 timeout-minutes: 121
536 env:
537 VFLAGS: -cc clang
538 VTEST_SHOW_LONGEST_BY_RUNTIME: 3
539 VTEST_SHOW_LONGEST_BY_COMPTIME: 3
540 VTEST_SHOW_LONGEST_BY_TOTALTIME: 3
541 steps:
542 - uses: actions/checkout@v7
543 - uses: ./.github/actions/cache-apt-packages-action
544 - name: Build V
545 run: make -j4 && ./v symlink
546 - name: All code is formatted
547 run: v run ci/linux_ci.vsh all_code_is_formatted_clang
548 - name: Install dependencies for examples and tools
549 run: v run ci/linux_ci.vsh install_dependencies_for_examples_and_tools_clang
550 - name: Recompile V with -cstrict and clang
551 run: v run ci/linux_ci.vsh recompile_v_with_cstrict_clang
552 - name: Valgrind
553 run: v run ci/linux_ci.vsh valgrind_clang
554 - name: Run sanitizers
555 run: v run ci/linux_ci.vsh run_sanitizers_clang
556 - name: v self compilation
557 run: v run ci/linux_ci.vsh v_self_compilation_clang
558 - name: v self compilation with -usecache
559 run: v run ci/linux_ci.vsh v_self_compilation_usecache_clang
560 - name: Verify `v test` works
561 run: v run ci/linux_ci.vsh verify_v_test_works_clang
562 - name: Test pure V math module
563 run: v run ci/linux_ci.vsh test_pure_v_math_module_clang
564 - name: Self tests
565 run: v run ci/linux_ci.vsh self_tests_clang
566 - name: Self tests (vprod)
567 run: v run ci/linux_ci.vsh self_tests_vprod_clang
568 - name: Self tests (-cstrict)
569 run: v run ci/linux_ci.vsh self_tests_cstrict_clang
570 - name: Build examples
571 run: v run ci/linux_ci.vsh build_examples_clang
572 - name: Build examples with -autofree
573 run: v run ci/linux_ci.vsh build_examples_autofree_clang
574 - name: Build modules
575 run: v run ci/linux_ci.vsh build_modules_clang
576