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