Open aeldemery opened 4 years ago
I just ran into this too. For completeness' sake, here's a minimal example to reproduce:
build file:
$ cat meson.build
project('meson-vulkan-test', 'cpp')
vulkan_dep = dependency('vulkan')
executable('main', 'test.cpp', dependencies: [vulkan_dep])
cpp file:
$ cat test.cpp
#include <vulkan/vulkan.h>
int main() {
return 0;
}
build output:
$ meson build ; and ninja -Cbuild
The Meson build system
Version: 0.59.1
Source dir: /home/mht/tmp/meson-vulkan
Build dir: /home/mht/tmp/meson-vulkan/build
Build type: native build
Project name: meson-vulkan-test
Project version: undefined
C++ compiler for the host machine: c++ (gcc 11.1.0 "c++ (GCC) 11.1.0")
C++ linker for the host machine: c++ ld.bfd 2.36.1
Host machine cpu family: x86_64
Host machine cpu: x86_64
Found pkg-config: /usr/bin/pkg-config (1.7.3)
Run-time dependency vulkan found: YES 1.2.191
Build targets in project: 1
Found ninja-1.10.2 at /usr/bin/ninja
ninja: Entering directory `build'
[1/2] Compiling C++ object main.p/test.cpp.o
FAILED: main.p/test.cpp.o
c++ -Imain.p -I. -I.. -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -g -MD -MQ main.p/test.cpp.o -MF main.p/test.cpp.o.d -o main.p/test.cpp.o -c ../test.cpp
../test.cpp:1:10: fatal error: vulkan/vulkan.h: No such file or directory
1 | #include <vulkan/vulkan.h>
| ^~~~~~~~~~~~~~~~~
compilation terminated.
ninja: build stopped: subcommand failed.
This dependency troubles and confuses me.
vulkan.pc, as distributed by the KhronosGroup, provides a dependency for the Vulkan Loader, not the Vulkan Headers. So the results you got are technically correct -- the SDK cannot be called "vulkan" as it clashes with the Vulkan ICD Loader.
I'm still fairly new to this, but the way Vulkan is handled seems fairly similar to, say, GLFW. Here's the .pc
files from my system:
vulkan.pc:
prefix=/usr
exec_prefix=/usr
libdir=/usr/lib
includedir=/usr/include
Name: Vulkan-Loader
Description: Vulkan Loader
Version: 1.2.191
Libs: -L${libdir} -lvulkan
Libs.private: -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
Cflags: -I${includedir}
glfw3.pc:
prefix=/usr
exec_prefix=${prefix}
includedir=/usr/include
libdir=/usr/lib
Name: GLFW
Description: A multi-platform library for OpenGL, window and input
Version: 3.3.4
URL: https://www.glfw.org/
Requires.private: x11
Libs: -L${libdir} -lglfw
Libs.private: -lrt -lm -ldl
Cflags: -I${includedir}
From what I can tell, both pkgconfig files just say which flags they're supposed to send to the compiler and linker, but there's no explicit checking that the required files are actually present. This seems to be deferred to the package managers of the distributions? I.e, how is a tool like Meson supposed to know whether the header files are actually installed on a given system or if just the libraries are present? The latter can be found, of course, since we know the exact linker flags from pkg-config
, but from what I can tell there doesn't seem to be any metadata regarding the exact headers that a given package is supposed to provide? In the Vulkan case it is vulkan/vulkan.h
, but with GLFW it is GLFW/glfw3.h
.
No, in the vulkan case it is NOT vulkan/vulkan.h
, that is the problem. vulkan.pc is installed by a different software project than vulkan.h actually.
There is a "vulkan-loader" package built from https://github.com/KhronosGroup/Vulkan-Loader/ which provides a pkg-config file teaching projects how to correctly link to libvulkan.so, and a vulkan-headers package built from https://github.com/KhronosGroup/Vulkan-Headers which has no pkg-config file, may be installed in a different prefix, may not be installed at all other than as a build-dep of vulkan-loader...
I don't understand what the intention is here or how this is expected to be implemented by distributors, but it seems rather incompletely specified.
As for pkg-config, the presence of a pkg-config file says that all files which it provides an interface for, are installed. Actually checking for individual header files is called "hacky and inaccurate heuristics", but usually works relatively okayish. But how do you know that all the headers are installed rather than just one of them??? How do you know that the library works, maybe you should check for the symbols it contains. Maybe you should check for all the symbols? Where does it end?
...
glfw provides both glfw3.h and libglfw.so in https://github.com/glfw/glfw
Okay, I think I got it. This is basically what I meant with "This seems to be deferred to the package managers of the distributions", as in the way the files are packaged and distributed should make sure that if you have the .pc
file you also get the libraries and headers and so on, which is the case with GLFW, since it includes everything, but not with Vulkan, since there are separate packages for the loader and the headers, and the .pc
file comes with the loader package.
I guess one could make a distinction being able to link with a library and having the header file so that you compile against it, and that it's not clear if having a .pc
file for the library should always imply that you can both, so maybe this is Khronos' take?
(to be clear, I think it's perfectly clear and that Vulkan is in the wrong here)
Actually checking for individual header files is called "hacky and inaccurate heuristics", but usually works relatively okayish.
Right, I wasn't actually suggesting that Meson should do this, I just wasn't sure how any build system looking at .pc
files were supposed to infer which headers are available since there is no information in them about headers.
Anyways, thanks for the clarifications!
Vulkan headers not found After configuring, meson reports that
vulkan
dependency is satisfied:but building by invoking
ninja
fails with this error:the gtk4
meson.build
file already include a test for vulkanI'm on
Manjaro/Gnome 3.38/X11
system.meson version: 0.56.0
ninja version: 1.10.1
Python 3.8.6
After installing
vulkan-headers
package the failure is resolved.