v / vlib / v2 / builder / util_test.v
249 lines · 225 sloc · 9.16 KB · ddb021b9866c3b4523b746fa2f4c16a594f8bd89
Raw
1// vtest build: macos
2module builder
3
4import os
5import v2.ast
6import v2.pref
7
8fn test_get_v_files_from_dir_uses_target_os() {
9 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_builder_target_os_${os.getpid()}')
10 os.mkdir_all(tmp_dir) or { panic(err) }
11 defer {
12 os.rmdir_all(tmp_dir) or {}
13 }
14 os.write_file(os.join_path(tmp_dir, 'common.v'), 'module test') or { panic(err) }
15 os.write_file(os.join_path(tmp_dir, 'platform_linux.v'), 'module test') or { panic(err) }
16 os.write_file(os.join_path(tmp_dir, 'platform_macos.v'), 'module test') or { panic(err) }
17
18 macos_files := get_v_files_from_dir(tmp_dir, []string{}, 'mac')
19 macos_names := macos_files.map(os.file_name(it))
20 assert 'common.v' in macos_names
21 assert 'platform_macos.v' in macos_names
22 assert 'platform_linux.v' !in macos_names
23
24 linux_files := get_v_files_from_dir(tmp_dir, []string{}, 'linux')
25 linux_names := linux_files.map(os.file_name(it))
26 assert 'common.v' in linux_names
27 assert 'platform_linux.v' in linux_names
28 assert 'platform_macos.v' !in linux_names
29}
30
31fn test_get_v_files_from_dir_uses_d_and_notd_suffixes() {
32 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_builder_define_suffix_${os.getpid()}')
33 os.mkdir_all(tmp_dir) or { panic(err) }
34 defer {
35 os.rmdir_all(tmp_dir) or {}
36 }
37 os.write_file(os.join_path(tmp_dir, 'common.v'), 'module test') or { panic(err) }
38 os.write_file(os.join_path(tmp_dir, 'ssl_d_use_openssl.v'), 'module test') or { panic(err) }
39 os.write_file(os.join_path(tmp_dir, 'ssl_notd_use_openssl.v'), 'module test') or { panic(err) }
40
41 default_names := get_v_files_from_dir(tmp_dir, []string{}, 'mac').map(os.file_name(it))
42 assert 'common.v' in default_names
43 assert 'ssl_d_use_openssl.v' !in default_names
44 assert 'ssl_notd_use_openssl.v' in default_names
45
46 openssl_names := get_v_files_from_dir(tmp_dir, ['use_openssl'], 'mac').map(os.file_name(it))
47 assert 'common.v' in openssl_names
48 assert 'ssl_d_use_openssl.v' in openssl_names
49 assert 'ssl_notd_use_openssl.v' !in openssl_names
50}
51
52fn test_get_v_files_from_dir_skips_prealloc_without_prealloc_flag() {
53 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_builder_prealloc_${os.getpid()}')
54 os.mkdir_all(tmp_dir) or { panic(err) }
55 defer {
56 os.rmdir_all(tmp_dir) or {}
57 }
58 os.write_file(os.join_path(tmp_dir, 'common.v'), 'module test') or { panic(err) }
59 os.write_file(os.join_path(tmp_dir, 'prealloc.c.v'), 'module test') or { panic(err) }
60
61 default_names := get_v_files_from_dir(tmp_dir, []string{}, 'mac').map(os.file_name(it))
62 assert 'common.v' in default_names
63 assert 'prealloc.c.v' !in default_names
64
65 prealloc_names := get_v_files_from_dir(tmp_dir, ['prealloc'], 'mac').map(os.file_name(it))
66 assert 'common.v' in prealloc_names
67 assert 'prealloc.c.v' in prealloc_names
68}
69
70fn test_get_v_files_from_dir_returns_lexically_sorted_files() {
71 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_builder_sorted_v_files_${os.getpid()}')
72 os.mkdir_all(tmp_dir) or { panic(err) }
73 defer {
74 os.rmdir_all(tmp_dir) or {}
75 }
76 os.write_file(os.join_path(tmp_dir, 'foo.v'), 'module test') or { panic(err) }
77 os.write_file(os.join_path(tmp_dir, 'foo.c.v'), 'module test') or { panic(err) }
78 os.write_file(os.join_path(tmp_dir, 'bar.v'), 'module test') or { panic(err) }
79 os.write_file(os.join_path(tmp_dir, 'ignore.txt'), 'not v') or { panic(err) }
80
81 names := get_v_files_from_dir(tmp_dir, []string{}, 'linux').map(os.file_name(it))
82 assert names == ['bar.v', 'foo.c.v', 'foo.v']
83 assert names.index('foo.c.v') or { -1 } < names.index('foo.v') or { -1 }
84}
85
86fn test_flag_helpers_use_target_os() {
87 assert flag_os_matches('macos', 'mac')
88 assert flag_os_matches('bsd', 'mac')
89 assert flag_os_matches('bsd', 'freebsd')
90 assert !flag_os_matches('linux', 'mac')
91 assert comptime_cond_matches('macos', 'mac')
92 assert comptime_cond_matches('linux || bsd', 'mac')
93 assert !comptime_cond_matches('linux', 'mac')
94 assert comptime_cond_matches('macos && !linux', 'mac')
95 macos_flag := parse_flag_directive_line('#flag macos -framework Cocoa', '/tmp/source.v', 'mac') or {
96 ''
97 }
98 linux_flag := parse_flag_directive_line('#flag linux -lm', '/tmp/source.v', 'mac') or { '' }
99 assert macos_flag == '-framework Cocoa'
100 assert linux_flag == ''
101}
102
103fn test_flag_helpers_expand_when_first_existing() {
104 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_builder_when_first_${os.getpid()}')
105 existing_dir := os.join_path(tmp_dir, 'openssl_include')
106 os.mkdir_all(existing_dir) or { panic(err) }
107 defer {
108 os.rmdir_all(tmp_dir) or {}
109 }
110 missing_dir := os.join_path(tmp_dir, 'missing')
111 flag := parse_flag_directive_line("#flag darwin -I\$when_first_existing('${missing_dir}','${existing_dir}')", os.join_path(tmp_dir,
112 'source.v'), 'mac') or { '' }
113 assert flag == '-I${existing_dir}'
114 none_flag := parse_flag_directive_line("#flag darwin -I\$when_first_existing('${missing_dir}')", os.join_path(tmp_dir,
115 'source.v'), 'mac') or { '' }
116 assert none_flag == ''
117}
118
119fn test_split_compile_and_link_flags_moves_c_sources_to_link_step() {
120 compile_flags, link_flags :=
121 split_compile_and_link_flags('-I /tmp/include -DMYFLAG thirdparty/sqlite/sqlite3.c -L/tmp/lib -lsqlite3 foo.o')
122 assert compile_flags == '-I /tmp/include -DMYFLAG'
123 assert link_flags == 'thirdparty/sqlite/sqlite3.c -L/tmp/lib -lsqlite3 foo.o'
124}
125
126fn test_sanitize_header_source_preserves_public_module_storage() {
127 source := 'module state
128
129pub __global (
130 mut count int
131 pub mut shared int
132)
133
134pub __global mut total int
135'
136 sanitized := sanitize_header_source(source, map[string]string{})
137 assert sanitized.contains('pub __global (')
138 assert sanitized.contains('mut count int')
139 assert sanitized.contains('pub mut shared int')
140 assert sanitized.contains('pub __global mut total int')
141}
142
143fn test_build_module_header_ast_preserves_module_storage_flags() {
144 mut prefs := pref.new_preferences()
145 mut b := new_builder(&prefs)
146 source_file := ast.File{
147 mod: 'state'
148 name: 'state.v'
149 stmts: [
150 ast.Stmt(ast.ModuleStmt{
151 name: 'state'
152 }),
153 ast.Stmt(ast.GlobalDecl{
154 is_public: true
155 fields: [
156 ast.FieldDecl{
157 name: 'private_count'
158 typ: ast.Ident{
159 name: 'int'
160 }
161 is_mut: true
162 is_public: false
163 },
164 ast.FieldDecl{
165 name: 'shared_count'
166 typ: ast.Ident{
167 name: 'int'
168 }
169 is_mut: true
170 is_public: true
171 },
172 ]
173 }),
174 ]
175 }
176 header := b.build_module_header_ast([source_file], 'state') or {
177 panic('missing module storage header')
178 }
179 mut found := false
180 for stmt in header.stmts {
181 if stmt is ast.GlobalDecl {
182 found = true
183 assert stmt.is_public
184 assert stmt.fields.len == 2
185 assert stmt.fields[0].name == 'private_count'
186 assert stmt.fields[0].is_mut
187 assert !stmt.fields[0].is_public
188 assert stmt.fields[1].name == 'shared_count'
189 assert stmt.fields[1].is_mut
190 assert stmt.fields[1].is_public
191 }
192 }
193 assert found
194}
195
196fn test_cflags_need_objc_mode_only_for_objc_inputs() {
197 assert cflags_need_objc_mode('-framework Cocoa')
198 assert cflags_need_objc_mode('/tmp/clipboard_darwin.m -framework Foundation')
199 assert !cflags_need_objc_mode('-I /tmp/include -lssl -lcrypto /tmp/sqlite3.c')
200 assert !cflags_need_objc_mode('-I /tmp/project.m/include')
201}
202
203fn test_file_has_incompatible_os_suffix_windows() {
204 assert pref.file_has_incompatible_os_suffix('time_solaris.c.v', 'windows')
205 assert pref.file_has_incompatible_os_suffix('time_freebsd.c.v', 'windows')
206 assert pref.file_has_incompatible_os_suffix('time_openbsd.c.v', 'windows')
207 assert pref.file_has_incompatible_os_suffix('time_netbsd.c.v', 'windows')
208 assert pref.file_has_incompatible_os_suffix('time_dragonfly.c.v', 'windows')
209 assert pref.file_has_incompatible_os_suffix('time_nix.c.v', 'windows')
210 assert !pref.file_has_incompatible_os_suffix('time_windows.c.v', 'windows')
211}
212
213fn test_file_has_incompatible_os_suffix_non_windows_targets() {
214 assert !pref.file_has_incompatible_os_suffix('time_solaris.c.v', 'solaris')
215 assert !pref.file_has_incompatible_os_suffix('time_freebsd.c.v', 'freebsd')
216 assert !pref.file_has_incompatible_os_suffix('time_bsd.c.v', 'macos')
217 assert pref.file_has_incompatible_os_suffix('time_bsd.c.v', 'linux')
218 assert !pref.file_has_incompatible_os_suffix('time_darwin.c.v', 'macos')
219 assert !pref.file_has_incompatible_os_suffix('time_macos.c.v', 'darwin')
220 assert !pref.file_has_incompatible_os_suffix('time_android_outside_termux.c.v', 'android')
221 assert pref.file_has_incompatible_os_suffix('time_windows.c.v', 'linux')
222 assert pref.file_has_incompatible_os_suffix('time_android_outside_termux.c.v', 'linux')
223}
224
225fn test_default_cc_uses_tcc_when_available() {
226 vroot := os.dir(os.dir(@FILE))
227 tcc_path := os.join_path(vroot, 'thirdparty', 'tcc', 'tcc.exe')
228 cc := default_cc(vroot)
229 if os.exists(tcc_path) {
230 assert cc.contains('tcc')
231 } else {
232 assert cc == 'cc'
233 }
234}
235
236fn test_cc_recompile_flags_from_cmd_keeps_include_paths() {
237 cmd := 'cc -I /tmp/include -I/tmp/other -Dfoo=1 -x objective-c -std=gnu11 -fwrapv "/tmp/main.c" -x none "/tmp/lib.o" -L/tmp/lib -lm -o "app"'
238 flags := cc_recompile_flags_from_cmd(cmd)
239 assert flags.contains('-I /tmp/include')
240 assert flags.contains('-I/tmp/other')
241 assert flags.contains('-Dfoo=1')
242 assert flags.contains('-x objective-c')
243 assert flags.contains('-std=gnu11')
244 assert flags.contains('-fwrapv')
245 assert !flags.contains('/tmp/lib.o')
246 assert !flags.contains('-L/tmp/lib')
247 assert !flags.contains('-lm')
248 assert !flags.contains('-o')
249}
250