We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`dependency('vulkan', version: ['>=1.X.X'])` fails on Windows
**Describe the bug**
`dependency('vulkan',  version: ['>=1.3.0'])` fails on Windows if a version is specified.
The Vulkan SDK is installed, and the environment variable (`VULKAN_SDK=C:\VulkanSDK\1.3.250.1`) is set.

Edit: The same does work on Linux.

**To Reproduce**
Install a recent Vulkan SDK (>= 1.3.0) and use this meson.build:
```python
project('test-project', 'cpp')

# this does not work
vulkan = dependency('vulkan', version: ['>=1.3.0'])
# this does work
# vulkan = dependency('vulkan')

executable('test-project', ['main.cpp'], dependencies : [vulkan])
```

**Expected behavior**
Vulkan is detected correctly.

**system parameters**
* native build
* Windows 11
* Python 3.9.13
* Meson 1.2.0
* Ninja 1.11.0


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mesonbuild/dependencies/ui.py`
Content:
```
1 # Copyright 2013-2017 The Meson development team
2 
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 # This file contains the detection logic for external dependencies that
16 # are UI-related.
17 from __future__ import annotations
18 
19 import os
20 import subprocess
21 import typing as T
22 
23 from .. import mlog
24 from .. import mesonlib
25 from ..mesonlib import (
26     Popen_safe, extract_as_list, version_compare_many
27 )
28 from ..environment import detect_cpu_family
29 
30 from .base import DependencyException, DependencyMethods, DependencyTypeName, SystemDependency
31 from .configtool import ConfigToolDependency
32 from .detect import packages
33 from .factory import DependencyFactory
34 
35 if T.TYPE_CHECKING:
36     from ..environment import Environment
37 
38 
39 class GLDependencySystem(SystemDependency):
40     def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
41         super().__init__(name, environment, kwargs)
42 
43         if self.env.machines[self.for_machine].is_darwin():
44             self.is_found = True
45             # FIXME: Use AppleFrameworks dependency
46             self.link_args = ['-framework', 'OpenGL']
47             # FIXME: Detect version using self.clib_compiler
48             return
49         elif self.env.machines[self.for_machine].is_windows():
50             self.is_found = True
51             # FIXME: Use self.clib_compiler.find_library()
52             self.link_args = ['-lopengl32']
53             # FIXME: Detect version using self.clib_compiler
54             return
55         else:
56             links = self.clib_compiler.find_library('GL', environment, [])
57             has_header = self.clib_compiler.has_header('GL/gl.h', '', environment)[0]
58             if links and has_header:
59                 self.is_found = True
60                 self.link_args = links
61             elif links:
62                 raise DependencyException('Found GL runtime library but no development header files')
63 
64 class GnuStepDependency(ConfigToolDependency):
65 
66     tools = ['gnustep-config']
67     tool_name = 'gnustep-config'
68 
69     def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
70         super().__init__('gnustep', environment, kwargs, language='objc')
71         if not self.is_found:
72             return
73         self.modules = kwargs.get('modules', [])
74         self.compile_args = self.filter_args(
75             self.get_config_value(['--objc-flags'], 'compile_args'))
76         self.link_args = self.weird_filter(self.get_config_value(
77             ['--gui-libs' if 'gui' in self.modules else '--base-libs'],
78             'link_args'))
79 
80     def find_config(self, versions: T.Optional[T.List[str]] = None, returncode: int = 0) -> T.Tuple[T.Optional[T.List[str]], T.Optional[str]]:
81         tool = [self.tools[0]]
82         try:
83             p, out = Popen_safe(tool + ['--help'])[:2]
84         except (FileNotFoundError, PermissionError):
85             return (None, None)
86         if p.returncode != returncode:
87             return (None, None)
88         self.config = tool
89         found_version = self.detect_version()
90         if versions and not version_compare_many(found_version, versions)[0]:
91             return (None, found_version)
92 
93         return (tool, found_version)
94 
95     @staticmethod
96     def weird_filter(elems: T.List[str]) -> T.List[str]:
97         """When building packages, the output of the enclosing Make is
98         sometimes mixed among the subprocess output. I have no idea why. As a
99         hack filter out everything that is not a flag.
100         """
101         return [e for e in elems if e.startswith('-')]
102 
103     @staticmethod
104     def filter_args(args: T.List[str]) -> T.List[str]:
105         """gnustep-config returns a bunch of garbage args such as -O2 and so
106         on. Drop everything that is not needed.
107         """
108         result = []
109         for f in args:
110             if f.startswith('-D') \
111                     or f.startswith('-f') \
112                     or f.startswith('-I') \
113                     or f == '-pthread' \
114                     or (f.startswith('-W') and not f == '-Wall'):
115                 result.append(f)
116         return result
117 
118     def detect_version(self) -> str:
119         gmake = self.get_config_value(['--variable=GNUMAKE'], 'variable')[0]
120         makefile_dir = self.get_config_value(['--variable=GNUSTEP_MAKEFILES'], 'variable')[0]
121         # This Makefile has the GNUStep version set
122         base_make = os.path.join(makefile_dir, 'Additional', 'base.make')
123         # Print the Makefile variable passed as the argument. For instance, if
124         # you run the make target `print-SOME_VARIABLE`, this will print the
125         # value of the variable `SOME_VARIABLE`.
126         printver = "print-%:\n\t@echo '$($*)'"
127         env = os.environ.copy()
128         # See base.make to understand why this is set
129         env['FOUNDATION_LIB'] = 'gnu'
130         p, o, e = Popen_safe([gmake, '-f', '-', '-f', base_make,
131                               'print-GNUSTEP_BASE_VERSION'],
132                              env=env, write=printver, stdin=subprocess.PIPE)
133         version = o.strip()
134         if not version:
135             mlog.debug("Couldn't detect GNUStep version, falling back to '1'")
136             # Fallback to setting some 1.x version
137             version = '1'
138         return version
139 
140 packages['gnustep'] = GnuStepDependency
141 
142 
143 class SDL2DependencyConfigTool(ConfigToolDependency):
144 
145     tools = ['sdl2-config']
146     tool_name = 'sdl2-config'
147 
148     def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
149         super().__init__(name, environment, kwargs)
150         if not self.is_found:
151             return
152         self.compile_args = self.get_config_value(['--cflags'], 'compile_args')
153         self.link_args = self.get_config_value(['--libs'], 'link_args')
154 
155 
156 class WxDependency(ConfigToolDependency):
157 
158     tools = ['wx-config-3.0', 'wx-config-3.1', 'wx-config', 'wx-config-gtk3']
159     tool_name = 'wx-config'
160 
161     def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
162         super().__init__('WxWidgets', environment, kwargs, language='cpp')
163         if not self.is_found:
164             return
165         self.requested_modules = self.get_requested(kwargs)
166 
167         extra_args = []
168         if self.static:
169             extra_args.append('--static=yes')
170 
171             # Check to make sure static is going to work
172             err = Popen_safe(self.config + extra_args)[2]
173             if 'No config found to match' in err:
174                 mlog.debug('WxWidgets is missing static libraries.')
175                 self.is_found = False
176                 return
177 
178         # wx-config seems to have a cflags as well but since it requires C++,
179         # this should be good, at least for now.
180         self.compile_args = self.get_config_value(['--cxxflags'] + extra_args + self.requested_modules, 'compile_args')
181         self.link_args = self.get_config_value(['--libs'] + extra_args + self.requested_modules, 'link_args')
182 
183     @staticmethod
184     def get_requested(kwargs: T.Dict[str, T.Any]) -> T.List[str]:
185         if 'modules' not in kwargs:
186             return []
187         candidates = extract_as_list(kwargs, 'modules')
188         for c in candidates:
189             if not isinstance(c, str):
190                 raise DependencyException('wxwidgets module argument is not a string')
191         return candidates
192 
193 packages['wxwidgets'] = WxDependency
194 
195 class VulkanDependencySystem(SystemDependency):
196 
197     def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None) -> None:
198         super().__init__(name, environment, kwargs, language=language)
199 
200         try:
201             self.vulkan_sdk = os.environ['VULKAN_SDK']
202             if not os.path.isabs(self.vulkan_sdk):
203                 raise DependencyException('VULKAN_SDK must be an absolute path.')
204         except KeyError:
205             self.vulkan_sdk = None
206 
207         if self.vulkan_sdk:
208             # TODO: this config might not work on some platforms, fix bugs as reported
209             # we should at least detect other 64-bit platforms (e.g. armv8)
210             lib_name = 'vulkan'
211             lib_dir = 'lib'
212             inc_dir = 'include'
213             if mesonlib.is_windows():
214                 lib_name = 'vulkan-1'
215                 lib_dir = 'Lib32'
216                 inc_dir = 'Include'
217                 if detect_cpu_family(self.env.coredata.compilers.host) == 'x86_64':
218                     lib_dir = 'Lib'
219 
220             # make sure header and lib are valid
221             inc_path = os.path.join(self.vulkan_sdk, inc_dir)
222             header = os.path.join(inc_path, 'vulkan', 'vulkan.h')
223             lib_path = os.path.join(self.vulkan_sdk, lib_dir)
224             find_lib = self.clib_compiler.find_library(lib_name, environment, [lib_path])
225 
226             if not find_lib:
227                 raise DependencyException('VULKAN_SDK point to invalid directory (no lib)')
228 
229             if not os.path.isfile(header):
230                 raise DependencyException('VULKAN_SDK point to invalid directory (no include)')
231 
232             # XXX: this is very odd, and may deserve being removed
233             self.type_name = DependencyTypeName('vulkan_sdk')
234             self.is_found = True
235             self.compile_args.append('-I' + inc_path)
236             self.link_args.append('-L' + lib_path)
237             self.link_args.append('-l' + lib_name)
238 
239             # TODO: find a way to retrieve the version from the sdk?
240             # Usually it is a part of the path to it (but does not have to be)
241             return
242         else:
243             # simply try to guess it, usually works on linux
244             libs = self.clib_compiler.find_library('vulkan', environment, [])
245             if libs is not None and self.clib_compiler.has_header('vulkan/vulkan.h', '', environment, disable_cache=True)[0]:
246                 self.is_found = True
247                 for lib in libs:
248                     self.link_args.append(lib)
249                 return
250 
251 packages['gl'] = gl_factory = DependencyFactory(
252     'gl',
253     [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM],
254     system_class=GLDependencySystem,
255 )
256 
257 packages['sdl2'] = sdl2_factory = DependencyFactory(
258     'sdl2',
259     [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.EXTRAFRAMEWORK, DependencyMethods.CMAKE],
260     configtool_class=SDL2DependencyConfigTool,
261     cmake_name='SDL2',
262 )
263 
264 packages['vulkan'] = vulkan_factory = DependencyFactory(
265     'vulkan',
266     [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM],
267     system_class=VulkanDependencySystem,
268 )
269
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -17,11 +17,13 @@
 from __future__ import annotations
 
 import os
+import re
 import subprocess
 import typing as T
 
 from .. import mlog
 from .. import mesonlib
+from ..compilers.compilers import CrossNoRunException
 from ..mesonlib import (
     Popen_safe, extract_as_list, version_compare_many
 )
@@ -235,10 +237,6 @@
             self.compile_args.append('-I' + inc_path)
             self.link_args.append('-L' + lib_path)
             self.link_args.append('-l' + lib_name)
-
-            # TODO: find a way to retrieve the version from the sdk?
-            # Usually it is a part of the path to it (but does not have to be)
-            return
         else:
             # simply try to guess it, usually works on linux
             libs = self.clib_compiler.find_library('vulkan', environment, [])
@@ -246,7 +244,33 @@
                 self.is_found = True
                 for lib in libs:
                     self.link_args.append(lib)
-                return
+
+        if self.is_found:
+            get_version = '''\
+#include <stdio.h>
+#include <vulkan/vulkan.h>
+
+int main() {
+    printf("%i.%i.%i", VK_VERSION_MAJOR(VK_HEADER_VERSION_COMPLETE),
+                       VK_VERSION_MINOR(VK_HEADER_VERSION_COMPLETE),
+                       VK_VERSION_PATCH(VK_HEADER_VERSION_COMPLETE));
+    return 0;
+}
+'''
+            try:
+                run = self.clib_compiler.run(get_version, environment, extra_args=self.compile_args)
+            except CrossNoRunException:
+                run = None
+            if run and run.compiled and run.returncode == 0:
+                self.version = run.stdout
+            elif self.vulkan_sdk:
+                # fall back to heuristics: detect version number in path
+                # matches the default install path on Windows
+                match = re.search(rf'VulkanSDK{re.escape(os.path.sep)}([0-9]+(?:\.[0-9]+)+)', self.vulkan_sdk)
+                if match:
+                    self.version = match.group(1)
+                else:
+                    mlog.warning(f'Environment variable VULKAN_SDK={self.vulkan_sdk} is present, but Vulkan version could not be extracted.')
 
 packages['gl'] = gl_factory = DependencyFactory(
     'gl',

{"golden_diff": "diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py\n--- a/mesonbuild/dependencies/ui.py\n+++ b/mesonbuild/dependencies/ui.py\n@@ -17,11 +17,13 @@\n from __future__ import annotations\n \n import os\n+import re\n import subprocess\n import typing as T\n \n from .. import mlog\n from .. import mesonlib\n+from ..compilers.compilers import CrossNoRunException\n from ..mesonlib import (\n     Popen_safe, extract_as_list, version_compare_many\n )\n@@ -235,10 +237,6 @@\n             self.compile_args.append('-I' + inc_path)\n             self.link_args.append('-L' + lib_path)\n             self.link_args.append('-l' + lib_name)\n-\n-            # TODO: find a way to retrieve the version from the sdk?\n-            # Usually it is a part of the path to it (but does not have to be)\n-            return\n         else:\n             # simply try to guess it, usually works on linux\n             libs = self.clib_compiler.find_library('vulkan', environment, [])\n@@ -246,7 +244,33 @@\n                 self.is_found = True\n                 for lib in libs:\n                     self.link_args.append(lib)\n-                return\n+\n+        if self.is_found:\n+            get_version = '''\\\n+#include <stdio.h>\n+#include <vulkan/vulkan.h>\n+\n+int main() {\n+    printf(\"%i.%i.%i\", VK_VERSION_MAJOR(VK_HEADER_VERSION_COMPLETE),\n+                       VK_VERSION_MINOR(VK_HEADER_VERSION_COMPLETE),\n+                       VK_VERSION_PATCH(VK_HEADER_VERSION_COMPLETE));\n+    return 0;\n+}\n+'''\n+            try:\n+                run = self.clib_compiler.run(get_version, environment, extra_args=self.compile_args)\n+            except CrossNoRunException:\n+                run = None\n+            if run and run.compiled and run.returncode == 0:\n+                self.version = run.stdout\n+            elif self.vulkan_sdk:\n+                # fall back to heuristics: detect version number in path\n+                # matches the default install path on Windows\n+                match = re.search(rf'VulkanSDK{re.escape(os.path.sep)}([0-9]+(?:\\.[0-9]+)+)', self.vulkan_sdk)\n+                if match:\n+                    self.version = match.group(1)\n+                else:\n+                    mlog.warning(f'Environment variable VULKAN_SDK={self.vulkan_sdk} is present, but Vulkan version could not be extracted.')\n \n packages['gl'] = gl_factory = DependencyFactory(\n     'gl',\n", "issue": "`dependency('vulkan', version: ['>=1.X.X'])` fails on Windows\n**Describe the bug**\r\n`dependency('vulkan',  version: ['>=1.3.0'])` fails on Windows if a version is specified.\r\nThe Vulkan SDK is installed, and the environment variable (`VULKAN_SDK=C:\\VulkanSDK\\1.3.250.1`) is set.\r\n\r\nEdit: The same does work on Linux.\r\n\r\n**To Reproduce**\r\nInstall a recent Vulkan SDK (>= 1.3.0) and use this meson.build:\r\n```python\r\nproject('test-project', 'cpp')\r\n\r\n# this does not work\r\nvulkan = dependency('vulkan', version: ['>=1.3.0'])\r\n# this does work\r\n# vulkan = dependency('vulkan')\r\n\r\nexecutable('test-project', ['main.cpp'], dependencies : [vulkan])\r\n```\r\n\r\n**Expected behavior**\r\nVulkan is detected correctly.\r\n\r\n**system parameters**\r\n* native build\r\n* Windows 11\r\n* Python 3.9.13\r\n* Meson 1.2.0\r\n* Ninja 1.11.0\r\n\n", "before_files": [{"content": "# Copyright 2013-2017 The Meson development team\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# This file contains the detection logic for external dependencies that\n# are UI-related.\nfrom __future__ import annotations\n\nimport os\nimport subprocess\nimport typing as T\n\nfrom .. import mlog\nfrom .. import mesonlib\nfrom ..mesonlib import (\n    Popen_safe, extract_as_list, version_compare_many\n)\nfrom ..environment import detect_cpu_family\n\nfrom .base import DependencyException, DependencyMethods, DependencyTypeName, SystemDependency\nfrom .configtool import ConfigToolDependency\nfrom .detect import packages\nfrom .factory import DependencyFactory\n\nif T.TYPE_CHECKING:\n    from ..environment import Environment\n\n\nclass GLDependencySystem(SystemDependency):\n    def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:\n        super().__init__(name, environment, kwargs)\n\n        if self.env.machines[self.for_machine].is_darwin():\n            self.is_found = True\n            # FIXME: Use AppleFrameworks dependency\n            self.link_args = ['-framework', 'OpenGL']\n            # FIXME: Detect version using self.clib_compiler\n            return\n        elif self.env.machines[self.for_machine].is_windows():\n            self.is_found = True\n            # FIXME: Use self.clib_compiler.find_library()\n            self.link_args = ['-lopengl32']\n            # FIXME: Detect version using self.clib_compiler\n            return\n        else:\n            links = self.clib_compiler.find_library('GL', environment, [])\n            has_header = self.clib_compiler.has_header('GL/gl.h', '', environment)[0]\n            if links and has_header:\n                self.is_found = True\n                self.link_args = links\n            elif links:\n                raise DependencyException('Found GL runtime library but no development header files')\n\nclass GnuStepDependency(ConfigToolDependency):\n\n    tools = ['gnustep-config']\n    tool_name = 'gnustep-config'\n\n    def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:\n        super().__init__('gnustep', environment, kwargs, language='objc')\n        if not self.is_found:\n            return\n        self.modules = kwargs.get('modules', [])\n        self.compile_args = self.filter_args(\n            self.get_config_value(['--objc-flags'], 'compile_args'))\n        self.link_args = self.weird_filter(self.get_config_value(\n            ['--gui-libs' if 'gui' in self.modules else '--base-libs'],\n            'link_args'))\n\n    def find_config(self, versions: T.Optional[T.List[str]] = None, returncode: int = 0) -> T.Tuple[T.Optional[T.List[str]], T.Optional[str]]:\n        tool = [self.tools[0]]\n        try:\n            p, out = Popen_safe(tool + ['--help'])[:2]\n        except (FileNotFoundError, PermissionError):\n            return (None, None)\n        if p.returncode != returncode:\n            return (None, None)\n        self.config = tool\n        found_version = self.detect_version()\n        if versions and not version_compare_many(found_version, versions)[0]:\n            return (None, found_version)\n\n        return (tool, found_version)\n\n    @staticmethod\n    def weird_filter(elems: T.List[str]) -> T.List[str]:\n        \"\"\"When building packages, the output of the enclosing Make is\n        sometimes mixed among the subprocess output. I have no idea why. As a\n        hack filter out everything that is not a flag.\n        \"\"\"\n        return [e for e in elems if e.startswith('-')]\n\n    @staticmethod\n    def filter_args(args: T.List[str]) -> T.List[str]:\n        \"\"\"gnustep-config returns a bunch of garbage args such as -O2 and so\n        on. Drop everything that is not needed.\n        \"\"\"\n        result = []\n        for f in args:\n            if f.startswith('-D') \\\n                    or f.startswith('-f') \\\n                    or f.startswith('-I') \\\n                    or f == '-pthread' \\\n                    or (f.startswith('-W') and not f == '-Wall'):\n                result.append(f)\n        return result\n\n    def detect_version(self) -> str:\n        gmake = self.get_config_value(['--variable=GNUMAKE'], 'variable')[0]\n        makefile_dir = self.get_config_value(['--variable=GNUSTEP_MAKEFILES'], 'variable')[0]\n        # This Makefile has the GNUStep version set\n        base_make = os.path.join(makefile_dir, 'Additional', 'base.make')\n        # Print the Makefile variable passed as the argument. For instance, if\n        # you run the make target `print-SOME_VARIABLE`, this will print the\n        # value of the variable `SOME_VARIABLE`.\n        printver = \"print-%:\\n\\t@echo '$($*)'\"\n        env = os.environ.copy()\n        # See base.make to understand why this is set\n        env['FOUNDATION_LIB'] = 'gnu'\n        p, o, e = Popen_safe([gmake, '-f', '-', '-f', base_make,\n                              'print-GNUSTEP_BASE_VERSION'],\n                             env=env, write=printver, stdin=subprocess.PIPE)\n        version = o.strip()\n        if not version:\n            mlog.debug(\"Couldn't detect GNUStep version, falling back to '1'\")\n            # Fallback to setting some 1.x version\n            version = '1'\n        return version\n\npackages['gnustep'] = GnuStepDependency\n\n\nclass SDL2DependencyConfigTool(ConfigToolDependency):\n\n    tools = ['sdl2-config']\n    tool_name = 'sdl2-config'\n\n    def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):\n        super().__init__(name, environment, kwargs)\n        if not self.is_found:\n            return\n        self.compile_args = self.get_config_value(['--cflags'], 'compile_args')\n        self.link_args = self.get_config_value(['--libs'], 'link_args')\n\n\nclass WxDependency(ConfigToolDependency):\n\n    tools = ['wx-config-3.0', 'wx-config-3.1', 'wx-config', 'wx-config-gtk3']\n    tool_name = 'wx-config'\n\n    def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]):\n        super().__init__('WxWidgets', environment, kwargs, language='cpp')\n        if not self.is_found:\n            return\n        self.requested_modules = self.get_requested(kwargs)\n\n        extra_args = []\n        if self.static:\n            extra_args.append('--static=yes')\n\n            # Check to make sure static is going to work\n            err = Popen_safe(self.config + extra_args)[2]\n            if 'No config found to match' in err:\n                mlog.debug('WxWidgets is missing static libraries.')\n                self.is_found = False\n                return\n\n        # wx-config seems to have a cflags as well but since it requires C++,\n        # this should be good, at least for now.\n        self.compile_args = self.get_config_value(['--cxxflags'] + extra_args + self.requested_modules, 'compile_args')\n        self.link_args = self.get_config_value(['--libs'] + extra_args + self.requested_modules, 'link_args')\n\n    @staticmethod\n    def get_requested(kwargs: T.Dict[str, T.Any]) -> T.List[str]:\n        if 'modules' not in kwargs:\n            return []\n        candidates = extract_as_list(kwargs, 'modules')\n        for c in candidates:\n            if not isinstance(c, str):\n                raise DependencyException('wxwidgets module argument is not a string')\n        return candidates\n\npackages['wxwidgets'] = WxDependency\n\nclass VulkanDependencySystem(SystemDependency):\n\n    def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None) -> None:\n        super().__init__(name, environment, kwargs, language=language)\n\n        try:\n            self.vulkan_sdk = os.environ['VULKAN_SDK']\n            if not os.path.isabs(self.vulkan_sdk):\n                raise DependencyException('VULKAN_SDK must be an absolute path.')\n        except KeyError:\n            self.vulkan_sdk = None\n\n        if self.vulkan_sdk:\n            # TODO: this config might not work on some platforms, fix bugs as reported\n            # we should at least detect other 64-bit platforms (e.g. armv8)\n            lib_name = 'vulkan'\n            lib_dir = 'lib'\n            inc_dir = 'include'\n            if mesonlib.is_windows():\n                lib_name = 'vulkan-1'\n                lib_dir = 'Lib32'\n                inc_dir = 'Include'\n                if detect_cpu_family(self.env.coredata.compilers.host) == 'x86_64':\n                    lib_dir = 'Lib'\n\n            # make sure header and lib are valid\n            inc_path = os.path.join(self.vulkan_sdk, inc_dir)\n            header = os.path.join(inc_path, 'vulkan', 'vulkan.h')\n            lib_path = os.path.join(self.vulkan_sdk, lib_dir)\n            find_lib = self.clib_compiler.find_library(lib_name, environment, [lib_path])\n\n            if not find_lib:\n                raise DependencyException('VULKAN_SDK point to invalid directory (no lib)')\n\n            if not os.path.isfile(header):\n                raise DependencyException('VULKAN_SDK point to invalid directory (no include)')\n\n            # XXX: this is very odd, and may deserve being removed\n            self.type_name = DependencyTypeName('vulkan_sdk')\n            self.is_found = True\n            self.compile_args.append('-I' + inc_path)\n            self.link_args.append('-L' + lib_path)\n            self.link_args.append('-l' + lib_name)\n\n            # TODO: find a way to retrieve the version from the sdk?\n            # Usually it is a part of the path to it (but does not have to be)\n            return\n        else:\n            # simply try to guess it, usually works on linux\n            libs = self.clib_compiler.find_library('vulkan', environment, [])\n            if libs is not None and self.clib_compiler.has_header('vulkan/vulkan.h', '', environment, disable_cache=True)[0]:\n                self.is_found = True\n                for lib in libs:\n                    self.link_args.append(lib)\n                return\n\npackages['gl'] = gl_factory = DependencyFactory(\n    'gl',\n    [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM],\n    system_class=GLDependencySystem,\n)\n\npackages['sdl2'] = sdl2_factory = DependencyFactory(\n    'sdl2',\n    [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.EXTRAFRAMEWORK, DependencyMethods.CMAKE],\n    configtool_class=SDL2DependencyConfigTool,\n    cmake_name='SDL2',\n)\n\npackages['vulkan'] = vulkan_factory = DependencyFactory(\n    'vulkan',\n    [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM],\n    system_class=VulkanDependencySystem,\n)\n", "path": "mesonbuild/dependencies/ui.py"}], "after_files": [{"content": "# Copyright 2013-2017 The Meson development team\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# This file contains the detection logic for external dependencies that\n# are UI-related.\nfrom __future__ import annotations\n\nimport os\nimport re\nimport subprocess\nimport typing as T\n\nfrom .. import mlog\nfrom .. import mesonlib\nfrom ..compilers.compilers import CrossNoRunException\nfrom ..mesonlib import (\n    Popen_safe, extract_as_list, version_compare_many\n)\nfrom ..environment import detect_cpu_family\n\nfrom .base import DependencyException, DependencyMethods, DependencyTypeName, SystemDependency\nfrom .configtool import ConfigToolDependency\nfrom .detect import packages\nfrom .factory import DependencyFactory\n\nif T.TYPE_CHECKING:\n    from ..environment import Environment\n\n\nclass GLDependencySystem(SystemDependency):\n    def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:\n        super().__init__(name, environment, kwargs)\n\n        if self.env.machines[self.for_machine].is_darwin():\n            self.is_found = True\n            # FIXME: Use AppleFrameworks dependency\n            self.link_args = ['-framework', 'OpenGL']\n            # FIXME: Detect version using self.clib_compiler\n            return\n        elif self.env.machines[self.for_machine].is_windows():\n            self.is_found = True\n            # FIXME: Use self.clib_compiler.find_library()\n            self.link_args = ['-lopengl32']\n            # FIXME: Detect version using self.clib_compiler\n            return\n        else:\n            links = self.clib_compiler.find_library('GL', environment, [])\n            has_header = self.clib_compiler.has_header('GL/gl.h', '', environment)[0]\n            if links and has_header:\n                self.is_found = True\n                self.link_args = links\n            elif links:\n                raise DependencyException('Found GL runtime library but no development header files')\n\nclass GnuStepDependency(ConfigToolDependency):\n\n    tools = ['gnustep-config']\n    tool_name = 'gnustep-config'\n\n    def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:\n        super().__init__('gnustep', environment, kwargs, language='objc')\n        if not self.is_found:\n            return\n        self.modules = kwargs.get('modules', [])\n        self.compile_args = self.filter_args(\n            self.get_config_value(['--objc-flags'], 'compile_args'))\n        self.link_args = self.weird_filter(self.get_config_value(\n            ['--gui-libs' if 'gui' in self.modules else '--base-libs'],\n            'link_args'))\n\n    def find_config(self, versions: T.Optional[T.List[str]] = None, returncode: int = 0) -> T.Tuple[T.Optional[T.List[str]], T.Optional[str]]:\n        tool = [self.tools[0]]\n        try:\n            p, out = Popen_safe(tool + ['--help'])[:2]\n        except (FileNotFoundError, PermissionError):\n            return (None, None)\n        if p.returncode != returncode:\n            return (None, None)\n        self.config = tool\n        found_version = self.detect_version()\n        if versions and not version_compare_many(found_version, versions)[0]:\n            return (None, found_version)\n\n        return (tool, found_version)\n\n    @staticmethod\n    def weird_filter(elems: T.List[str]) -> T.List[str]:\n        \"\"\"When building packages, the output of the enclosing Make is\n        sometimes mixed among the subprocess output. I have no idea why. As a\n        hack filter out everything that is not a flag.\n        \"\"\"\n        return [e for e in elems if e.startswith('-')]\n\n    @staticmethod\n    def filter_args(args: T.List[str]) -> T.List[str]:\n        \"\"\"gnustep-config returns a bunch of garbage args such as -O2 and so\n        on. Drop everything that is not needed.\n        \"\"\"\n        result = []\n        for f in args:\n            if f.startswith('-D') \\\n                    or f.startswith('-f') \\\n                    or f.startswith('-I') \\\n                    or f == '-pthread' \\\n                    or (f.startswith('-W') and not f == '-Wall'):\n                result.append(f)\n        return result\n\n    def detect_version(self) -> str:\n        gmake = self.get_config_value(['--variable=GNUMAKE'], 'variable')[0]\n        makefile_dir = self.get_config_value(['--variable=GNUSTEP_MAKEFILES'], 'variable')[0]\n        # This Makefile has the GNUStep version set\n        base_make = os.path.join(makefile_dir, 'Additional', 'base.make')\n        # Print the Makefile variable passed as the argument. For instance, if\n        # you run the make target `print-SOME_VARIABLE`, this will print the\n        # value of the variable `SOME_VARIABLE`.\n        printver = \"print-%:\\n\\t@echo '$($*)'\"\n        env = os.environ.copy()\n        # See base.make to understand why this is set\n        env['FOUNDATION_LIB'] = 'gnu'\n        p, o, e = Popen_safe([gmake, '-f', '-', '-f', base_make,\n                              'print-GNUSTEP_BASE_VERSION'],\n                             env=env, write=printver, stdin=subprocess.PIPE)\n        version = o.strip()\n        if not version:\n            mlog.debug(\"Couldn't detect GNUStep version, falling back to '1'\")\n            # Fallback to setting some 1.x version\n            version = '1'\n        return version\n\npackages['gnustep'] = GnuStepDependency\n\n\nclass SDL2DependencyConfigTool(ConfigToolDependency):\n\n    tools = ['sdl2-config']\n    tool_name = 'sdl2-config'\n\n    def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):\n        super().__init__(name, environment, kwargs)\n        if not self.is_found:\n            return\n        self.compile_args = self.get_config_value(['--cflags'], 'compile_args')\n        self.link_args = self.get_config_value(['--libs'], 'link_args')\n\n\nclass WxDependency(ConfigToolDependency):\n\n    tools = ['wx-config-3.0', 'wx-config-3.1', 'wx-config', 'wx-config-gtk3']\n    tool_name = 'wx-config'\n\n    def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]):\n        super().__init__('WxWidgets', environment, kwargs, language='cpp')\n        if not self.is_found:\n            return\n        self.requested_modules = self.get_requested(kwargs)\n\n        extra_args = []\n        if self.static:\n            extra_args.append('--static=yes')\n\n            # Check to make sure static is going to work\n            err = Popen_safe(self.config + extra_args)[2]\n            if 'No config found to match' in err:\n                mlog.debug('WxWidgets is missing static libraries.')\n                self.is_found = False\n                return\n\n        # wx-config seems to have a cflags as well but since it requires C++,\n        # this should be good, at least for now.\n        self.compile_args = self.get_config_value(['--cxxflags'] + extra_args + self.requested_modules, 'compile_args')\n        self.link_args = self.get_config_value(['--libs'] + extra_args + self.requested_modules, 'link_args')\n\n    @staticmethod\n    def get_requested(kwargs: T.Dict[str, T.Any]) -> T.List[str]:\n        if 'modules' not in kwargs:\n            return []\n        candidates = extract_as_list(kwargs, 'modules')\n        for c in candidates:\n            if not isinstance(c, str):\n                raise DependencyException('wxwidgets module argument is not a string')\n        return candidates\n\npackages['wxwidgets'] = WxDependency\n\nclass VulkanDependencySystem(SystemDependency):\n\n    def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None) -> None:\n        super().__init__(name, environment, kwargs, language=language)\n\n        try:\n            self.vulkan_sdk = os.environ['VULKAN_SDK']\n            if not os.path.isabs(self.vulkan_sdk):\n                raise DependencyException('VULKAN_SDK must be an absolute path.')\n        except KeyError:\n            self.vulkan_sdk = None\n\n        if self.vulkan_sdk:\n            # TODO: this config might not work on some platforms, fix bugs as reported\n            # we should at least detect other 64-bit platforms (e.g. armv8)\n            lib_name = 'vulkan'\n            lib_dir = 'lib'\n            inc_dir = 'include'\n            if mesonlib.is_windows():\n                lib_name = 'vulkan-1'\n                lib_dir = 'Lib32'\n                inc_dir = 'Include'\n                if detect_cpu_family(self.env.coredata.compilers.host) == 'x86_64':\n                    lib_dir = 'Lib'\n\n            # make sure header and lib are valid\n            inc_path = os.path.join(self.vulkan_sdk, inc_dir)\n            header = os.path.join(inc_path, 'vulkan', 'vulkan.h')\n            lib_path = os.path.join(self.vulkan_sdk, lib_dir)\n            find_lib = self.clib_compiler.find_library(lib_name, environment, [lib_path])\n\n            if not find_lib:\n                raise DependencyException('VULKAN_SDK point to invalid directory (no lib)')\n\n            if not os.path.isfile(header):\n                raise DependencyException('VULKAN_SDK point to invalid directory (no include)')\n\n            # XXX: this is very odd, and may deserve being removed\n            self.type_name = DependencyTypeName('vulkan_sdk')\n            self.is_found = True\n            self.compile_args.append('-I' + inc_path)\n            self.link_args.append('-L' + lib_path)\n            self.link_args.append('-l' + lib_name)\n        else:\n            # simply try to guess it, usually works on linux\n            libs = self.clib_compiler.find_library('vulkan', environment, [])\n            if libs is not None and self.clib_compiler.has_header('vulkan/vulkan.h', '', environment, disable_cache=True)[0]:\n                self.is_found = True\n                for lib in libs:\n                    self.link_args.append(lib)\n\n        if self.is_found:\n            get_version = '''\\\n#include <stdio.h>\n#include <vulkan/vulkan.h>\n\nint main() {\n    printf(\"%i.%i.%i\", VK_VERSION_MAJOR(VK_HEADER_VERSION_COMPLETE),\n                       VK_VERSION_MINOR(VK_HEADER_VERSION_COMPLETE),\n                       VK_VERSION_PATCH(VK_HEADER_VERSION_COMPLETE));\n    return 0;\n}\n'''\n            try:\n                run = self.clib_compiler.run(get_version, environment, extra_args=self.compile_args)\n            except CrossNoRunException:\n                run = None\n            if run and run.compiled and run.returncode == 0:\n                self.version = run.stdout\n            elif self.vulkan_sdk:\n                # fall back to heuristics: detect version number in path\n                # matches the default install path on Windows\n                match = re.search(rf'VulkanSDK{re.escape(os.path.sep)}([0-9]+(?:\\.[0-9]+)+)', self.vulkan_sdk)\n                if match:\n                    self.version = match.group(1)\n                else:\n                    mlog.warning(f'Environment variable VULKAN_SDK={self.vulkan_sdk} is present, but Vulkan version could not be extracted.')\n\npackages['gl'] = gl_factory = DependencyFactory(\n    'gl',\n    [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM],\n    system_class=GLDependencySystem,\n)\n\npackages['sdl2'] = sdl2_factory = DependencyFactory(\n    'sdl2',\n    [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.EXTRAFRAMEWORK, DependencyMethods.CMAKE],\n    configtool_class=SDL2DependencyConfigTool,\n    cmake_name='SDL2',\n)\n\npackages['vulkan'] = vulkan_factory = DependencyFactory(\n    'vulkan',\n    [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM],\n    system_class=VulkanDependencySystem,\n)\n", "path": "mesonbuild/dependencies/ui.py"}]}