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