xref: /aosp_15_r20/external/igt-gpu-tools/meson.build (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1project('igt-gpu-tools', 'c',
2	version : '1.24',
3        default_options: [
4          'warning_level=2',
5          'c_std=gnu11',
6          'b_ndebug=false',
7          'buildtype=debugoptimized',
8        ],
9	license : 'MIT',
10	meson_version : '>=0.47.0')
11
12if get_option('b_ndebug') != 'false'
13	error('Building without -Db_ndebug=false is not supported')
14endif
15
16cc = meson.get_compiler('c')
17
18# Also make sure that the user doesn't have -DNDEBUG defined in their config
19if not cc.compiles(files('lib/check-ndebug.h'), args: get_option('c_args'))
20	error('Building with NDEBUG defined is not supported')
21endif
22
23cc_args = [
24	'-Wbad-function-cast',
25	'-Wdeclaration-after-statement',
26	'-Wformat=2',
27# igt_assert(0) in switch statements triggers a bunch of this.
28	'-Wimplicit-fallthrough=0',
29	'-Wlogical-op',
30	'-Wmissing-declarations',
31	'-Wmissing-format-attribute',
32	'-Wmissing-noreturn',
33	'-Wmissing-prototypes',
34	'-Wnested-externs',
35	'-Wold-style-definition',
36	'-Wpointer-arith',
37	'-Wredundant-decls',
38	'-Wshadow',
39	'-Wstrict-prototypes',
40	'-Wuninitialized',
41	'-Wunused',
42
43	'-Wno-clobbered',
44	'-Wno-maybe-uninitialized',
45	'-Wno-missing-field-initializers',
46	'-Wno-pointer-arith',
47	'-Wno-sign-compare',
48# Macros asserting on the range of their arguments triggers this.
49	'-Wno-type-limits',
50	'-Wno-unused-parameter',
51	'-Wno-unused-result',
52
53	'-Werror=address',
54	'-Werror=array-bounds',
55	'-Werror=implicit',
56	'-Werror=init-self',
57	'-Werror=int-to-pointer-cast',
58	'-Werror=main',
59	'-Werror=missing-braces',
60	'-Werror=nonnull',
61	'-Werror=pointer-to-int-cast',
62	'-Werror=return-type',
63	'-Werror=sequence-point',
64	'-Werror=trigraphs',
65	'-Werror=write-strings',
66# Disable the memory allocating builtins as they may cause unexpected behavior
67# with our framework. They *may* get optimized out in favor of a register or
68# stack variable, making them effectively local. Local variables do not play
69# well with longjmp which is heavily used by IGT framework.
70	'-fno-builtin-malloc',
71	'-fno-builtin-calloc',
72]
73
74foreach cc_arg : cc_args
75  if cc.has_argument(cc_arg)
76    add_global_arguments(cc_arg, language : 'c')
77  endif
78endforeach
79
80build_chamelium = get_option('chamelium')
81build_docs = get_option('docs')
82build_tests = not get_option('tests').disabled()
83with_libdrm = get_option('libdrm_drivers')
84
85build_info = ['Build type: ' + get_option('buildtype')]
86
87inc = include_directories('include/drm-uapi', 'lib', 'lib/stubs/syscalls', '.')
88
89inc_for_gtkdoc = include_directories('lib')
90
91config = configuration_data()
92
93null_dep = dependency('', required : false)
94
95libdrm_info = []
96libdrm_intel = null_dep
97libdrm_nouveau = null_dep
98libdrm_amdgpu = null_dep
99
100libdrm_version = '>=2.4.82'
101libdrm = dependency('libdrm', version : libdrm_version)
102if with_libdrm.contains('auto') or with_libdrm.contains('intel')
103	libdrm_intel = dependency('libdrm_intel', version : libdrm_version, required : with_libdrm.contains('intel'))
104	libdrm_info += 'intel'
105endif
106if with_libdrm.contains('auto') or with_libdrm.contains('nouveau')
107	libdrm_nouveau = dependency('libdrm_nouveau', version : libdrm_version, required : with_libdrm.contains('nouveau'))
108	libdrm_info += 'nouveau'
109endif
110if with_libdrm.contains('auto') or with_libdrm.contains('amdgpu')
111	libdrm_amdgpu = dependency('libdrm_amdgpu', version : libdrm_version, required : with_libdrm.contains('amdgpu'))
112	libdrm_info += 'amdgpu'
113endif
114
115build_info += 'With libdrm: ' + ','.join(libdrm_info)
116
117pciaccess = dependency('pciaccess', version : '>=0.10')
118libkmod = dependency('libkmod')
119libprocps = dependency('libprocps', required : true)
120
121libunwind = dependency('libunwind', required : get_option('libunwind'))
122build_info += 'With libunwind: @0@'.format(libunwind.found())
123
124libdw = dependency('libdw', required : true)
125pixman = dependency('pixman-1', required : true)
126
127valgrind = dependency('valgrind', required : get_option('valgrind'))
128if valgrind.found()
129	config.set('HAVE_VALGRIND', 1)
130endif
131build_info += 'Valgrind annotations: @0@'.format(valgrind.found())
132
133cairo = dependency('cairo', version : '>1.12.0', required : true)
134libudev = dependency('libudev', required : true)
135glib = dependency('glib-2.0', required : true)
136
137xmlrpc = dependency('xmlrpc', required : false)
138xmlrpc_util = dependency('xmlrpc_util', required : false)
139xmlrpc_client = dependency('xmlrpc_client', required : false)
140
141xmlrpc_cmd = find_program('xmlrpc-c-config', required : false)
142if not xmlrpc.found() and xmlrpc_cmd.found()
143	libs_cmd = run_command(xmlrpc_cmd, 'client', '--libs')
144	cflags_cmd = run_command(xmlrpc_cmd, 'client', '--cflags')
145
146	if libs_cmd.returncode() == 0 and cflags_cmd.returncode() == 0
147		xmlrpc = declare_dependency(compile_args: cflags_cmd.stdout().strip().split(),
148					    link_args : libs_cmd.stdout().strip().split())
149		xmlrpc_util = declare_dependency()
150		xmlrpc_client = declare_dependency()
151	endif
152endif
153
154if build_chamelium.enabled() and not (xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found())
155	error('Chamelium build forced and required dependency xmlrpc not found')
156endif
157
158gsl = dependency('gsl', required : build_chamelium)
159alsa = dependency('alsa', required : build_chamelium)
160libcurl = dependency('libcurl', required : build_chamelium)
161
162if xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found() and gsl.found() and alsa.found() and libcurl.found()
163	config.set('HAVE_CHAMELIUM', 1)
164	chamelium = declare_dependency(dependencies : [
165		xmlrpc,
166		xmlrpc_util,
167		xmlrpc_client,
168		gsl,
169		alsa,
170	])
171else
172	chamelium = disabler()
173endif
174
175build_info += 'Build Chamelium test: @0@'.format(chamelium.found())
176
177pthreads = dependency('threads')
178math = cc.find_library('m')
179realtime = cc.find_library('rt')
180dlsym = cc.find_library('dl')
181zlib = cc.find_library('z')
182
183if cc.links('''
184#include <stdint.h>
185int main(void) {
186  uint32_t x32 = 0;
187  uint64_t x64 = 0;
188  __atomic_load_n(&x32, __ATOMIC_SEQ_CST);
189  __atomic_load_n(&x64, __ATOMIC_SEQ_CST);
190  return 0;
191}''', name : 'built-in atomics')
192	libatomic = null_dep
193else
194	libatomic = cc.find_library('atomic')
195endif
196
197if cc.has_header('linux/kd.h')
198	config.set('HAVE_LINUX_KD_H', 1)
199endif
200if cc.has_header('sys/kd.h')
201	config.set('HAVE_SYS_KD_H', 1)
202endif
203if cc.has_header('libgen.h')
204	config.set('HAVE_LIBGEN_H', 1)
205endif
206if cc.has_header('sys/io.h')
207	config.set('HAVE_SYS_IO_H', 1)
208endif
209if cc.has_header('cpuid.h')
210	# FIXME: Do we need the example link test from configure.ac?
211	config.set('HAVE_CPUID_H', 1)
212endif
213if cc.has_header_symbol('unistd.h', 'gettid', args : '-D_GNU_SOURCE')
214	config.set('HAVE_GETTID', 1)
215endif
216
217if cc.has_member('struct sysinfo', 'totalram',
218		prefix : '#include <sys/sysinfo.h>')
219	config.set('HAVE_STRUCT_SYSINFO_TOTALRAM', 1)
220endif
221
222have = cc.has_function('memfd_create', prefix : '''#include <sys/mman.h>''', args : '-D_GNU_SOURCE')
223config.set10('HAVE_MEMFD_CREATE', have)
224
225add_project_arguments('-D_GNU_SOURCE', language : 'c')
226add_project_arguments('-include', 'config.h', language : 'c')
227
228# FEATURE_TEST_MACROS(7)
229# performs lightweight overflow checks on quite a few libc functions
230# requires -O optimizations
231if  ['debugoptimized', 'release', 'minsize'].contains(get_option('buildtype'))
232	add_project_arguments('-D_FORTIFY_SOURCE=2', language : 'c')
233endif
234
235config.set('PACKAGE_NAME', meson.project_name())
236config.set_quoted('PACKAGE_VERSION', meson.project_version())
237config.set_quoted('PACKAGE', meson.project_name())
238config.set('PACKAGE_STRING', meson.project_name() + ' ' + meson.project_version())
239config.set_quoted('TARGET_CPU_PLATFORM', host_machine.cpu_family())
240
241configure_file(output: 'config.h', install: false, configuration: config)
242
243prefix = get_option('prefix')
244bindir = get_option('bindir')
245datadir = join_paths(get_option('datadir'), 'igt-gpu-tools')
246includedir = get_option('includedir')
247libdir = get_option('libdir')
248libexecdir = join_paths(get_option('libexecdir'), 'igt-gpu-tools')
249amdgpudir = join_paths(libexecdir, 'amdgpu')
250mandir = get_option('mandir')
251pkgconfigdir = join_paths(libdir, 'pkgconfig')
252
253if get_option('use_rpath')
254	# Set up runpath for the test executables towards libigt.so.
255	# The path should be relative to $ORIGIN so the library is
256	# still found properly even if installed to a path other than
257	# prefix.
258
259	# libdir and bindir are pathnames relative to prefix. meson
260	# enforces this.
261
262	# 1. Start from the executable.
263	# 2. Executables are installed in certain dir. Add a .. for each
264	#    directory name in it.
265	# 3. Add relative path to libdir.
266
267	bindir_rpathdir = '$ORIGIN'
268	foreach p : bindir.split('/')
269		bindir_rpathdir = join_paths(bindir_rpathdir, '..')
270	endforeach
271	bindir_rpathdir = join_paths(bindir_rpathdir, libdir)
272
273	libexecdir_rpathdir = '$ORIGIN'
274	foreach p : libexecdir.split('/')
275		libexecdir_rpathdir = join_paths(libexecdir_rpathdir, '..')
276	endforeach
277	libexecdir_rpathdir = join_paths(libexecdir_rpathdir, libdir)
278
279	amdgpudir_rpathdir = '$ORIGIN'
280	foreach p : amdgpudir.split('/')
281		amdgpudir_rpathdir = join_paths(amdgpudir_rpathdir, '..')
282	endforeach
283	amdgpudir_rpathdir = join_paths(amdgpudir_rpathdir, libdir)
284else
285	bindir_rpathdir = ''
286	libexecdir_rpathdir = ''
287	amdgpudir_rpathdir = ''
288endif
289
290subdir('lib')
291if build_tests
292	subdir('tests')
293endif
294build_info += 'Build tests: @0@'.format(build_tests)
295
296subdir('benchmarks')
297subdir('tools')
298subdir('runner')
299if libdrm_intel.found()
300	subdir('assembler')
301endif
302subdir('overlay')
303subdir('man')
304
305gtk_doc = dependency('gtk-doc', required : build_docs)
306python3 = find_program('python3', required : build_docs)
307if build_tests and gtk_doc.found() and python3.found()
308	subdir('docs')
309elif build_docs.enabled()
310	error('Documentation requires building tests')
311endif
312build_info += 'Build documentation: @0@'.format(build_tests and gtk_doc.found())
313
314message('Build options')
315message('=============')
316foreach str : build_info
317	message(str)
318endforeach
319
320if cairo.version().version_compare('<1.17.2')
321	if pixman.version().version_compare('<0.36.0')
322		warning('Pixman < 0.36.0 found, cannot test HDR formats')
323	endif
324	warning('Cairo < 1.17.2 found, cannot test HDR formats')
325elif pixman.version().version_compare('<0.36.0')
326	# Cairo 1.17.2 requires 0.36.0 to compile, but somehow it went missing?
327	error('Cairo with floating point support found, but pixman version too old')
328endif
329