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