From e470ea51810b9d68fc4a04dcb8defdeb93873032 Mon Sep 17 00:00:00 2001 From: GitHackerz Date: Sun, 19 Jul 2026 15:26:14 +0100 Subject: [PATCH 1/2] cmd: validate explicit C compiler before dispatch --- cmd/v/v.v | 11 +++++++++++ cmd/v/v_windows_test.v | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 cmd/v/v_windows_test.v diff --git a/cmd/v/v.v b/cmd/v/v.v index 9a3c13006dbca4..2d6c17085ac499 100644 --- a/cmd/v/v.v +++ b/cmd/v/v.v @@ -116,6 +116,17 @@ fn main() { } mut args_and_flags := util.join_env_vflags_and_os_args()[1..] prefs, command := pref.parse_args_and_show_errors(external_tools, args_and_flags, true) + $if windows { + // Check an explicitly selected C compiler before dispatching the command, so + // invalid or missing commands do not hide the more useful `-cc` diagnostic. + if builder.should_find_windows_host_c_compiler(prefs) && prefs.ccompiler_set_by_flag + && prefs.ccompiler != 'msvc' { + mut probe := builder.Builder{ + pref: unsafe { prefs } + } + probe.find_win_cc() or { builder.verror(err.msg()) } + } + } maybe_delegate_to_vvmrc(command, prefs) maybe_delegate_to_ownership(command, prefs) if prefs.use_cache && os.user_os() == 'windows' { diff --git a/cmd/v/v_windows_test.v b/cmd/v/v_windows_test.v new file mode 100644 index 00000000000000..b2850e1ee71970 --- /dev/null +++ b/cmd/v/v_windows_test.v @@ -0,0 +1,16 @@ +module main + +import os + +fn test_invalid_c_compiler_is_reported_before_command_dispatch() { + $if !windows { + return + } + missing_compiler := 'missing_compiler_27868' + expected_error := 'builder error: C compiler `${missing_compiler}` was requested with `-cc`, but was not found.' + for command in ['', 'not-a-command'] { + result := os.execute('${os.quoted_path(@VEXE)} -cc ${missing_compiler} ${command}') + assert result.exit_code == 1 + assert result.output.contains(expected_error), result.output + } +} From b28e2837032c3ab40f0ce358d397cc0c3c227212 Mon Sep 17 00:00:00 2001 From: GitHackerz Date: Sun, 19 Jul 2026 21:31:05 +0100 Subject: [PATCH 2/2] cmd: preserve non-build command dispatch --- cmd/v/v.v | 22 +++++++++++----------- cmd/v/v_windows_test.v | 8 ++++++++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/cmd/v/v.v b/cmd/v/v.v index 2d6c17085ac499..e3bfc214db244c 100644 --- a/cmd/v/v.v +++ b/cmd/v/v.v @@ -116,17 +116,6 @@ fn main() { } mut args_and_flags := util.join_env_vflags_and_os_args()[1..] prefs, command := pref.parse_args_and_show_errors(external_tools, args_and_flags, true) - $if windows { - // Check an explicitly selected C compiler before dispatching the command, so - // invalid or missing commands do not hide the more useful `-cc` diagnostic. - if builder.should_find_windows_host_c_compiler(prefs) && prefs.ccompiler_set_by_flag - && prefs.ccompiler != 'msvc' { - mut probe := builder.Builder{ - pref: unsafe { prefs } - } - probe.find_win_cc() or { builder.verror(err.msg()) } - } - } maybe_delegate_to_vvmrc(command, prefs) maybe_delegate_to_ownership(command, prefs) if prefs.use_cache && os.user_os() == 'windows' { @@ -194,6 +183,17 @@ fn main() { if prefs.is_help { invoke_help_and_exit(args) } + $if windows { + // An invalid `-cc` setting should take precedence over an unknown command, + // but must not affect commands that do not compile code. + if builder.should_find_windows_host_c_compiler(prefs) && prefs.ccompiler_set_by_flag + && prefs.ccompiler != 'msvc' { + mut probe := builder.Builder{ + pref: unsafe { prefs } + } + probe.find_win_cc() or { builder.verror(err.msg()) } + } + } other_commands := ['run', 'crun', 'build', 'build-module', 'help', 'version', 'new', 'init', 'install', 'link', 'list', 'outdated', 'remove', 'search', 'show', 'unlink', 'update', diff --git a/cmd/v/v_windows_test.v b/cmd/v/v_windows_test.v index b2850e1ee71970..3cb01a85d65b7d 100644 --- a/cmd/v/v_windows_test.v +++ b/cmd/v/v_windows_test.v @@ -13,4 +13,12 @@ fn test_invalid_c_compiler_is_reported_before_command_dispatch() { assert result.exit_code == 1 assert result.output.contains(expected_error), result.output } + help_result := os.execute('${os.quoted_path(@VEXE)} -cc ${missing_compiler} help') + assert help_result.exit_code == 1 + assert help_result.output.contains('provide only one help topic.'), help_result.output + assert !help_result.output.contains(expected_error), help_result.output + + version_result := os.execute('${os.quoted_path(@VEXE)} -cc ${missing_compiler} version') + assert version_result.exit_code == 0, version_result.output + assert !version_result.output.contains(expected_error), version_result.output }