• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1project('libinput', 'c',
2	version : '1.19.4',
3	license : 'MIT/Expat',
4	default_options : [ 'c_std=gnu99', 'warning_level=2' ],
5	meson_version : '>= 0.49.0')
6
7libinput_version = meson.project_version().split('.')
8
9dir_data        = get_option('prefix') / get_option('datadir') / 'libinput'
10dir_etc         = get_option('prefix') / get_option('sysconfdir')
11dir_overrides   = get_option('prefix') / get_option('sysconfdir') / 'libinput'
12dir_libexec     = get_option('prefix') / get_option('libexecdir') / 'libinput'
13dir_lib         = get_option('prefix') / get_option('libdir')
14dir_man1        = get_option('prefix') / get_option('mandir') / 'man1'
15dir_system_udev = get_option('prefix') / 'lib' / 'udev'
16dir_src_quirks  = meson.current_source_dir() / 'quirks'
17dir_src_test    = meson.current_source_dir() / 'test'
18dir_src         = meson.current_source_dir() / 'src'
19
20dir_udev = get_option('udev-dir')
21if dir_udev == ''
22	dir_udev = dir_system_udev
23endif
24dir_udev_callouts = dir_udev
25dir_udev_rules    = dir_udev / 'rules.d'
26
27# Collection of man pages, we'll append to that
28src_man = files()
29
30# We use libtool-version numbers because it's easier to understand.
31# Before making a release, the libinput_so_*
32# numbers should be modified. The components are of the form C:R:A.
33# a) If binary compatibility has been broken (eg removed or changed interfaces)
34#    change to C+1:0:0.
35# b) If interfaces have been changed or added, but binary compatibility has
36#    been preserved, change to C+1:0:A+1
37# c) If the interface is the same as the previous version, change to C:R+1:A
38libinput_lt_c=23
39libinput_lt_r=0
40libinput_lt_a=13
41
42# convert to soname
43libinput_so_version = '@0@.@1@.@2@'.format((libinput_lt_c - libinput_lt_a),
44                                            libinput_lt_a, libinput_lt_r)
45
46# Compiler setup
47cc = meson.get_compiler('c')
48cflags = [
49	'-Wno-unused-parameter',
50	'-Wmissing-prototypes',
51	'-Wstrict-prototypes',
52	'-Wundef',
53	'-Wlogical-op',
54	'-Wpointer-arith',
55	'-Wuninitialized',
56	'-Winit-self',
57	'-Wstrict-prototypes',
58	'-Wimplicit-fallthrough',
59	'-Wredundant-decls',
60	'-Wincompatible-pointer-types',
61	'-Wformat=2',
62	'-Wno-missing-field-initializers',
63	'-Wmissing-declarations',
64
65	'-fvisibility=hidden',
66]
67add_project_arguments(cc.get_supported_arguments(cflags), language : 'c')
68
69# config.h
70config_h = configuration_data()
71
72doc_url_base = 'https://wayland.freedesktop.org/libinput/doc'
73if libinput_version[2].to_int() >= 90
74	doc_url = '@0@/latest'.format(doc_url_base)
75else
76	doc_url = '@0@/@1@'.format(doc_url_base, meson.project_version())
77endif
78config_h.set_quoted('HTTP_DOC_LINK', doc_url)
79
80config_h.set('_GNU_SOURCE', '1')
81if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
82	config_h.set_quoted('MESON_BUILD_ROOT', meson.current_build_dir())
83else
84	config_h.set_quoted('MESON_BUILD_ROOT', '')
85endif
86
87prefix = '''#define _GNU_SOURCE 1
88#include <assert.h>
89'''
90if cc.get_define('static_assert', prefix : prefix) == ''
91	config_h.set('static_assert(...)', '/* */')
92endif
93
94# Coverity breaks because it doesn't define _Float128 correctly, you'll end
95# up with a bunch of messages in the form:
96# "/usr/include/stdlib.h", line 133: error #20: identifier "_Float128" is
97#           undefined
98#   extern _Float128 strtof128 (const char *__restrict __nptr,
99#          ^
100# We don't use float128 ourselves, it gets pulled in from math.h or
101# something, so let's just define it as uint128 and move on.
102# Unfortunately we can't detect the coverity build at meson configure
103# time, we only know it fails at runtime. So make this an option instead, to
104# be removed when coverity fixes this again.
105if get_option('coverity')
106	config_h.set('_Float128', '__uint128_t')
107	config_h.set('_Float32', 'int')
108	config_h.set('_Float32x', 'int')
109	config_h.set('_Float64', 'long')
110	config_h.set('_Float64x', 'long')
111endif
112
113if cc.has_header_symbol('dirent.h', 'versionsort', prefix : prefix)
114	config_h.set('HAVE_VERSIONSORT', '1')
115endif
116
117if not cc.has_header_symbol('errno.h', 'program_invocation_short_name', prefix : prefix)
118	if cc.has_header_symbol('stdlib.h', 'getprogname')
119		config_h.set('program_invocation_short_name', 'getprogname()')
120	endif
121endif
122
123if cc.has_header('xlocale.h')
124	config_h.set('HAVE_XLOCALE_H', '1')
125endif
126
127code = '''
128#include <locale.h>
129void main(void) { newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); }
130'''
131if cc.links(code, name : 'locale.h')
132	config_h.set('HAVE_LOCALE_H', '1')
133endif
134
135if not cc.has_header_symbol('sys/ptrace.h', 'PTRACE_ATTACH', prefix : prefix)
136	config_h.set('PTRACE_ATTACH', 'PT_ATTACH')
137	config_h.set('PTRACE_CONT', 'PT_CONTINUE')
138	config_h.set('PTRACE_DETACH', 'PT_DETACH')
139endif
140
141# Dependencies
142pkgconfig = import('pkgconfig')
143dep_udev = dependency('libudev')
144dep_mtdev = dependency('mtdev', version : '>= 1.1.0')
145dep_libevdev = dependency('libevdev')
146config_h.set10('HAVE_LIBEVDEV_DISABLE_PROPERTY',
147		dep_libevdev.version().version_compare('>= 1.9.902'))
148
149dep_lm = cc.find_library('m', required : false)
150dep_rt = cc.find_library('rt', required : false)
151
152# Include directories
153includes_include = include_directories('include')
154includes_src = include_directories('src')
155
156############ libwacom configuration ############
157
158have_libwacom = get_option('libwacom')
159config_h.set10('HAVE_LIBWACOM', have_libwacom)
160if have_libwacom
161	dep_libwacom = dependency('libwacom', version : '>= 0.27')
162else
163	dep_libwacom = declare_dependency()
164endif
165
166############ udev bits ############
167
168executable('libinput-device-group',
169	   'udev/libinput-device-group.c',
170	   dependencies : [dep_udev, dep_libwacom],
171	   include_directories : [includes_src, includes_include],
172	   install : true,
173	   install_dir : dir_udev_callouts)
174executable('libinput-fuzz-extract',
175	   'udev/libinput-fuzz-extract.c',
176	   'src/util-strings.c',
177	   'src/util-prop-parsers.c',
178	   dependencies : [dep_udev, dep_libevdev, dep_lm],
179	   include_directories : [includes_src, includes_include],
180	   install : true,
181	   install_dir : dir_udev_callouts)
182executable('libinput-fuzz-to-zero',
183	   'udev/libinput-fuzz-to-zero.c',
184	   dependencies : [dep_udev, dep_libevdev],
185	   include_directories : [includes_src, includes_include],
186	   install : true,
187	   install_dir : dir_udev_callouts)
188
189udev_rules_config = configuration_data()
190udev_rules_config.set('UDEV_TEST_PATH', '')
191configure_file(input : 'udev/80-libinput-device-groups.rules.in',
192	       output : '80-libinput-device-groups.rules',
193	       install_dir : dir_udev_rules,
194	       configuration : udev_rules_config)
195configure_file(input : 'udev/90-libinput-fuzz-override.rules.in',
196	       output : '90-libinput-fuzz-override.rules',
197	       install_dir : dir_udev_rules,
198	       configuration : udev_rules_config)
199
200litest_udev_rules_config = configuration_data()
201litest_udev_rules_config.set('UDEV_TEST_PATH', meson.current_build_dir() + '/')
202litest_groups_rules_file = configure_file(input : 'udev/80-libinput-device-groups.rules.in',
203	       output : '80-libinput-device-groups-litest.rules',
204	       configuration : litest_udev_rules_config)
205litest_fuzz_override_file = configure_file(input : 'udev/90-libinput-fuzz-override.rules.in',
206					   output : '90-libinput-fuzz-override-litest.rules',
207					   configuration : litest_udev_rules_config)
208
209############ Check for leftover udev rules ########
210
211# This test should be defined first so we don't waste time testing anything
212# else if we're about to fail anyway. ninja test will execute tests in the
213# order of them defined in meson.build
214
215if get_option('tests')
216	test('leftover-rules',
217	     find_program('test/check-leftover-udev-rules.sh'),
218	     is_parallel : false,
219	     suite : ['all'])
220endif
221
222############ libepoll-shim (BSD) ############
223
224if cc.has_header_symbol('sys/epoll.h', 'epoll_create1', prefix : prefix)
225	# epoll is built-in (Linux, illumos)
226	dep_libepoll = declare_dependency()
227else
228	# epoll is implemented in userspace by libepoll-shim (FreeBSD)
229	dir_libepoll = get_option('epoll-dir')
230	if dir_libepoll == ''
231		dir_libepoll = get_option('prefix')
232	endif
233	includes_epoll = include_directories(dir_libepoll / 'include' / 'libepoll-shim')
234	dep_libepoll = cc.find_library('epoll-shim', dirs : dir_libepoll / 'lib')
235	code = '''
236	#include <sys/epoll.h>
237	int main(void) { epoll_create1(0); }
238	'''
239	if not cc.links(code,
240		name : 'libepoll-shim check',
241		dependencies : [dep_libepoll, dep_rt],
242		include_directories : includes_epoll) # note: wants an include_directories object
243		error('No built-in epoll or libepoll-shim found.')
244	endif
245	dep_libepoll = declare_dependency(
246		include_directories : includes_epoll,
247		dependencies : [dep_libepoll, dep_rt])
248endif
249
250############ libinput-util.a ############
251
252# Basic compilation test to make sure the headers include and define all the
253# necessary bits.
254util_headers = [
255		'util-bits.h',
256		'util-input-event.h',
257		'util-list.h',
258		'util-macros.h',
259		'util-matrix.h',
260		'util-prop-parsers.h',
261		'util-ratelimit.h',
262		'util-strings.h',
263		'util-time.h',
264]
265foreach h: util_headers
266	c = configuration_data()
267	c.set_quoted('FILE', h)
268	testfile = configure_file(input : 'test/test-util-includes.c',
269			          output : 'test-util-includes-@0@.c'.format(h),
270				  configuration : c)
271	executable('test-build-@0@'.format(h),
272		   testfile, dir_src / h,
273		   include_directories : [includes_src, includes_include],
274		   install : false)
275endforeach
276
277src_libinput_util = [
278	'src/util-bits.h',
279	'src/util-list.c',
280	'src/util-list.h',
281	'src/util-macros.h',
282	'src/util-matrix.h',
283	'src/util-ratelimit.c',
284	'src/util-ratelimit.h',
285	'src/util-strings.h',
286	'src/util-strings.c',
287	'src/util-time.h',
288	'src/util-prop-parsers.h',
289	'src/util-prop-parsers.c',
290	'src/libinput-util.h',
291]
292libinput_util = static_library('libinput-util',
293			       src_libinput_util,
294			       dependencies : [dep_udev, dep_libevdev, dep_libwacom],
295			       include_directories : includes_include)
296dep_libinput_util = declare_dependency(link_with : libinput_util)
297
298############ libfilter.a ############
299src_libfilter = [
300		'src/filter.c',
301		'src/filter-flat.c',
302		'src/filter-low-dpi.c',
303		'src/filter-mouse.c',
304		'src/filter-touchpad.c',
305		'src/filter-touchpad-flat.c',
306		'src/filter-touchpad-x230.c',
307		'src/filter-tablet.c',
308		'src/filter-trackpoint.c',
309		'src/filter.h',
310		'src/filter-private.h'
311]
312libfilter = static_library('filter', src_libfilter,
313			   dependencies : [dep_udev, dep_libwacom],
314			   include_directories : includes_include)
315dep_libfilter = declare_dependency(link_with : libfilter)
316
317############ libquirks.a #############
318libinput_data_path = dir_data
319libinput_data_override_path = dir_overrides / 'local-overrides.quirks'
320config_h.set_quoted('LIBINPUT_QUIRKS_DIR', dir_data)
321config_h.set_quoted('LIBINPUT_QUIRKS_OVERRIDE_FILE', libinput_data_override_path)
322
323config_h.set_quoted('LIBINPUT_QUIRKS_SRCDIR', dir_src_quirks)
324install_subdir('quirks',
325	       exclude_files: ['README.md'],
326	       install_dir : dir_data,
327	       strip_directory : true)
328
329src_libquirks = [
330	'src/quirks.c',
331	'src/quirks.h',
332	'src/builddir.h',
333]
334
335deps_libquirks = [dep_udev, dep_libwacom, dep_libinput_util]
336libquirks = static_library('quirks', src_libquirks,
337			   dependencies : deps_libquirks,
338			   include_directories : includes_include)
339dep_libquirks = declare_dependency(link_with : libquirks)
340
341# Create /etc/libinput
342install_subdir('libinput', install_dir : dir_etc)
343
344############ libinput.so ############
345install_headers('src/libinput.h')
346src_libinput = src_libfilter + [
347	'src/libinput.c',
348	'src/libinput.h',
349	'src/libinput-private-config.c',
350	'src/libinput-private-config.h',
351	'src/libinput-private.h',
352	'src/evdev.c',
353	'src/evdev.h',
354	'src/evdev-debounce.c',
355	'src/evdev-fallback.c',
356	'src/evdev-fallback.h',
357	'src/evdev-totem.c',
358	'src/evdev-middle-button.c',
359	'src/evdev-mt-touchpad.c',
360	'src/evdev-mt-touchpad.h',
361	'src/evdev-mt-touchpad-tap.c',
362	'src/evdev-mt-touchpad-thumb.c',
363	'src/evdev-mt-touchpad-buttons.c',
364	'src/evdev-mt-touchpad-edge-scroll.c',
365	'src/evdev-mt-touchpad-gestures.c',
366	'src/evdev-tablet.c',
367	'src/evdev-tablet.h',
368	'src/evdev-tablet-pad.c',
369	'src/evdev-tablet-pad.h',
370	'src/evdev-tablet-pad-leds.c',
371	'src/path-seat.c',
372	'src/udev-seat.c',
373	'src/udev-seat.h',
374	'src/timer.c',
375	'src/timer.h',
376	'include/linux/input.h'
377]
378
379deps_libinput = [
380	dep_mtdev,
381	dep_udev,
382	dep_libevdev,
383	dep_libepoll,
384	dep_lm,
385	dep_rt,
386	dep_libwacom,
387	dep_libinput_util,
388	dep_libquirks
389]
390
391libinput_version_h_config = configuration_data()
392libinput_version_h_config.set('LIBINPUT_VERSION_MAJOR', libinput_version[0])
393libinput_version_h_config.set('LIBINPUT_VERSION_MINOR', libinput_version[1])
394libinput_version_h_config.set('LIBINPUT_VERSION_MICRO', libinput_version[2])
395libinput_version_h_config.set('LIBINPUT_VERSION', meson.project_version())
396
397libinput_version_h = configure_file(
398		input : 'src/libinput-version.h.in',
399		output : 'libinput-version.h',
400		configuration : libinput_version_h_config,
401)
402
403mapfile = dir_src / 'libinput.sym'
404version_flag = '-Wl,--version-script,@0@'.format(mapfile)
405lib_libinput = shared_library('input',
406		src_libinput,
407		include_directories : [include_directories('.'), includes_include],
408		dependencies : deps_libinput,
409		version : libinput_so_version,
410		link_args : version_flag,
411		link_depends : mapfile,
412		install : true
413		)
414
415dep_libinput = declare_dependency(
416		link_with : lib_libinput,
417		dependencies : deps_libinput)
418
419pkgconfig.generate(
420	filebase : 'libinput',
421	name : 'Libinput',
422	description : 'Input device library',
423	version : meson.project_version(),
424	libraries : lib_libinput
425)
426
427git_version_h = vcs_tag(command : ['git', 'describe'],
428			fallback : 'unknown',
429			input : 'src/libinput-git-version.h.in',
430			output :'libinput-git-version.h')
431
432############ documentation ############
433
434if get_option('documentation')
435	subdir('doc/api')
436	subdir('doc/user')
437endif
438
439############ shell completion #########
440
441subdir('completion/zsh')
442
443############ tools ############
444libinput_tool_path = dir_libexec
445config_h.set_quoted('LIBINPUT_TOOL_PATH', libinput_tool_path)
446tools_shared_sources = [ 'tools/shared.c',
447			 'tools/shared.h',
448			 'src/builddir.h' ]
449deps_tools_shared = [ dep_libinput, dep_libevdev ]
450lib_tools_shared = static_library('tools_shared',
451				  tools_shared_sources,
452				  include_directories : [includes_src, includes_include],
453				  dependencies : deps_tools_shared)
454dep_tools_shared = declare_dependency(link_with : lib_tools_shared,
455				      dependencies : deps_tools_shared)
456
457deps_tools = [ dep_tools_shared, dep_libinput ]
458libinput_debug_events_sources = [
459	'tools/libinput-debug-events.c',
460	libinput_version_h,
461]
462executable('libinput-debug-events',
463	   libinput_debug_events_sources,
464	   dependencies : deps_tools,
465	   include_directories : [includes_src, includes_include],
466	   install_dir : libinput_tool_path,
467	   install : true
468	   )
469
470libinput_debug_tablet_sources = [ 'tools/libinput-debug-tablet.c' ]
471executable('libinput-debug-tablet',
472	   libinput_debug_tablet_sources,
473	   dependencies : deps_tools,
474	   include_directories : [includes_src, includes_include],
475	   install_dir : libinput_tool_path,
476	   install : true)
477
478
479libinput_quirks_sources = [ 'tools/libinput-quirks.c' ]
480libinput_quirks = executable('libinput-quirks',
481			     libinput_quirks_sources,
482			     dependencies : [dep_libquirks, dep_tools_shared, dep_libinput],
483			     include_directories : [includes_src, includes_include],
484			     install_dir : libinput_tool_path,
485			     install : true
486			    )
487test('validate-quirks',
488     libinput_quirks,
489     args: ['validate', '--data-dir=@0@'.format(dir_src_quirks)],
490     suite : ['all']
491     )
492
493libinput_list_devices_sources = [ 'tools/libinput-list-devices.c' ]
494libinput_list_devices = executable('libinput-list-devices',
495				   libinput_list_devices_sources,
496				   dependencies : deps_tools,
497				   include_directories : [includes_src, includes_include],
498				   install_dir : libinput_tool_path,
499				   install : true,
500				  )
501test('list-devices',
502     libinput_list_devices,
503     suite : ['all', 'root', 'hardware'])
504
505libinput_measure_sources = [ 'tools/libinput-measure.c' ]
506executable('libinput-measure',
507	   libinput_measure_sources,
508	   dependencies : deps_tools,
509	   include_directories : [includes_src, includes_include],
510	   install_dir : libinput_tool_path,
511	   install : true,
512	   )
513
514libinput_analyze_sources = [ 'tools/libinput-analyze.c' ]
515executable('libinput-analyze',
516	   libinput_analyze_sources,
517	   dependencies : deps_tools,
518	   include_directories : [includes_src, includes_include],
519	   install_dir : libinput_tool_path,
520	   install : true,
521	   )
522
523src_python_tools = files(
524	      'tools/libinput-analyze-per-slot-delta.py',
525	      'tools/libinput-analyze-recording.py',
526	      'tools/libinput-analyze-touch-down-state.py',
527	      'tools/libinput-measure-fuzz.py',
528	      'tools/libinput-measure-touchpad-size.py',
529	      'tools/libinput-measure-touchpad-tap.py',
530	      'tools/libinput-measure-touchpad-pressure.py',
531	      'tools/libinput-measure-touch-size.py',
532	      'tools/libinput-replay.py'
533)
534
535foreach t : src_python_tools
536	configure_file(input: t,
537		       output: '@BASENAME@',
538		       copy: true,
539		       install_dir : libinput_tool_path
540		      )
541endforeach
542
543libinput_record_sources = [ 'tools/libinput-record.c', git_version_h ]
544executable('libinput-record',
545	   libinput_record_sources,
546	   dependencies : deps_tools + [dep_udev],
547	   include_directories : [includes_src, includes_include],
548	   install_dir : libinput_tool_path,
549	   install : true,
550	   )
551
552if get_option('debug-gui')
553	dep_gtk = dependency('gtk4', version : '>= 4.0', required : false)
554	config_h.set10('HAVE_GTK4', dep_gtk.found())
555	if not dep_gtk.found()
556		dep_gtk = dependency('gtk+-3.0', version : '>= 3.20')
557		config_h.set10('HAVE_GTK3', dep_gtk.found())
558	endif
559
560	dep_cairo = dependency('cairo')
561	dep_glib = dependency('glib-2.0')
562	dep_wayland_client = dependency('wayland-client', required : false)
563	dep_wayland_protocols = dependency('wayland-protocols', required : false)
564	dep_x11 = dependency('x11', required : false)
565
566	debug_gui_sources = [ 'tools/libinput-debug-gui.c' ]
567
568	if dep_wayland_client.found() and dep_wayland_protocols.found()
569		wayland_scanner = find_program('wayland-scanner')
570		wlproto_dir = dep_wayland_protocols.get_pkgconfig_variable('pkgdatadir')
571
572		proto_name = 'pointer-constraints-unstable-v1'
573		input = files(wlproto_dir / 'unstable' / 'pointer-constraints' / '@0@.xml'.format(proto_name))
574
575		wayland_headers = custom_target('@0@ client header'.format(proto_name),
576			input: input,
577			output: '@0@-client-protocol.h'.format(proto_name),
578			command: [wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@'],
579		)
580
581		wayland_sources = custom_target('@0@ source'.format(proto_name),
582			input: input,
583			output: '@0@-protocol.c'.format(proto_name),
584			command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'],
585		)
586
587		debug_gui_sources += [ wayland_headers, wayland_sources ]
588	endif
589
590	deps_debug_gui = [
591			dep_gtk,
592			dep_cairo,
593			dep_glib,
594			dep_wayland_client,
595			dep_wayland_protocols,
596			dep_x11,
597			] + deps_tools
598	executable('libinput-debug-gui',
599		   debug_gui_sources,
600		   dependencies : deps_debug_gui,
601		   include_directories : [includes_src, includes_include],
602		   install_dir : libinput_tool_path,
603		   install : true
604		   )
605	src_man += files('tools/libinput-debug-gui.man')
606endif
607
608libinput_sources = [ 'tools/libinput-tool.c' ]
609
610libinput_tool = executable('libinput',
611			   libinput_sources,
612			   dependencies : deps_tools,
613			   include_directories : [includes_src, includes_include],
614			   install : true
615			  )
616
617ptraccel_debug_sources = [ 'tools/ptraccel-debug.c' ]
618executable('ptraccel-debug',
619	   ptraccel_debug_sources,
620	   dependencies : [ dep_libfilter, dep_libinput ],
621	   include_directories : [includes_src, includes_include],
622	   install : false
623	   )
624
625# Don't run the test during a release build because we rely on the magic
626# subtool lookup
627if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
628	config_tool_option_test = configuration_data()
629	config_tool_option_test.set('DISABLE_WARNING', 'yes')
630	config_tool_option_test.set('MESON_ENABLED_DEBUG_GUI', get_option('debug-gui'))
631	config_tool_option_test.set('MESON_BUILD_ROOT', meson.current_build_dir())
632	config_tool_option_test.set('TOOL_PATH', libinput_tool.full_path())
633	tool_option_test = configure_file(input: 'tools/test_tool_option_parsing.py',
634					  output: '@PLAINNAME@',
635					  configuration : config_tool_option_test)
636	test('tool-option-parsing',
637	     tool_option_test,
638	     args : [tool_option_test, '-n', 'auto'],
639	     suite : ['all', 'root'],
640	     timeout : 240)
641endif
642
643# the libinput tools check whether we execute from the builddir, this is
644# the test to verify that lookup. We test twice, once as normal test
645# run from the builddir, once after copying to /tmp
646test_builddir_lookup = executable('test-builddir-lookup',
647				  'test/test-builddir-lookup.c',
648				  dependencies : [ dep_tools_shared],
649				  include_directories : [includes_src, includes_include],
650				  install : false)
651test('tools-builddir-lookup',
652     test_builddir_lookup,
653     args : ['--builddir-is-set'],
654     suite : ['all'])
655test('tools-builddir-lookup-installed',
656     find_program('test/helper-copy-and-exec-from-tmp.sh'),
657     args : [test_builddir_lookup.full_path(), '--builddir-is-null'],
658     env : ['LD_LIBRARY_PATH=@0@'.format(meson.current_build_dir())],
659     suite : ['all'],
660     workdir : '/tmp')
661
662############ tests ############
663
664test('symbols-leak-test',
665     find_program('test/symbols-leak-test'),
666     args : [ dir_src / 'libinput.sym', dir_src],
667     suite : ['all'])
668
669# build-test only
670executable('test-build-pedantic',
671	   'test/build-pedantic.c',
672	   dependencies : [dep_udev],
673	   include_directories : [includes_src, includes_include],
674	   c_args : ['-std=c99', '-pedantic', '-Werror'],
675	   install : false)
676# build-test only
677executable('test-build-std-gnuc90',
678	   'test/build-pedantic.c',
679	   dependencies : [dep_udev],
680	   include_directories : [includes_src, includes_include],
681	   c_args : ['-std=gnu89', '-Werror'],
682	   install : false)
683# test for linking with the minimal linker flags
684executable('test-build-linker',
685	   'test/build-pedantic.c',
686	   include_directories : [includes_src, includes_include],
687	   dependencies : [ dep_libinput, dep_libinput_util ],
688	   install : false)
689# test including from C++ (in case CPP compiler is available)
690if add_languages('cpp', required: false)
691	executable('test-build-cxx',
692		   'test/build-cxx.cc',
693		   dependencies : [dep_udev],
694		   include_directories : [includes_src, includes_include],
695		   install : false)
696endif
697
698# This is the test suite runner, we allow disabling that one because of
699# dependencies
700if get_option('tests')
701	dep_check = dependency('check', version : '>= 0.9.10')
702
703	gstack = find_program('gstack', required : false)
704	config_h.set10('HAVE_GSTACK', gstack.found())
705
706	# for inhibit support during test run
707	dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false)
708	config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found())
709
710	litest_sources = [
711		'src/libinput-private-config.c',
712		'src/libinput-private-config.h',
713		'test/litest.h',
714		'test/litest-int.h',
715		'test/litest-device-absinfo-override.c',
716		'test/litest-device-acer-hawaii-keyboard.c',
717		'test/litest-device-acer-hawaii-touchpad.c',
718		'test/litest-device-aiptek-tablet.c',
719		'test/litest-device-alps-3fg.c',
720		'test/litest-device-alps-semi-mt.c',
721		'test/litest-device-alps-dualpoint.c',
722		'test/litest-device-anker-mouse-kbd.c',
723		'test/litest-device-apple-appletouch.c',
724		'test/litest-device-apple-internal-keyboard.c',
725		'test/litest-device-apple-magicmouse.c',
726		'test/litest-device-asus-rog-gladius.c',
727		'test/litest-device-atmel-hover.c',
728		'test/litest-device-bcm5974.c',
729		'test/litest-device-calibrated-touchscreen.c',
730		'test/litest-device-cyborg-rat-5.c',
731		'test/litest-device-dell-canvas-totem.c',
732		'test/litest-device-dell-canvas-totem-touch.c',
733		'test/litest-device-elantech-touchpad.c',
734		'test/litest-device-elan-tablet.c',
735		'test/litest-device-format-string.c',
736		'test/litest-device-generic-pressurepad.c',
737		'test/litest-device-generic-singletouch.c',
738		'test/litest-device-gpio-keys.c',
739		'test/litest-device-huion-pentablet.c',
740		'test/litest-device-hp-wmi-hotkeys.c',
741		'test/litest-device-ignored-mouse.c',
742		'test/litest-device-keyboard.c',
743		'test/litest-device-keyboard-all-codes.c',
744		'test/litest-device-keyboard-quirked.c',
745		'test/litest-device-keyboard-razer-blackwidow.c',
746		'test/litest-device-keyboard-razer-blade-stealth.c',
747		'test/litest-device-keyboard-razer-blade-stealth-videoswitch.c',
748		'test/litest-device-lid-switch.c',
749		'test/litest-device-lid-switch-surface3.c',
750		'test/litest-device-logitech-media-keyboard-elite.c',
751		'test/litest-device-logitech-trackball.c',
752		'test/litest-device-nexus4-touch-screen.c',
753		'test/litest-device-magic-trackpad.c',
754		'test/litest-device-mouse.c',
755		'test/litest-device-mouse-wheel-tilt.c',
756		'test/litest-device-mouse-roccat.c',
757		'test/litest-device-mouse-low-dpi.c',
758		'test/litest-device-mouse-wheel-click-angle.c',
759		'test/litest-device-mouse-wheel-click-count.c',
760		'test/litest-device-ms-nano-transceiver-mouse.c',
761		'test/litest-device-ms-surface-cover.c',
762		'test/litest-device-protocol-a-touch-screen.c',
763		'test/litest-device-qemu-usb-tablet.c',
764		'test/litest-device-sony-vaio-keys.c',
765		'test/litest-device-synaptics-x220.c',
766		'test/litest-device-synaptics-hover.c',
767		'test/litest-device-synaptics-i2c.c',
768		'test/litest-device-synaptics-pressurepad.c',
769		'test/litest-device-synaptics-rmi4.c',
770		'test/litest-device-synaptics-st.c',
771		'test/litest-device-synaptics-t440.c',
772		'test/litest-device-synaptics-x1-carbon-3rd.c',
773		'test/litest-device-tablet-mode-switch.c',
774		'test/litest-device-thinkpad-extrabuttons.c',
775		'test/litest-device-trackpoint.c',
776		'test/litest-device-touch-screen.c',
777		'test/litest-device-touchscreen-invalid-range.c',
778		'test/litest-device-touchscreen-fuzz.c',
779		'test/litest-device-touchscreen-mt-tool.c',
780		'test/litest-device-uclogic-tablet.c',
781		'test/litest-device-wacom-bamboo-2fg-finger.c',
782		'test/litest-device-wacom-bamboo-2fg-pad.c',
783		'test/litest-device-wacom-bamboo-2fg-pen.c',
784		'test/litest-device-wacom-bamboo-16fg-pen.c',
785		'test/litest-device-wacom-cintiq-12wx-pen.c',
786		'test/litest-device-wacom-cintiq-13hdt-finger.c',
787		'test/litest-device-wacom-cintiq-13hdt-pad.c',
788		'test/litest-device-wacom-cintiq-13hdt-pen.c',
789		'test/litest-device-wacom-cintiq-24hd-pen.c',
790		'test/litest-device-wacom-cintiq-24hdt-pad.c',
791		'test/litest-device-wacom-cintiq-pro-16-finger.c',
792		'test/litest-device-wacom-cintiq-pro-16-pad.c',
793		'test/litest-device-wacom-cintiq-pro-16-pen.c',
794		'test/litest-device-wacom-ekr.c',
795		'test/litest-device-wacom-hid4800-pen.c',
796		'test/litest-device-wacom-intuos3-pad.c',
797		'test/litest-device-wacom-intuos5-finger.c',
798		'test/litest-device-wacom-intuos5-pad.c',
799		'test/litest-device-wacom-intuos5-pen.c',
800		'test/litest-device-wacom-isdv4-4200-pen.c',
801		'test/litest-device-wacom-isdv4-e6-pen.c',
802		'test/litest-device-wacom-isdv4-e6-finger.c',
803		'test/litest-device-wacom-mobilestudio-pro-pad.c',
804		'test/litest-device-waltop-tablet.c',
805		'test/litest-device-wheel-only.c',
806		'test/litest-device-xen-virtual-pointer.c',
807		'test/litest-device-vmware-virtual-usb-mouse.c',
808		'test/litest-device-yubikey.c',
809		'test/litest.c',
810		'include/valgrind/valgrind.h'
811	]
812
813	dep_dl = cc.find_library('dl')
814	deps_litest = [
815		dep_libinput,
816		dep_check,
817		dep_udev,
818		dep_libevdev,
819		dep_dl,
820		dep_lm,
821		dep_libsystemd,
822		dep_libquirks,
823	]
824
825	litest_config_h = configuration_data()
826	litest_config_h.set_quoted('LIBINPUT_DEVICE_GROUPS_RULES_FILE',
827				   meson.current_build_dir() /
828				   '80-libinput-device-groups-litest.rules')
829	litest_config_h.set_quoted('LIBINPUT_FUZZ_OVERRIDE_UDEV_RULES_FILE',
830				   meson.current_build_dir() /
831				   '90-libinput-fuzz-override-litest.rules')
832
833	def_no_main = '-DLITEST_NO_MAIN'
834	def_disable_backtrace = '-DLITEST_DISABLE_BACKTRACE_LOGGING'
835	defs_litest_selftest = [
836		def_no_main,
837		def_disable_backtrace
838	]
839	test_litest_selftest_sources = [
840		'test/litest-selftest.c',
841		'test/litest.c',
842		'test/litest.h'
843	]
844	test_litest_selftest = executable('test-litest-selftest',
845					  test_litest_selftest_sources,
846					  include_directories : [includes_src, includes_include],
847					  dependencies : deps_litest,
848					  c_args : defs_litest_selftest,
849					  install : false)
850	test('test-litest-selftest',
851	     test_litest_selftest,
852	     suite : ['all'],
853	     timeout : 100)
854
855	def_LT_VERSION = '-DLIBINPUT_LT_VERSION="@0@:@1@:@2@"'.format(libinput_lt_c, libinput_lt_r, libinput_lt_a)
856	test_library_version = executable('test-library-version',
857					  ['test/test-library-version.c'],
858					  c_args : [ def_LT_VERSION ],
859					  install : false)
860	test('test-library-version',
861	     test_library_version,
862	     suite : ['all'])
863
864	test_utils_sources = [
865		'src/libinput-util.h',
866		'test/test-utils.c',
867	]
868	test_utils = executable('test-utils',
869				test_utils_sources,
870				include_directories : [includes_src, includes_include],
871				dependencies : deps_litest,
872				install: false)
873	test('test-utils',
874	     test_utils,
875	     suite : ['all'])
876
877	# When adding new files to this list, update the CI
878	tests_sources = [
879		'test/test-udev.c',
880		'test/test-path.c',
881		'test/test-pointer.c',
882		'test/test-touch.c',
883		'test/test-log.c',
884		'test/test-tablet.c',
885		'test/test-totem.c',
886		'test/test-pad.c',
887		'test/test-touchpad.c',
888		'test/test-touchpad-tap.c',
889		'test/test-touchpad-buttons.c',
890		'test/test-trackpoint.c',
891		'test/test-trackball.c',
892		'test/test-misc.c',
893		'test/test-keyboard.c',
894		'test/test-device.c',
895		'test/test-gestures.c',
896		'test/test-switch.c',
897		'test/test-quirks.c',
898	]
899	libinput_test_runner_sources = litest_sources + tests_sources + [
900		'src/libinput-util.h',
901	]
902	libinput_test_runner = executable('libinput-test-suite',
903					  libinput_test_runner_sources,
904					  include_directories : [includes_src, includes_include],
905					  dependencies : deps_litest,
906					  install_dir : libinput_tool_path,
907					  install : get_option('install-tests'))
908
909	src_man += 'test/libinput-test-suite.man'
910
911	foreach testfile : tests_sources
912		tfile = testfile.split('test/test-')[1]
913		group = tfile.split('.c')[0]
914		test('libinput-test-suite-@0@'.format(group),
915		     libinput_test_runner,
916		     suite : ['all', 'valgrind', 'root', 'hardware'],
917		     args : ['--filter-group=@0@'.format(group),
918			     '--xml-output=junit-@0@-XXXXXX.xml'.format(group)],
919		     is_parallel : false,
920		     timeout : 1200)
921        endforeach
922
923	test('libinput-test-deviceless',
924	     libinput_test_runner,
925	     suite : ['all', 'valgrind'],
926	     args: ['--filter-deviceless',
927	            '--xml-output=junit-deviceless-XXXXXX.xml'])
928
929	valgrind = find_program('valgrind', required : false)
930	if valgrind.found()
931		valgrind_env = environment()
932		valgrind_suppressions_file = dir_src_test / 'valgrind.suppressions'
933		add_test_setup('valgrind',
934				exe_wrapper : [ valgrind,
935						'--leak-check=full',
936						'--gen-suppressions=all',
937						'--error-exitcode=3',
938						'--suppressions=' + valgrind_suppressions_file ],
939				env :  valgrind_env,
940				timeout_multiplier : 100)
941	else
942		message('valgrind not found, disabling valgrind test suite')
943	endif
944	configure_file(output : 'litest-config.h',
945		       configuration : litest_config_h)
946endif
947
948
949############ man pages ############
950man_config = configuration_data()
951man_config.set('LIBINPUT_VERSION', meson.project_version())
952man_config.set('LIBINPUT_DATA_DIR', dir_data)
953src_man += files(
954	'tools/libinput.man',
955	'tools/libinput-analyze.man',
956	'tools/libinput-analyze-per-slot-delta.man',
957	'tools/libinput-analyze-recording.man',
958	'tools/libinput-analyze-touch-down-state.man',
959	'tools/libinput-debug-events.man',
960	'tools/libinput-debug-tablet.man',
961	'tools/libinput-list-devices.man',
962	'tools/libinput-measure.man',
963	'tools/libinput-measure-fuzz.man',
964	'tools/libinput-measure-touchpad-size.man',
965	'tools/libinput-measure-touchpad-tap.man',
966	'tools/libinput-measure-touchpad-pressure.man',
967	'tools/libinput-measure-touch-size.man',
968	'tools/libinput-quirks.man',
969	'tools/libinput-record.man',
970	'tools/libinput-replay.man',
971)
972
973foreach m : src_man
974	configure_file(input : m,
975		       output : '@BASENAME@.1',
976		       configuration : man_config,
977		       install_dir : dir_man1)
978endforeach
979
980# Same man page for the subtools to stay consistent with the other tools
981configure_file(input : 'tools/libinput-quirks.man',
982	       output : 'libinput-quirks-list.1',
983	       configuration : man_config,
984	       install_dir : dir_man1,
985	       )
986configure_file(input : 'tools/libinput-quirks.man',
987	       output : 'libinput-quirks-validate.1',
988	       configuration : man_config,
989	       install_dir : dir_man1,
990	       )
991
992############ output files ############
993configure_file(output : 'config.h', configuration : config_h)
994