• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright © 2017-2020 Intel Corporation
2# SPDX-License-Identifier: MIT
3
4project(
5  'mesa',
6  ['c', 'cpp'],
7  version : files('VERSION'),
8  license : 'MIT',
9  meson_version : '>= 1.1.0',
10  default_options : [
11    'buildtype=debugoptimized',
12    'b_ndebug=if-release',
13    'c_std=c11',
14    'cpp_std=c++17',
15    'rust_std=2021',
16    'build.rust_std=2021',
17  ],
18)
19
20if host_machine.system() == 'darwin'
21  add_languages('objc', native : false)
22  add_project_arguments('-fobjc-arc', language : 'objc')
23  libname_suffix = 'dylib'
24elif host_machine.system() == 'windows'
25  libname_suffix = 'dll'
26else
27  libname_suffix = 'so'
28endif
29
30cc = meson.get_compiler('c')
31cpp = meson.get_compiler('cpp')
32
33sizeof_pointer = cc.sizeof('void*').to_string()
34
35null_dep = dependency('', required : false)
36
37if get_option('layout') != 'mirror'
38  error('`mirror` is the only build directory layout supported')
39endif
40
41with_mesa_debug = get_option('buildtype') == 'debug'
42
43# This means the final value of b_ndebug==true
44with_mesa_ndebug = get_option('b_ndebug') == 'true' or (get_option('buildtype') == 'release' and get_option('b_ndebug') == 'if-release')
45
46# Arguments for the preprocessor, put these in a separate array from the C and
47# C++ (cpp in meson terminology) arguments since they need to be added to the
48# default arguments for both C and C++.
49pre_args = [
50  '-D__STDC_CONSTANT_MACROS',
51  '-D__STDC_FORMAT_MACROS',
52  '-D__STDC_LIMIT_MACROS',
53  '-DPACKAGE_VERSION="@0@"'.format(meson.project_version()),
54  '-DPACKAGE_BUGREPORT="https://gitlab.freedesktop.org/mesa/mesa/-/issues"',
55]
56# Arguments for c or cpp compiler, can be compiler options
57c_cpp_args = []
58
59c_args = []
60cpp_args = []
61
62with_moltenvk_dir = get_option('moltenvk-dir')
63with_vulkan_icd_dir = get_option('vulkan-icd-dir')
64with_tests = get_option('build-tests')
65with_glcpp_tests = get_option('enable-glcpp-tests')
66with_aco_tests = get_option('build-aco-tests')
67with_glx_read_only_text = get_option('glx-read-only-text')
68with_glx_direct = get_option('glx-direct')
69with_osmesa = get_option('osmesa')
70with_vulkan_overlay_layer = get_option('vulkan-layers').contains('overlay')
71with_vulkan_device_select_layer = get_option('vulkan-layers').contains('device-select')
72with_vulkan_screenshot_layer = get_option('vulkan-layers').contains('screenshot')
73with_tools = get_option('tools')
74if with_tools.contains('all')
75  with_tools = [
76    'drm-shim',
77    'dlclose-skip',
78    'etnaviv',
79    'freedreno',
80    'glsl',
81    'intel',
82    'intel-ui',
83    'lima',
84    'nir',
85    'nouveau',
86    'asahi',
87    'imagination',
88  ]
89endif
90
91with_any_vulkan_layers = get_option('vulkan-layers').length() != 0
92with_intel_tools = with_tools.contains('intel') or with_tools.contains('intel-ui')
93with_imgui = with_intel_tools or with_vulkan_overlay_layer
94
95dri_drivers_path = get_option('dri-drivers-path')
96if dri_drivers_path == ''
97  dri_drivers_path = join_paths(get_option('prefix'), get_option('libdir'), 'dri')
98endif
99
100gbm_backends_path = get_option('gbm-backends-path')
101if gbm_backends_path == ''
102  gbm_backends_path = join_paths(get_option('prefix'), get_option('libdir'), 'gbm')
103endif
104
105# Default shared glapi disabled for windows, enabled elsewhere.
106with_shared_glapi = get_option('shared-glapi') \
107  .disable_auto_if(host_machine.system() == 'windows') \
108  .allowed()
109
110with_opengl = get_option('opengl')
111
112with_gles1 = get_option('gles1') \
113  .require(with_shared_glapi, error_message : 'OpengGL ES 1.x requires shared-glapi') \
114  .allowed()
115
116with_gles2 = get_option('gles2') \
117  .require(with_shared_glapi, error_message : 'OpengGL ES 2.x requires shared-glapi') \
118  .allowed()
119
120pre_args += '-DHAVE_OPENGL=@0@'.format(with_opengl.to_int())
121pre_args += '-DHAVE_OPENGL_ES_1=@0@'.format(with_gles1.to_int())
122pre_args += '-DHAVE_OPENGL_ES_2=@0@'.format(with_gles2.to_int())
123
124with_any_opengl = with_opengl or with_gles1 or with_gles2
125# Only build shared_glapi if at least one OpenGL API is enabled
126with_shared_glapi = with_shared_glapi and with_any_opengl
127
128system_has_kms_drm = ['openbsd', 'netbsd', 'freebsd', 'gnu/kfreebsd', 'dragonfly', 'linux', 'sunos', 'android', 'managarm'].contains(host_machine.system())
129
130gallium_drivers = get_option('gallium-drivers')
131if gallium_drivers.contains('auto')
132  if system_has_kms_drm
133    # TODO: Sparc
134    if ['x86', 'x86_64'].contains(host_machine.cpu_family())
135      gallium_drivers = [
136        'r300', 'r600', 'radeonsi', 'nouveau', 'virgl', 'svga', 'llvmpipe', 'softpipe',
137        'iris', 'crocus', 'i915', 'zink'
138      ]
139    elif ['arm', 'aarch64'].contains(host_machine.cpu_family())
140      gallium_drivers = [
141        'v3d', 'vc4', 'freedreno', 'etnaviv', 'nouveau', 'svga',
142        'tegra', 'virgl', 'lima', 'panfrost', 'llvmpipe', 'softpipe', 'iris',
143        'zink'
144      ]
145    elif ['mips', 'mips64', 'ppc', 'ppc64', 'riscv32', 'riscv64'].contains(host_machine.cpu_family())
146      gallium_drivers = [
147        'r300', 'r600', 'radeonsi', 'nouveau', 'virgl', 'llvmpipe', 'softpipe', 'zink'
148      ]
149    elif ['loongarch64'].contains(host_machine.cpu_family())
150      gallium_drivers = [
151        'r300', 'r600', 'radeonsi', 'nouveau', 'virgl', 'etnaviv', 'llvmpipe', 'softpipe', 'zink'
152      ]
153    else
154      error('Unknown architecture @0@. Please pass -Dgallium-drivers to set driver options. Patches gladly accepted to fix this.'.format(
155            host_machine.cpu_family()))
156    endif
157  elif ['windows'].contains(host_machine.system())
158    gallium_drivers = ['llvmpipe', 'softpipe', 'zink', 'd3d12']
159  elif ['darwin', 'cygwin', 'haiku'].contains(host_machine.system())
160    gallium_drivers = ['llvmpipe', 'softpipe']
161  else
162    error('Unknown OS @0@. Please pass -Dgallium-drivers to set driver options. Patches gladly accepted to fix this.'.format(
163          host_machine.system()))
164  endif
165elif gallium_drivers.contains('all')
166   # Build-test everything except for i915, which depends on libdrm-intel which
167   # is not available on non-Intel distros.
168   gallium_drivers = [
169     'r300', 'r600', 'radeonsi', 'crocus', 'v3d', 'vc4', 'freedreno', 'etnaviv',
170     'nouveau', 'svga', 'tegra', 'virgl', 'lima', 'panfrost', 'llvmpipe', 'softpipe', 'iris',
171     'zink', 'd3d12', 'asahi'
172   ]
173endif
174
175# compatibility for meson configurations asking for 'swrast'
176with_swrast = gallium_drivers.contains('swrast')
177if with_swrast
178  warning('`gallium-drivers=swrast` is a deprecated alias for `gallium-drivers=softpipe,llvmpipe` and will be removed in version 25.0')
179endif
180
181with_amdgpu_virtio = get_option('amdgpu-virtio')
182
183with_gallium_radeonsi = gallium_drivers.contains('radeonsi')
184with_gallium_r300 = gallium_drivers.contains('r300')
185with_gallium_r600 = gallium_drivers.contains('r600')
186with_gallium_nouveau = gallium_drivers.contains('nouveau')
187with_gallium_freedreno = gallium_drivers.contains('freedreno')
188with_gallium_softpipe = with_swrast or gallium_drivers.contains('softpipe')
189with_gallium_llvmpipe = with_swrast or gallium_drivers.contains('llvmpipe')
190with_gallium_vc4 = gallium_drivers.contains('vc4')
191with_gallium_v3d = gallium_drivers.contains('v3d')
192with_gallium_panfrost = gallium_drivers.contains('panfrost')
193with_gallium_etnaviv = gallium_drivers.contains('etnaviv')
194with_gallium_tegra = gallium_drivers.contains('tegra')
195with_gallium_crocus = gallium_drivers.contains('crocus')
196with_gallium_iris = gallium_drivers.contains('iris')
197with_gallium_i915 = gallium_drivers.contains('i915')
198with_gallium_svga = gallium_drivers.contains('svga')
199with_gallium_virgl = gallium_drivers.contains('virgl')
200with_gallium_lima = gallium_drivers.contains('lima')
201with_gallium_zink = gallium_drivers.contains('zink')
202with_gallium_d3d12 = gallium_drivers.contains('d3d12')
203with_gallium_asahi = gallium_drivers.contains('asahi')
204foreach gallium_driver : gallium_drivers
205  pre_args += '-DHAVE_@0@'.format(gallium_driver.to_upper())
206endforeach
207
208# compatibility for "swrast" as an internal-ish driver name
209with_gallium_swrast = with_gallium_softpipe or with_gallium_llvmpipe
210if with_gallium_swrast
211  pre_args += '-DHAVE_SWRAST'
212endif
213
214with_gallium = gallium_drivers.length() != 0
215with_gallium_kmsro = system_has_kms_drm and [
216  with_gallium_asahi,
217  with_gallium_etnaviv,
218  with_gallium_freedreno,
219  with_gallium_lima,
220  with_gallium_panfrost,
221  with_gallium_v3d,
222  with_gallium_vc4,
223].contains(true)
224
225_vulkan_drivers = get_option('vulkan-drivers')
226if _vulkan_drivers.contains('auto')
227  if system_has_kms_drm
228    if host_machine.cpu_family().startswith('x86')
229      _vulkan_drivers = ['amd', 'intel', 'intel_hasvk', 'nouveau', 'swrast']
230    elif ['arm', 'aarch64'].contains(host_machine.cpu_family())
231      _vulkan_drivers = ['swrast', 'intel']
232    elif ['mips', 'mips64', 'ppc', 'ppc64', 'riscv32', 'riscv64'].contains(host_machine.cpu_family())
233      _vulkan_drivers = ['amd', 'swrast']
234    elif ['loongarch64'].contains(host_machine.cpu_family())
235      _vulkan_drivers = ['amd', 'swrast']
236    else
237      error('Unknown architecture @0@. Please pass -Dvulkan-drivers to set driver options. Patches gladly accepted to fix this.'.format(
238            host_machine.cpu_family()))
239    endif
240  elif ['darwin', 'windows', 'cygwin', 'haiku'].contains(host_machine.system())
241    # No vulkan driver supports windows or macOS currently
242    _vulkan_drivers = []
243  else
244    error('Unknown OS @0@. Please pass -Dvulkan-drivers to set driver options. Patches gladly accepted to fix this.'.format(
245          host_machine.system()))
246  endif
247elif _vulkan_drivers.contains('all')
248   # Build every vulkan driver regardless of architecture.
249   _vulkan_drivers = ['amd', 'intel', 'intel_hasvk', 'swrast',
250                      'freedreno', 'panfrost', 'virtio', 'broadcom',
251                      'imagination-experimental', 'microsoft-experimental',
252                      'nouveau', 'asahi', 'gfxstream']
253endif
254
255with_intel_vk = _vulkan_drivers.contains('intel')
256with_intel_hasvk = _vulkan_drivers.contains('intel_hasvk')
257with_amd_vk = _vulkan_drivers.contains('amd')
258with_freedreno_vk = _vulkan_drivers.contains('freedreno')
259with_panfrost_vk = _vulkan_drivers.contains('panfrost')
260with_swrast_vk = _vulkan_drivers.contains('swrast')
261with_virtio_vk = _vulkan_drivers.contains('virtio')
262with_broadcom_vk = _vulkan_drivers.contains('broadcom')
263with_imagination_vk = _vulkan_drivers.contains('imagination-experimental')
264with_imagination_srv = get_option('imagination-srv')
265with_microsoft_vk = _vulkan_drivers.contains('microsoft-experimental')
266with_nouveau_vk = _vulkan_drivers.contains('nouveau')
267with_asahi_vk = _vulkan_drivers.contains('asahi')
268with_gfxstream_vk = _vulkan_drivers.contains('gfxstream')
269with_any_vk = _vulkan_drivers.length() != 0
270
271if with_any_vk and host_machine.system() == 'windows' and meson.version().version_compare('< 1.3')
272  error('Vulkan drivers on Windows require meson 1.3 or newer')
273endif
274
275with_any_llvmpipe = with_gallium_llvmpipe or with_swrast_vk
276with_gallium_or_lvp = with_gallium or with_swrast_vk
277
278freedreno_kmds = get_option('freedreno-kmds')
279if freedreno_kmds.length() != 0 and freedreno_kmds != [ 'msm' ] and with_freedreno_vk
280  if freedreno_kmds.contains('msm')
281      warning('Turnip with the DRM KMD will require libdrm to always be present at runtime which may not always be the case on platforms such as Android.')
282  elif with_gallium_kmsro
283      warning('As a side-effect, Turnip is forced to link with libdrm when built alongside Gallium DRM drivers which platforms such as Android may not have available at runtime.')
284  elif _vulkan_drivers != [ 'freedreno' ]
285      warning('Turnip is forced to link with libdrm when built alongside other Vulkan drivers which platforms such as Android may not have available at runtime.')
286  else
287    # If DRM support isn't needed, we can get rid of it since linking
288    # to libdrm can be a potential compatibility hazard.
289    system_has_kms_drm = false
290  endif
291endif
292
293with_dri = false
294if with_gallium and system_has_kms_drm
295  _glx = get_option('glx')
296  _egl = get_option('egl')
297  if _glx == 'dri' or _egl.enabled() or (_glx == 'disabled' and _egl.allowed())
298    with_dri = true
299  endif
300endif
301
302with_any_broadcom = [
303  with_gallium_vc4,
304  with_gallium_v3d,
305  with_broadcom_vk,
306].contains(true)
307
308if get_option('intel-clc') != 'system' and get_option('precomp-compiler') != 'system'
309  # Require intel-clc with Anv & Iris (for internal shaders)
310  with_intel_clc = get_option('intel-clc') == 'enabled' or \
311                   get_option('precomp-compiler') == 'enabled' or \
312                   with_intel_vk or with_gallium_iris
313else
314  with_intel_clc = false
315endif
316
317with_intel_vk_rt = get_option('intel-rt') \
318  .disable_auto_if(not with_intel_vk) \
319  .disable_if(host_machine.cpu_family() != 'x86_64', error_message : 'Intel Ray Tracing is only supported on x86_64') \
320  .allowed()
321
322if with_intel_vk_rt
323  with_intel_bvh_grl = get_option('intel-bvh-grl')
324endif
325
326with_any_intel = [
327  with_gallium_crocus,
328  with_gallium_i915,
329  with_gallium_iris,
330  with_intel_clc,
331  with_intel_hasvk,
332  with_intel_tools,
333  with_intel_vk,
334].contains(true)
335with_any_nouveau = with_gallium_nouveau or with_nouveau_vk
336
337# needed in the loader
338if with_nouveau_vk
339  pre_args += '-DHAVE_NVK'
340endif
341
342if with_gallium_tegra and not with_gallium_nouveau
343  error('tegra driver requires nouveau driver')
344endif
345if with_aco_tests and not with_amd_vk
346  error('ACO tests require Radv')
347endif
348
349with_microsoft_clc = get_option('microsoft-clc').enabled()
350with_spirv_to_dxil = get_option('spirv-to-dxil')
351
352if host_machine.system() == 'darwin'
353  with_dri_platform = 'apple'
354  pre_args += '-DBUILDING_MESA'
355elif ['windows', 'cygwin'].contains(host_machine.system())
356  with_dri_platform = 'windows'
357elif system_has_kms_drm
358  with_dri_platform = 'drm'
359else
360  # FIXME: haiku doesn't use dri, and xlib doesn't use dri, probably should
361  # assert here that one of those cases has been met.
362  # FIXME: illumos ends up here as well
363  with_dri_platform = 'none'
364endif
365
366with_vulkan_beta = get_option('vulkan-beta')
367if host_machine.system() == 'darwin'
368  #macOS seems to need beta extensions to build for now:
369  with_vulkan_beta = true
370endif
371if with_vulkan_beta
372  pre_args += '-DVK_ENABLE_BETA_EXTENSIONS'
373endif
374
375_codecs = get_option('video-codecs')
376patent_codecs = ['vc1dec', 'h264dec', 'h264enc', 'h265dec', 'h265enc']
377free_codecs = ['av1dec', 'av1enc', 'vp9dec']
378all_codecs = patent_codecs + free_codecs
379
380if _codecs.contains('all')
381  _codecs = all_codecs
382elif _codecs.contains('all_free')
383  selected_codecs = _codecs
384  _codecs = free_codecs
385  foreach c : patent_codecs
386    if selected_codecs.contains(c)
387      _codecs += c
388    endif
389  endforeach
390endif
391foreach c : all_codecs
392   pre_args += '-DVIDEO_CODEC_@0@=@1@'.format(c.to_upper(), _codecs.contains(c).to_int())
393endforeach
394
395_platforms = get_option('platforms')
396if _platforms.contains('auto')
397  if system_has_kms_drm
398    _platforms = ['x11', 'wayland']
399  elif host_machine.system() == 'cygwin'
400    _platforms = ['x11']
401  elif host_machine.system() == 'haiku'
402    _platforms = ['haiku']
403  elif host_machine.system() == 'windows'
404    _platforms = ['windows']
405  elif host_machine.system() == 'darwin'
406    _platforms = ['x11', 'macos']
407  else
408    error('Unknown OS @0@. Please pass -Dplatforms to set platforms. Patches gladly accepted to fix this.'.format(
409          host_machine.system()))
410  endif
411endif
412
413with_platform_android = _platforms.contains('android')
414with_platform_x11 = _platforms.contains('x11')
415with_platform_xcb = _platforms.contains('xcb')
416with_platform_wayland = _platforms.contains('wayland')
417with_platform_haiku = _platforms.contains('haiku')
418with_platform_windows = _platforms.contains('windows')
419with_platform_macos = _platforms.contains('macos')
420
421with_glx = get_option('glx')
422if with_glx == 'auto'
423  if not with_opengl
424    with_glx = 'disabled'
425  elif with_platform_android
426    with_glx = 'disabled'
427  elif with_dri
428    with_glx = 'dri'
429  elif with_platform_haiku
430    with_glx = 'disabled'
431  elif host_machine.system() == 'windows'
432    with_glx = 'disabled'
433  elif with_gallium
434    # Even when building just gallium drivers the user probably wants dri
435    with_glx = 'dri'
436  elif with_platform_x11 and with_any_opengl and not with_any_vk
437    # The automatic behavior should not be to turn on xlib based glx when
438    # building only vulkan drivers
439    with_glx = 'xlib'
440  else
441    with_glx = 'disabled'
442  endif
443endif
444if with_glx == 'dri'
445   if with_gallium
446      with_dri = true
447   endif
448endif
449
450if not with_opengl and with_glx != 'disabled'
451  error('Building GLX without OpenGL is not supported.')
452endif
453
454if not (with_dri or with_gallium or with_glx != 'disabled')
455  with_gles1 = false
456  with_gles2 = false
457  with_opengl = false
458  with_any_opengl = false
459  with_shared_glapi = false
460endif
461
462with_gbm = get_option('gbm') \
463  .require(system_has_kms_drm, error_message : 'GBM only supports DRM/KMS platforms') \
464  .disable_auto_if(not with_dri) \
465  .allowed()
466
467with_xlib_lease = get_option('xlib-lease') \
468  .require(with_platform_x11 and (system_has_kms_drm or with_dri_platform == 'apple'), error_message : 'xlib-lease requires X11 and KMS/DRM support') \
469  .allowed()
470
471with_egl = get_option('egl') \
472  .require(with_platform_windows or with_platform_haiku or with_dri or with_platform_android, error_message : 'EGL requires DRI, Haiku, Windows or Android') \
473  .require(with_shared_glapi, error_message : 'EGL requires shared-glapi') \
474  .require(with_glx != 'xlib', error_message :'EGL requires DRI, but GLX is being built with xlib support') \
475  .disable_auto_if(with_platform_haiku) \
476  .allowed()
477
478if with_egl
479  _platforms += 'surfaceless'
480  if with_gbm and not with_platform_android
481    _platforms += 'drm'
482  endif
483
484  egl_native_platform = get_option('egl-native-platform')
485  if egl_native_platform.contains('auto')
486    egl_native_platform = _platforms[0]
487  endif
488endif
489
490if with_egl and not _platforms.contains(egl_native_platform)
491  error('-Degl-native-platform does not specify an enabled platform')
492endif
493
494if 'x11' in _platforms
495  _platforms += 'xcb'
496endif
497
498foreach platform : _platforms
499  pre_args += '-DHAVE_@0@_PLATFORM'.format(platform.to_upper())
500endforeach
501
502if with_platform_android and get_option('platform-sdk-version') >= 29
503  # By default the NDK compiler, at least, emits emutls references instead of
504  # ELF TLS, even when building targeting newer API levels.  Make it actually do
505  # ELF TLS instead.
506  c_cpp_args += '-fno-emulated-tls'
507  add_project_link_arguments('-Wl,-plugin-opt=-emulated-tls=0', language: ['c', 'cpp'])
508endif
509
510# -mtls-dialect=gnu2 speeds up non-initial-exec TLS significantly but requires
511# full toolchain (including libc) support.
512have_mtls_dialect = false
513foreach c_arg : get_option('c_args')
514  if c_arg.startswith('-mtls-dialect=')
515    have_mtls_dialect = true
516    break
517  endif
518endforeach
519if not have_mtls_dialect
520  # need .run to check libc support. meson aborts when calling .run when
521  # cross-compiling, but because this is just an optimization we can skip it
522  if meson.is_cross_build() and not meson.can_run_host_binaries()
523    warning('cannot auto-detect -mtls-dialect when cross-compiling, using compiler default')
524  else
525    # The way to specify the TLSDESC dialect is architecture-specific.
526    # We probe both because there is not a fallback guaranteed to work for all
527    # future architectures.
528    foreach tlsdesc_arg : ['-mtls-dialect=gnu2', '-mtls-dialect=desc']
529      # -fpic to force dynamic tls, otherwise TLS relaxation defeats check
530      tlsdesc_test = cc.run('int __thread x; int main() { return x; }',
531                            args: [tlsdesc_arg, '-fpic'],
532                            name: tlsdesc_arg)
533      if tlsdesc_test.returncode() == 0 and (
534            # check for lld 13 bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5665
535            host_machine.cpu_family() != 'x86_64' or
536            # get_linker_id misses LDFLAGS=-fuse-ld=lld: https://github.com/mesonbuild/meson/issues/6377
537            #cc.get_linker_id() != 'ld.lld' or
538            cc.links('''int __thread x; int y; int main() { __asm__(
539                  "leaq x@TLSDESC(%rip), %rax\n"
540                  "movq y@GOTPCREL(%rip), %rdx\n"
541                  "call *x@TLSCALL(%rax)\n"); }''', name: 'split TLSDESC')
542            )
543        c_cpp_args += tlsdesc_arg
544        break
545      endif
546    endforeach
547  endif
548endif
549
550if with_glx != 'disabled'
551  if not (with_platform_x11 and with_any_opengl)
552    error('Cannot build GLX support without X11 platform support and at least one OpenGL API')
553  elif with_glx == 'xlib'
554    if not with_gallium
555      error('xlib based GLX requires at least one gallium driver')
556    elif not with_gallium_swrast
557      error('xlib based GLX requires softpipe or llvmpipe.')
558    elif with_dri
559      error('xlib conflicts with any dri driver')
560    endif
561  elif with_glx == 'dri'
562    if not with_shared_glapi
563      error('dri based GLX requires shared-glapi')
564    endif
565  endif
566endif
567
568_glvnd = get_option('glvnd') \
569  .require(not with_platform_windows,
570           error_message: 'glvnd cannot be used on Windows') \
571  .require(with_glx != 'xlib',
572           error_message: 'Cannot build glvnd support for GLX that is not DRI based.') \
573  .require(with_glx != 'disabled' or with_egl,
574           error_message: 'glvnd requires DRI based GLX and/or EGL') \
575  .require(get_option('egl-lib-suffix') == '',
576           error_message: '''EGL lib suffix can't be used with libglvnd''')
577dep_glvnd = dependency('libglvnd', version : '>= 1.3.2', required : _glvnd)
578with_glvnd = dep_glvnd.found()
579pre_args += '-DUSE_LIBGLVND=@0@'.format(with_glvnd.to_int())
580glvnd_vendor_name = get_option('glvnd-vendor-name')
581
582if with_vulkan_icd_dir == ''
583  with_vulkan_icd_dir = join_paths(get_option('datadir'), 'vulkan/icd.d')
584endif
585
586with_dri2 = (with_dri or with_any_vk) and (with_dri_platform == 'drm' or with_dri_platform == 'apple')
587
588with_x11_dri2 = with_dri2 and get_option('legacy-x11').contains('dri2')
589
590if with_dri
591  if with_glx == 'disabled' and not with_egl and not with_gbm
592    error('building dri drivers require at least one windowing system')
593  endif
594endif
595
596dep_dxheaders = null_dep
597if with_gallium_d3d12 or with_microsoft_clc or with_microsoft_vk or with_gfxstream_vk and host_machine.system() == 'windows'
598  dep_dxheaders = dependency('directx-headers', required : false)
599  if not dep_dxheaders.found()
600    dep_dxheaders = dependency('DirectX-Headers',
601      version : '>= 1.614.1',
602      fallback : ['DirectX-Headers', 'dep_dxheaders'],
603      required : with_gallium_d3d12 or with_microsoft_vk
604    )
605  endif
606endif
607
608_with_gallium_d3d12_video = get_option('gallium-d3d12-video')
609with_gallium_d3d12_video = false
610if with_gallium_d3d12 and not _with_gallium_d3d12_video.disabled()
611  with_gallium_d3d12_video = true
612  pre_args += '-DHAVE_GALLIUM_D3D12_VIDEO'
613endif
614
615_vdpau_drivers = [
616  with_gallium_d3d12_video,
617  with_gallium_nouveau,
618  with_gallium_r600,
619  with_gallium_radeonsi,
620  with_gallium_virgl,
621]
622
623vdpau = get_option('gallium-vdpau') \
624  .require(system_has_kms_drm, error_message : 'VDPAU state tracker can only be build on unix-like OSes.') \
625  .require(with_platform_x11, error_message : 'VDPAU state tracker requires X11 support.') \
626  .require(_vdpau_drivers.contains(true), error_message : 'VDPAU state tracker requires at least one of the following gallium drivers: r600, radeonsi, nouveau, d3d12 (with option gallium-d3d12-video, virgl).')
627
628dep_vdpau = dependency('vdpau', version : '>= 1.5', required : vdpau)
629if dep_vdpau.found()
630  dep_vdpau = dep_vdpau.partial_dependency(compile_args : true)
631  pre_args += '-DHAVE_ST_VDPAU'
632endif
633with_gallium_vdpau = dep_vdpau.found()
634
635vdpau_drivers_path = get_option('vdpau-libs-path')
636if vdpau_drivers_path == ''
637  vdpau_drivers_path = join_paths(get_option('libdir'), 'vdpau')
638endif
639
640# GLSL has interesting version output and Meson doesn't parse it correctly as of
641# Meson 1.4.0
642prog_glslang = find_program(
643  'glslangValidator',
644  native : true,
645  required : with_vulkan_overlay_layer or with_aco_tests or with_amd_vk or with_intel_vk or with_swrast_vk
646)
647
648if prog_glslang.found()
649  # Check if glslang has depfile support. Support was added in 11.3.0, but
650  # Windows path support was broken until 11.9.0.
651  #
652  # It is intentional to check the build machine, since we need to ensure that
653  # glslang will output valid paths on the build platform
654  _glslang_check = build_machine.system() == 'windows' ? '>= 11.9.0' : '>= 11.3.0'
655  if run_command(prog_glslang, ['--version'], check : false).stdout().split(':')[2].version_compare(_glslang_check)
656    glslang_depfile = ['--depfile', '@DEPFILE@']
657  else
658    glslang_depfile = []
659  endif
660  if run_command(prog_glslang, [ '--quiet', '--version' ], check : false).returncode() == 0
661    glslang_quiet = ['--quiet']
662  else
663    glslang_quiet = []
664  endif
665endif
666
667_va_drivers = [
668  with_gallium_d3d12_video,
669  with_gallium_nouveau,
670  with_gallium_r600,
671  with_gallium_radeonsi,
672  with_gallium_virgl,
673]
674
675_va = get_option('gallium-va') \
676  .require(_va_drivers.contains(true),
677           error_message : 'VA state tracker requires at least one of the following gallium drivers: r600, radeonsi, nouveau, d3d12 (with option gallium-d3d12-video), virgl.')
678_dep_va_name = host_machine.system() == 'windows' ? 'libva-win32' : 'libva'
679dep_va = dependency(_dep_va_name, version : '>= 1.8.0', required : _va)
680if dep_va.found()
681  dep_va_headers = dep_va.partial_dependency(compile_args : true)
682  if cc.has_header_symbol('va/va.h', 'VASurfaceAttribDRMFormatModifiers',
683                          dependencies: dep_va_headers)
684    pre_args += '-DHAVE_VA_SURFACE_ATTRIB_DRM_FORMAT_MODIFIERS'
685  endif
686endif
687with_gallium_va = dep_va.found()
688
689va_drivers_path = get_option('va-libs-path')
690if va_drivers_path == ''
691  va_drivers_path = join_paths(get_option('libdir'), 'dri')
692endif
693
694with_gallium_xa = get_option('gallium-xa') \
695  .require(system_has_kms_drm, error_message : 'XA state tracker can only be built on unix-like OSes.') \
696  .require(with_gallium_nouveau or with_gallium_freedreno or with_gallium_i915 or with_gallium_svga,
697           error_message : 'XA state tracker requires at least one of the following gallium drivers: nouveau, freedreno, i915, svga.') \
698  .allowed()
699
700d3d_drivers_path = get_option('d3d-drivers-path')
701if d3d_drivers_path == ''
702  d3d_drivers_path = join_paths(get_option('prefix'), get_option('libdir'), 'd3d')
703endif
704
705with_gallium_st_nine =  get_option('gallium-nine')
706if with_gallium_st_nine
707  if not with_gallium_swrast
708    error('The nine state tracker requires gallium softpipe/llvmpipe.')
709  elif not [
710             with_gallium_crocus,
711             with_gallium_freedreno,
712             with_gallium_i915,
713             with_gallium_iris,
714             with_gallium_nouveau,
715             with_gallium_panfrost,
716             with_gallium_r300,
717             with_gallium_r600,
718             with_gallium_radeonsi,
719             with_gallium_svga,
720             with_gallium_zink,
721           ].contains(true)
722    error('The nine state tracker requires at least one non-swrast gallium driver.')
723  endif
724endif
725with_gallium_st_d3d10umd =  get_option('gallium-d3d10umd')
726if with_gallium_st_d3d10umd
727  if not with_gallium_swrast
728    error('The d3d10umd state tracker requires gallium softpipe/llvmpipe.')
729  endif
730endif
731_power8 = get_option('power8')
732if _power8.allowed()
733  if host_machine.cpu_family() == 'ppc64' and host_machine.endian() == 'little'
734    if cc.get_id() == 'gcc' and cc.version().version_compare('< 4.8')
735      error('Altivec is not supported with gcc version < 4.8.')
736    endif
737    if cc.compiles('''
738        #include <altivec.h>
739        int main() {
740          vector unsigned char r;
741          vector unsigned int v = vec_splat_u32 (1);
742          r = __builtin_vec_vgbbd ((vector unsigned char) v);
743          return 0;
744        }''',
745        args : '-mpower8-vector',
746        name : 'POWER8 intrinsics')
747      pre_args += ['-D_ARCH_PWR8']
748      c_cpp_args += '-mpower8-vector'
749    elif _power8.enabled()
750      error('POWER8 intrinsic support required but not found.')
751    endif
752  endif
753endif
754
755if get_option('vmware-mks-stats')
756  if not with_gallium_svga
757    error('vmware-mks-stats requires gallium VMware/svga driver.')
758  endif
759  pre_args += '-DVMX86_STATS=1'
760endif
761
762_opencl = get_option('gallium-opencl')
763_rtti = get_option('cpp_rtti')
764if _opencl != 'disabled'
765  if not with_gallium
766    error('OpenCL Clover implementation requires at least one gallium driver.')
767  endif
768  if not _rtti
769    error('The Clover OpenCL state tracker requires rtti')
770  endif
771
772  with_gallium_clover = true
773  with_opencl_icd = _opencl == 'icd'
774else
775  with_gallium_clover = false
776  with_opencl_icd = false
777endif
778
779with_gallium_rusticl = get_option('gallium-rusticl')
780if with_gallium_rusticl
781  if not with_gallium
782    error('rusticl requires at least one gallium driver.')
783  endif
784endif
785
786if with_gallium_rusticl or with_nouveau_vk or with_tools.contains('etnaviv')
787  if with_gallium_rusticl
788    # uses rust.bindgen.output_inline_wrapper needing 1.4.0
789    if meson.version().version_compare('< 1.4.0')
790      error('Rusticl requires meson 1.4.0 or newer')
791    endif
792  else
793    # see https://github.com/mesonbuild/meson/issues/12758 (backported to 1.3.2)
794    if meson.version().version_compare('< 1.3.2')
795      error('Mesa Rust support requires meson 1.3.2 or newer')
796    endif
797  endif
798
799  add_languages('rust', required: true)
800  rustc = meson.get_compiler('rust')
801  rust = import('rust')
802
803  if rustc.version().version_compare('< 1.78')
804    error('Mesa requires Rust 1.78.0 or newer')
805  endif
806
807  bindgen_version = find_program('bindgen').version()
808  if bindgen_version == 'unknown'
809    error('Failed to detect bindgen version. If you are using bindgen 0.69.0, ' +
810          'please either update to 0.69.1 or downgrade to 0.68.1. ' +
811          'You can install the latest version for your user with `cargo install bindgen-cli`.')
812  endif
813
814  if bindgen_version.version_compare('< 0.65')
815    error('Mesa requires bindgen 0.65 or newer. ' +
816          'If your distribution does not ship a recent enough version, ' +
817          'you can install the latest version for your user with `cargo install bindgen-cli`.')
818  endif
819endif
820
821if get_option('precomp-compiler') != 'system'
822  with_drivers_clc = get_option('precomp-compiler') == 'enabled'
823else
824  with_drivers_clc = false
825endif
826
827with_clc = get_option('mesa-clc') != 'auto' or with_microsoft_clc or with_intel_clc or with_drivers_clc or with_gallium_asahi or with_asahi_vk or with_gallium_rusticl
828
829dep_clc = null_dep
830if with_gallium_clover or with_clc
831  dep_clc = dependency('libclc')
832endif
833
834gl_pkgconfig_c_flags = []
835with_glx_indirect_rendering = false
836if with_platform_x11
837  if with_glx == 'xlib'
838    pre_args += '-DUSE_XSHM'
839  else
840    with_glx_indirect_rendering = true
841    pre_args += '-DGLX_INDIRECT_RENDERING'
842    if with_glx_direct
843      pre_args += '-DGLX_DIRECT_RENDERING'
844    endif
845    if with_dri_platform == 'drm'
846      pre_args += '-DGLX_USE_DRM'
847    elif with_dri_platform == 'apple'
848      pre_args += '-DGLX_USE_APPLEGL'
849      # Check to see if more than just the default 'swrast' is required
850      if (not with_gallium_softpipe) or 1 < gallium_drivers.length()
851        # Switch the MacOS code from "forwarding to the OpenGL.framework" mode
852        # and into actual Gallium Driver mode
853        pre_args += '-DGLX_USE_APPLE'
854      endif
855    elif with_dri_platform == 'windows'
856      pre_args += '-DGLX_USE_WINDOWSGL'
857    endif
858  endif
859endif
860
861with_glapi_export_proto_entry_points = false
862if with_shared_glapi and not with_glx_indirect_rendering
863  # Imply !defined(GLX_INDIRECT_RENDERING)
864  with_glapi_export_proto_entry_points = true
865endif
866pre_args += '-DGLAPI_EXPORT_PROTO_ENTRY_POINTS=@0@'.format(with_glapi_export_proto_entry_points.to_int())
867
868with_android_stub = get_option('android-stub')
869if with_android_stub and not with_platform_android
870  error('`-D android-stub=true` makes no sense without `-D platforms=android`')
871endif
872
873with_libbacktrace = get_option('android-libbacktrace') \
874  .require(with_platform_android, error_message : '`-D android-libbacktrace=enabled` makes no sense without `-D platforms=android`') \
875  .disable_auto_if(not with_platform_android) \
876  .allowed()
877
878if with_libbacktrace
879  cpp_args += '-DWITH_LIBBACKTRACE'
880endif
881
882if with_platform_android
883  dep_android_ui = null_dep
884  dep_android_mapper4 = null_dep
885  if not with_android_stub
886    dep_android = [
887      dependency('cutils'),
888      dependency('hardware'),
889      dependency('log'),
890      dependency('sync'),
891    ]
892    if with_libbacktrace
893      dep_android += dependency('backtrace')
894    endif
895    if get_option('platform-sdk-version') >= 26
896      dep_android += dependency('nativewindow')
897    endif
898    if get_option('platform-sdk-version') >= 30
899      dep_android_mapper4 = dependency('android.hardware.graphics.mapper', version : '>= 4.0', required : false)
900    endif
901    if get_option('platform-sdk-version') >= 35
902      dep_android_ui = dependency('ui', required : false)
903    endif
904  endif
905  pre_args += '-DANDROID_API_LEVEL=' + get_option('platform-sdk-version').to_string()
906  if get_option('android-strict')
907    pre_args += '-DANDROID_STRICT'
908  endif
909endif
910
911# On Android, seccomp kills the process on kernels without
912# CONFIG_KCMP/CONFIG_CHECKPOINT_RESTORE if it attemps to use KCMP.
913# Since we can't detect that, err on the side of caution and disable
914# KCMP by default on Android.
915if get_option('allow-kcmp') \
916    .disable_auto_if(with_platform_android) \
917    .allowed()
918  pre_args += '-DALLOW_KCMP'
919endif
920
921# On Windows, a venv has no versioned aliased to 'python'.
922prog_python = find_program('python3', 'python', version : '>= 3.8')
923
924has_mako = run_command(
925  prog_python, '-c',
926  '''
927try:
928  from packaging.version import Version
929except:
930  from distutils.version import StrictVersion as Version
931import mako
932assert Version(mako.__version__) >= Version("0.8.0")
933  ''', check: false)
934if has_mako.returncode() != 0
935  error('Python (3.x) mako module >= 0.8.0 required to build mesa.')
936endif
937
938has_yaml = run_command(
939  prog_python, '-c',
940  '''
941import yaml
942  ''', check: false)
943if has_yaml.returncode() != 0
944  error('Python (3.x) yaml module (PyYAML) required to build mesa.')
945endif
946
947if cc.get_id() == 'gcc' and cc.version().version_compare('< 4.4.6')
948  error('When using GCC, version 4.4.6 or later is required.')
949endif
950
951# Support systems without ETIME (e.g. FreeBSD)
952if cc.get_define('ETIME', prefix : '#include <errno.h>') == ''
953  pre_args += '-DETIME=ETIMEDOUT'
954endif
955
956# Define MESA_DEBUG to 1 for debug builds only (debugoptimized is not included on this one);
957# otherwise define MESA_DEBUG to 0
958pre_args += '-DMESA_DEBUG=@0@'.format(with_mesa_debug.to_int())
959
960with_split_debug = get_option('split-debug') \
961  .disable_if(not cc.has_argument('-gsplit-dwarf'),
962    error_message : 'split-debug requires compiler -gsplit-dwarf support') \
963  .disable_if(not cc.has_link_argument('-Wl,--gdb-index'),
964    error_message : 'split-debug requires the linker argument -Wl,--gdb-index')
965
966if with_split_debug.allowed() and get_option('debug')
967  add_project_arguments('-gsplit-dwarf', language : ['c', 'cpp'])
968  add_project_link_arguments('-Wl,--gdb-index', language : ['c', 'cpp'])
969endif
970
971with_shader_cache = get_option('shader-cache') \
972  .require(host_machine.system() != 'windows', error_message : 'Shader Cache does not currently work on Windows') \
973  .allowed()
974
975if with_shader_cache
976  pre_args += '-DENABLE_SHADER_CACHE'
977  if not get_option('shader-cache-default')
978    pre_args += '-DSHADER_CACHE_DISABLE_BY_DEFAULT'
979  endif
980
981  shader_cache_max_size = get_option('shader-cache-max-size')
982  if shader_cache_max_size != ''
983    pre_args += '-DMESA_SHADER_CACHE_MAX_SIZE="@0@"'.format(shader_cache_max_size)
984  endif
985endif
986
987# Check for GCC style builtins
988foreach b : ['bswap32', 'bswap64', 'clz', 'clzll', 'ctz', 'expect', 'ffs',
989             'ffsll', 'popcount', 'popcountll', 'unreachable', 'types_compatible_p']
990  if cc.has_function(b)
991    pre_args += '-DHAVE___BUILTIN_@0@'.format(b.to_upper())
992  endif
993endforeach
994
995# check for GCC __attribute__
996_attributes = [
997  'const', 'flatten', 'malloc', 'pure', 'unused', 'warn_unused_result',
998  'weak', 'format', 'packed', 'returns_nonnull', 'alias', 'noreturn',
999  'optimize',
1000]
1001foreach a : cc.get_supported_function_attributes(_attributes)
1002  pre_args += '-DHAVE_FUNC_ATTRIBUTE_@0@'.format(a.to_upper())
1003endforeach
1004if cc.has_function_attribute('visibility:hidden')
1005  pre_args += '-DHAVE_FUNC_ATTRIBUTE_VISIBILITY'
1006endif
1007if cc.compiles('__uint128_t foo(void) { return 0; }',
1008               name : '__uint128_t')
1009  pre_args += '-DHAVE_UINT128'
1010endif
1011
1012if cc.has_function('reallocarray')
1013   pre_args += '-DHAVE_REALLOCARRAY'
1014endif
1015if cc.has_function('fmemopen')
1016   pre_args += '-DHAVE_FMEMOPEN'
1017endif
1018
1019# TODO: this is very incomplete
1020if ['linux', 'cygwin', 'gnu', 'freebsd', 'gnu/kfreebsd', 'haiku', 'android', 'managarm'].contains(host_machine.system())
1021  pre_args += '-D_GNU_SOURCE'
1022elif host_machine.system() == 'sunos'
1023  pre_args += '-D__EXTENSIONS__'
1024elif host_machine.system() == 'windows'
1025  pre_args += [
1026    '-D_WINDOWS', '-D_WIN32_WINNT=0x0A00', '-DWINVER=0x0A00',
1027    '-DPIPE_SUBSYSTEM_WINDOWS_USER',
1028    '-D_USE_MATH_DEFINES',  # XXX: scons didn't use this for mingw
1029  ]
1030  if cc.get_argument_syntax() == 'msvc'
1031    pre_args += [
1032      '-DVC_EXTRALEAN',
1033      '-D_CRT_SECURE_NO_WARNINGS',
1034      '-D_CRT_SECURE_NO_DEPRECATE',
1035      '-D_SCL_SECURE_NO_WARNINGS',
1036      '-D_SCL_SECURE_NO_DEPRECATE',
1037      '-D_ALLOW_KEYWORD_MACROS',
1038      '-D_HAS_EXCEPTIONS=0', # Tell C++ STL to not use exceptions
1039      '-DNOMINMAX',
1040    ]
1041  else
1042    # When the target is not mingw/ucrt
1043    # NOTE: clang's stddef.h are conflict with mingw/ucrt's stddef.h
1044    # So do not include headers that defined in clang for detecting
1045    # _UCRT
1046    if cc.compiles('''
1047      #include <string.h>
1048      #if defined(__MINGW32__) && defined(_UCRT)
1049      #error
1050      #endif
1051      int main(void) { return 0; }''')
1052      pre_args += ['-D__MSVCRT_VERSION__=0x0700']
1053    endif
1054  endif
1055elif host_machine.system() == 'openbsd'
1056  pre_args += '-D_ISOC11_SOURCE'
1057endif
1058
1059# Check for generic C arguments
1060c_msvc_compat_args = []
1061no_override_init_args = []
1062cpp_msvc_compat_args = []
1063ld_args_gc_sections = []
1064if cc.get_argument_syntax() == 'msvc'
1065  _trial = [
1066    '/wd4018',  # signed/unsigned mismatch
1067    '/wd4056',  # overflow in floating-point constant arithmetic
1068    '/wd4244',  # conversion from 'type1' to 'type2', possible loss of data
1069    '/wd4267',  # 'var' : conversion from 'size_t' to 'type', possible loss of data
1070    '/wd4305',  # truncation from 'type1' to 'type2'
1071    '/wd4351',  # new behavior: elements of array 'array' will be default initialized
1072    '/wd4756',  # overflow in constant arithmetic
1073    '/wd4800',  # forcing value to bool 'true' or 'false' (performance warning)
1074    '/wd4996',  # disabled deprecated POSIX name warnings
1075    '/wd4291',  # no matching operator delete found
1076    '/wd4146',  # unary minus operator applied to unsigned type, result still unsigned
1077    '/wd4200',  # nonstandard extension used: zero-sized array in struct/union
1078    '/wd4624',  # destructor was implicitly defined as deleted [from LLVM]
1079    '/wd4309',  # 'initializing': truncation of constant value
1080    '/wd4838',  # conversion from 'int' to 'const char' requires a narrowing conversion
1081    '/wd5105',  # macro expansion producing 'defined' has undefined behavior (winbase.h, need Windows SDK upgrade)
1082    '/we4020',  # Error when passing the wrong number of parameters
1083    '/we4024',  # Error when passing different type of parameter
1084    '/we4189',  # 'identifier' : local variable is initialized but not referenced
1085    '/Zc:__cplusplus', #Set __cplusplus macro to match the /std:c++<version> on the command line
1086  ]
1087  c_args += cc.get_supported_arguments(_trial)
1088  cpp_args += cpp.get_supported_arguments(_trial)
1089else
1090  _trial_c = [
1091    '-Werror=implicit-function-declaration',
1092    '-Werror=missing-prototypes',
1093    '-Werror=return-type',
1094    '-Werror=empty-body',
1095    '-Werror=incompatible-pointer-types',
1096    '-Werror=int-conversion',
1097    '-Wimplicit-fallthrough',
1098    '-Wmisleading-indentation',
1099    '-Wno-missing-field-initializers',
1100    '-Wno-format-truncation',
1101    '-Wno-nonnull-compare',
1102    '-fno-math-errno',
1103    '-fno-trapping-math',
1104    '-Qunused-arguments',
1105    '-fno-common',
1106    '-Wno-unknown-pragmas',
1107    # Clang
1108    '-Wno-microsoft-enum-value',
1109    '-Wno-unused-function',
1110  ]
1111  _trial_cpp = [
1112    '-Werror=return-type',
1113    '-Werror=empty-body',
1114    '-Wmisleading-indentation',
1115    '-Wno-non-virtual-dtor',
1116    '-Wno-missing-field-initializers',
1117    '-Wno-format-truncation',
1118    '-fno-math-errno',
1119    '-fno-trapping-math',
1120    '-Qunused-arguments',
1121    # Some classes use custom new operator which zeroes memory, however
1122    # gcc does aggressive dead-store elimination which threats all writes
1123    # to the memory before the constructor as "dead stores".
1124    # For now we disable this optimization.
1125    '-flifetime-dse=1',
1126    '-Wno-unknown-pragmas',
1127    # Clang
1128    '-Wno-microsoft-enum-value',
1129  ]
1130
1131  # MinGW chokes on format specifiers and I can't get it all working
1132  if not (cc.get_argument_syntax() == 'gcc' and host_machine.system() == 'windows')
1133    _trial_c += ['-Werror=format', '-Wformat-security']
1134    _trial_cpp += ['-Werror=format', '-Wformat-security']
1135  endif
1136
1137  # FreeBSD annotated <pthread.h> but Mesa isn't ready
1138  if not (cc.get_id() == 'clang' and host_machine.system() == 'freebsd')
1139    _trial_c += ['-Werror=thread-safety']
1140  endif
1141
1142  # If the compiler supports it, put function and data symbols in their
1143  # own sections and GC the sections after linking.  This lets drivers
1144  # drop shared code unused by that specific driver (particularly
1145  # relevant for Vulkan drivers).
1146  if cc.links('static char unused() { return 5; } int main() { return 0; }',
1147              args : '-Wl,--gc-sections', name : 'gc-sections')
1148    ld_args_gc_sections += '-Wl,--gc-sections'
1149    _trial_c += ['-ffunction-sections', '-fdata-sections']
1150    _trial_cpp += ['-ffunction-sections', '-fdata-sections']
1151  endif
1152
1153  # Variables that are only used for assertions are considered unused when assertions
1154  # are disabled. Don't treat this as an error, since we build with -Werror even if
1155  # assertions are disabled.
1156  if with_mesa_ndebug
1157    _trial_c += ['-Wno-unused-variable', '-Wno-unused-but-set-variable', '/wd4189']
1158    _trial_cpp += ['-Wno-unused-variable', '-Wno-unused-but-set-variable', '/wd4189']
1159  endif
1160
1161  c_args += cc.get_supported_arguments(_trial_c)
1162  cpp_args += cpp.get_supported_arguments(_trial_cpp)
1163
1164  no_override_init_args += cc.get_supported_arguments(
1165    ['-Wno-override-init', '-Wno-initializer-overrides']
1166  )
1167
1168  # Check for C and C++ arguments for MSVC compatibility. These are only used
1169  # in parts of the mesa code base that need to compile with MSVC, mainly
1170  # common code
1171  _trial_msvc = ['-Werror=pointer-arith', '-Werror=vla', '-Werror=gnu-empty-initializer']
1172  c_msvc_compat_args += cc.get_supported_arguments(_trial_msvc)
1173  cpp_msvc_compat_args += cpp.get_supported_arguments(_trial_msvc)
1174endif
1175
1176# set linker arguments
1177if host_machine.system() == 'windows'
1178  if cc.get_argument_syntax() == 'msvc'
1179    add_project_link_arguments(
1180      '/fixed:no',
1181      '/dynamicbase',
1182      '/nxcompat',
1183      language : ['c', 'cpp'],
1184    )
1185    if get_option('buildtype') != 'debug'
1186      add_project_link_arguments(
1187        '/incremental:no',
1188        language : ['c', 'cpp'],
1189      )
1190    endif
1191  else
1192    add_project_link_arguments(
1193      cc.get_supported_link_arguments(
1194        '-Wl,--nxcompat',
1195        '-Wl,--dynamicbase',
1196        '-static-libgcc',
1197        '-static-libstdc++',
1198      ),
1199      language : ['c'],
1200    )
1201    add_project_link_arguments(
1202      cpp.get_supported_link_arguments(
1203        '-Wl,--nxcompat',
1204        '-Wl,--dynamicbase',
1205        '-static-libgcc',
1206        '-static-libstdc++',
1207      ),
1208      language : ['cpp'],
1209    )
1210  endif
1211endif
1212
1213sse2_arg = []
1214sse2_args = []
1215sse41_args = []
1216with_sse41 = false
1217if host_machine.cpu_family().startswith('x86')
1218  pre_args += '-DUSE_SSE41'
1219  with_sse41 = true
1220
1221  if cc.get_id() != 'msvc'
1222    sse41_args = ['-msse4.1']
1223
1224    if host_machine.cpu_family() == 'x86'
1225      # x86_64 have sse2 by default, so sse2 args only for x86
1226      sse2_arg = ['-msse2', '-mfpmath=sse']
1227      sse2_args = [sse2_arg, '-mstackrealign']
1228      if get_option('sse2')
1229        # These settings make generated GCC code match MSVC and follow
1230        # GCC advice on https://gcc.gnu.org/wiki/FloatingPointMath#x86note
1231        #
1232        # NOTE: We need to ensure stack is realigned given that we
1233        # produce shared objects, and have no control over the stack
1234        # alignment policy of the application. Therefore we need
1235        # -mstackrealign or -mincoming-stack-boundary=2.
1236        #
1237        # XXX: We could have SSE without -mstackrealign if we always used
1238        # __attribute__((force_align_arg_pointer)), but that's not
1239        # always the case.
1240        c_cpp_args += sse2_args
1241        # sse2_args are adopted into c_cpp_args to avoid duplicated sse2 command line args
1242        sse2_arg = []
1243        sse2_args = []
1244      else
1245        # GCC on x86 (not x86_64) with -msse* assumes a 16 byte aligned stack, but
1246        # that's not guaranteed
1247        sse41_args += '-mstackrealign'
1248      endif
1249    endif
1250  endif
1251endif
1252
1253# Detect __builtin_ia32_clflushopt support
1254if cc.has_function('__builtin_ia32_clflushopt', args : '-mclflushopt')
1255  pre_args += '-DHAVE___BUILTIN_IA32_CLFLUSHOPT'
1256  clflushopt_args = ['-mclflushopt']
1257  with_clflushopt = true
1258else
1259  clflushopt_args = []
1260  with_clflushopt = false
1261endif
1262
1263# Check for GCC style atomics
1264dep_atomic = null_dep
1265
1266if cc.compiles('''#include <stdint.h>
1267                  int main() {
1268                    struct {
1269                      uint64_t *v;
1270                    } x;
1271                    return (int)__atomic_load_n(x.v, __ATOMIC_ACQUIRE) &
1272                           (int)__atomic_add_fetch(x.v, (uint64_t)1, __ATOMIC_ACQ_REL);
1273
1274                  }''',
1275               name : 'GCC atomic builtins')
1276  pre_args += '-DUSE_GCC_ATOMIC_BUILTINS'
1277
1278  # Not all atomic calls can be turned into lock-free instructions, in which
1279  # GCC will make calls into the libatomic library. Check whether we need to
1280  # link with -latomic.
1281  #
1282  # This can happen for 64-bit atomic operations on 32-bit architectures such
1283  # as ARM.
1284  if not cc.links('''#include <stdint.h>
1285                     int main() {
1286                       struct {
1287                         uint64_t *v;
1288                       } x;
1289                       return (int)__atomic_load_n(x.v, __ATOMIC_ACQUIRE) &
1290                              (int)__atomic_add_fetch(x.v, (uint64_t)1, __ATOMIC_ACQ_REL);
1291                     }''',
1292                  name : 'GCC atomic builtins required -latomic')
1293    dep_atomic = cc.find_library('atomic')
1294  endif
1295endif
1296if not cc.links('''#include <stdint.h>
1297                   uint64_t v;
1298                   int main() {
1299                     return __sync_add_and_fetch(&v, (uint64_t)1);
1300                   }''',
1301                dependencies : dep_atomic,
1302                name : 'GCC 64bit atomics')
1303  pre_args += '-DMISSING_64BIT_ATOMICS'
1304endif
1305
1306dep_ws2_32 = cc.find_library('ws2_32', required : with_platform_windows)
1307
1308# TODO: shared/static? Is this even worth doing?
1309
1310with_asm_arch = ''
1311if host_machine.cpu_family() == 'x86'
1312  if system_has_kms_drm or host_machine.system() == 'gnu'
1313    with_asm_arch = 'x86'
1314    pre_args += ['-DUSE_X86_ASM']
1315
1316    if with_glx_read_only_text
1317      pre_args += ['-DGLX_X86_READONLY_TEXT']
1318    endif
1319  endif
1320elif host_machine.cpu_family() == 'x86_64'
1321  if system_has_kms_drm
1322    with_asm_arch = 'x86_64'
1323    pre_args += ['-DUSE_X86_64_ASM']
1324  endif
1325elif host_machine.cpu_family() == 'arm'
1326  if system_has_kms_drm
1327    with_asm_arch = 'arm'
1328    pre_args += ['-DUSE_ARM_ASM']
1329  endif
1330elif host_machine.cpu_family() == 'aarch64'
1331  if system_has_kms_drm
1332    with_asm_arch = 'aarch64'
1333    pre_args += ['-DUSE_AARCH64_ASM']
1334  endif
1335elif host_machine.cpu_family() == 'sparc64'
1336  if system_has_kms_drm
1337    with_asm_arch = 'sparc'
1338    pre_args += ['-DUSE_SPARC_ASM']
1339  endif
1340elif host_machine.cpu_family() == 'ppc64' and host_machine.endian() == 'little'
1341  if system_has_kms_drm
1342    with_asm_arch = 'ppc64le'
1343    pre_args += ['-DUSE_PPC64LE_ASM']
1344  endif
1345elif host_machine.cpu_family() == 'mips64' and host_machine.endian() == 'little'
1346  if system_has_kms_drm
1347    with_asm_arch = 'mips64el'
1348    pre_args += ['-DUSE_MIPS64EL_ASM']
1349  endif
1350elif host_machine.cpu_family() == 'loongarch64'
1351  if system_has_kms_drm
1352    with_asm_arch = 'loongarch64'
1353    pre_args += ['-DUSE_LOONGARCH64_ASM']
1354  endif
1355endif
1356
1357# Check for standard headers and functions
1358if (cc.has_header_symbol('sys/sysmacros.h', 'major') and
1359  cc.has_header_symbol('sys/sysmacros.h', 'minor') and
1360  cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1361  pre_args += '-DMAJOR_IN_SYSMACROS'
1362endif
1363if (cc.has_header_symbol('sys/mkdev.h', 'major') and
1364  cc.has_header_symbol('sys/mkdev.h', 'minor') and
1365  cc.has_header_symbol('sys/mkdev.h', 'makedev'))
1366  pre_args += '-DMAJOR_IN_MKDEV'
1367endif
1368
1369if cc.check_header('sched.h')
1370  pre_args += '-DHAS_SCHED_H'
1371  if cc.has_function('sched_getaffinity')
1372    pre_args += '-DHAS_SCHED_GETAFFINITY'
1373  endif
1374endif
1375
1376if not ['linux'].contains(host_machine.system())
1377  # Deprecated on Linux and requires <sys/types.h> on FreeBSD and OpenBSD
1378  if cc.check_header('sys/sysctl.h', prefix : '#include <sys/types.h>')
1379    pre_args += '-DHAVE_SYS_SYSCTL_H'
1380  endif
1381endif
1382
1383foreach h : ['xlocale.h', 'linux/futex.h', 'endian.h', 'dlfcn.h', 'sys/shm.h',
1384             'cet.h', 'pthread_np.h', 'sys/inotify.h', 'linux/udmabuf.h']
1385  if cc.check_header(h)
1386    pre_args += '-DHAVE_@0@'.format(h.to_upper().underscorify())
1387  endif
1388endforeach
1389
1390functions_to_detect = {
1391  'strtof': '',
1392  'mkostemp': '',
1393  'memfd_create': '',
1394  'random_r': '',
1395  'flock': '',
1396  'strtok_r': '',
1397  'getrandom': '',
1398  'qsort_s': '',
1399  'posix_fallocate': '',
1400  'secure_getenv': '',
1401}
1402
1403foreach f, prefix: functions_to_detect
1404  if cc.has_function(f, prefix: prefix)
1405    pre_args += '-DHAVE_@0@'.format(f.to_upper())
1406  endif
1407endforeach
1408
1409if cpp.links('''
1410    #define _GNU_SOURCE
1411    #include <stdlib.h>
1412
1413    static int dcomp(const void *l, const void *r, void *t) { return 0; }
1414
1415    int main(int ac, char **av) {
1416      int arr[] = { 1 };
1417      void *t = NULL;
1418      qsort_r((void*)&arr[0], 1, 1, dcomp, t);
1419      return (0);
1420    }''',
1421    args : pre_args,
1422    name : 'GNU qsort_r')
1423  pre_args += '-DHAVE_GNU_QSORT_R'
1424elif cpp.links('''
1425    #include <stdlib.h>
1426
1427    static int dcomp(void *t, const void *l, const void *r) { return 0; }
1428
1429    int main(int ac, char **av) {
1430      int arr[] = { 1 };
1431      void *t = NULL;
1432      qsort_r((void*)&arr[0], 1, 1, t, dcomp);
1433      return (0);
1434    }''',
1435    args : pre_args,
1436    name : 'BSD qsort_r')
1437  pre_args += '-DHAVE_BSD_QSORT_R'
1438endif
1439
1440if cc.has_header_symbol('time.h', 'struct timespec')
1441   pre_args += '-DHAVE_STRUCT_TIMESPEC'
1442endif
1443
1444with_c11_threads = false
1445if cc.has_function('thrd_create', prefix: '#include <threads.h>')
1446  if with_platform_android
1447    # Current only Android's c11 <threads.h> are verified
1448    pre_args += '-DHAVE_THRD_CREATE'
1449    with_c11_threads = true
1450  endif
1451endif
1452
1453if cc.has_header_symbol('errno.h', 'program_invocation_name',
1454                        args : '-D_GNU_SOURCE')
1455   pre_args += '-DHAVE_PROGRAM_INVOCATION_NAME'
1456elif with_tools.contains('intel')
1457  error('Intel tools require the program_invocation_name variable')
1458endif
1459
1460if cc.has_header_symbol('math.h', 'issignaling',
1461                        args : '-D_GNU_SOURCE')
1462   pre_args += '-DHAVE_ISSIGNALING'
1463endif
1464
1465# MinGW provides a __builtin_posix_memalign function, but not a posix_memalign.
1466# This means that this check will succeed, but then compilation will later
1467# fail. MSVC doesn't have this function at all, so only check for it on
1468# non-windows platforms.
1469if host_machine.system() != 'windows'
1470  if cc.has_function('posix_memalign')
1471    pre_args += '-DHAVE_POSIX_MEMALIGN'
1472  endif
1473endif
1474
1475if cc.has_member('struct dirent', 'd_type', prefix: '''#include <sys/types.h>
1476   #include <dirent.h>''')
1477   pre_args += '-DHAVE_DIRENT_D_TYPE'
1478endif
1479
1480# strtod locale support
1481if cc.links('''
1482    #define _GNU_SOURCE
1483    #include <stdlib.h>
1484    #include <locale.h>
1485    #ifdef HAVE_XLOCALE_H
1486    #include <xlocale.h>
1487    #endif
1488    int main() {
1489      locale_t loc = newlocale(LC_CTYPE_MASK, "C", NULL);
1490      const char *s = "1.0";
1491      char *end;
1492      double d = strtod_l(s, &end, loc);
1493      float f = strtof_l(s, &end, loc);
1494      freelocale(loc);
1495      return 0;
1496    }''',
1497    args : pre_args,
1498    name : 'strtod has locale support')
1499  pre_args += '-DHAVE_STRTOD_L'
1500endif
1501
1502# Check for some linker flags
1503ld_args_bsymbolic = []
1504if cc.links('int main() { return 0; }', args : '-Wl,-Bsymbolic', name : 'Bsymbolic')
1505  ld_args_bsymbolic += '-Wl,-Bsymbolic'
1506endif
1507with_ld_version_script = false
1508if cc.links('int main() { return 0; }',
1509            args : '-Wl,--version-script=@0@'.format(
1510              join_paths(meson.current_source_dir(), 'build-support/conftest.map')),
1511            name : 'version-script')
1512  with_ld_version_script = true
1513endif
1514with_ld_dynamic_list = false
1515if cc.links('int main() { return 0; }',
1516            args : '-Wl,--dynamic-list=@0@'.format(
1517              join_paths(meson.current_source_dir(), 'build-support/conftest.dyn')),
1518            name : 'dynamic-list')
1519  with_ld_dynamic_list = true
1520endif
1521
1522ld_args_build_id = cc.get_supported_link_arguments('-Wl,--build-id=sha1')
1523
1524# check for dl support
1525dep_dl = null_dep
1526if host_machine.system() != 'windows'
1527  if not cc.has_function('dlopen')
1528    dep_dl = cc.find_library('dl', required : true)
1529  endif
1530  if cc.has_function('dladdr', dependencies : dep_dl)
1531    # This is really only required for util/disk_cache.h
1532    pre_args += '-DHAVE_DLADDR'
1533  endif
1534endif
1535
1536if cc.has_function('dl_iterate_phdr')
1537  pre_args += '-DHAVE_DL_ITERATE_PHDR'
1538elif with_intel_vk or with_intel_hasvk
1539  error('Intel "Anvil" Vulkan driver requires the dl_iterate_phdr function')
1540endif
1541
1542if with_any_intel and ['x86', 'x86_64'].contains(host_machine.cpu_family())
1543  pre_args += '-DSUPPORT_INTEL_INTEGRATED_GPUS'
1544endif
1545
1546if with_gallium_i915 and host_machine.cpu_family().startswith('x86') == false
1547  error('Intel "i915" Gallium driver requires x86 or x86_64 CPU family')
1548endif
1549
1550# Determine whether or not the rt library is needed for time functions
1551if host_machine.system() == 'windows' or cc.has_function('clock_gettime')
1552  dep_clock = null_dep
1553else
1554  dep_clock = cc.find_library('rt')
1555endif
1556
1557# IMPORTANT: We can't upgrade Zlib beyond 1.2.5 because it would break Viewperf.
1558dep_zlib = dependency('zlib', version : '>= 1.2.3',
1559                      allow_fallback: true,
1560                      required : get_option('zlib'))
1561if dep_zlib.found()
1562  pre_args += '-DHAVE_ZLIB'
1563endif
1564
1565dep_zstd = dependency('libzstd', required : get_option('zstd'))
1566if dep_zstd.found()
1567  pre_args += '-DHAVE_ZSTD'
1568endif
1569
1570with_compression = dep_zlib.found() or dep_zstd.found()
1571if with_compression
1572  pre_args += '-DHAVE_COMPRESSION'
1573elif with_shader_cache
1574  error('Shader Cache requires compression')
1575endif
1576
1577if host_machine.system() == 'windows'
1578  # For MSVC and MinGW we aren't using pthreads, and dependency('threads') will add linkage
1579  # to pthread for MinGW, so leave the dependency null_dep for Windows. For Windows linking to
1580  # kernel32 is enough for c11/threads.h and it's already linked by meson by default
1581  dep_thread = null_dep
1582else
1583  dep_thread = dependency('threads')
1584endif
1585if dep_thread.found()
1586  pre_args += '-DHAVE_PTHREAD'
1587  if host_machine.system() != 'netbsd' and cc.has_function(
1588      'pthread_setaffinity_np',
1589      dependencies : dep_thread,
1590      prefix : '#include <pthread.h>',
1591      args : '-D_GNU_SOURCE')
1592    pre_args += '-DHAVE_PTHREAD_SETAFFINITY'
1593  endif
1594endif
1595
1596with_expat = get_option('expat') \
1597  .disable_auto_if(with_platform_android or with_platform_windows)
1598
1599if host_machine.system() == 'darwin'
1600  dep_expat = meson.get_compiler('c').find_library('expat', required : with_expat)
1601else
1602  dep_expat = dependency('expat', allow_fallback: true,
1603                         required : with_expat)
1604endif
1605
1606# TODO: with Meson 1.1.0 this can be replaced with with_expat.enable_if(with_intel_tools)
1607if with_intel_tools and not dep_expat.found()
1608  error('Intel tools require expat')
1609endif
1610
1611# We don't require expat on Android or Windows
1612use_xmlconfig = get_option('xmlconfig') \
1613  .require(not (with_platform_android or with_platform_windows),
1614           error_message : 'xmlconfig not available on Android or Windows') \
1615  .require(dep_expat.found(),
1616           error_message : 'requires expat') \
1617  .allowed()
1618
1619# Predefined macros for windows
1620if host_machine.system() == 'windows'
1621  pre_args += '-DWIN32_LEAN_AND_MEAN' # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx
1622endif
1623# this only exists on linux so either this is linux and it will be found, or
1624# it's not linux and wont
1625dep_m = cc.find_library('m', required : false)
1626
1627if host_machine.system() == 'windows'
1628  dep_regex = meson.get_compiler('c').find_library('regex', required : false)
1629  if not dep_regex.found()
1630    dep_regex = declare_dependency(compile_args : ['-DNO_REGEX'])
1631  endif
1632else
1633  dep_regex = null_dep
1634endif
1635
1636if with_platform_haiku
1637  dep_network = cc.find_library('network')
1638endif
1639
1640dep_futex = null_dep
1641if host_machine.system() == 'windows'
1642  if (get_option('min-windows-version') < 8)
1643    pre_args += '-DWINDOWS_NO_FUTEX'
1644  else
1645    dep_futex = cc.find_library('synchronization', required : true)
1646  endif
1647endif
1648
1649# Check for libdrm. Various drivers have different libdrm version requirements,
1650# but we always want to use the same version for all libdrm modules. That means
1651# even if driver foo requires 2.4.0 and driver bar requires 2.4.3, if foo and
1652# bar are both on use 2.4.3 for both of them
1653dep_libdrm_amdgpu = null_dep
1654dep_libdrm_intel = null_dep
1655
1656_drm_amdgpu_ver = '2.4.121'
1657_drm_intel_ver = '2.4.75'
1658_drm_ver = '2.4.109'
1659
1660_libdrm_checks = [
1661  ['intel', with_gallium_i915],
1662  ['amdgpu', (with_amd_vk and not with_platform_windows) or with_gallium_radeonsi],
1663]
1664
1665# Loop over the enables versions and get the highest libdrm requirement for all
1666# active drivers.
1667_drm_blame = ''
1668foreach d : _libdrm_checks
1669  ver = get_variable('_drm_@0@_ver'.format(d[0]))
1670  if d[1] and ver.version_compare('>' + _drm_ver)
1671    _drm_ver = ver
1672    _drm_blame = d[0]
1673  endif
1674endforeach
1675if _drm_blame != ''
1676  message('libdrm @0@ needed because @1@ has the highest requirement'.format(_drm_ver, _drm_blame))
1677endif
1678
1679# Then get each libdrm module
1680foreach d : _libdrm_checks
1681  if d[1]
1682    set_variable(
1683      'dep_libdrm_' + d[0],
1684      dependency('libdrm_' + d[0], version : '>=' + _drm_ver)
1685    )
1686  endif
1687endforeach
1688
1689with_gallium_drisw_kms = false
1690if system_has_kms_drm
1691  dep_libdrm = dependency(
1692    'libdrm', version : '>=' + _drm_ver,
1693    required : with_dri2 or with_dri or with_gbm
1694  )
1695else
1696  # We should prevent libdrm from being available when the target doesn't have it to avoid transitive
1697  # dependencies (such as vk-runtime) linking to it
1698  dep_libdrm = null_dep
1699endif
1700if dep_libdrm.found()
1701  pre_args += '-DHAVE_LIBDRM'
1702  if with_dri_platform == 'drm' and with_dri
1703    with_gallium_drisw_kms = true
1704  endif
1705endif
1706
1707dep_libudev = dependency('libudev', required : false)
1708if dep_libudev.found()
1709  pre_args += '-DHAVE_LIBUDEV'
1710endif
1711
1712llvm_modules = ['bitwriter', 'engine', 'mcdisassembler', 'mcjit', 'core', 'executionengine', 'scalaropts', 'transformutils', 'instcombine']
1713llvm_optional_modules = ['coroutines']
1714if with_amd_vk or with_gallium_radeonsi or with_gallium_r600
1715  llvm_modules += ['amdgpu', 'bitreader', 'ipo']
1716  if with_gallium_r600
1717    llvm_modules += 'asmparser'
1718  endif
1719endif
1720if with_gallium_clover
1721  llvm_modules += [
1722    'linker', 'coverage', 'instrumentation', 'ipo', 'irreader',
1723    'lto', 'option', 'objcarcopts', 'profiledata'
1724  ]
1725  # all-targets is needed to support static linking LLVM build with multiple targets
1726  # windowsdriver is needded with LLVM>=15, but we don't know what LLVM verrsion we are using yet
1727  llvm_optional_modules += ['all-targets', 'frontendopenmp', 'windowsdriver']
1728endif
1729if with_clc
1730  llvm_modules += ['coverage', 'target', 'linker', 'irreader', 'option', 'libdriver', 'lto']
1731  # all-targets is needed to support static linking LLVM build with multiple targets.
1732  # windowsdriver is needded with LLVM>=15 and frontendhlsl is needed with LLVM>=16,
1733  # but we don't know what LLVM version we are using yet
1734  llvm_optional_modules += ['all-targets', 'windowsdriver', 'frontendhlsl', 'frontenddriver']
1735endif
1736draw_with_llvm = get_option('draw-use-llvm')
1737if draw_with_llvm
1738  llvm_modules += 'native'
1739  # lto is needded with LLVM>=15, but we don't know what LLVM verrsion we are using yet
1740  llvm_optional_modules += ['lto']
1741endif
1742amd_with_llvm = get_option('amd-use-llvm')
1743
1744# MCJIT is deprecated in LLVM and will not accept new architecture ports,
1745# so any architecture not in the exhaustive list will have to rely on LLVM
1746# ORCJIT for llvmpipe functionality.
1747llvm_has_mcjit = host_machine.cpu_family() in ['aarch64', 'arm', 'ppc', 'ppc64', 's390x', 'x86', 'x86_64']
1748llvm_with_orcjit = get_option('llvm-orcjit') or not llvm_has_mcjit
1749
1750if with_amd_vk or with_gallium_radeonsi or with_clc or llvm_with_orcjit
1751  _llvm_version = '>= 15.0.0'
1752elif with_gallium_clover
1753  _llvm_version = '>= 11.0.0'
1754else
1755  _llvm_version = '>= 5.0.0'
1756endif
1757
1758_shared_llvm = get_option('shared-llvm') \
1759  .disable_auto_if(host_machine.system() == 'windows') \
1760  .allowed()
1761
1762_llvm = get_option('llvm')
1763dep_llvm = null_dep
1764with_llvm = false
1765if _llvm.allowed()
1766  dep_llvm = dependency(
1767    'llvm',
1768    method : host_machine.system() == 'windows' ? 'auto' : 'config-tool',
1769    version : _llvm_version,
1770    modules : llvm_modules,
1771    optional_modules : llvm_optional_modules,
1772    required : (
1773      with_amd_vk or with_gallium_radeonsi or with_gallium_clover or with_clc
1774      or _llvm.enabled()
1775    ),
1776    static : not _shared_llvm,
1777    fallback : ['llvm', 'dep_llvm'],
1778    include_type : 'system',
1779  )
1780  with_llvm = dep_llvm.found()
1781endif
1782if with_llvm
1783  pre_args += '-DMESA_LLVM_VERSION_STRING="@0@"'.format(dep_llvm.version())
1784  pre_args += '-DLLVM_IS_SHARED=@0@'.format(_shared_llvm.to_int())
1785
1786  if (with_swrast_vk or with_gallium_llvmpipe) and not draw_with_llvm
1787    error('Lavapipe and llvmpipe require LLVM draw support.')
1788  endif
1789
1790  if with_gallium_r600 and not amd_with_llvm
1791    error('R600 requires LLVM AMD support.')
1792  endif
1793
1794  if host_machine.system() != 'windows'
1795    # LLVM can be built without rtti, turning off rtti changes the ABI of C++
1796    # programs, so we need to build all C++ code in mesa without rtti as well to
1797    # ensure that linking works. Note that Win32 compilers does handle mismatching RTTI
1798    # without issues, so only apply this for other compilers.
1799    if dep_llvm.type_name() == 'internal'
1800      _llvm_rtti = subproject('llvm').get_variable('has_rtti', true)
1801    else
1802      # The CMake finder will return 'ON', the llvm-config will return 'YES'
1803      _llvm_rtti = ['ON', 'YES'].contains(dep_llvm.get_variable(cmake : 'LLVM_ENABLE_RTTI', configtool: 'has-rtti'))
1804    endif
1805    if _rtti != _llvm_rtti
1806      if _llvm_rtti
1807        error('LLVM was built with RTTI, cannot build Mesa with RTTI disabled. Remove cpp_rtti disable switch or use LLVM built without LLVM_ENABLE_RTTI.')
1808      else
1809        error('LLVM was built without RTTI, so Mesa must also disable RTTI. Use an LLVM built with LLVM_ENABLE_RTTI or add cpp_rtti=false.')
1810      endif
1811    endif
1812  endif
1813
1814  if cc.get_argument_syntax() == 'msvc'
1815    # Suppress "/DELAYLOAD:ole32.dll/shell32.dll ignored" warnings that LLVM adds
1816    add_project_link_arguments(
1817      '/ignore:4199',
1818      language : ['c', 'cpp'],
1819    )
1820  endif
1821elif with_amd_vk and with_aco_tests
1822  error('ACO tests require LLVM, but LLVM is disabled.')
1823elif with_swrast_vk
1824  error('lavapipe requires LLVM and is enabled, but LLVM is disabled.')
1825elif with_any_llvmpipe
1826  error('llvmpipe requires LLVM and is enabled, but LLVM is disabled.')
1827elif with_gallium_clover
1828  error('The OpenCL "Clover" state tracker requires LLVM, but LLVM is disabled.')
1829elif with_clc
1830  error('The CLC compiler requires LLVM, but LLVM is disabled.')
1831else
1832  draw_with_llvm = false
1833endif
1834amd_with_llvm = amd_with_llvm and with_llvm
1835pre_args += '-DLLVM_AVAILABLE=@0@'.format(with_llvm.to_int())
1836pre_args += '-DDRAW_LLVM_AVAILABLE=@0@'.format((with_llvm and draw_with_llvm).to_int())
1837pre_args += '-DAMD_LLVM_AVAILABLE=@0@'.format(amd_with_llvm.to_int())
1838pre_args += '-DGALLIVM_USE_ORCJIT=@0@'.format((with_llvm and llvm_with_orcjit).to_int())
1839
1840if with_clc
1841  chosen_llvm_version_array = dep_llvm.version().split('.')
1842  chosen_llvm_version_major = chosen_llvm_version_array[0].to_int()
1843  chosen_llvm_version_minor = chosen_llvm_version_array[1].to_int()
1844
1845  # Require an SPIRV-LLVM-Translator version compatible with the chosen LLVM
1846  # one.
1847
1848  # This first version check is still needed as maybe LLVM 8.0 was picked but
1849  # we do not want to accept SPIRV-LLVM-Translator 8.0.0.1 as that version
1850  # does not have the required API and those are only available starting from
1851  # 8.0.1.3.
1852  _llvmspirvlib_min_version = '>= 8.0.1.3'
1853  if with_clc
1854    _llvmspirvlib_min_version = '>= 15.0.0.0'
1855  endif
1856
1857  _llvmspirvlib_version = [
1858    _llvmspirvlib_min_version,
1859    '>= @0@.@1@'.format(chosen_llvm_version_major, chosen_llvm_version_minor),
1860    '< @0@.@1@'.format(chosen_llvm_version_major, chosen_llvm_version_minor + 1) ]
1861
1862  # LLVMSPIRVLib is available at https://github.com/KhronosGroup/SPIRV-LLVM-Translator
1863  dep_llvmspirvlib = dependency('LLVMSPIRVLib', required : true, version : _llvmspirvlib_version)
1864else
1865  dep_llvmspirvlib = null_dep
1866endif
1867
1868dep_spirv_tools = dependency(
1869  'SPIRV-Tools',
1870  required : with_clc,
1871  version : '>= 2022.1'
1872)
1873if dep_spirv_tools.found()
1874  pre_args += '-DHAVE_SPIRV_TOOLS'
1875endif
1876
1877dep_clang = null_dep
1878if with_clc or with_gallium_clover
1879  llvm_libdir = dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir')
1880
1881  dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false)
1882
1883  if not dep_clang.found() or not _shared_llvm
1884    clang_modules = [
1885      'clangBasic', 'clangAST', 'clangCodeGen', 'clangLex',
1886      'clangDriver', 'clangFrontend', 'clangFrontendTool',
1887      'clangHandleCXX', 'clangHandleLLVM', 'clangSerialization',
1888      'clangSema', 'clangParse', 'clangEdit', 'clangAnalysis'
1889    ]
1890    if dep_llvm.version().version_compare('>= 15.0')
1891      clang_modules += 'clangSupport'
1892    endif
1893    if dep_llvm.version().version_compare('>= 16.0') or with_gallium_clover
1894      clang_modules += 'clangASTMatchers'
1895    endif
1896    if dep_llvm.version().version_compare('>= 18.0')
1897      clang_modules += 'clangAPINotes'
1898    endif
1899
1900    dep_clang = []
1901    foreach m : clang_modules
1902      dep_clang += cpp.find_library(m, dirs : llvm_libdir, required : true)
1903    endforeach
1904  endif
1905endif
1906
1907dep_lua = dependency('lua54', 'lua5.4', 'lua-5.4',
1908                     'lua53', 'lua5.3', 'lua-5.3',
1909                     'lua', required: false,
1910                     allow_fallback: with_tools.contains('freedreno'),
1911                     version: '>=5.3')
1912
1913# Be explicit about only using this lib on Windows, to avoid picking
1914# up random libs with the generic name 'libversion'
1915dep_version = null_dep
1916if host_machine.system() == 'windows'
1917  dep_version = cpp.find_library('version')
1918endif
1919
1920dep_elf = dependency('libelf', required : false)
1921if not with_platform_windows and not dep_elf.found()
1922  dep_elf = cc.find_library('elf', required : false)
1923endif
1924if dep_elf.found()
1925  pre_args += '-DUSE_LIBELF'
1926elif with_gallium_radeonsi
1927  error('Gallium driver radeonsi requires libelf')
1928endif
1929
1930dep_valgrind = dependency('valgrind', required : get_option('valgrind'))
1931if dep_valgrind.found()
1932  pre_args += '-DHAVE_VALGRIND'
1933endif
1934
1935# AddressSanitizer's leak reports need all the symbols to be present at exit to
1936# decode well, which runs afoul of our dlopen()/dlclose()ing of the DRI drivers.
1937# Set a flag so we can skip the dlclose for asan builds.
1938if ['address', 'address,undefined'].contains(get_option('b_sanitize'))
1939  asan_c_args = ['-DBUILT_WITH_ASAN=1']
1940else
1941  asan_c_args = ['-DBUILT_WITH_ASAN=0']
1942endif
1943
1944# ThreadSanitizer can't deal with futexes, and reports races for cases we don't care about
1945# so add a define to work silence these issues.
1946if get_option('b_sanitize') == 'thread'
1947  pre_args += '-DTHREAD_SANITIZER=1'
1948  # meson versions prior to 1.4 will warn "Consider using the built-in option for sanitizers ..."
1949  # later on because it only checks whether the option starts with "-fsanitize",
1950  # but there is no built-in option for adding a blacklist
1951  tsan_blacklist = '-fsanitize-blacklist=@0@'.format(join_paths(meson.project_source_root(), 'build-support', 'tsan-blacklist.txt'))
1952  if cc.has_argument(tsan_blacklist)
1953    pre_args += tsan_blacklist
1954  else
1955    warning('Compiler does not support "-fsanitize-blacklist", expected race conditions will not be surpressed')
1956  endif
1957else
1958  pre_args += '-DTHREAD_SANITIZER=0'
1959endif
1960
1961yacc_is_bison = true
1962needs_flex_bison = with_any_opengl or with_freedreno_vk or with_intel_tools or with_gallium
1963
1964if build_machine.system() == 'windows'
1965  # Prefer the winflexbison versions, they're much easier to install and have
1966  # better windows support.
1967
1968  prog_flex = find_program('win_flex', required : false)
1969  if prog_flex.found()
1970    # windows compatibility (uses <io.h> instead of <unistd.h> and _isatty,
1971    # _fileno functions)
1972    prog_flex = [prog_flex, '--wincompat']
1973  else
1974    prog_flex = [find_program('flex', 'lex', required : needs_flex_bison, disabler : true)]
1975  endif
1976  # Force flex to use const keyword in prototypes, as relies on __cplusplus or
1977  # __STDC__ macro to determine whether it's safe to use const keyword
1978  prog_flex += '-DYY_USE_CONST='
1979
1980  prog_flex_cpp = prog_flex
1981  # Convince win_flex to use <inttypes.h> for C++ files
1982  # Note that we are using a C99 version here rather than C11,
1983  # because using a C11 version can cause the MSVC CRT headers to define
1984  # static_assert to _Static_assert, which breaks other parts of the CRT
1985  prog_flex_cpp += '-D__STDC_VERSION__=199901'
1986
1987  prog_bison = find_program('win_bison', required : false)
1988  if not prog_bison.found()
1989    prog_bison = find_program('bison', 'yacc', required : needs_flex_bison, disabler : true)
1990  endif
1991else
1992  prog_bison = find_program('bison', required : false)
1993
1994  if not prog_bison.found()
1995    prog_bison = find_program('byacc', required : needs_flex_bison, disabler : true)
1996    yacc_is_bison = false
1997  endif
1998
1999  # Disable deprecated keyword warnings, since we have to use them for
2000  # old-bison compat.  See discussion in
2001  # https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2161
2002  if find_program('bison', required : false, version : '> 2.3').found()
2003    prog_bison = [prog_bison, '-Wno-deprecated']
2004  endif
2005
2006  prog_flex = find_program('flex', required : needs_flex_bison, disabler : true)
2007  prog_flex_cpp = prog_flex
2008endif
2009
2010_libunwind = get_option('libunwind') \
2011  .require(not with_platform_android, error_message : 'Android requires the use of the backtrace library, not libunwind')
2012if host_machine.system() == 'darwin'
2013  dep_unwind = meson.get_compiler('c').find_library('System', required : _libunwind)
2014else
2015  dep_unwind = dependency('libunwind', required : _libunwind)
2016endif
2017if dep_unwind.found()
2018  pre_args += '-DHAVE_LIBUNWIND'
2019endif
2020
2021if with_osmesa
2022  if not with_gallium_swrast
2023    error('OSMesa gallium requires gallium softpipe or llvmpipe.')
2024  endif
2025  if host_machine.system() == 'windows'
2026    osmesa_lib_name = 'osmesa'
2027  else
2028    osmesa_lib_name = 'OSMesa'
2029  endif
2030endif
2031
2032# TODO: symbol mangling
2033
2034if with_platform_wayland
2035  dep_wl_scanner = dependency('wayland-scanner', native: true)
2036  prog_wl_scanner = find_program(dep_wl_scanner.get_variable(pkgconfig : 'wayland_scanner'))
2037  if dep_wl_scanner.version().version_compare('>= 1.15')
2038    wl_scanner_arg = 'private-code'
2039  else
2040    wl_scanner_arg = 'code'
2041  endif
2042  dep_wl_protocols = dependency('wayland-protocols', version : '>= 1.38', default_options: [ 'tests=false' ])
2043  dep_wayland_client = dependency('wayland-client', version : '>=1.18')
2044  dep_wayland_server = dependency('wayland-server', version : '>=1.18')
2045  if with_egl
2046    dep_wayland_egl = dependency('wayland-egl-backend', version : '>= 3')
2047    dep_wayland_egl_headers = dep_wayland_egl.partial_dependency(compile_args : true)
2048  endif
2049  pre_args += '-DWL_HIDE_DEPRECATED'
2050  if cc.has_function(
2051      'wl_display_dispatch_queue_timeout',
2052      prefix : '#include <wayland-client.h>',
2053      dependencies: dep_wayland_client)
2054    pre_args += ['-DHAVE_WL_DISPATCH_QUEUE_TIMEOUT']
2055  endif
2056  if cc.has_function(
2057      'wl_display_create_queue_with_name',
2058      prefix : '#include <wayland-client.h>',
2059      dependencies: dep_wayland_client)
2060    pre_args += ['-DHAVE_WL_CREATE_QUEUE_WITH_NAME']
2061  endif
2062endif
2063
2064# Even if we find OpenMP, Gitlab CI fails to link with gcc/i386 and clang/anyarch.
2065dep_openmp = null_dep
2066if host_machine.cpu_family() == 'x86_64' and cc.get_id() == 'gcc'
2067  dep_openmp = dependency('openmp', required : false)
2068  if dep_openmp.found()
2069    pre_args += ['-DHAVE_OPENMP']
2070  endif
2071endif
2072
2073dep_x11 = null_dep
2074dep_xext = null_dep
2075dep_xfixes = null_dep
2076dep_x11_xcb = null_dep
2077dep_xcb = null_dep
2078dep_xcb_keysyms = null_dep
2079dep_xcb_glx = null_dep
2080dep_xcb_dri2 = null_dep
2081dep_xcb_dri3 = null_dep
2082dep_dri2proto = null_dep
2083dep_glproto = null_dep
2084dep_xxf86vm = null_dep
2085dep_xcb_present = null_dep
2086dep_xcb_sync = null_dep
2087dep_xcb_xfixes = null_dep
2088dep_xshmfence = null_dep
2089dep_xcb_xrandr = null_dep
2090dep_xcb_shm = null_dep
2091dep_xlib_xrandr = null_dep
2092
2093dep_dri2proto_version = '>= 2.8'
2094dep_glproto_version = '>= 1.4.14'
2095dep_xcb_dri2_version = '>= 1.8'
2096dep_xcb_dri3_version = '>= 1.13'
2097dep_xcb_glx_version = '>= 1.8.1'
2098dep_xcb_present_version = '>= 1.13'
2099dep_xfixes_version = '>= 2.0'
2100dep_xlib_xrandr_version = '>= 1.3'
2101dep_xshmfence_version = '>= 1.1'
2102
2103with_dri3_explicit_sync = false
2104with_xcb_keysyms = false
2105if with_platform_x11
2106  dep_xcb = dependency('xcb')
2107  dep_xcb_xrandr = dependency('xcb-randr')
2108  if with_glx == 'xlib'
2109    dep_x11 = dependency('x11')
2110    dep_xext = dependency('xext')
2111  elif with_glx == 'dri'
2112    dep_x11 = dependency('x11')
2113    dep_xext = dependency('xext')
2114    dep_xfixes = dependency('xfixes', version : dep_xfixes_version)
2115    dep_xcb_glx = dependency('xcb-glx', version : dep_xcb_glx_version)
2116    dep_xcb_shm = dependency('xcb-shm')
2117  elif with_gallium_rusticl
2118    # needed for GL sharing extension
2119    dep_x11 = dependency('x11')
2120  endif
2121  if (with_any_vk or with_glx == 'dri' or with_egl or
2122       (with_gallium_vdpau or with_gallium_va))
2123    dep_xcb = dependency('xcb')
2124    dep_xcb_keysyms = dependency('xcb-keysyms', required : false)
2125    with_xcb_keysyms = dep_xcb_keysyms.found()
2126    if with_xcb_keysyms
2127      pre_args += '-DXCB_KEYSYMS_AVAILABLE'
2128    endif
2129    dep_x11_xcb = dependency('x11-xcb')
2130    dep_xcb_dri2 = dependency('xcb-dri2', version : dep_xcb_dri2_version, required : with_x11_dri2)
2131    if with_dri_platform == 'drm' and not dep_libdrm.found()
2132      error('libdrm required for gallium video statetrackers when using x11')
2133    endif
2134  endif
2135  if with_dri_platform == 'drm'
2136    dep_xcb_dri2 = dependency('xcb-dri2', version : dep_xcb_dri2_version, required : with_x11_dri2)
2137
2138    dep_xcb_dri3 = dependency('xcb-dri3', version : dep_xcb_dri3_version)
2139    dep_xcb_present = dependency('xcb-present', version : dep_xcb_present_version)
2140    if (dep_xcb_dri3.version().version_compare('>= 1.17') and
2141        dep_xcb_present.version().version_compare('>= 1.17'))
2142      with_dri3_explicit_sync = true
2143    endif
2144    dep_xcb_shm = dependency('xcb-shm')
2145    dep_xcb_sync = dependency('xcb-sync')
2146    dep_xshmfence = dependency('xshmfence', version : dep_xshmfence_version)
2147    pre_args += '-DHAVE_X11_DRM'
2148  endif
2149  if with_glx == 'dri' or with_glx == 'xlib'
2150    dep_glproto = dependency('glproto', version : dep_glproto_version)
2151  endif
2152  if with_glx == 'dri'
2153    if with_dri_platform == 'drm'
2154      dep_dri2proto = dependency('dri2proto', version : dep_dri2proto_version)
2155      if with_glx_direct
2156        dep_xxf86vm = dependency('xxf86vm')
2157      endif
2158    endif
2159  endif
2160  if (with_egl or
2161      with_dri or
2162      with_any_vk or
2163      with_gallium_vdpau or with_gallium_xa)
2164    dep_xcb_xfixes = dependency('xcb-xfixes')
2165  endif
2166  if with_any_vk
2167    dep_xcb_dri3 = dependency('xcb-dri3', version : dep_xcb_dri3_version)
2168    dep_xcb_present = dependency('xcb-present', version : dep_xcb_present_version)
2169    dep_xcb_shm = dependency('xcb-shm')
2170    dep_xshmfence = dependency('xshmfence', version : dep_xshmfence_version)
2171  endif
2172  if with_xlib_lease or with_any_vk
2173    dep_xcb_xrandr = dependency('xcb-randr')
2174  endif
2175  if with_xlib_lease
2176    dep_xlib_xrandr = dependency('xrandr', version : dep_xlib_xrandr_version)
2177  endif
2178endif
2179
2180if with_dri
2181  pre_args += '-DHAVE_DRI'
2182endif
2183if with_dri2
2184  pre_args += '-DHAVE_DRI2'
2185endif
2186if with_x11_dri2
2187  pre_args += '-DHAVE_X11_DRI2'
2188endif
2189if with_dri3_explicit_sync
2190  pre_args += '-DHAVE_DRI3_EXPLICIT_SYNC'
2191endif
2192if with_gallium_drisw_kms
2193  pre_args += '-DHAVE_DRISW_KMS'
2194endif
2195
2196if get_option('gallium-extra-hud')
2197  pre_args += '-DHAVE_GALLIUM_EXTRA_HUD=1'
2198endif
2199
2200dep_lmsensors = cc.find_library('sensors', required : get_option('lmsensors'))
2201if dep_lmsensors.found()
2202  pre_args += '-DHAVE_LIBSENSORS=1'
2203endif
2204
2205_shader_replacement = get_option('custom-shader-replacement')
2206if _shader_replacement == ''
2207else
2208  pre_args += '-DCUSTOM_SHADER_REPLACEMENT'
2209endif
2210
2211with_perfetto = get_option('perfetto')
2212with_datasources = get_option('datasources')
2213with_any_datasource = with_datasources.length() != 0
2214if with_perfetto
2215  dep_perfetto = dependency('perfetto', fallback: ['perfetto', 'dep_perfetto'])
2216  pre_args += '-DHAVE_PERFETTO'
2217endif
2218
2219with_teflon = get_option('teflon')
2220if with_teflon and with_tests
2221  dep_xtensor = dependency('xtensor')
2222  dep_flatbuffers = dependency('flatbuffers')
2223  prog_flatc = find_program('flatc')
2224endif
2225
2226with_gpuvis = get_option('gpuvis')
2227if with_gpuvis
2228  pre_args += '-DHAVE_GPUVIS'
2229endif
2230
2231add_project_arguments(pre_args, language : ['c', 'cpp'])
2232add_project_arguments(c_cpp_args, language : ['c', 'cpp'])
2233
2234add_project_arguments(c_args,   language : ['c'])
2235add_project_arguments(cpp_args, language : ['cpp'])
2236
2237gl_priv_reqs = []
2238
2239if with_glx == 'xlib'
2240  gl_priv_reqs += ['x11', 'xext', 'xcb']
2241elif with_glx == 'dri'
2242  gl_priv_reqs += [
2243    'x11', 'xext', 'xfixes', 'x11-xcb', 'xcb',
2244    'xcb-glx >= 1.8.1']
2245  if with_dri_platform == 'drm'
2246    gl_priv_reqs += 'xcb-dri2 >= 1.8'
2247    if with_glx_direct
2248      gl_priv_reqs += 'xxf86vm'
2249    endif
2250  endif
2251endif
2252if dep_libdrm.found()
2253  gl_priv_reqs += 'libdrm >= 2.4.75'
2254endif
2255
2256gl_priv_libs = []
2257if dep_thread.found()
2258  gl_priv_libs += ['-lpthread', '-pthread']
2259endif
2260if dep_m.found()
2261  gl_priv_libs += '-lm'
2262endif
2263if dep_dl.found()
2264  gl_priv_libs += '-ldl'
2265endif
2266
2267# FIXME: autotools lists this as incomplete
2268gbm_priv_libs = []
2269if dep_dl.found()
2270  gbm_priv_libs += '-ldl'
2271endif
2272
2273pkg = import('pkgconfig')
2274
2275if host_machine.system() == 'windows'
2276  prog_dumpbin = find_program('dumpbin', required : false)
2277  with_symbols_check = prog_dumpbin.found() and with_tests
2278  if with_symbols_check
2279    symbols_check_args = ['--dumpbin', prog_dumpbin.full_path()]
2280  endif
2281else
2282  prog_nm = find_program('nm')
2283  with_symbols_check = with_tests
2284  symbols_check_args = ['--nm', prog_nm.full_path()]
2285endif
2286
2287# This quirk needs to be applied to sources with functions defined in assembly
2288# as GCC LTO drops them. See: https://bugs.freedesktop.org/show_bug.cgi?id=109391
2289gcc_lto_quirk = (cc.get_id() == 'gcc') ? ['-fno-lto'] : []
2290
2291devenv = environment()
2292
2293dir_compiler_nir = join_paths(meson.current_source_dir(), 'src/compiler/nir/')
2294dir_source_root = meson.project_source_root()
2295
2296
2297subdir('include')
2298subdir('bin')
2299subdir('src')
2300
2301meson.add_devenv(devenv)
2302
2303sphinx = find_program('sphinx-build', version : '>= 4.3',
2304                      required: get_option('html-docs'))
2305if sphinx.found()
2306  subdir('docs')
2307endif
2308
2309summary(
2310  {
2311    'prefix': get_option('prefix'),
2312    'libdir': get_option('libdir'),
2313    'includedir': get_option('includedir'),
2314  },
2315  section: 'Directories'
2316)
2317
2318summary(
2319  {
2320    'c_cpp_args': c_cpp_args,
2321  },
2322  section: 'Common C and C++ arguments'
2323)
2324
2325summary(
2326  {
2327    'OpenGL': with_opengl,
2328    'ES1': with_gles1,
2329    'ES2': with_gles2,
2330    'Shared glapi': with_shared_glapi,
2331    'GLVND': with_glvnd,
2332  },
2333  section: 'OpenGL', bool_yn: true
2334)
2335
2336summary(
2337  {
2338    'Platform': with_dri_platform,
2339    'Driver dir': dri_drivers_path,
2340  },
2341  section: 'DRI', bool_yn: true, list_sep: ' '
2342)
2343
2344summary(
2345  {
2346    'Enabled': with_glx != 'disabled',
2347    'Provider': with_glx == 'disabled' ? 'None' : with_glx
2348  },
2349  section: 'GLX', bool_yn: true, list_sep: ' '
2350)
2351
2352egl_summary = {'Enabled': with_egl}
2353if with_egl
2354  egl_drivers = []
2355  if with_dri
2356    egl_drivers += 'builtin:egl_dri2'
2357  endif
2358  if with_dri_platform == 'drm'
2359    egl_drivers += 'builtin:egl_dri3'
2360  endif
2361  if with_platform_windows
2362    egl_drivers += 'builtin:wgl'
2363  endif
2364  egl_summary += {'Drivers': egl_drivers}
2365  egl_summary += {'Platforms': _platforms}
2366endif
2367summary(egl_summary, section: 'EGL', bool_yn: true, list_sep: ' ')
2368
2369gbm_summary = {'Enabled': with_gbm}
2370if with_gbm
2371  gbm_summary += {'Backends path': gbm_backends_path}
2372endif
2373summary(gbm_summary, section: 'GBM', bool_yn: true, list_sep: ' ')
2374
2375vulkan_summary = {'Drivers': _vulkan_drivers.length() != 0 ? _vulkan_drivers : false }
2376if with_any_vk
2377  vulkan_summary += {'Platforms': _platforms}
2378  vulkan_summary += {'ICD dir': with_vulkan_icd_dir}
2379  if with_any_vulkan_layers
2380    vulkan_summary += {'Layers': get_option('vulkan-layers')}
2381  endif
2382  vulkan_summary += {'Intel Ray tracing': with_intel_vk_rt}
2383endif
2384summary(vulkan_summary, section: 'Vulkan', bool_yn: true, list_sep: ' ')
2385
2386video_summary = {'Codecs': _codecs.length() != 0 ? _codecs : false}
2387video_apis = []
2388if with_gallium_vdpau
2389  video_apis += 'vdpau'
2390endif
2391if with_gallium_va
2392  video_apis += 'va'
2393endif
2394if with_any_vk
2395  video_apis += 'vulkan'
2396endif
2397if with_gallium_xa
2398  video_apis += 'xa'
2399endif
2400video_summary += {'APIs': video_apis.length() != 0 ? video_apis : false}
2401summary(video_summary, section: 'Video', bool_yn: true, list_sep: ' ')
2402
2403llvm_summary = {'Enabled': with_llvm}
2404if with_llvm
2405  llvm_summary += {'Version': dep_llvm.version()}
2406endif
2407summary(llvm_summary, section: 'LLVM', bool_yn: true, list_sep: ' ')
2408
2409gallium_summary = {'Enabled': with_gallium}
2410if with_gallium
2411  gallium_summary += {'Drivers': gallium_drivers}
2412  gallium_summary += {'Platforms': _platforms}
2413
2414  gallium_frontends = ['mesa']
2415  if with_gallium_xa
2416    gallium_frontends += 'xa'
2417  endif
2418  if with_gallium_vdpau
2419    gallium_frontends += 'vdpau'
2420  endif
2421  if with_gallium_va
2422    gallium_frontends += 'va'
2423  endif
2424  if with_gallium_st_nine
2425    gallium_frontends += 'nine'
2426  endif
2427  if with_gallium_clover
2428    gallium_frontends += 'clover'
2429  endif
2430  if with_gallium_rusticl
2431    gallium_frontends += 'rusticl'
2432  endif
2433  gallium_summary += {'Frontends': gallium_frontends}
2434  gallium_summary += {'Off-screen rendering (OSMesa)': with_osmesa ? 'lib' + osmesa_lib_name : false}
2435  gallium_summary += {'HUD lm-sensors': dep_lmsensors.found()}
2436endif
2437summary(gallium_summary, section: 'Gallium', bool_yn: true, list_sep: ' ')
2438
2439perfetto_summary = {'Enabled': with_perfetto}
2440if with_perfetto and with_any_datasource
2441  perfetto_summary += {'Data source': with_datasources}
2442endif
2443summary(perfetto_summary, section: 'Perfetto', bool_yn: true, list_sep: ' ')
2444
2445teflon_summary = {'Enabled': with_teflon}
2446summary(teflon_summary, section: 'Teflon (TensorFlow Lite delegate)', bool_yn: true, list_sep: ' ')
2447