vxx2 / vlib / v / builder / gc_flags_test.v
128 lines · 117 sloc · 4.31 KB · 1af0718f01f025ad5f66fe45b3079dbb48298af9
Raw
1module builder
2
3import os
4
5fn execute_without_vflags(cmd string) os.Result {
6 old_vflags := os.getenv_opt('VFLAGS')
7 os.unsetenv('VFLAGS')
8 res := os.execute(cmd)
9 if vflags := old_vflags {
10 os.setenv('VFLAGS', vflags, true)
11 } else {
12 os.unsetenv('VFLAGS')
13 }
14 return res
15}
16
17fn test_macos_tcc_boehm_uses_bundled_libgc() {
18 $if !macos {
19 return
20 }
21 $if arm64 {
22 // TCC on macOS arm64 cannot link the i386/asm path that this test exercises.
23 return
24 }
25 exe_path := os.join_path(os.vtmp_dir(), 'builder_gc_flags_test')
26 source_path := os.join_path(@VEXEROOT, 'examples', 'hello_world.v')
27 cmd := '${os.quoted_path(@VEXE)} -showcc -cc tcc -no-retry-compilation -o ${os.quoted_path(exe_path)} ${os.quoted_path(source_path)}'
28 res := execute_without_vflags(cmd)
29 defer {
30 os.rm(exe_path) or {}
31 }
32 assert res.exit_code == 0
33 // macOS amd64 tccbin only ships libgc.a (no .dylib).
34 assert res.output.contains('thirdparty/tcc/lib/libgc.a')
35 assert !res.output.contains(' -lgc')
36}
37
38fn test_linux_musl_tcc_boehm_uses_system_libgc() {
39 $if !linux {
40 return
41 }
42 source_path := os.join_path(@VEXEROOT, 'examples', 'hello_world.v')
43 cmd := '${os.quoted_path(@VEXE)} -dump-c-flags - -cc tcc -musl ${os.quoted_path(source_path)}'
44 res := execute_without_vflags(cmd)
45 assert res.exit_code == 0, res.output
46 assert res.output.contains('-lgc')
47 assert !res.output.contains('thirdparty/tcc/lib/libgc.a')
48}
49
50fn test_no_gc_thread_local_alloc_uses_source_libgc_without_tla_define() {
51 source_path := os.join_path(@VEXEROOT, 'examples', 'hello_world.v')
52 cmd := '${os.quoted_path(@VEXE)} -dump-c-flags - -d no_gc_thread_local_alloc ${os.quoted_path(source_path)}'
53 res := execute_without_vflags(cmd)
54 assert res.exit_code == 0, res.output
55 normalized := res.output.replace('\\', '/')
56 assert !normalized.contains('thirdparty/tcc/lib/libgc')
57 assert !normalized.contains('\n-lgc\n')
58 assert normalized.contains('-D GC_THREADS=1')
59 assert !normalized.contains('THREAD_LOCAL_ALLOC')
60}
61
62fn tcc_compiler_for_test() string {
63 bundled_tcc := os.join_path(@VEXEROOT, 'thirdparty', 'tcc', 'tcc.exe')
64 if tcc_compiler_is_usable(bundled_tcc) {
65 return bundled_tcc
66 }
67 system_tcc := os.find_abs_path_of_executable('tcc') or { return '' }
68 if tcc_compiler_is_usable(system_tcc) {
69 return system_tcc
70 }
71 return ''
72}
73
74fn tcc_compiler_is_usable(tcc_path string) bool {
75 if tcc_path == '' || !os.is_file(tcc_path) || !os.is_executable(tcc_path) {
76 return false
77 }
78 probe := os.execute('${os.quoted_path(tcc_path)} -v')
79 return probe.exit_code == 0
80}
81
82fn tcc_can_compile_v_program(tcc_path string, test_dir string) bool {
83 exe_path := os.join_path(test_dir, 'tcc_probe')
84 source_path := os.join_path(@VEXEROOT, 'examples', 'hello_world.v')
85 res :=
86 execute_without_vflags('${os.quoted_path(@VEXE)} -cc ${os.quoted_path(tcc_path)} -gc none -no-retry-compilation -o ${os.quoted_path(exe_path)} ${os.quoted_path(source_path)}')
87 return res.exit_code == 0
88}
89
90fn test_tcc_use_libbacktrace_does_not_compile_libbacktrace() {
91 test_dir := os.join_path(os.vtmp_dir(), 'builder_use_libbacktrace_tcc_${os.getpid()}')
92 os.mkdir_all(test_dir) or { panic(err) }
93 defer {
94 os.rmdir_all(test_dir) or {}
95 }
96 tcc_path := tcc_compiler_for_test()
97 vmodules_path := os.join_path(test_dir, 'vmodules')
98 old_vmodules := os.getenv_opt('VMODULES')
99 old_vcache := os.getenv_opt('VCACHE')
100 os.setenv('VMODULES', vmodules_path, true)
101 os.setenv('VCACHE', os.join_path(vmodules_path, '.cache'), true)
102 defer {
103 if vcache := old_vcache {
104 os.setenv('VCACHE', vcache, true)
105 } else {
106 os.unsetenv('VCACHE')
107 }
108 if vmodules := old_vmodules {
109 os.setenv('VMODULES', vmodules, true)
110 } else {
111 os.unsetenv('VMODULES')
112 }
113 }
114 if tcc_path == '' || !tcc_can_compile_v_program(tcc_path, test_dir) {
115 return
116 }
117 source_path := os.join_path(test_dir, 'main.v')
118 exe_path := os.join_path(test_dir, 'main')
119 os.write_file(source_path, "fn main() {\n\tpanic('aaaa')\n}\n") or { panic(err) }
120
121 res :=
122 execute_without_vflags('${os.quoted_path(@VEXE)} -cc ${os.quoted_path(tcc_path)} -gc none -no-retry-compilation -d use_libbacktrace -d trace_thirdparty_obj_files -o ${os.quoted_path(exe_path)} ${os.quoted_path(source_path)}')
123
124 assert res.exit_code == 0, res.output
125 normalized := res.output.replace('\\', '/')
126 assert !normalized.contains('thirdparty/libbacktrace/backtrace'), res.output
127 assert !normalized.contains('Failed build_thirdparty_obj_file'), res.output
128}
129