From 0c6c80c92cf02525e375e2f6a973dcf2fdec6e92 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 21 Apr 2026 16:54:36 +0300 Subject: [PATCH] cgen: fix parallel compilation failing on windows (fixes #26877) --- vlib/v/builder/parallel_cc_failure_test.v | 7 +++- vlib/v/gen/c/cgen.v | 3 ++ vlib/v/gen/c/cheaders.v | 6 +++- vlib/v/gen/c/link_generated_c_files_test.v | 37 ++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/vlib/v/builder/parallel_cc_failure_test.v b/vlib/v/builder/parallel_cc_failure_test.v index b3204eea0..cd098e651 100644 --- a/vlib/v/builder/parallel_cc_failure_test.v +++ b/vlib/v/builder/parallel_cc_failure_test.v @@ -10,6 +10,11 @@ fn run_parallel_cc_case(case_name string, files map[string]string) os.Result { } fn run_parallel_cc_case_with_env(case_name string, files map[string]string, env_overrides map[string]string) os.Result { + return run_parallel_cc_case_with_args(case_name, ['-parallel-cc', 'main.v'], files, + env_overrides) +} + +fn run_parallel_cc_case_with_args(case_name string, args []string, files map[string]string, env_overrides map[string]string) os.Result { case_dir := os.join_path(parallel_cc_test_path, case_name) os.rmdir_all(case_dir) or {} os.mkdir_all(case_dir) or { panic(err) } @@ -27,7 +32,7 @@ fn run_parallel_cc_case_with_env(case_name string, files map[string]string, env_ } mut p := os.new_process(parallel_cc_vexe) p.set_work_folder(case_dir) - p.set_args(['-parallel-cc', 'main.v']) + p.set_args(args) p.set_environment(env) p.set_redirect_stdio() p.wait() diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index ff4603101..24c50dbc2 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1229,6 +1229,9 @@ pub fn (mut g Gen) init() { if g.pref.autofree { g.comptime_definitions.writeln('#define _VAUTOFREE (1)') } + if g.pref.parallel_cc { + g.comptime_definitions.writeln('#define _VPARALLELCC (1)') + } if g.pref.prealloc { g.comptime_definitions.writeln('#define _VPREALLOC (1)') } diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index 1904b36d0..04da01808 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -179,7 +179,11 @@ const c_common_macros = ' #endif #if defined(_WIN32) || defined(__CYGWIN__) #define VV_EXP extern __declspec(dllexport) - #define VV_LOC static + #ifdef _VPARALLELCC + #define VV_LOC + #else + #define VV_LOC static + #endif #else // 4 < gcc < 5 is used by some older Ubuntu LTS and Centos versions, // and does not support __has_attribute(visibility) ... diff --git a/vlib/v/gen/c/link_generated_c_files_test.v b/vlib/v/gen/c/link_generated_c_files_test.v index cc4370b88..d23183f17 100644 --- a/vlib/v/gen/c/link_generated_c_files_test.v +++ b/vlib/v/gen/c/link_generated_c_files_test.v @@ -1,6 +1,8 @@ module c import os +import v.builder +import v.pref const test_vexe = os.quoted_path(@VEXE) @@ -53,3 +55,38 @@ int main(void) { assert res.exit_code == 0, res.output assert res.output.trim_space() == '1 2' } + +fn test_parallel_cc_windows_header_keeps_vv_loc_external() { + tmp_dir := os.join_path(os.vtmp_dir(), 'parallel_cc_windows_linkage_${os.getpid()}') + os.mkdir_all(tmp_dir)! + defer { + os.rmdir_all(tmp_dir) or {} + } + source_path := os.join_path(tmp_dir, 'main.v') + os.write_file(source_path, 'module main +fn helper() string { + return "ok" +} + +fn main() { + println(helper()) +} +')! + mut prefs, _ := pref.parse_args_and_show_errors([], [ + '', + '-parallel-cc', + '-os', + 'windows', + source_path, + ], false) + mut b := builder.new_builder(prefs) + mut files := b.get_builtin_files() + files << b.get_user_files() + b.set_module_lookup_paths() + b.front_and_middle_stages(files)! + result := gen(b.parsed_files, mut b.table, b.pref) + header := result.header.replace('\r\n', '\n') + assert header.contains('#define _VPARALLELCC (1)'), header + 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 + assert header.contains('VV_LOC string main__helper(void);'), header +} -- 2.39.5