| 1 | import os |
| 2 | import v.builder |
| 3 | import v.gen.c |
| 4 | import v.pref |
| 5 | |
| 6 | const test_vexe = os.quoted_path(@VEXE) |
| 7 | |
| 8 | fn test_is_o_generated_c_files_can_be_linked_together() { |
| 9 | cc_path := os.find_abs_path_of_executable('cc') or { return } |
| 10 | cc := os.quoted_path(cc_path) |
| 11 | workdir := os.join_path(os.vtmp_dir(), 'v_cgen_is_o_link_${os.getpid()}') |
| 12 | os.mkdir_all(workdir)! |
| 13 | defer { |
| 14 | os.rmdir_all(workdir) or {} |
| 15 | } |
| 16 | a_v := os.join_path(workdir, 'a.v') |
| 17 | b_v := os.join_path(workdir, 'b.v') |
| 18 | host_c := os.join_path(workdir, 'main.c') |
| 19 | a_c := os.join_path(workdir, 'a.c') |
| 20 | b_c := os.join_path(workdir, 'b.c') |
| 21 | prog := os.join_path(workdir, 'prog') |
| 22 | os.write_file(a_v, 'module main |
| 23 | |
| 24 | @[markused] |
| 25 | pub fn a() int { |
| 26 | return 1 |
| 27 | } |
| 28 | ')! |
| 29 | os.write_file(b_v, 'module main |
| 30 | |
| 31 | @[markused] |
| 32 | pub fn b() int { |
| 33 | return 2 |
| 34 | } |
| 35 | ')! |
| 36 | os.write_file(host_c, '#include <stdio.h> |
| 37 | int main__a(void); |
| 38 | int main__b(void); |
| 39 | |
| 40 | int main(void) { |
| 41 | printf("%d %d\\n", main__a(), main__b()); |
| 42 | return 0; |
| 43 | } |
| 44 | ')! |
| 45 | for cmd in [ |
| 46 | '${test_vexe} -cc ${cc} -gc none -no-skip-unused -is_o -o ${os.quoted_path(a_c)} ${os.quoted_path(a_v)}', |
| 47 | '${test_vexe} -cc ${cc} -gc none -no-skip-unused -is_o -o ${os.quoted_path(b_c)} ${os.quoted_path(b_v)}', |
| 48 | '${cc} -o ${os.quoted_path(prog)} ${os.quoted_path(a_c)} ${os.quoted_path(b_c)} ${os.quoted_path(host_c)} -lm', |
| 49 | ] { |
| 50 | res := os.execute(cmd) |
| 51 | assert res.exit_code == 0, '${cmd}\n${res.output}' |
| 52 | } |
| 53 | res := os.execute(os.quoted_path(prog)) |
| 54 | assert res.exit_code == 0, res.output |
| 55 | assert res.output.trim_space() == '1 2' |
| 56 | } |
| 57 | |
| 58 | fn test_parallel_cc_windows_header_keeps_vv_loc_external() { |
| 59 | tmp_dir := os.join_path(os.vtmp_dir(), 'parallel_cc_windows_linkage_${os.getpid()}') |
| 60 | os.mkdir_all(tmp_dir)! |
| 61 | defer { |
| 62 | os.rmdir_all(tmp_dir) or {} |
| 63 | } |
| 64 | source_path := os.join_path(tmp_dir, 'main.v') |
| 65 | os.write_file(source_path, 'module main |
| 66 | fn helper() string { |
| 67 | return "ok" |
| 68 | } |
| 69 | |
| 70 | fn main() { |
| 71 | println(helper()) |
| 72 | } |
| 73 | ')! |
| 74 | mut prefs, _ := pref.parse_args_and_show_errors([], [ |
| 75 | '', |
| 76 | '-parallel-cc', |
| 77 | '-os', |
| 78 | 'windows', |
| 79 | source_path, |
| 80 | ], false) |
| 81 | mut b := builder.new_builder(prefs) |
| 82 | mut files := b.get_builtin_files() |
| 83 | files << b.get_user_files() |
| 84 | b.set_module_lookup_paths() |
| 85 | b.front_and_middle_stages(files)! |
| 86 | result := c.gen(b.parsed_files, mut b.table, b.pref) |
| 87 | header := result.header.replace('\r\n', '\n') |
| 88 | assert header.contains('#define _VPARALLELCC (1)'), header |
| 89 | assert header.contains('#ifdef _VPARALLELCC\n\t\t#define VV_LOC\n\t#else\n\t\t#define VV_LOC static\n\t#endif'), header |
| 90 | assert header.contains('VV_LOC string main__helper(void);'), header |
| 91 | } |
| 92 | |
| 93 | fn test_parallel_cc_usecache_interface_index_definition_stays_out_of_header() { |
| 94 | $if windows { |
| 95 | return |
| 96 | } |
| 97 | tmp_dir := os.join_path(os.vtmp_dir(), 'parallel_cc_usecache_interface_index_${os.getpid()}') |
| 98 | os.mkdir_all(tmp_dir)! |
| 99 | defer { |
| 100 | os.rmdir_all(tmp_dir) or {} |
| 101 | } |
| 102 | source_path := os.join_path(tmp_dir, 'main.v') |
| 103 | os.write_file(source_path, "fn main() {\n\tprintln('hello world')\n}\n")! |
| 104 | mut prefs, _ := pref.parse_args_and_show_errors([], [ |
| 105 | '', |
| 106 | '-usecache', |
| 107 | '-parallel-cc', |
| 108 | source_path, |
| 109 | ], false) |
| 110 | mut b := builder.new_builder(prefs) |
| 111 | mut files := b.get_builtin_files() |
| 112 | files << b.get_user_files() |
| 113 | b.set_module_lookup_paths() |
| 114 | b.front_and_middle_stages(files)! |
| 115 | result := c.gen(b.parsed_files, mut b.table, b.pref) |
| 116 | header := result.header.replace('\r\n', '\n') |
| 117 | out0 := result.out0_str.replace('\r\n', '\n') |
| 118 | assert header.contains('enum { _IError_None___index_enum ='), header |
| 119 | assert header.contains('extern const u32 _IError_None___index;'), header |
| 120 | assert !header.contains('const u32 _IError_None___index = _IError_None___index_enum;') |
| 121 | assert out0.contains('const u32 _IError_None___index = _IError_None___index_enum;'), out0 |
| 122 | } |
| 123 | |