From 12c7816c5844852e71628b0360ffec8d6d731545 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 25 Mar 2026 16:42:22 +0300 Subject: [PATCH] cgen: improve error message when running shader examples (fixes #16125) --- .../07_simple_shader_glsl/simple_shader.v | 2 +- .../tests/missing_shader_header_1.glsl | 1 + .../checker/tests/missing_shader_header_1.out | 1 + .../checker/tests/missing_shader_header_1.vv | 3 ++ vlib/v/gen/c/cgen.v | 36 ++++++++++++++++--- 5 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 vlib/v/checker/tests/missing_shader_header_1.glsl create mode 100644 vlib/v/checker/tests/missing_shader_header_1.out create mode 100644 vlib/v/checker/tests/missing_shader_header_1.vv diff --git a/examples/sokol/07_simple_shader_glsl/simple_shader.v b/examples/sokol/07_simple_shader_glsl/simple_shader.v index db1d07bb5..d6d5606d6 100644 --- a/examples/sokol/07_simple_shader_glsl/simple_shader.v +++ b/examples/sokol/07_simple_shader_glsl/simple_shader.v @@ -10,7 +10,7 @@ import sokol.gfx // Use `v shader` or `sokol-shdc` to generate the necessary `.h` file // Using `v shader -v .` in this directory will show some additional // info - and what you should include to make things work. -#include "@VMODROOT/simple_shader.h" # # It should be generated with `v shader .` +#include "@VMODROOT/simple_shader.h" # It should be generated with `v shader .` // simple_shader_desc is a C function declaration defined by // the `@program` entry in the `simple_shader.glsl` shader file. diff --git a/vlib/v/checker/tests/missing_shader_header_1.glsl b/vlib/v/checker/tests/missing_shader_header_1.glsl new file mode 100644 index 000000000..2dad8e152 --- /dev/null +++ b/vlib/v/checker/tests/missing_shader_header_1.glsl @@ -0,0 +1 @@ +// A matching .glsl file lets the compiler suggest `v shader`. diff --git a/vlib/v/checker/tests/missing_shader_header_1.out b/vlib/v/checker/tests/missing_shader_header_1.out new file mode 100644 index 000000000..bdb3f62d8 --- /dev/null +++ b/vlib/v/checker/tests/missing_shader_header_1.out @@ -0,0 +1 @@ +builder error: Header file "missing_shader_header_1.h", needed for module `main` was not found. This header can be generated from `missing_shader_header_1.glsl`. Run `v shader .` in that directory to create it. diff --git a/vlib/v/checker/tests/missing_shader_header_1.vv b/vlib/v/checker/tests/missing_shader_header_1.vv new file mode 100644 index 000000000..5814319d9 --- /dev/null +++ b/vlib/v/checker/tests/missing_shader_header_1.vv @@ -0,0 +1,3 @@ +module main + +#include "missing_shader_header_1.h" diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index a6862b922..939720ea8 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -7701,13 +7701,39 @@ fn (g &Gen) is_error_type(typ ast.Type) bool { return false } -fn (mut g Gen) hash_stmt_guarded_include(node ast.HashStmt) string { - mut missing_message := 'Header file ${node.main}, needed for module `${node.mod}` was not found.' +fn missing_shader_header_message(node ast.HashStmt) string { if node.msg != '' { - missing_message += ' ${node.msg}.' - } else { - missing_message += ' Please install the corresponding development headers.' + return '${node.msg}.' + } + if shader_source := matching_generated_shader_source(node) { + shader_name := os.file_name(shader_source) + return 'This header can be generated from `${shader_name}`. Run `v shader .` in that directory to create it.' + } + return 'Please install the corresponding development headers.' +} + +fn matching_generated_shader_source(node ast.HashStmt) ?string { + if node.main.starts_with('<') && node.main.ends_with('>') { + return none } + header_path := node.main.trim('"') + if os.file_ext(header_path) != '.h' { + return none + } + mut resolved_header_path := header_path + if !os.is_abs_path(resolved_header_path) { + resolved_header_path = os.join_path(os.dir(node.source_file), resolved_header_path) + } + shader_source := resolved_header_path.all_before_last('.') + '.glsl' + if !os.is_file(shader_source) { + return none + } + return shader_source +} + +fn (mut g Gen) hash_stmt_guarded_include(node ast.HashStmt) string { + mut missing_message := 'Header file ${node.main}, needed for module `${node.mod}` was not found.' + missing_message += ' ${missing_shader_header_message(node)}' mut guarded_include := get_guarded_include_text(node.main, missing_message) if node.main == '' { // fails with musl-gcc and msvc; but an unguarded include works: -- 2.39.5