Add support for the meson build system
[platform/upstream/libevdev.git] / meson.build
1 project('libevdev', 'c',
2         version: '1.8.0',
3         license: 'MIT/Expat',
4         default_options: [ 'c_std=gnu99', 'warning_level=2' ],
5         meson_version: '>= 0.47.0')
6
7 libevdev_version = meson.project_version().split('.')
8
9 dir_src         = join_paths(meson.source_root(), 'libevdev')
10 dir_src_test    = join_paths(meson.source_root(), 'test')
11 dir_man1        = join_paths(get_option('prefix'), get_option('mandir'), 'man1')
12
13 # Include directories
14 includes_include = include_directories('include')
15
16 # We use libtool-version numbers because it's easier to understand.
17 # Before making a release, the libinput_so_*
18 # numbers should be modified. The components are of the form C:R:A.
19 # a) If binary compatibility has been broken (eg removed or changed interfaces)
20 #    change to C+1:0:0.
21 # b) If interfaces have been changed or added, but binary compatibility has
22 #    been preserved, change to C+1:0:A+1
23 # c) If the interface is the same as the previous version, change to C:R+1:A
24 libevdev_lt_c=5
25 libevdev_lt_r=0
26 libevdev_lt_a=3
27
28 # convert to soname
29 libevdev_so_version = '@0@.@1@.@2@'.format((libevdev_lt_c - libevdev_lt_a),
30                                            libevdev_lt_a, libevdev_lt_r)
31
32
33 # Compiler setup
34 cc = meson.get_compiler('c')
35 cppflags = ['-Wno-unused-parameter', '-fvisibility=hidden']
36 cflags = cppflags + ['-Wmissing-prototypes', '-Wstrict-prototypes']
37 add_project_arguments(cflags, language : 'c')
38 add_project_arguments(cppflags, language : 'cpp')
39
40 # config.h
41 config_h = configuration_data()
42 config_h.set('_GNU_SOURCE', '1')
43
44 # Dependencies
45 pkgconfig = import('pkgconfig')
46 dep_lm = cc.find_library('m')
47
48 # event-names.h
49 input_h = join_paths(meson.source_root(), 'include', 'linux', 'input.h')
50 input_event_codes_h = join_paths(meson.source_root(), 'include', 'linux', 'input-event-codes.h')
51
52 make_event_names = find_program('libevdev/make-event-names.py')
53 event_names_h = configure_file(input: 'libevdev/libevdev.h',
54                                output: 'event-names.h',
55                                command: [make_event_names, input_h, input_event_codes_h],
56                                capture: true)
57
58
59 # libevdev.so
60 install_headers('libevdev/libevdev.h',
61                 'libevdev/libevdev-uinput.h',
62                 subdir: 'libevdev-1.0/libevdev')
63 src_libevdev = [
64         event_names_h,
65         'libevdev/libevdev.h',
66         'libevdev/libevdev-int.h',
67         'libevdev/libevdev-util.h',
68         'libevdev/libevdev-uinput.c',
69         'libevdev/libevdev-uinput.h',
70         'libevdev/libevdev-uinput-int.h',
71         'libevdev/libevdev.c',
72         'libevdev/libevdev-names.c',
73         'include/linux/input-event-codes.h',
74         'include/linux/input.h',
75         'include/linux/uinput.h'
76 ]
77
78 mapfile = join_paths(dir_src, 'libevdev.sym')
79 version_flag = '-Wl,--version-script,@0@'.format(mapfile)
80 lib_libevdev = shared_library('evdev',
81         src_libevdev,
82         include_directories: [includes_include],
83         dependencies: [],
84         version: libevdev_so_version,
85         link_args: version_flag,
86         link_depends: mapfile,
87         install: true
88 )
89
90 dep_libevdev = declare_dependency(link_with: lib_libevdev)
91
92 pkgconfig.generate(
93         filebase: 'libevdev',
94         name: 'libevdev',
95         description: 'Handler library for evdev events',
96         version: meson.project_version(),
97         libraries: lib_libevdev,
98         subdirs: 'libevdev-1.0',
99 )
100
101 man_config = configuration_data()
102 man_config.set('PACKAGE_VERSION', meson.project_version())
103 manpage = configure_file(input: 'doc/libevdev.man.in',
104                          output: 'libevdev.3',
105                          configuration: man_config)
106 install_man(manpage)
107
108
109 # tools
110 executable('libevdev-events',
111            sources: ['tools/libevdev-events.c'],
112            dependencies: dep_libevdev,
113            install: false)
114 executable('touchpad-edge-detector',
115            sources: ['tools/touchpad-edge-detector.c'],
116            dependencies: [dep_libevdev, dep_lm],
117            install: true)
118 executable('mouse-dpi-tool',
119            sources: ['tools/mouse-dpi-tool.c'],
120            dependencies: dep_libevdev,
121            install: true)
122 executable('libevdev-tweak-device',
123            sources: ['tools/libevdev-tweak-device.c'],
124            dependencies: dep_libevdev,
125            install: true)
126
127
128 # tests
129 dep_check = dependency('check', version: '>= 0.9.9',
130                        required: get_option('tests'))
131 if dep_check.found()
132         executable('test-link',
133                    sources: ['test/test-link.c'],
134                    dependencies: dep_libevdev,
135                    install: false)
136         executable('test-compile-pedantic',
137                    sources: ['test/test-compile-pedantic.c'],
138                    c_args: ['-pedantic', '-Werror', '-std=c89'],
139                    dependencies: dep_libevdev,
140                    install: false)
141
142         src_common = [
143                 'test/test-common-uinput.c',
144                 'test/test-common-uinput.h',
145                 'test/test-common.c',
146                 'test/test-common.h',
147                 'test/test-main.c',
148         ]
149         test_event_codes = executable('test-event-codes',
150                                       sources: src_common + [
151                                         'test/test-event-codes.c',
152                                         'test/test-event-names.c',
153                                         'test/test-context.c',
154                                       ],
155                                       dependencies: [dep_libevdev, dep_check],
156                                       install: false)
157         test('test-event-codes', test_event_codes)
158
159         test_internals = executable('test-internals',
160                                     sources: src_common + [
161                                         'test/test-int-queue.c',
162                                     ],
163                                     dependencies: [dep_libevdev, dep_check],
164                                     install: false)
165         test('test-internals', test_internals)
166
167         test_uinput = executable('test-uinput',
168                                  sources: src_common + [
169                                         'test/test-uinput.c',
170                                  ],
171                                  dependencies: [dep_libevdev, dep_check],
172                                  install: false)
173         test('test-uinput', test_uinput)
174
175         test_libevdev = executable('test-libevdev',
176                                    sources: src_common + [
177                                         'test/test-libevdev-init.c',
178                                         'test/test-libevdev-has-event.c',
179                                         'test/test-libevdev-events.c',
180                                    ],
181                                    dependencies: [dep_libevdev, dep_check],
182                                    install: false)
183         test('test-libevdev', test_libevdev)
184
185         test_kernel = executable('test-kernel',
186                                  sources: src_common + [
187                                         'test/test-kernel.c',
188                                  ],
189                                  dependencies: [dep_libevdev, dep_check],
190                                  install: false)
191         test('test-kernel', test_kernel)
192
193
194         valgrind = find_program('valgrind', required : false)
195         if valgrind.found()
196                 valgrind_env = environment()
197                 valgrind_suppressions_file = join_paths(dir_src_test, 'valgrind.suppressions')
198                 add_test_setup('valgrind',
199                                 exe_wrapper : [ valgrind,
200                                                 '--leak-check=full',
201                                                 '--gen-suppressions=all',
202                                                 '--error-exitcode=3',
203                                                 '--suppressions=' + valgrind_suppressions_file ],
204                                 env :  valgrind_env,
205                                 timeout_multiplier : 100)
206         else
207                 message('valgrind not found, disabling valgrind test suite')
208         endif
209
210         # FIXME: static link test
211 endif
212
213 doxygen = find_program('doxygen', required: get_option('documentation'))
214 if doxygen.found()
215         doxygen = find_program('doxygen')
216
217         src_doxygen = files(
218                 # source files
219                 join_paths(dir_src, 'libevdev.h'),
220                 join_paths(dir_src, 'libevdev-uinput.h'),
221                 # style files
222                 'doc/style/bootstrap.css',
223                 'doc/style/customdoxygen.css',
224                 'doc/style/doxy-boot.js',
225                 'doc/style/dynsections.js',
226                 'doc/style/footer.html',
227                 'doc/style/header.html',
228                 'doc/style/layout.xml',
229                 'doc/style/libevdevdoxygen.css',
230                 'doc/style/LICENSE',
231                 'doc/style/README.md',
232                 'doc/style/style.css',
233         )
234         doxyfiles = []
235         foreach f: src_doxygen
236                 df = configure_file(input: f,
237                                     output: '@PLAINNAME@',
238                                     copy: true)
239                 doxyfiles += [df]
240         endforeach
241
242         doc_config = configuration_data()
243         doc_config.set('PACKAGE_NAME', meson.project_name())
244         doc_config.set('PACKAGE_VERSION', meson.project_version())
245         doc_config.set('builddir', meson.current_build_dir())
246         doc_config.set('top_srcdir', meson.source_root())
247         doc_config.set('srcdir', join_paths(meson.source_root(), 'doc'))
248
249         doxyfile = configure_file(input: 'doc/libevdev.doxygen.in',
250                                   output: 'libevdev.doxygen',
251                                   configuration: doc_config)
252         custom_target('doxygen',
253                       input: [doxyfiles, doxyfile] + src_doxygen,
254                       output: ['.'],
255                       command: [doxygen, doxyfile],
256                       install: false,
257                       build_by_default: true)
258 endif
259
260 # Coverity breaks because it doesn't define _Float128 correctly, you'll end
261 # up with a bunch of messages in the form:
262 # "/usr/include/stdlib.h", line 133: error #20: identifier "_Float128" is
263 #           undefined
264 #   extern _Float128 strtof128 (const char *__restrict __nptr,
265 #          ^
266 # We don't use float128 ourselves, it gets pulled in from math.h or
267 # something, so let's just define it as uint128 and move on.
268 # Unfortunately we can't detect the coverity build at meson configure
269 # time, we only know it fails at runtime. So make this an option instead, to
270 # be removed when coverity fixes this again.
271 if get_option('coverity')
272         config_h.set('_Float128', '__uint128_t')
273         config_h.set('_Float32', 'int')
274         config_h.set('_Float32x', 'int')
275         config_h.set('_Float64', 'long')
276         config_h.set('_Float64x', 'long')
277 endif
278
279 ############ output files ############
280 configure_file(output : 'config.h', configuration : config_h)