Add tests for some device & address variables
[tinc] / src / meson.build
1 inc_conf = include_directories('include')
2
3 cdata = configuration_data()
4
5 cdata.set_quoted('PACKAGE', meson.project_name())
6 cdata.set_quoted('VERSION', meson.project_version())
7 cdata.set_quoted('CONFDIR', dir_sysconf)
8 cdata.set_quoted('RUNSTATEDIR', dir_run_state)
9 cdata.set_quoted('LOCALSTATEDIR', dir_local_state)
10 cdata.set_quoted('SBINDIR', dir_sbin)
11
12 cdata.set('HAVE_' + os_name.to_upper(), 1)
13
14 foreach attr : ['malloc', 'nonnull', 'warn_unused_result', 'packed', 'format']
15   if cc.has_function_attribute(attr)
16     cdata.set('HAVE_ATTR_' + attr.to_upper(), 1,
17               description: '__attribute__((__@0@__))'.format(attr))
18   endif
19 endforeach
20
21 if cc.compiles('''
22     #include <stdlib.h>
23     extern void *make() __attribute__((malloc(free)));
24     int main(void) { return 0; }
25 ''')
26   cdata.set('HAVE_ATTR_MALLOC_WITH_ARG', 1,
27             description: 'support for __attribute__((malloc(deallocator)))')
28 endif
29
30 if cc.compiles('''
31     _Static_assert(1, "ok");
32     int main(void) { return 0; }
33 ''')
34   cdata.set('HAVE_STATIC_ASSERT', 1,
35             description: 'C11 _Static_assert()')
36 endif
37
38 check_headers = [
39   'alloca.h',
40   'arpa/inet.h',
41   'arpa/nameser.h',
42   'dirent.h',
43   'getopt.h',
44   'inttypes.h',
45   'net/ethernet.h',
46   'net/if.h',
47   'net/if_arp.h',
48   'net/if_types.h',
49   'netdb.h',
50   'netinet/icmp6.h',
51   'netinet/if_ether.h',
52   'netinet/in.h',
53   'netinet/in6.h',
54   'netinet/in_systm.h',
55   'netinet/ip.h',
56   'netinet/ip6.h',
57   'netinet/ip_icmp.h',
58   'netinet/tcp.h',
59   'resolv.h',
60   'stddef.h',
61   'sys/file.h',
62   'sys/ioctl.h',
63   'sys/mman.h',
64   'sys/param.h',
65   'sys/random.h',
66   'sys/resource.h',
67   'sys/socket.h',
68   'sys/stat.h',
69   'sys/time.h',
70   'sys/types.h',
71   'sys/wait.h',
72   'syslog.h',
73   'string.h',
74   'termios.h',
75   'unistd.h',
76 ]
77
78 # 'struct msghdr' misses some required fields
79 if os_name != 'sunos'
80   check_headers += 'sys/un.h'
81 endif
82
83 check_functions = [
84   'asprintf',
85   'daemon',
86   'explicit_bzero',
87   'explicit_memset',
88   'fchmod',
89   'getentropy',
90   'gettimeofday',
91   'memset_s',
92   'mlockall',
93   'putenv',
94   'strsignal',
95   'unsetenv',
96 ]
97
98 # Broken definition, fails to link
99 if os_name != 'windows'
100   check_functions += 'fork'
101 endif
102
103 check_types = [
104   'struct arphdr',
105   'struct ether_arp',
106   'struct ether_header',
107   'struct icmp',
108   'struct icmp6_hdr',
109   'struct ip',
110   'struct ip6_hdr',
111   'struct nd_neighbor_solicit',
112   'struct nd_opt_hdr',
113 ]
114
115 subdir('ed25519')
116 subdir('chacha-poly1305')
117
118 src_lib_common = [
119   'conf.c',
120   'console.c',
121   'dropin.c',
122   'fs.c',
123   'keys.c',
124   'list.c',
125   'logger.c',
126   'names.c',
127   'netutl.c',
128   'pidfile.c',
129   'script.c',
130   'splay_tree.c',
131   'sptps.c',
132   'subnet_parse.c',
133   'utils.c',
134   'version.c',
135   'xoshiro.c',
136 ]
137
138 src_tinc = [
139   'fsck.c',
140   'ifconfig.c',
141   'info.c',
142   'invitation.c',
143   'top.c',
144 ]
145
146 src_tincd = [
147   'address_cache.c',
148   'autoconnect.c',
149   'buffer.c',
150   'compression.h',
151   'conf_net.c',
152   'connection.c',
153   'control.c',
154   'dummy_device.c',
155   'edge.c',
156   'event.c',
157   'graph.c',
158   'meta.c',
159   'multicast_device.c',
160   'net.c',
161   'net_packet.c',
162   'net_setup.c',
163   'net_socket.c',
164   'node.c',
165   'process.c',
166   'protocol.c',
167   'protocol_auth.c',
168   'protocol_edge.c',
169   'protocol_key.c',
170   'protocol_misc.c',
171   'protocol_subnet.c',
172   'proxy.c',
173   'raw_socket_device.c',
174   'route.c',
175   'subnet.c',
176 ]
177
178 src_event_select = files('event_select.c')
179
180 if os_name != 'windows'
181   src_tincd += 'signal.c'
182 endif
183
184 cc_flags_tinc = cc_flags
185 cc_flags_tincd = cc_flags
186
187 deps_common = []
188 deps_tinc = []
189 deps_tincd = [cc.find_library('m', required: false)]
190
191 if os_name != 'windows'
192   src_lib_common += 'random.c'
193 endif
194
195 if os_name in ['linux', 'android']
196   subdir('linux')
197 elif os_name.endswith('bsd') or os_name in ['dragonfly', 'darwin']
198   subdir('bsd')
199 elif os_name == 'sunos'
200   subdir('solaris')
201 elif os_name == 'windows'
202   subdir('windows')
203 endif
204
205 foreach h : check_headers
206   if cc.has_header(h)
207     cdata.set('HAVE_' + h.to_upper().underscorify(),
208               1,
209               description: '#include <' + h + '>')
210   endif
211 endforeach
212
213 if cdata.has('HAVE_SYS_UN_H')
214   src_tincd += 'fd_device.c'
215   cdata.set('HAVE_FD_DEVICE', 1)
216 endif
217
218 confdata = configuration_data()
219 confdata.merge_from(cdata)
220 configure_file(output: 'meson_config.h', configuration: confdata)
221
222 have_prefix = '''
223   #include "@0@/src/meson_config.h"
224   #include "@1@/have.h"
225 '''.format(build_root, meson.current_source_dir())
226
227 foreach f : check_functions
228   if cc.has_function(f, prefix: have_prefix, args: cc_defs)
229     cdata.set('HAVE_' + f.to_upper(),
230               1,
231               description: 'function ' + f)
232   endif
233 endforeach
234
235 if cc.has_function('res_init', prefix: '''
236   #include <netinet/in.h>
237   #include <resolv.h>
238 ''', args: cc_defs)
239   cdata.set('HAVE_DECL_RES_INIT', 1)
240 endif
241
242 foreach type : check_types
243   if cc.has_type(type, prefix: have_prefix, args: cc_defs)
244     name = 'HAVE_' + type.to_upper().underscorify()
245     cdata.set(name, 1, description: type)
246   endif
247 endforeach
248
249 src_getopt = []
250 if not cdata.has('HAVE_GETOPT_H') or not cc.has_function('getopt_long', prefix: have_prefix, args: cc_defs)
251   src_getopt = ['getopt.c', 'getopt1.c']
252   src_lib_common += src_getopt
253 endif
254
255 if not opt_miniupnpc.disabled()
256   dep_miniupnpc = dependency('miniupnpc', required: false, static: static)
257   if not dep_miniupnpc.found()
258     # No pkg-config files on MinGW
259     dep_miniupnpc = cc.find_library('miniupnpc', required: opt_miniupnpc, static: static)
260   endif
261   if dep_miniupnpc.found()
262     src_tincd += 'upnp.c'
263     deps_tincd += [
264       dependency('threads', static: static),
265       dep_miniupnpc,
266     ]
267     if static
268       cc_flags_tincd += '-DMINIUPNP_STATICLIB'
269     endif
270     cdata.set('HAVE_MINIUPNPC', 1)
271   endif
272 endif
273
274 if not opt_curses.disabled()
275   # The meta-dependency covers more alternatives, but is only available in 0.54+
276   curses_name = meson_version.version_compare('>=0.54') ? 'curses' : 'ncurses'
277   dep_curses = dependency(curses_name, required: opt_curses, static: static)
278   if dep_curses.found()
279     cdata.set('HAVE_CURSES', 1)
280     deps_tinc += dep_curses
281     if static
282       cc_flags_tinc += '-DNCURSES_STATIC'
283     endif
284   endif
285 endif
286
287 # Some distributions do not supply pkg-config files for readline
288 if opt_readline.auto() and os_name == 'windows'
289   message('readline not available on Windows')
290 else
291   dep_readline = dependency('readline', required: opt_readline, static: static)
292   if not dep_readline.found()
293     dep_readline = cc.find_library('readline', required: opt_readline, static: static)
294   endif
295   if not dep_readline.found()
296     dep_readline = cc.find_library('libedit', required: opt_readline, static: static)
297   endif
298   if dep_readline.found() and \
299      cc.has_header('readline/readline.h', dependencies: dep_readline) and \
300      cc.has_header('readline/history.h', dependencies: dep_readline)
301     cdata.set('HAVE_READLINE', 1)
302     deps_tinc += dep_readline
303   endif
304 endif
305
306 dep_zlib = dependency('zlib',
307                       required: opt_zlib,
308                       static: static,
309                       fallback: ['zlib', 'zlib_dep'])
310 if dep_zlib.found()
311   cdata.set('HAVE_ZLIB', 1)
312   deps_tincd += dep_zlib
313 endif
314
315 if not opt_lzo.disabled()
316   dep_lzo = dependency('lzo2', required: false, static: static)
317   if not dep_lzo.found()
318     dep_lzo = cc.find_library('lzo2', required: opt_lzo, static: static)
319   endif
320   if not dep_lzo.found()
321     dep_lzo = dependency('lzo2',
322                          required: false,
323                          static: static,
324                          fallback: ['lzo2', 'lzo2_dep'])
325   endif
326   if dep_lzo.found()
327     if dep_lzo.type_name() == 'internal' or cc.has_header('lzo/lzo1x.h', dependencies: dep_lzo)
328       cdata.set('LZO1X_H', '<lzo/lzo1x.h>')
329     elif cc.has_header('lzo1x.h', dependencies: dep_lzo)
330       cdata.set('LZO1X_H', '<lzo1x.h>')
331     else
332       msg = 'lzo1x.h not found'
333       if opt_lzo.auto()
334         warning(msg)
335       else
336         error(msg)
337       endif
338     endif
339     if cdata.has('LZO1X_H')
340       cdata.set('HAVE_LZO', 1)
341       deps_tincd += dep_lzo
342     endif
343   endif
344 endif
345
346 dep_lz4 = dependency('liblz4',
347                      required: opt_lz4,
348                      static: static,
349                      fallback: ['lz4', 'liblz4_dep'])
350 if dep_lz4.found()
351   deps_tincd += dep_lz4
352   cdata.set('HAVE_LZ4', 1)
353 endif
354
355 dep_vde = dependency('vdeplug', required: opt_vde, static: static)
356 dep_dl = cc.find_library('dl', required: opt_vde)
357 if dep_vde.found() and dep_dl.found()
358   cdata.set('ENABLE_VDE', 1)
359   src_tincd += 'vde_device.c'
360   deps_tincd += [dep_dl, dep_vde]
361 endif
362
363 if opt_jumbograms
364   cdata.set('ENABLE_JUMBOGRAMS', 1)
365 endif
366
367 subdir(opt_crypto)
368
369 if opt_crypto != 'nolegacy'
370   src_lib_crypto += ['cipher.c', 'digest.c']
371 endif
372
373 subdir('include')
374
375 have_sandbox = cdata.has('HAVE_SANDBOX')
376 if not have_sandbox
377   src_lib_common += 'sandbox.c'
378 endif
379
380 lib_crypto = static_library(
381   'tinc_crypto',
382   sources: src_lib_crypto,
383   dependencies: dep_crypto,
384   implicit_include_directories: false,
385   include_directories: inc_conf,
386   build_by_default: false,
387 )
388
389 deps_lib_common = [deps_common, dep_crypto]
390 deps_tinc += deps_lib_common
391 deps_tincd += deps_lib_common
392
393 lib_common = static_library(
394   'common',
395   sources: src_lib_common,
396   dependencies: deps_lib_common,
397   link_with: [lib_ed25519, lib_chacha_poly, lib_crypto],
398   implicit_include_directories: false,
399   include_directories: inc_conf,
400   build_by_default: false,
401 )
402
403 lib_tinc = static_library(
404   'tinc',
405   sources: src_tinc,
406   dependencies: deps_tinc,
407   link_with: lib_common,
408   c_args: cc_flags_tinc,
409   implicit_include_directories: false,
410   include_directories: inc_conf,
411   build_by_default: false,
412 )
413
414 lib_tincd = static_library(
415   'tincd',
416   sources: src_tincd,
417   dependencies: deps_tincd,
418   link_with: lib_common,
419   c_args: cc_flags_tincd,
420   implicit_include_directories: false,
421   include_directories: inc_conf,
422   build_by_default: false,
423 )
424
425 exe_tinc = executable(
426   'tinc',
427   sources: 'tincctl.c',
428   dependencies: deps_tinc,
429   link_with: lib_tinc,
430   implicit_include_directories: false,
431   include_directories: inc_conf,
432   install: true,
433   install_dir: dir_sbin,
434 )
435
436 exe_tincd = executable(
437   'tincd',
438   sources: 'tincd.c',
439   dependencies: deps_tincd,
440   link_with: lib_tincd,
441   c_args: cc_flags_tincd,
442   implicit_include_directories: false,
443   include_directories: inc_conf,
444   install: true,
445   install_dir: dir_sbin,
446 )
447
448 exe_sptps_test = executable(
449   'sptps_test',
450   sources: [src_getopt, 'sptps_test.c'],
451   dependencies: deps_lib_common,
452   link_with: lib_common,
453   implicit_include_directories: false,
454   include_directories: inc_conf,
455   build_by_default: false,
456 )
457
458 exe_sptps_keypair = executable(
459   'sptps_keypair',
460   sources: [src_getopt, 'sptps_keypair.c'],
461   dependencies: deps_lib_common,
462   link_with: lib_common,
463   implicit_include_directories: false,
464   include_directories: inc_conf,
465   build_by_default: false,
466 )
467
468 if os_name == 'linux'
469   dep_rt = cc.find_library('rt')
470
471   exe_sptps_speed = executable(
472     'sptps_speed',
473     sources: 'sptps_speed.c',
474     dependencies: [deps_lib_common, dep_rt],
475     link_with: lib_common,
476     implicit_include_directories: false,
477     include_directories: inc_conf,
478     build_by_default: false,
479   )
480
481   benchmark('sptps_speed', exe_sptps_speed, timeout: 90)
482 endif
483