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