-
|
I want compile shaders from their glsl source to spir-v and then embed them in C sources (using C23 #embed). This seems to work if I create custom_targets like spirv_shaders = []
foreach shader: shader_sources
spirv_shaders += custom_target(
shader + '.spv',
input: files(shader),
output: shader + '.spv',
command: [glslang, '-V', '@INPUT@', '-o', '@OUTPUT@'] + extra_args,
)
endforeachand then either add spirv_shaders directly to the sources of an executable, or create a dependency with But in both cases, whenever I make changes to a shader, apparently all C files are recompiled, not just the ones which actually embed the updated spv. How do I make meson/ninja use the compiler's |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 5 replies
-
|
glslang is a pain. what does As an aside to your question, here's the code from mesa (mostly written by me) to check if glslang supports depfile generation of its own, which you may find helpful. # GLSL has interesting version output and Meson doesn't parse it correctly as of
# Meson 1.4.0
prog_glslang = find_program('glslangValidator', native : true)
if prog_glslang.found()
_glslang_version = run_command(prog_glslang, ['--version'], check : false).stdout().split(':')[2]
# Check if glslang has depfile support. Support was added in 11.3.0, but
# Windows path support was broken until 11.9.0.
#
# It is intentional to check the build machine, since we need to ensure that
# glslang will output valid paths on the build platform
_glslang_check = build_machine.system() == 'windows' ? '>= 11.9.0' : '>= 11.3.0'
if _glslang_version.version_compare(_glslang_check)
glslang_depfile = ['--depfile', '@DEPFILE@']
else
glslang_depfile = []
endif
if run_command(prog_glslang, [ '--quiet', '--version' ], check : false).returncode() == 0
glslang_quiet = ['--quiet']
else
glslang_quiet = []
endif
endif |
Beta Was this translation helpful? Give feedback.
-
|
Actually I was testing with an older version of Meson, with Meson 1.9.1 the problem is no longer that everything is rebuilt, but instead I have to run ninja two times after changing the source file, because the first time only generates the embedded file again but doesn't recompile the program. I don't think it is related to glslang, the shaders don't include anything for now, so their only dependency is the input file. Here is another minimal example without glslang: meson.build: project('demo', 'c',
version: '1.0.0',
default_options: ['c_std=c23']
)
generated_file = custom_target('generate_output',
input: 'demo.txt.in',
output: 'demo.txt',
command: ['sed', 's/Meson/World/g', '@INPUT@'],
capture: true,
)
exe = executable('demo',
'main.c',
dependencies: [declare_dependency(sources: generated_file)],
c_args: ['--embed-dir=' + meson.current_build_dir()],
)main.c: #include <stdio.h>
static const unsigned char text[] = {
#embed "demo.txt" suffix(,)
0
};
int main(void) {
printf("%s", text);
}demo.txt.in: The build after |
Beta Was this translation helpful? Give feedback.
-
|
Reproduced with both Meson 1.8.5 and 1.9.1, but it seems to be a ninja bug. I cannot reproduce it with samurai and I could even reproduce without Meson at all, replacing its output-capture wrapper with a script like this ( and a minimal Note that wihle build.ninja has an order-only dependency on Removing |
Beta Was this translation helpful? Give feedback.
-
|
As discussed above, my problem was adding an absolute path with This seems to work well, even with includes between glsl sources: shader_sources = ['test.vert', 'test.frag']
spirv_shaders = []
foreach shader: shader_sources
spirv_shaders += custom_target(
shader + '.spv',
input: shader,
output: shader + '.spv',
depfile: shader + '.d',
command: [glslang, '-V', '@INPUT@', '-o', '@OUTPUT@', '--depfile', '@DEPFILE@'],
)
endforeach
shaders_dep = declare_dependency(
sources: spirv_shaders,
compile_args: '--embed-dir=' + import('fs').relative_to(meson.current_build_dir(), meson.project_build_root()),
)
# possibly in another subdir:
executable(
# .....
dependencies: [shaders_dep],
) |
Beta Was this translation helpful? Give feedback.
As discussed above, my problem was adding an absolute path with
'--embed-dir=' + meson.current_build_dir(), so a solution for now is not to usemeson.current_build_dir(), and instead either simply hardcode the correct relative path from the project build directory (e.g.'--embed-dir=shaders'), or to usefs.relative_to.This seems to work well, even with includes between glsl sources: