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