Revert "sd-bus: remove 'hint_sync_call' parameter from various function calls"
[platform/upstream/systemd.git] / meson.build
1 # SPDX-License-Identifier: LGPL-2.1+
2 #
3 # Copyright 2017 Zbigniew JÄ™drzejewski-Szmek
4 #
5 # systemd is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU Lesser General Public License as published by
7 # the Free Software Foundation; either version 2.1 of the License, or
8 # (at your option) any later version.
9 #
10 # systemd is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with systemd; If not, see <http://www.gnu.org/licenses/>.
17
18 project('systemd', 'c',
19         version : '237',
20         license : 'LGPLv2+',
21         default_options: [
22                 'c_std=gnu99',
23                 'prefix=/usr',
24                 'sysconfdir=/etc',
25                 'localstatedir=/var',
26         ],
27         meson_version : '>= 0.41',
28        )
29
30 libsystemd_version = '0.21.0'
31 libudev_version = '1.6.9'
32
33 # We need the same data in three different formats, ugh!
34 # Also, for hysterical reasons, we use different variable
35 # names, sometimes. Not all variables are included in every
36 # set. Ugh, ugh, ugh!
37 conf = configuration_data()
38 conf.set_quoted('PACKAGE_STRING',  meson.project_name() + ' ' + meson.project_version())
39 conf.set_quoted('PACKAGE_VERSION', meson.project_version())
40
41 substs = configuration_data()
42 substs.set('PACKAGE_URL',          'https://www.freedesktop.org/wiki/Software/systemd')
43 substs.set('PACKAGE_VERSION',      meson.project_version())
44
45 m4_defines = []
46
47 #####################################################################
48
49 # Try to install the git pre-commit hook
50 git_hook = run_command(join_paths(meson.source_root(), 'tools/add-git-hook.sh'))
51 if git_hook.returncode() == 0
52         message(git_hook.stdout().strip())
53 endif
54
55 #####################################################################
56
57 split_usr = get_option('split-usr')
58 conf.set10('HAVE_SPLIT_USR', split_usr)
59
60 rootprefixdir = get_option('rootprefix')
61 # Unusual rootprefixdir values are used by some distros
62 # (see https://github.com/systemd/systemd/pull/7461).
63 rootprefix_default = get_option('split-usr') ? '/' : '/usr'
64 if rootprefixdir == ''
65         rootprefixdir = rootprefix_default
66 endif
67
68 sysvinit_path = get_option('sysvinit-path')
69 sysvrcnd_path = get_option('sysvrcnd-path')
70 have = sysvinit_path != '' and sysvrcnd_path != ''
71 conf.set10('HAVE_SYSV_COMPAT', have,
72            description : 'SysV init scripts and rcN.d links are supported')
73 m4_defines += have ? ['-DHAVE_SYSV_COMPAT'] : []
74
75 # join_paths ignore the preceding arguments if an absolute component is
76 # encountered, so this should canonicalize various paths when they are
77 # absolute or relative.
78 prefixdir = get_option('prefix')
79 if not prefixdir.startswith('/')
80         error('Prefix is not absolute: "@0@"'.format(prefixdir))
81 endif
82 bindir = join_paths(prefixdir, get_option('bindir'))
83 libdir = join_paths(prefixdir, get_option('libdir'))
84 sysconfdir = join_paths(prefixdir, get_option('sysconfdir'))
85 includedir = join_paths(prefixdir, get_option('includedir'))
86 datadir = join_paths(prefixdir, get_option('datadir'))
87 localstatedir = join_paths('/', get_option('localstatedir'))
88
89 rootbindir = join_paths(rootprefixdir, 'bin')
90 rootlibexecdir = join_paths(rootprefixdir, 'lib/systemd')
91
92 rootlibdir = get_option('rootlibdir')
93 if rootlibdir == ''
94         rootlibdir = join_paths(rootprefixdir, libdir.split('/')[-1])
95 endif
96
97 # Dirs of external packages
98 pkgconfigdatadir = join_paths(datadir, 'pkgconfig')
99 pkgconfiglibdir = join_paths(libdir, 'pkgconfig')
100 polkitpolicydir = join_paths(datadir, 'polkit-1/actions')
101 polkitrulesdir = join_paths(datadir, 'polkit-1/rules.d')
102 polkitpkladir = join_paths(localstatedir, 'lib/polkit-1/localauthority/10-vendor.d')
103 varlogdir = join_paths(localstatedir, 'log')
104 xinitrcdir = join_paths(sysconfdir, 'X11/xinit/xinitrc.d')
105 rpmmacrosdir = get_option('rpmmacrosdir')
106 if rpmmacrosdir != 'no'
107         rpmmacrosdir = join_paths(prefixdir, rpmmacrosdir)
108 endif
109 modprobedir = join_paths(rootprefixdir, 'lib/modprobe.d')
110
111 # Our own paths
112 pkgdatadir = join_paths(datadir, 'systemd')
113 environmentdir = join_paths(prefixdir, 'lib/environment.d')
114 pkgsysconfdir = join_paths(sysconfdir, 'systemd')
115 userunitdir = join_paths(prefixdir, 'lib/systemd/user')
116 userpresetdir = join_paths(prefixdir, 'lib/systemd/user-preset')
117 tmpfilesdir = join_paths(prefixdir, 'lib/tmpfiles.d')
118 sysusersdir = join_paths(prefixdir, 'lib/sysusers.d')
119 sysctldir = join_paths(prefixdir, 'lib/sysctl.d')
120 binfmtdir = join_paths(prefixdir, 'lib/binfmt.d')
121 modulesloaddir = join_paths(prefixdir, 'lib/modules-load.d')
122 networkdir = join_paths(rootprefixdir, 'lib/systemd/network')
123 pkgincludedir = join_paths(includedir, 'systemd')
124 systemgeneratordir = join_paths(rootlibexecdir, 'system-generators')
125 usergeneratordir = join_paths(prefixdir, 'lib/systemd/user-generators')
126 systemenvgeneratordir = join_paths(prefixdir, 'lib/systemd/system-environment-generators')
127 userenvgeneratordir = join_paths(prefixdir, 'lib/systemd/user-environment-generators')
128 systemshutdowndir = join_paths(rootlibexecdir, 'system-shutdown')
129 systemsleepdir = join_paths(rootlibexecdir, 'system-sleep')
130 systemunitdir = join_paths(rootprefixdir, 'lib/systemd/system')
131 systempresetdir = join_paths(rootprefixdir, 'lib/systemd/system-preset')
132 udevlibexecdir = join_paths(rootprefixdir, 'lib/udev')
133 udevhomedir = udevlibexecdir
134 udevrulesdir = join_paths(udevlibexecdir, 'rules.d')
135 udevhwdbdir = join_paths(udevlibexecdir, 'hwdb.d')
136 catalogdir = join_paths(prefixdir, 'lib/systemd/catalog')
137 kernelinstalldir = join_paths(prefixdir, 'lib/kernel/install.d')
138 factorydir = join_paths(datadir, 'factory')
139 docdir = join_paths(datadir, 'doc/systemd')
140 bootlibdir = join_paths(prefixdir, 'lib/systemd/boot/efi')
141 testsdir = join_paths(prefixdir, 'lib/systemd/tests')
142 systemdstatedir = join_paths(localstatedir, 'lib/systemd')
143 catalogstatedir = join_paths(systemdstatedir, 'catalog')
144 randomseeddir = join_paths(localstatedir, 'lib/systemd')
145
146 dbuspolicydir = get_option('dbuspolicydir')
147 if dbuspolicydir == ''
148         dbuspolicydir = join_paths(datadir, 'dbus-1/system.d')
149 endif
150
151 dbussessionservicedir = get_option('dbussessionservicedir')
152 if dbussessionservicedir == ''
153         dbussessionservicedir = join_paths(datadir, 'dbus-1/services')
154 endif
155
156 dbussystemservicedir = get_option('dbussystemservicedir')
157 if dbussystemservicedir == ''
158         dbussystemservicedir = join_paths(datadir, 'dbus-1/system-services')
159 endif
160
161 pamlibdir = get_option('pamlibdir')
162 if pamlibdir == ''
163         pamlibdir = join_paths(rootlibdir, 'security')
164 endif
165
166 pamconfdir = get_option('pamconfdir')
167 if pamconfdir == ''
168         pamconfdir = join_paths(sysconfdir, 'pam.d')
169 endif
170
171 conf.set_quoted('PKGSYSCONFDIR',                              pkgsysconfdir)
172 conf.set_quoted('SYSTEM_CONFIG_UNIT_PATH',                    join_paths(pkgsysconfdir, 'system'))
173 conf.set_quoted('SYSTEM_DATA_UNIT_PATH',                      systemunitdir)
174 conf.set_quoted('SYSTEM_SYSVINIT_PATH',                       sysvinit_path)
175 conf.set_quoted('SYSTEM_SYSVRCND_PATH',                       sysvrcnd_path)
176 conf.set_quoted('RC_LOCAL_SCRIPT_PATH_START',                 get_option('rc-local'))
177 conf.set_quoted('RC_LOCAL_SCRIPT_PATH_STOP',                  get_option('halt-local'))
178 conf.set_quoted('USER_CONFIG_UNIT_PATH',                      join_paths(pkgsysconfdir, 'user'))
179 conf.set_quoted('USER_DATA_UNIT_PATH',                        userunitdir)
180 conf.set_quoted('CERTIFICATE_ROOT',                           get_option('certificate-root'))
181 conf.set_quoted('CATALOG_DATABASE',                           join_paths(catalogstatedir, 'database'))
182 conf.set_quoted('SYSTEMD_CGROUP_AGENT_PATH',                  join_paths(rootlibexecdir, 'systemd-cgroups-agent'))
183 conf.set_quoted('SYSTEMD_BINARY_PATH',                        join_paths(rootlibexecdir, 'systemd'))
184 conf.set_quoted('SYSTEMD_FSCK_PATH',                          join_paths(rootlibexecdir, 'systemd-fsck'))
185 conf.set_quoted('SYSTEMD_MAKEFS_PATH',                        join_paths(rootlibexecdir, 'systemd-makefs'))
186 conf.set_quoted('SYSTEMD_GROWFS_PATH',                        join_paths(rootlibexecdir, 'systemd-growfs'))
187 conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH',               join_paths(rootlibexecdir, 'systemd-shutdown'))
188 conf.set_quoted('SYSTEMD_SLEEP_BINARY_PATH',                  join_paths(rootlibexecdir, 'systemd-sleep'))
189 conf.set_quoted('SYSTEMCTL_BINARY_PATH',                      join_paths(rootbindir, 'systemctl'))
190 conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', join_paths(rootbindir, 'systemd-tty-ask-password-agent'))
191 conf.set_quoted('SYSTEMD_STDIO_BRIDGE_BINARY_PATH',           join_paths(bindir, 'systemd-stdio-bridge'))
192 conf.set_quoted('ROOTPREFIX',                                 rootprefixdir)
193 conf.set_quoted('RANDOM_SEED_DIR',                            randomseeddir)
194 conf.set_quoted('RANDOM_SEED',                                join_paths(randomseeddir, 'random-seed'))
195 conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH',                    join_paths(rootlibexecdir, 'systemd-cryptsetup'))
196 conf.set_quoted('SYSTEM_GENERATOR_PATH',                      systemgeneratordir)
197 conf.set_quoted('USER_GENERATOR_PATH',                        usergeneratordir)
198 conf.set_quoted('SYSTEM_ENV_GENERATOR_PATH',                  systemenvgeneratordir)
199 conf.set_quoted('USER_ENV_GENERATOR_PATH',                    userenvgeneratordir)
200 conf.set_quoted('SYSTEM_SHUTDOWN_PATH',                       systemshutdowndir)
201 conf.set_quoted('SYSTEM_SLEEP_PATH',                          systemsleepdir)
202 conf.set_quoted('SYSTEMD_KBD_MODEL_MAP',                      join_paths(pkgdatadir, 'kbd-model-map'))
203 conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP',              join_paths(pkgdatadir, 'language-fallback-map'))
204 conf.set_quoted('UDEVLIBEXECDIR',                             udevlibexecdir)
205 conf.set_quoted('POLKIT_AGENT_BINARY_PATH',                   join_paths(bindir, 'pkttyagent'))
206 conf.set_quoted('LIBDIR',                                     libdir)
207 conf.set_quoted('ROOTLIBDIR',                                 rootlibdir)
208 conf.set_quoted('ROOTLIBEXECDIR',                             rootlibexecdir)
209 conf.set_quoted('BOOTLIBDIR',                                 bootlibdir)
210 conf.set_quoted('SYSTEMD_PULL_PATH',                          join_paths(rootlibexecdir, 'systemd-pull'))
211 conf.set_quoted('SYSTEMD_IMPORT_PATH',                        join_paths(rootlibexecdir, 'systemd-import'))
212 conf.set_quoted('SYSTEMD_EXPORT_PATH',                        join_paths(rootlibexecdir, 'systemd-export'))
213 conf.set_quoted('VENDOR_KEYRING_PATH',                        join_paths(rootlibexecdir, 'import-pubring.gpg'))
214 conf.set_quoted('USER_KEYRING_PATH',                          join_paths(pkgsysconfdir, 'import-pubring.gpg'))
215 conf.set_quoted('DOCUMENT_ROOT',                              join_paths(pkgdatadir, 'gatewayd'))
216
217 conf.set_quoted('ABS_BUILD_DIR',                              meson.build_root())
218 conf.set_quoted('ABS_SRC_DIR',                                meson.source_root())
219
220 substs.set('prefix',                                          prefixdir)
221 substs.set('exec_prefix',                                     prefixdir)
222 substs.set('libdir',                                          libdir)
223 substs.set('rootlibdir',                                      rootlibdir)
224 substs.set('includedir',                                      includedir)
225 substs.set('pkgsysconfdir',                                   pkgsysconfdir)
226 substs.set('bindir',                                          bindir)
227 substs.set('rootbindir',                                      rootbindir)
228 substs.set('rootlibexecdir',                                  rootlibexecdir)
229 substs.set('systemunitdir',                                   systemunitdir)
230 substs.set('userunitdir',                                     userunitdir)
231 substs.set('systempresetdir',                                 systempresetdir)
232 substs.set('userpresetdir',                                   userpresetdir)
233 substs.set('udevhwdbdir',                                     udevhwdbdir)
234 substs.set('udevrulesdir',                                    udevrulesdir)
235 substs.set('udevlibexecdir',                                  udevlibexecdir)
236 substs.set('catalogdir',                                      catalogdir)
237 substs.set('tmpfilesdir',                                     tmpfilesdir)
238 substs.set('sysusersdir',                                     sysusersdir)
239 substs.set('sysctldir',                                       sysctldir)
240 substs.set('binfmtdir',                                       binfmtdir)
241 substs.set('modulesloaddir',                                  modulesloaddir)
242 substs.set('systemgeneratordir',                              systemgeneratordir)
243 substs.set('usergeneratordir',                                usergeneratordir)
244 substs.set('systemenvgeneratordir',                           systemenvgeneratordir)
245 substs.set('userenvgeneratordir',                             userenvgeneratordir)
246 substs.set('systemshutdowndir',                               systemshutdowndir)
247 substs.set('systemsleepdir',                                  systemsleepdir)
248 substs.set('VARLOGDIR',                                       varlogdir)
249 substs.set('CERTIFICATEROOT',                                 get_option('certificate-root'))
250 substs.set('SYSTEMCTL',                                       join_paths(rootbindir, 'systemctl'))
251 substs.set('RANDOM_SEED',                                     join_paths(randomseeddir, 'random-seed'))
252 substs.set('SYSTEM_SYSVINIT_PATH',                            sysvinit_path)
253 substs.set('SYSTEM_SYSVRCND_PATH',                            sysvrcnd_path)
254 substs.set('RC_LOCAL_SCRIPT_PATH_START',                      get_option('rc-local'))
255 substs.set('RC_LOCAL_SCRIPT_PATH_STOP',                       get_option('halt-local'))
256
257 #####################################################################
258
259 cc = meson.get_compiler('c')
260 pkgconfig = import('pkgconfig')
261 check_compilation_sh = find_program('tools/meson-check-compilation.sh')
262 meson_build_sh = find_program('tools/meson-build.sh')
263
264 if get_option('tests') != 'false'
265         cxx = find_program('c++', required : false)
266         if cxx.found()
267                 #  Used only for tests
268                 add_languages('cpp')
269         endif
270 endif
271
272 want_ossfuzz = get_option('oss-fuzz')
273 want_libfuzzer = get_option('llvm-fuzz')
274 fuzzer_build = want_ossfuzz or want_libfuzzer
275 if want_ossfuzz and want_libfuzzer
276         error('only one of oss-fuzz and llvm-fuzz can be specified')
277 endif
278 if want_libfuzzer
279         fuzzing_engine = meson.get_compiler('cpp').find_library('Fuzzer')
280 endif
281 if want_ossfuzz
282         fuzzing_engine = meson.get_compiler('cpp').find_library('FuzzingEngine')
283 endif
284
285 foreach arg : ['-Wextra',
286                '-Werror=undef',
287                '-Wlogical-op',
288                '-Wmissing-include-dirs',
289                '-Wold-style-definition',
290                '-Wpointer-arith',
291                '-Winit-self',
292                '-Wdeclaration-after-statement',
293                '-Wfloat-equal',
294                '-Wsuggest-attribute=noreturn',
295                '-Werror=missing-prototypes',
296                '-Werror=implicit-function-declaration',
297                '-Werror=missing-declarations',
298                '-Werror=return-type',
299                '-Werror=incompatible-pointer-types',
300                '-Werror=format=2',
301                '-Wstrict-prototypes',
302                '-Wredundant-decls',
303                '-Wmissing-noreturn',
304                '-Wimplicit-fallthrough=5',
305                '-Wshadow',
306                '-Wendif-labels',
307                '-Wstrict-aliasing=2',
308                '-Wwrite-strings',
309                '-Werror=overflow',
310                '-Wdate-time',
311                '-Wnested-externs',
312                '-ffast-math',
313                '-fno-common',
314                '-fdiagnostics-show-option',
315                '-fno-strict-aliasing',
316                '-fvisibility=hidden',
317                '-fstack-protector',
318                '-fstack-protector-strong',
319                '--param=ssp-buffer-size=4',
320               ]
321         if cc.has_argument(arg)
322                 add_project_arguments(arg, language : 'c')
323         endif
324 endforeach
325
326 # the oss-fuzz fuzzers are not built with -fPIE, so don't
327 # enable it when we are linking against them
328 if not fuzzer_build
329         if cc.has_argument('-fPIE')
330               add_project_arguments('-fPIE', language : 'c')
331         endif
332 endif
333
334 # "negative" arguments: gcc on purpose does not return an error for "-Wno-"
335 # arguments, just emits a warnings. So test for the "positive" version instead.
336 foreach arg : ['unused-parameter',
337                'missing-field-initializers',
338                'unused-result',
339                'format-signedness',
340                'error=nonnull', # work-around for gcc 7.1 turning this on on its own
341               ]
342         if cc.has_argument('-W' + arg)
343                 add_project_arguments('-Wno-' + arg, language : 'c')
344         endif
345 endforeach
346
347 if cc.compiles('
348    #include <time.h>
349    #include <inttypes.h>
350    typedef uint64_t usec_t;
351    usec_t now(clockid_t clock);
352    int main(void) {
353            struct timespec now;
354            return 0;
355    }
356 ', name : '-Werror=shadow with local shadowing')
357         add_project_arguments('-Werror=shadow', language : 'c')
358 endif
359
360 if cc.get_id() == 'clang'
361         foreach arg : ['-Wno-typedef-redefinition',
362                        '-Wno-gnu-variable-sized-type-not-at-end',
363                       ]
364                 if cc.has_argument(arg,
365                                    name : '@0@ is supported'.format(arg))
366                         add_project_arguments(arg, language : 'c')
367                 endif
368         endforeach
369 endif
370
371 link_test_c = files('tools/meson-link-test.c')
372
373 # --as-needed and --no-undefined are provided by meson by default,
374 # run mesonconf to see what is enabled
375 foreach arg : ['-Wl,-z,relro',
376                '-Wl,-z,now',
377                '-pie',
378               ]
379
380         have = run_command(check_compilation_sh,
381                            cc.cmd_array(), '-x', 'c', arg,
382                            '-include', link_test_c).returncode() == 0
383         message('Linking with @0@ supported: @1@'.format(arg, have ? 'yes' : 'no'))
384         if have and (arg != '-pie' or not fuzzer_build)
385                 add_project_link_arguments(arg, language : 'c')
386         endif
387 endforeach
388
389 # Check if various sanitizers are supported
390 sanitizers = []
391 foreach arg : ['address']
392
393         have = run_command(check_compilation_sh,
394                            cc.cmd_array(), '-x', 'c',
395                            '-fsanitize=@0@'.format(arg),
396                            '-include', link_test_c).returncode() == 0
397         message('@0@ sanitizer supported: @1@'.format(arg, have ? 'yes' : 'no'))
398         if have
399                 sanitizers += arg
400         endif
401 endforeach
402
403 if get_option('buildtype') != 'debug'
404         foreach arg : ['-ffunction-sections',
405                        '-fdata-sections']
406                 if cc.has_argument(arg,
407                                    name : '@0@ is supported'.format(arg))
408                         add_project_arguments(arg, language : 'c')
409                 endif
410         endforeach
411
412         foreach arg : ['-Wl,--gc-sections']
413                 have = run_command(check_compilation_sh,
414                                    cc.cmd_array(), '-x', 'c', arg,
415                                    '-include', link_test_c).returncode() == 0
416                 message('Linking with @0@ supported: @1@'.format(arg, have ? 'yes' : 'no'))
417                 if have
418                         add_project_link_arguments(arg, language : 'c')
419                 endif
420         endforeach
421 endif
422
423 cpp = ' '.join(cc.cmd_array()) + ' -E'
424
425 #####################################################################
426 # compilation result tests
427
428 conf.set('_GNU_SOURCE', true)
429 conf.set('__SANE_USERSPACE_TYPES__', true)
430
431 conf.set('SIZEOF_PID_T', cc.sizeof('pid_t', prefix : '#include <sys/types.h>'))
432 conf.set('SIZEOF_UID_T', cc.sizeof('uid_t', prefix : '#include <sys/types.h>'))
433 conf.set('SIZEOF_GID_T', cc.sizeof('gid_t', prefix : '#include <sys/types.h>'))
434 conf.set('SIZEOF_DEV_T', cc.sizeof('dev_t', prefix : '#include <sys/types.h>'))
435 conf.set('SIZEOF_INO_T', cc.sizeof('ino_t', prefix : '#include <sys/types.h>'))
436 conf.set('SIZEOF_TIME_T', cc.sizeof('time_t', prefix : '#include <sys/time.h>'))
437 conf.set('SIZEOF_RLIM_T', cc.sizeof('rlim_t', prefix : '#include <sys/resource.h>'))
438
439 decl_headers = '''
440 #include <uchar.h>
441 #include <linux/ethtool.h>
442 #include <linux/fib_rules.h>
443 '''
444 # FIXME: key_serial_t is only defined in keyutils.h, this is bound to fail
445
446 foreach decl : ['char16_t',
447                 'char32_t',
448                 'key_serial_t',
449                 'struct ethtool_link_settings',
450                 'struct fib_rule_uid_range',
451                ]
452
453         # We get -1 if the size cannot be determined
454         have = cc.sizeof(decl, prefix : decl_headers) > 0
455         conf.set10('HAVE_' + decl.underscorify().to_upper(), have)
456 endforeach
457
458 foreach decl : [['IFLA_INET6_ADDR_GEN_MODE',         'linux/if_link.h'],
459                 ['IN6_ADDR_GEN_MODE_STABLE_PRIVACY', 'linux/if_link.h'],
460                 ['IFLA_VRF_TABLE',                   'linux/if_link.h'],
461                 ['IFLA_MACVLAN_FLAGS',               'linux/if_link.h'],
462                 ['IFLA_IPVLAN_FLAGS',                'linux/if_link.h'],
463                 ['IFLA_PHYS_PORT_ID',                'linux/if_link.h'],
464                 ['IFLA_BOND_AD_INFO',                'linux/if_link.h'],
465                 ['IFLA_VLAN_PROTOCOL',               'linux/if_link.h'],
466                 ['IFLA_VXLAN_REMCSUM_NOPARTIAL',     'linux/if_link.h'],
467                 ['IFLA_VXLAN_GPE',                   'linux/if_link.h'],
468                 ['IFLA_GENEVE_LABEL',                'linux/if_link.h'],
469                 # if_tunnel.h is buggy and cannot be included on its own
470                 ['IFLA_VTI_REMOTE',                  'linux/if_tunnel.h', '#include <net/if.h>'],
471                 ['IFLA_IPTUN_ENCAP_DPORT',           'linux/if_tunnel.h', '#include <net/if.h>'],
472                 ['IFLA_GRE_ENCAP_DPORT',             'linux/if_tunnel.h', '#include <net/if.h>'],
473                 ['IFLA_BRIDGE_VLAN_INFO',            'linux/if_bridge.h'],
474                 ['IFLA_BRPORT_PROXYARP',             'linux/if_link.h'],
475                 ['IFLA_BRPORT_LEARNING_SYNC',        'linux/if_link.h'],
476                 ['IFLA_BR_VLAN_DEFAULT_PVID',        'linux/if_link.h'],
477                 ['IPVLAN_F_PRIVATE',                 'linux/if_link.h'],
478                 ['NDA_IFINDEX',                      'linux/neighbour.h'],
479                 ['IFA_FLAGS',                        'linux/if_addr.h'],
480                 ['FRA_UID_RANGE',                    'linux/fib_rules.h'],
481                 ['LO_FLAGS_PARTSCAN',                'linux/loop.h'],
482                 ['VXCAN_INFO_PEER',                  'linux/can/vxcan.h'],
483                ]
484         prefix = decl.length() > 2 ? decl[2] : ''
485         have = cc.has_header_symbol(decl[1], decl[0], prefix : prefix)
486         conf.set10('HAVE_' + decl[0], have)
487 endforeach
488
489 foreach ident : ['secure_getenv', '__secure_getenv']
490         conf.set10('HAVE_' + ident.to_upper(), cc.has_function(ident))
491 endforeach
492
493 foreach ident : [
494         ['memfd_create',      '''#include <sys/mman.h>'''],
495         ['gettid',            '''#include <sys/types.h>
496                                  #include <unistd.h>'''],
497         ['pivot_root',        '''#include <stdlib.h>
498                                  #include <unistd.h>'''],     # no known header declares pivot_root
499         ['name_to_handle_at', '''#include <sys/types.h>
500                                  #include <sys/stat.h>
501                                  #include <fcntl.h>'''],
502         ['setns',             '''#include <sched.h>'''],
503         ['renameat2',         '''#include <stdio.h>
504                                  #include <fcntl.h>'''],
505         ['kcmp',              '''#include <linux/kcmp.h>'''],
506         ['keyctl',            '''#include <sys/types.h>
507                                  #include <keyutils.h>'''],
508         ['copy_file_range',   '''#include <sys/syscall.h>
509                                  #include <unistd.h>'''],
510         ['bpf',               '''#include <sys/syscall.h>
511                                  #include <unistd.h>'''],
512         ['explicit_bzero' ,   '''#include <string.h>'''],
513 ]
514
515         have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
516         conf.set10('HAVE_' + ident[0].to_upper(), have)
517 endforeach
518
519 if cc.has_function('getrandom', prefix : '''#include <sys/random.h>''', args : '-D_GNU_SOURCE')
520         conf.set10('USE_SYS_RANDOM_H', true)
521         conf.set10('HAVE_GETRANDOM', true)
522 else
523         have = cc.has_function('getrandom', prefix : '''#include <linux/random.h>''')
524         conf.set10('USE_SYS_RANDOM_H', false)
525         conf.set10('HAVE_GETRANDOM', have)
526 endif
527
528 #####################################################################
529
530 sed = find_program('sed')
531 awk = find_program('awk')
532 m4 = find_program('m4')
533 stat = find_program('stat')
534 git = find_program('git', required : false)
535 env = find_program('env')
536
537 meson_make_symlink = meson.source_root() + '/tools/meson-make-symlink.sh'
538 mkdir_p = 'mkdir -p $DESTDIR/@0@'
539 test_efi_create_disk_sh = find_program('test/test-efi-create-disk.sh')
540 splash_bmp = files('test/splash.bmp')
541
542 # if -Dxxx-path option is found, use that. Otherwise, check in $PATH,
543 # /usr/sbin, /sbin, and fall back to the default from middle column.
544 progs = [['quotaon',    '/usr/sbin/quotaon'    ],
545          ['quotacheck', '/usr/sbin/quotacheck' ],
546          ['kill',       '/usr/bin/kill'        ],
547          ['kmod',       '/usr/bin/kmod'        ],
548          ['kexec',      '/usr/sbin/kexec'      ],
549          ['sulogin',    '/usr/sbin/sulogin'    ],
550          ['mount',      '/usr/bin/mount',      'MOUNT_PATH'],
551          ['umount',     '/usr/bin/umount',     'UMOUNT_PATH'],
552          ['loadkeys',   '/usr/bin/loadkeys',   'KBD_LOADKEYS'],
553          ['setfont',    '/usr/bin/setfont',    'KBD_SETFONT'],
554         ]
555 foreach prog : progs
556         path = get_option(prog[0] + '-path')
557         if path != ''
558                 message('Using @1@ for @0@'.format(prog[0], path))
559         else
560                 exe = find_program(prog[0],
561                                    '/usr/sbin/' + prog[0],
562                                    '/sbin/' + prog[0],
563                                    required: false)
564                 path = exe.found() ? exe.path() : prog[1]
565         endif
566         name = prog.length() > 2 ? prog[2] : prog[0].to_upper()
567         conf.set_quoted(name, path)
568         substs.set(name, path)
569 endforeach
570
571 conf.set_quoted('TELINIT', get_option('telinit-path'))
572
573 #if run_command('ln', '--relative', '--help').returncode() != 0
574 #        error('ln does not support --relative')
575 #endif
576
577 ############################################################
578
579 gperf = find_program('gperf')
580
581 gperf_test_format = '''
582 #include <string.h>
583 const char * in_word_set(const char *, @0@);
584 @1@
585 '''
586 gperf_snippet_format = 'echo foo,bar | @0@ -L ANSI-C'
587 gperf_snippet = run_command('sh', '-c', gperf_snippet_format.format(gperf.path()))
588 gperf_test = gperf_test_format.format('size_t', gperf_snippet.stdout())
589 if cc.compiles(gperf_test)
590         gperf_len_type = 'size_t'
591 else
592         gperf_test = gperf_test_format.format('unsigned', gperf_snippet.stdout())
593         if cc.compiles(gperf_test)
594                 gperf_len_type = 'unsigned'
595         else
596                 error('unable to determine gperf len type')
597         endif
598 endif
599 message('gperf len type is @0@'.format(gperf_len_type))
600 conf.set('GPERF_LEN_TYPE', gperf_len_type,
601          description : 'The type of gperf "len" parameter')
602
603 ############################################################
604
605 if not cc.has_header('sys/capability.h')
606         error('POSIX caps headers not found')
607 endif
608 foreach header : ['crypt.h',
609                   'linux/btrfs.h',
610                   'linux/memfd.h',
611                   'linux/vm_sockets.h',
612                   'sys/auxv.h',
613                   'valgrind/memcheck.h',
614                   'valgrind/valgrind.h',
615                  ]
616
617         conf.set10('HAVE_' + header.underscorify().to_upper(),
618                    cc.has_header(header))
619 endforeach
620
621 ############################################################
622
623 conf.set_quoted('FALLBACK_HOSTNAME', get_option('fallback-hostname'))
624 conf.set10('ENABLE_COMPAT_GATEWAY_HOSTNAME', get_option('compat-gateway-hostname'))
625 gateway_hostnames = ['_gateway'] + (conf.get('ENABLE_COMPAT_GATEWAY_HOSTNAME') == 1 ? ['gateway'] : [])
626
627 default_hierarchy = get_option('default-hierarchy')
628 conf.set_quoted('DEFAULT_HIERARCHY_NAME', default_hierarchy,
629                 description : 'default cgroup hierarchy as string')
630 if default_hierarchy == 'legacy'
631         conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_NONE')
632 elif default_hierarchy == 'hybrid'
633         conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_SYSTEMD')
634 else
635         conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL')
636 endif
637
638 time_epoch = get_option('time-epoch')
639 if time_epoch == ''
640         NEWS = files('NEWS')
641         time_epoch = run_command(stat, '-c', '%Y', NEWS).stdout()
642 endif
643 time_epoch = time_epoch.to_int()
644 conf.set('TIME_EPOCH', time_epoch)
645
646 system_uid_max = get_option('system-uid-max')
647 if system_uid_max == ''
648         system_uid_max = run_command(
649                 awk,
650                 'BEGIN { uid=999 } /^\s*SYS_UID_MAX\s+/ { uid=$2 } END { print uid }',
651                 '/etc/login.defs').stdout()
652 endif
653 system_uid_max = system_uid_max.to_int()
654 conf.set('SYSTEM_UID_MAX', system_uid_max)
655 substs.set('systemuidmax', system_uid_max)
656 message('maximum system UID is @0@'.format(system_uid_max))
657
658 system_gid_max = get_option('system-gid-max')
659 if system_gid_max == ''
660         system_gid_max = run_command(
661                 awk,
662                 'BEGIN { gid=999 } /^\s*SYS_GID_MAX\s+/ { gid=$2 } END { print gid }',
663                 '/etc/login.defs').stdout()
664 endif
665 system_gid_max = system_gid_max.to_int()
666 conf.set('SYSTEM_GID_MAX', system_gid_max)
667 substs.set('systemgidmax', system_gid_max)
668 message('maximum system GID is @0@'.format(system_gid_max))
669
670 dynamic_uid_min = get_option('dynamic-uid-min').to_int()
671 dynamic_uid_max = get_option('dynamic-uid-max').to_int()
672 conf.set('DYNAMIC_UID_MIN', dynamic_uid_min)
673 conf.set('DYNAMIC_UID_MAX', dynamic_uid_max)
674 substs.set('dynamicuidmin', dynamic_uid_min)
675 substs.set('dynamicuidmax', dynamic_uid_max)
676
677 container_uid_base_min = get_option('container-uid-base-min').to_int()
678 container_uid_base_max = get_option('container-uid-base-max').to_int()
679 conf.set('CONTAINER_UID_BASE_MIN', container_uid_base_min)
680 conf.set('CONTAINER_UID_BASE_MAX', container_uid_base_max)
681 substs.set('containeruidbasemin', container_uid_base_min)
682 substs.set('containeruidbasemax', container_uid_base_max)
683
684 nobody_user = get_option('nobody-user')
685 nobody_group = get_option('nobody-group')
686
687 getent_result = run_command('getent', 'passwd', '65534')
688 if getent_result.returncode() == 0
689         name = getent_result.stdout().split(':')[0]
690         if name != nobody_user
691                 message('WARNING:\n' +
692                         '        The local user with the UID 65534 does not match the configured user name "@0@" of the nobody user (its name is @1@).\n'.format(nobody_user, name) +
693                         '        Your build will result in an user table setup that is incompatible with the local system.')
694         endif
695 endif
696 id_result = run_command('id', '-u', nobody_user)
697 if id_result.returncode() == 0
698         id = id_result.stdout().to_int()
699         if id != 65534
700                 message('WARNING:\n' +
701                         '        The local user with the configured user name "@0@" of the nobody user does not have UID 65534 (it has @1@).\n'.format(nobody_user, id) +
702                         '        Your build will result in an user table setup that is incompatible with the local system.')
703         endif
704 endif
705
706 getent_result = run_command('getent', 'group', '65534')
707 if getent_result.returncode() == 0
708         name = getent_result.stdout().split(':')[0]
709         if name != nobody_group
710                 message('WARNING:\n' +
711                         '        The local group with the GID 65534 does not match the configured group name "@0@" of the nobody group (its name is @1@).\n'.format(nobody_group, name) +
712                         '        Your build will result in an group table setup that is incompatible with the local system.')
713         endif
714 endif
715 id_result = run_command('id', '-g', nobody_group)
716 if id_result.returncode() == 0
717         id = id_result.stdout().to_int()
718         if id != 65534
719                 message('WARNING:\n' +
720                         '        The local group with the configured group name "@0@" of the nobody group does not have UID 65534 (it has @1@).\n'.format(nobody_group, id) +
721                         '        Your build will result in an group table setup that is incompatible with the local system.')
722         endif
723 endif
724 if nobody_user != nobody_group and not (nobody_user == 'nobody' and nobody_group == 'nogroup')
725         message('WARNING:\n' +
726                 '        The configured user name "@0@" and group name "@0@" of the nobody user/group are not equivalent.\n'.format(nobody_user, nobody_group) +
727                 '        Please re-check that both "nobody-user" and "nobody-group" options are correctly set.')
728 endif
729
730 conf.set_quoted('NOBODY_USER_NAME', nobody_user)
731 conf.set_quoted('NOBODY_GROUP_NAME', nobody_group)
732 substs.set('NOBODY_USER_NAME', nobody_user)
733 substs.set('NOBODY_GROUP_NAME', nobody_group)
734
735 tty_gid = get_option('tty-gid')
736 conf.set('TTY_GID', tty_gid)
737 substs.set('TTY_GID', tty_gid)
738
739 # Ensure provided GID argument is numeric, otherwise fallback to default assignment
740 if get_option('users-gid') != ''
741         users_gid = get_option('users-gid').to_int()
742 else
743         users_gid = '-'
744 endif
745 substs.set('USERS_GID', users_gid)
746
747 if get_option('adm-group')
748         m4_defines += ['-DENABLE_ADM_GROUP']
749 endif
750
751 if get_option('wheel-group')
752         m4_defines += ['-DENABLE_WHEEL_GROUP']
753 endif
754
755 substs.set('DEV_KVM_MODE', get_option('dev-kvm-mode'))
756 substs.set('GROUP_RENDER_MODE', get_option('group-render-mode'))
757
758 kill_user_processes = get_option('default-kill-user-processes')
759 conf.set10('KILL_USER_PROCESSES', kill_user_processes)
760 substs.set('KILL_USER_PROCESSES', kill_user_processes ? 'yes' : 'no')
761
762 dns_servers = get_option('dns-servers')
763 conf.set_quoted('DNS_SERVERS', dns_servers)
764 substs.set('DNS_SERVERS', dns_servers)
765
766 ntp_servers = get_option('ntp-servers')
767 conf.set_quoted('NTP_SERVERS', ntp_servers)
768 substs.set('NTP_SERVERS', ntp_servers)
769
770 conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
771
772 substs.set('SUSHELL', get_option('debug-shell'))
773 substs.set('DEBUGTTY', get_option('debug-tty'))
774
775 debug = get_option('debug-extra')
776 enable_debug_hashmap = false
777 enable_debug_mmap_cache = false
778 if debug != ''
779         foreach name : debug.split(',')
780                 if name == 'hashmap'
781                         enable_debug_hashmap = true
782                 elif name == 'mmap-cache'
783                         enable_debug_mmap_cache = true
784                 else
785                         message('unknown debug option "@0@", ignoring'.format(name))
786                 endif
787         endforeach
788 endif
789 conf.set10('ENABLE_DEBUG_HASHMAP', enable_debug_hashmap)
790 conf.set10('ENABLE_DEBUG_MMAP_CACHE', enable_debug_mmap_cache)
791
792 #####################################################################
793
794 threads = dependency('threads')
795 librt = cc.find_library('rt')
796 libm = cc.find_library('m')
797 libdl = cc.find_library('dl')
798 libcrypt = cc.find_library('crypt')
799
800 libcap = dependency('libcap', required : false)
801 if not libcap.found()
802         # Compat with Ubuntu 14.04 which ships libcap w/o .pc file
803         libcap = cc.find_library('cap')
804 endif
805
806 libmount = dependency('mount',
807                       version : '>= 2.30',
808                       required : not fuzzer_build)
809
810 want_seccomp = get_option('seccomp')
811 if want_seccomp != 'false' and not fuzzer_build
812         libseccomp = dependency('libseccomp',
813                                 version : '>= 2.3.1',
814                                 required : want_seccomp == 'true')
815         have = libseccomp.found()
816 else
817         have = false
818         libseccomp = []
819 endif
820 conf.set10('HAVE_SECCOMP', have)
821 m4_defines += have ? ['-DHAVE_SECCOMP'] : []
822
823 want_selinux = get_option('selinux')
824 if want_selinux != 'false' and not fuzzer_build
825         libselinux = dependency('libselinux',
826                                 version : '>= 2.1.9',
827                                 required : want_selinux == 'true')
828         have = libselinux.found()
829 else
830         have = false
831         libselinux = []
832 endif
833 conf.set10('HAVE_SELINUX', have)
834 m4_defines += have ? ['-DHAVE_SELINUX'] : []
835
836 want_apparmor = get_option('apparmor')
837 if want_apparmor != 'false' and not fuzzer_build
838         libapparmor = dependency('libapparmor',
839                                  required : want_apparmor == 'true')
840         have = libapparmor.found()
841 else
842         have = false
843         libapparmor = []
844 endif
845 conf.set10('HAVE_APPARMOR', have)
846 m4_defines += have ? ['-DHAVE_APPARMOR'] : []
847
848 smack_run_label = get_option('smack-run-label')
849 if smack_run_label != ''
850         conf.set_quoted('SMACK_RUN_LABEL', smack_run_label)
851         m4_defines += ['-DHAVE_SMACK_RUN_LABEL']
852 endif
853
854 want_polkit = get_option('polkit')
855 install_polkit = false
856 install_polkit_pkla = false
857 if want_polkit != 'false' and not fuzzer_build
858         install_polkit = true
859
860         libpolkit = dependency('polkit-gobject-1',
861                                required : false)
862         if libpolkit.found() and libpolkit.version().version_compare('< 0.106')
863                 message('Old polkit detected, will install pkla files')
864                 install_polkit_pkla = true
865         endif
866 endif
867 conf.set10('ENABLE_POLKIT', install_polkit)
868
869 want_acl = get_option('acl')
870 if want_acl != 'false' and not fuzzer_build
871         libacl = cc.find_library('acl', required : want_acl == 'true')
872         have = libacl.found()
873 else
874         have = false
875         libacl = []
876 endif
877 conf.set10('HAVE_ACL', have)
878 m4_defines += have ? ['-DHAVE_ACL'] : []
879
880 want_audit = get_option('audit')
881 if want_audit != 'false' and not fuzzer_build
882         libaudit = dependency('audit', required : want_audit == 'true')
883         have = libaudit.found()
884 else
885         have = false
886         libaudit = []
887 endif
888 conf.set10('HAVE_AUDIT', have)
889
890 want_blkid = get_option('blkid')
891 if want_blkid != 'false' and not fuzzer_build
892         libblkid = dependency('blkid', required : want_blkid == 'true')
893         have = libblkid.found()
894 else
895         have = false
896         libblkid = []
897 endif
898 conf.set10('HAVE_BLKID', have)
899
900 want_kmod = get_option('kmod')
901 if want_kmod != 'false' and not fuzzer_build
902         libkmod = dependency('libkmod',
903                              version : '>= 15',
904                              required : want_kmod == 'true')
905         have = libkmod.found()
906 else
907         have = false
908         libkmod = []
909 endif
910 conf.set10('HAVE_KMOD', have)
911
912 want_pam = get_option('pam')
913 if want_pam != 'false' and not fuzzer_build
914         libpam = cc.find_library('pam', required : want_pam == 'true')
915         libpam_misc = cc.find_library('pam_misc', required : want_pam == 'true')
916         have = libpam.found() and libpam_misc.found()
917 else
918         have = false
919         libpam = []
920         libpam_misc = []
921 endif
922 conf.set10('HAVE_PAM', have)
923 m4_defines += have ? ['-DHAVE_PAM'] : []
924
925 want_microhttpd = get_option('microhttpd')
926 if want_microhttpd != 'false' and not fuzzer_build
927         libmicrohttpd = dependency('libmicrohttpd',
928                                    version : '>= 0.9.33',
929                                    required : want_microhttpd == 'true')
930         have = libmicrohttpd.found()
931 else
932         have = false
933         libmicrohttpd = []
934 endif
935 conf.set10('HAVE_MICROHTTPD', have)
936 m4_defines += have ? ['-DHAVE_MICROHTTPD'] : []
937
938 want_libcryptsetup = get_option('libcryptsetup')
939 if want_libcryptsetup != 'false' and not fuzzer_build
940         libcryptsetup = dependency('libcryptsetup',
941                                    version : '>= 1.6.0',
942                                    required : want_libcryptsetup == 'true')
943         have = libcryptsetup.found()
944 else
945         have = false
946         libcryptsetup = []
947 endif
948 conf.set10('HAVE_LIBCRYPTSETUP', have)
949
950 want_libcurl = get_option('libcurl')
951 if want_libcurl != 'false' and not fuzzer_build
952         libcurl = dependency('libcurl',
953                              version : '>= 7.32.0',
954                              required : want_libcurl == 'true')
955         have = libcurl.found()
956 else
957         have = false
958         libcurl = []
959 endif
960 conf.set10('HAVE_LIBCURL', have)
961 m4_defines += have ? ['-DHAVE_LIBCURL'] : []
962
963 want_libidn = get_option('libidn')
964 want_libidn2 = get_option('libidn2')
965 if want_libidn == 'true' and want_libidn2 == 'true'
966         error('libidn and libidn2 cannot be requested simultaneously')
967 endif
968
969 if want_libidn != 'false' and want_libidn2 != 'true' and not fuzzer_build
970         libidn = dependency('libidn',
971                             required : want_libidn == 'true')
972         have = libidn.found()
973 else
974         have = false
975         libidn = []
976 endif
977 conf.set10('HAVE_LIBIDN', have)
978 m4_defines += have ? ['-DHAVE_LIBIDN'] : []
979 if not have and want_libidn2 != 'false' and not fuzzer_build
980         # libidn is used for both libidn and libidn2 objects
981         libidn = dependency('libidn2',
982                             required : want_libidn2 == 'true')
983         have = libidn.found()
984 else
985         have = false
986 endif
987 conf.set10('HAVE_LIBIDN2', have)
988 m4_defines += have ? ['-DHAVE_LIBIDN2'] : []
989
990 want_libiptc = get_option('libiptc')
991 if want_libiptc != 'false' and not fuzzer_build
992         libiptc = dependency('libiptc',
993                              required : want_libiptc == 'true')
994         have = libiptc.found()
995 else
996         have = false
997         libiptc = []
998 endif
999 conf.set10('HAVE_LIBIPTC', have)
1000 m4_defines += have ? ['-DHAVE_LIBIPTC'] : []
1001
1002 want_qrencode = get_option('qrencode')
1003 if want_qrencode != 'false' and not fuzzer_build
1004         libqrencode = dependency('libqrencode',
1005                                  required : want_qrencode == 'true')
1006         have = libqrencode.found()
1007 else
1008         have = false
1009         libqrencode = []
1010 endif
1011 conf.set10('HAVE_QRENCODE', have)
1012
1013 want_gcrypt = get_option('gcrypt')
1014 if want_gcrypt != 'false' and not fuzzer_build
1015         libgcrypt = cc.find_library('gcrypt', required : want_gcrypt == 'true')
1016         libgpg_error = cc.find_library('gpg-error', required : want_gcrypt == 'true')
1017         have = libgcrypt.found() and libgpg_error.found()
1018 else
1019         have = false
1020 endif
1021 if not have
1022         # link to neither of the libs if one is not found
1023         libgcrypt = []
1024         libgpg_error = []
1025 endif
1026 conf.set10('HAVE_GCRYPT', have)
1027
1028 want_gnutls = get_option('gnutls')
1029 if want_gnutls != 'false' and not fuzzer_build
1030         libgnutls = dependency('gnutls',
1031                                version : '>= 3.1.4',
1032                                required : want_gnutls == 'true')
1033         have = libgnutls.found()
1034 else
1035         have = false
1036         libgnutls = []
1037 endif
1038 conf.set10('HAVE_GNUTLS', have)
1039
1040 want_elfutils = get_option('elfutils')
1041 if want_elfutils != 'false' and not fuzzer_build
1042         libdw = dependency('libdw',
1043                            required : want_elfutils == 'true')
1044         have = libdw.found()
1045 else
1046         have = false
1047         libdw = []
1048 endif
1049 conf.set10('HAVE_ELFUTILS', have)
1050
1051 want_zlib = get_option('zlib')
1052 if want_zlib != 'false' and not fuzzer_build
1053         libz = dependency('zlib',
1054                           required : want_zlib == 'true')
1055         have = libz.found()
1056 else
1057         have = false
1058         libz = []
1059 endif
1060 conf.set10('HAVE_ZLIB', have)
1061
1062 want_bzip2 = get_option('bzip2')
1063 if want_bzip2 != 'false' and not fuzzer_build
1064         libbzip2 = cc.find_library('bz2',
1065                                    required : want_bzip2 == 'true')
1066         have = libbzip2.found()
1067 else
1068         have = false
1069         libbzip2 = []
1070 endif
1071 conf.set10('HAVE_BZIP2', have)
1072
1073 want_xz = get_option('xz')
1074 if want_xz != 'false' and not fuzzer_build
1075         libxz = dependency('liblzma',
1076                            required : want_xz == 'true')
1077         have = libxz.found()
1078 else
1079         have = false
1080         libxz = []
1081 endif
1082 conf.set10('HAVE_XZ', have)
1083
1084 want_lz4 = get_option('lz4')
1085 if want_lz4 != 'false' and not fuzzer_build
1086         liblz4 = dependency('liblz4',
1087                             required : want_lz4 == 'true')
1088         have = liblz4.found()
1089 else
1090         have = false
1091         liblz4 = []
1092 endif
1093 conf.set10('HAVE_LZ4', have)
1094
1095 want_xkbcommon = get_option('xkbcommon')
1096 if want_xkbcommon != 'false' and not fuzzer_build
1097         libxkbcommon = dependency('xkbcommon',
1098                                   version : '>= 0.3.0',
1099                                   required : want_xkbcommon == 'true')
1100         have = libxkbcommon.found()
1101 else
1102         have = false
1103         libxkbcommon = []
1104 endif
1105 conf.set10('HAVE_XKBCOMMON', have)
1106
1107 want_pcre2 = get_option('pcre2')
1108 if want_pcre2 != 'false'
1109         libpcre2 = dependency('libpcre2-8',
1110                               required : want_pcre2 == 'true')
1111         have = libpcre2.found()
1112 else
1113         have = false
1114         libpcre2 = []
1115 endif
1116 conf.set10('HAVE_PCRE2', have)
1117
1118 want_glib = get_option('glib')
1119 if want_glib != 'false' and not fuzzer_build
1120         libglib =    dependency('glib-2.0',
1121                                 version : '>= 2.22.0',
1122                                 required : want_glib == 'true')
1123         libgobject = dependency('gobject-2.0',
1124                                 version : '>= 2.22.0',
1125                                 required : want_glib == 'true')
1126         libgio =     dependency('gio-2.0',
1127                                 required : want_glib == 'true')
1128         have = libglib.found() and libgobject.found() and libgio.found()
1129 else
1130         have = false
1131         libglib = []
1132         libgobject = []
1133         libgio = []
1134 endif
1135 conf.set10('HAVE_GLIB', have)
1136
1137 want_dbus = get_option('dbus')
1138 if want_dbus != 'false' and not fuzzer_build
1139         libdbus = dependency('dbus-1',
1140                              version : '>= 1.3.2',
1141                              required : want_dbus == 'true')
1142         have = libdbus.found()
1143 else
1144         have = false
1145         libdbus = []
1146 endif
1147 conf.set10('HAVE_DBUS', have)
1148
1149 default_dnssec = get_option('default-dnssec')
1150 if fuzzer_build
1151         default_dnssec = 'no'
1152 endif
1153 if default_dnssec != 'no' and conf.get('HAVE_GCRYPT') == 0
1154         message('default-dnssec cannot be set to yes or allow-downgrade when gcrypt is disabled. Setting default-dnssec to no.')
1155         default_dnssec = 'no'
1156 endif
1157 conf.set('DEFAULT_DNSSEC_MODE',
1158          'DNSSEC_' + default_dnssec.underscorify().to_upper())
1159 substs.set('DEFAULT_DNSSEC_MODE', default_dnssec)
1160
1161 want_importd = get_option('importd')
1162 if want_importd != 'false'
1163         have = (conf.get('HAVE_LIBCURL') == 1 and
1164                 conf.get('HAVE_ZLIB') == 1 and
1165                 conf.get('HAVE_BZIP2') == 1 and
1166                 conf.get('HAVE_XZ') == 1 and
1167                 conf.get('HAVE_GCRYPT') == 1)
1168         if want_importd == 'true' and not have
1169                 error('importd support was requested, but dependencies are not available')
1170         endif
1171 else
1172         have = false
1173 endif
1174 conf.set10('ENABLE_IMPORTD', have)
1175
1176 want_remote = get_option('remote')
1177 if want_remote != 'false'
1178         have_deps = [conf.get('HAVE_MICROHTTPD') == 1,
1179                      conf.get('HAVE_LIBCURL') == 1]
1180         # sd-j-remote requires Âµhttpd, and sd-j-upload requires libcurl, so
1181         # it's possible to build one without the other. Complain only if
1182         # support was explictly requested. The auxiliary files like sysusers
1183         # config should be installed when any of the programs are built.
1184         if want_remote == 'true' and not (have_deps[0] and have_deps[1])
1185                 error('remote support was requested, but dependencies are not available')
1186         endif
1187         have = have_deps[0] or have_deps[1]
1188 else
1189         have = false
1190 endif
1191 conf.set10('ENABLE_REMOTE', have)
1192
1193 foreach term : ['utmp',
1194                 'kdbus',
1195                 'hibernate',
1196                 'environment-d',
1197                 'binfmt',
1198                 'coredump',
1199                 'resolve',
1200                 'logind',
1201                 'hostnamed',
1202                 'localed',
1203                 'machined',
1204                 'networkd',
1205                 'timedated',
1206                 'timesyncd',
1207                 'myhostname',
1208                 'firstboot',
1209                 'randomseed',
1210                 'backlight',
1211                 'vconsole',
1212                 'quotacheck',
1213                 'sysusers',
1214                 'tmpfiles',
1215                 'hwdb',
1216                 'rfkill',
1217                 'ldconfig',
1218                 'efi',
1219                 'tpm',
1220                 'ima',
1221                 'smack',
1222                 'gshadow',
1223                 'idn',
1224                 'nss-systemd']
1225         have = get_option(term)
1226         name = 'ENABLE_' + term.underscorify().to_upper()
1227         conf.set10(name, have)
1228         m4_defines += have ? ['-D' + name] : []
1229 endforeach
1230
1231 want_tests = get_option('tests')
1232 install_tests = get_option('install-tests')
1233 slow_tests = get_option('slow-tests')
1234 tests = []
1235 fuzzers = []
1236
1237 conf.set10('SYSTEMD_SLOW_TESTS_DEFAULT', slow_tests)
1238
1239 #####################################################################
1240
1241 if get_option('efi')
1242         efi_arch = host_machine.cpu_family()
1243
1244         if efi_arch == 'x86'
1245                 EFI_MACHINE_TYPE_NAME = 'ia32'
1246                 gnu_efi_arch = 'ia32'
1247         elif efi_arch == 'x86_64'
1248                 EFI_MACHINE_TYPE_NAME = 'x64'
1249                 gnu_efi_arch = 'x86_64'
1250         elif efi_arch == 'arm'
1251                 EFI_MACHINE_TYPE_NAME = 'arm'
1252                 gnu_efi_arch = 'arm'
1253         elif efi_arch == 'aarch64'
1254                 EFI_MACHINE_TYPE_NAME = 'aa64'
1255                 gnu_efi_arch = 'aarch64'
1256         else
1257                 EFI_MACHINE_TYPE_NAME = ''
1258                 gnu_efi_arch = ''
1259         endif
1260
1261         have = true
1262         conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
1263
1264         conf.set('SD_TPM_PCR', get_option('tpm-pcrindex').to_int())
1265 else
1266         have = false
1267 endif
1268 conf.set10('ENABLE_EFI', have)
1269
1270 #####################################################################
1271
1272 config_h = configure_file(
1273         output : 'config.h',
1274         configuration : conf)
1275
1276 includes = include_directories('src/basic',
1277                                'src/shared',
1278                                'src/systemd',
1279                                'src/journal',
1280                                'src/resolve',
1281                                'src/timesync',
1282                                'src/login',
1283                                'src/udev',
1284                                'src/libudev',
1285                                'src/core',
1286                                'src/libsystemd/sd-bus',
1287                                'src/libsystemd/sd-device',
1288                                'src/libsystemd/sd-hwdb',
1289                                'src/libsystemd/sd-id128',
1290                                'src/libsystemd/sd-netlink',
1291                                'src/libsystemd/sd-network',
1292                                'src/libsystemd-network',
1293                                '.')
1294
1295 add_project_arguments('-include', 'config.h', language : 'c')
1296
1297 subdir('po')
1298 subdir('catalog')
1299 subdir('src/systemd')
1300 subdir('src/basic')
1301 subdir('src/libsystemd')
1302 subdir('src/libsystemd-network')
1303 subdir('src/journal')
1304 subdir('src/login')
1305
1306 libjournal_core = static_library(
1307         'journal-core',
1308         libjournal_core_sources,
1309         journald_gperf_c,
1310         include_directories : includes,
1311         install : false)
1312
1313 libsystemd_sym_path = '@0@/@1@'.format(meson.current_source_dir(), libsystemd_sym)
1314 libsystemd = shared_library(
1315         'systemd',
1316         'src/systemd/sd-id128.h', # pick a header file at random to work around old meson bug
1317         version : libsystemd_version,
1318         include_directories : includes,
1319         link_args : ['-shared',
1320                      '-Wl,--version-script=' + libsystemd_sym_path],
1321         link_with : [libbasic,
1322                      libbasic_gcrypt],
1323         link_whole : [libsystemd_static,
1324                       libjournal_client],
1325         dependencies : [threads,
1326                         librt,
1327                         libxz,
1328                         liblz4],
1329         link_depends : libsystemd_sym,
1330         install : true,
1331         install_dir : rootlibdir)
1332
1333 ############################################################
1334
1335 # binaries that have --help and are intended for use by humans,
1336 # usually, but not always, installed in /bin.
1337 public_programs = []
1338
1339 subdir('src/libudev')
1340 subdir('src/shared')
1341 subdir('src/core')
1342 subdir('src/udev')
1343 subdir('src/network')
1344
1345 subdir('src/analyze')
1346 subdir('src/journal-remote')
1347 subdir('src/coredump')
1348 subdir('src/hostname')
1349 subdir('src/import')
1350 subdir('src/kernel-install')
1351 subdir('src/locale')
1352 subdir('src/machine')
1353 subdir('src/nspawn')
1354 subdir('src/resolve')
1355 subdir('src/timedate')
1356 subdir('src/timesync')
1357 subdir('src/vconsole')
1358 subdir('src/boot/efi')
1359
1360 subdir('src/test')
1361 subdir('src/fuzz')
1362 subdir('rules')
1363 subdir('test')
1364
1365 ############################################################
1366
1367 # only static linking apart from libdl, to make sure that the
1368 # module is linked to all libraries that it uses.
1369 test_dlopen = executable(
1370         'test-dlopen',
1371         test_dlopen_c,
1372         include_directories : includes,
1373         link_with : [libbasic],
1374         dependencies : [libdl])
1375
1376 foreach tuple : [['myhostname', 'ENABLE_MYHOSTNAME'],
1377                  ['systemd',    'ENABLE_NSS_SYSTEMD'],
1378                  ['mymachines', 'ENABLE_MACHINED'],
1379                  ['resolve',    'ENABLE_RESOLVE']]
1380
1381         condition = tuple[1] == '' or conf.get(tuple[1]) == 1
1382         if condition
1383                 module = tuple[0]
1384
1385                 sym = 'src/nss-@0@/nss-@0@.sym'.format(module)
1386                 version_script_arg = join_paths(meson.current_source_dir(), sym)
1387
1388                 nss = shared_library(
1389                         'nss_' + module,
1390                         'src/nss-@0@/nss-@0@.c'.format(module),
1391                         version : '2',
1392                         include_directories : includes,
1393                         # Note that we link NSS modules with '-z nodelete' so that mempools never get orphaned
1394                         link_args : ['-Wl,-z,nodelete',
1395                                      '-shared',
1396                                      '-Wl,--version-script=' + version_script_arg,
1397                                      '-Wl,--undefined'],
1398                         link_with : [libsystemd_static,
1399                                      libbasic],
1400                         dependencies : [threads,
1401                                         librt],
1402                         link_depends : sym,
1403                         install : true,
1404                         install_dir : rootlibdir)
1405
1406                 # We cannot use shared_module because it does not support version suffix.
1407                 # Unfortunately shared_library insists on creating the symlink…
1408                 meson.add_install_script('sh', '-c',
1409                                          'rm $DESTDIR@0@/libnss_@1@.so'
1410                                          .format(rootlibdir, module))
1411
1412                 test('dlopen-nss_' + module,
1413                      test_dlopen,
1414                      args : [nss.full_path()]) # path to dlopen must include a slash
1415         endif
1416 endforeach
1417
1418 ############################################################
1419
1420 executable('systemd',
1421            systemd_sources,
1422            include_directories : includes,
1423            link_with : [libcore,
1424                         libshared],
1425            dependencies : [threads,
1426                            librt,
1427                            libseccomp,
1428                            libselinux,
1429                            libmount,
1430                            libblkid],
1431            install_rpath : rootlibexecdir,
1432            install : true,
1433            install_dir : rootlibexecdir)
1434
1435 exe = executable('systemd-analyze',
1436                  systemd_analyze_sources,
1437                  include_directories : includes,
1438                  link_with : [libcore,
1439                               libshared],
1440                  dependencies : [threads,
1441                                  librt,
1442                                  libseccomp,
1443                                  libselinux,
1444                                  libmount,
1445                                  libblkid],
1446                  install_rpath : rootlibexecdir,
1447                  install : true)
1448 public_programs += [exe]
1449
1450 executable('systemd-journald',
1451            systemd_journald_sources,
1452            include_directories : includes,
1453            link_with : [libjournal_core,
1454                         libshared],
1455            dependencies : [threads,
1456                            libxz,
1457                            liblz4,
1458                            libselinux],
1459            install_rpath : rootlibexecdir,
1460            install : true,
1461            install_dir : rootlibexecdir)
1462
1463 exe = executable('systemd-cat',
1464                  systemd_cat_sources,
1465                  include_directories : includes,
1466                  link_with : [libjournal_core,
1467                               libshared],
1468                  dependencies : [threads],
1469                  install_rpath : rootlibexecdir,
1470                  install : true)
1471 public_programs += [exe]
1472
1473 exe = executable('journalctl',
1474                  journalctl_sources,
1475                  include_directories : includes,
1476                  link_with : [libshared],
1477                  dependencies : [threads,
1478                                  libqrencode,
1479                                  libxz,
1480                                  liblz4,
1481                                  libpcre2],
1482                  install_rpath : rootlibexecdir,
1483                  install : true,
1484                  install_dir : rootbindir)
1485 public_programs += [exe]
1486
1487 executable('systemd-getty-generator',
1488            'src/getty-generator/getty-generator.c',
1489            include_directories : includes,
1490            link_with : [libshared],
1491            install_rpath : rootlibexecdir,
1492            install : true,
1493            install_dir : systemgeneratordir)
1494
1495 executable('systemd-debug-generator',
1496            'src/debug-generator/debug-generator.c',
1497            include_directories : includes,
1498            link_with : [libshared],
1499            install_rpath : rootlibexecdir,
1500            install : true,
1501            install_dir : systemgeneratordir)
1502
1503 executable('systemd-fstab-generator',
1504            'src/fstab-generator/fstab-generator.c',
1505            'src/core/mount-setup.c',
1506            include_directories : includes,
1507            link_with : [libshared],
1508            install_rpath : rootlibexecdir,
1509            install : true,
1510            install_dir : systemgeneratordir)
1511
1512 if conf.get('ENABLE_ENVIRONMENT_D') == 1
1513         executable('30-systemd-environment-d-generator',
1514                    'src/environment-d-generator/environment-d-generator.c',
1515                    include_directories : includes,
1516                    link_with : [libshared],
1517                    install_rpath : rootlibexecdir,
1518                    install : true,
1519                    install_dir : userenvgeneratordir)
1520
1521         meson.add_install_script(meson_make_symlink,
1522                                  join_paths(sysconfdir, 'environment'),
1523                                  join_paths(environmentdir, '99-environment.conf'))
1524 endif
1525
1526 if conf.get('ENABLE_HIBERNATE') == 1
1527         executable('systemd-hibernate-resume-generator',
1528                    'src/hibernate-resume/hibernate-resume-generator.c',
1529                    include_directories : includes,
1530                    link_with : [libshared],
1531                    install_rpath : rootlibexecdir,
1532                    install : true,
1533                    install_dir : systemgeneratordir)
1534
1535         executable('systemd-hibernate-resume',
1536                    'src/hibernate-resume/hibernate-resume.c',
1537                    include_directories : includes,
1538                    link_with : [libshared],
1539                    install_rpath : rootlibexecdir,
1540                    install : true,
1541                    install_dir : rootlibexecdir)
1542 endif
1543
1544 if conf.get('HAVE_BLKID') == 1
1545         executable('systemd-gpt-auto-generator',
1546                    'src/gpt-auto-generator/gpt-auto-generator.c',
1547                    'src/basic/blkid-util.h',
1548                    include_directories : includes,
1549                    link_with : [libshared],
1550                    dependencies : libblkid,
1551                    install_rpath : rootlibexecdir,
1552                    install : true,
1553                    install_dir : systemgeneratordir)
1554
1555         exe = executable('systemd-dissect',
1556                          'src/dissect/dissect.c',
1557                          include_directories : includes,
1558                          link_with : [libshared],
1559                          install_rpath : rootlibexecdir,
1560                          install : true,
1561                          install_dir : rootlibexecdir)
1562         public_programs += [exe]
1563 endif
1564
1565 if conf.get('ENABLE_RESOLVE') == 1
1566         executable('systemd-resolved',
1567                    systemd_resolved_sources,
1568                    include_directories : includes,
1569                    link_with : [libshared,
1570                                 libbasic_gcrypt,
1571                                 libsystemd_resolve_core],
1572                    dependencies : [threads,
1573                                    libgpg_error,
1574                                    libm,
1575                                    libidn],
1576                    install_rpath : rootlibexecdir,
1577                    install : true,
1578                    install_dir : rootlibexecdir)
1579
1580         exe = executable('systemd-resolve',
1581                          systemd_resolve_sources,
1582                          include_directories : includes,
1583                          link_with : [libshared,
1584                                       libbasic_gcrypt,
1585                                       libsystemd_resolve_core],
1586                          dependencies : [threads,
1587                                          libgpg_error,
1588                                          libm,
1589                                          libidn],
1590                          install_rpath : rootlibexecdir,
1591                          install : true)
1592         public_programs += [exe]
1593 endif
1594
1595 if conf.get('ENABLE_LOGIND') == 1
1596         executable('systemd-logind',
1597                    systemd_logind_sources,
1598                    include_directories : includes,
1599                    link_with : [liblogind_core,
1600                                 libshared],
1601                    dependencies : [threads,
1602                                    libacl],
1603                    install_rpath : rootlibexecdir,
1604                    install : true,
1605                    install_dir : rootlibexecdir)
1606
1607         exe = executable('loginctl',
1608                          loginctl_sources,
1609                          include_directories : includes,
1610                          link_with : [libshared],
1611                          dependencies : [threads,
1612                                          liblz4,
1613                                          libxz],
1614                          install_rpath : rootlibexecdir,
1615                          install : true,
1616                          install_dir : rootbindir)
1617         public_programs += [exe]
1618
1619         exe = executable('systemd-inhibit',
1620                          'src/login/inhibit.c',
1621                          include_directories : includes,
1622                          link_with : [libshared],
1623                          install_rpath : rootlibexecdir,
1624                          install : true,
1625                          install_dir : rootbindir)
1626         public_programs += [exe]
1627
1628         if conf.get('HAVE_PAM') == 1
1629                 version_script_arg = join_paths(meson.current_source_dir(), pam_systemd_sym)
1630                 pam_systemd = shared_library(
1631                         'pam_systemd',
1632                         pam_systemd_c,
1633                         name_prefix : '',
1634                         include_directories : includes,
1635                         link_args : ['-shared',
1636                                      '-Wl,--version-script=' + version_script_arg],
1637                         link_with : [libsystemd_static,
1638                                      libshared_static],
1639                         dependencies : [threads,
1640                                         libpam,
1641                                         libpam_misc],
1642                         link_depends : pam_systemd_sym,
1643                         install : true,
1644                         install_dir : pamlibdir)
1645
1646                 test('dlopen-pam_systemd',
1647                      test_dlopen,
1648                      args : [pam_systemd.full_path()]) # path to dlopen must include a slash
1649         endif
1650 endif
1651
1652 if conf.get('HAVE_PAM') == 1
1653         executable('systemd-user-sessions',
1654                    'src/user-sessions/user-sessions.c',
1655                    include_directories : includes,
1656                    link_with : [libshared],
1657                    install_rpath : rootlibexecdir,
1658                    install : true,
1659                    install_dir : rootlibexecdir)
1660 endif
1661
1662 if conf.get('ENABLE_EFI') == 1 and conf.get('HAVE_BLKID') == 1
1663         exe = executable('bootctl',
1664                          'src/boot/bootctl.c',
1665                          include_directories : includes,
1666                          link_with : [libshared],
1667                          dependencies : [libblkid],
1668                          install_rpath : rootlibexecdir,
1669                          install : true)
1670         public_programs += [exe]
1671 endif
1672
1673 exe = executable('systemd-socket-activate', 'src/activate/activate.c',
1674                  include_directories : includes,
1675                  link_with : [libshared],
1676                  dependencies : [threads],
1677                  install_rpath : rootlibexecdir,
1678                  install : true)
1679 public_programs += [exe]
1680
1681 exe = executable('systemctl', 'src/systemctl/systemctl.c',
1682                  include_directories : includes,
1683                  link_with : [libshared],
1684                  dependencies : [threads,
1685                                  libcap,
1686                                  libselinux,
1687                                  libxz,
1688                                  liblz4],
1689                  install_rpath : rootlibexecdir,
1690                  install : true,
1691                  install_dir : rootbindir)
1692 public_programs += [exe]
1693
1694 if conf.get('ENABLE_BACKLIGHT') == 1
1695         executable('systemd-backlight',
1696                    'src/backlight/backlight.c',
1697                    include_directories : includes,
1698                    link_with : [libshared],
1699                    install_rpath : rootlibexecdir,
1700                    install : true,
1701                    install_dir : rootlibexecdir)
1702 endif
1703
1704 if conf.get('ENABLE_RFKILL') == 1
1705         executable('systemd-rfkill',
1706                    'src/rfkill/rfkill.c',
1707                    include_directories : includes,
1708                    link_with : [libshared],
1709                    install_rpath : rootlibexecdir,
1710                    install : true,
1711                    install_dir : rootlibexecdir)
1712 endif
1713
1714 executable('systemd-system-update-generator',
1715            'src/system-update-generator/system-update-generator.c',
1716            include_directories : includes,
1717            link_with : [libshared],
1718            install_rpath : rootlibexecdir,
1719            install : true,
1720            install_dir : systemgeneratordir)
1721
1722 if conf.get('HAVE_LIBCRYPTSETUP') == 1
1723         executable('systemd-cryptsetup',
1724                    'src/cryptsetup/cryptsetup.c',
1725                    include_directories : includes,
1726                    link_with : [libshared],
1727                    dependencies : [libcryptsetup],
1728                    install_rpath : rootlibexecdir,
1729                    install : true,
1730                    install_dir : rootlibexecdir)
1731
1732         executable('systemd-cryptsetup-generator',
1733                    'src/cryptsetup/cryptsetup-generator.c',
1734                    include_directories : includes,
1735                    link_with : [libshared],
1736                    dependencies : [libcryptsetup],
1737                    install_rpath : rootlibexecdir,
1738                    install : true,
1739                    install_dir : systemgeneratordir)
1740
1741         executable('systemd-veritysetup',
1742                    'src/veritysetup/veritysetup.c',
1743                    include_directories : includes,
1744                    link_with : [libshared],
1745                    dependencies : [libcryptsetup],
1746                    install_rpath : rootlibexecdir,
1747                    install : true,
1748                    install_dir : rootlibexecdir)
1749
1750         executable('systemd-veritysetup-generator',
1751                    'src/veritysetup/veritysetup-generator.c',
1752                    include_directories : includes,
1753                    link_with : [libshared],
1754                    dependencies : [libcryptsetup],
1755                    install_rpath : rootlibexecdir,
1756                    install : true,
1757                    install_dir : systemgeneratordir)
1758 endif
1759
1760 if conf.get('HAVE_SYSV_COMPAT') == 1
1761         executable('systemd-sysv-generator',
1762                    'src/sysv-generator/sysv-generator.c',
1763                    include_directories : includes,
1764                    link_with : [libshared],
1765                    install_rpath : rootlibexecdir,
1766                    install : true,
1767                    install_dir : systemgeneratordir)
1768
1769         executable('systemd-rc-local-generator',
1770                    'src/rc-local-generator/rc-local-generator.c',
1771                    include_directories : includes,
1772                    link_with : [libshared],
1773                    install_rpath : rootlibexecdir,
1774                    install : true,
1775                    install_dir : systemgeneratordir)
1776 endif
1777
1778 if conf.get('ENABLE_HOSTNAMED') == 1
1779         executable('systemd-hostnamed',
1780                    'src/hostname/hostnamed.c',
1781                    include_directories : includes,
1782                    link_with : [libshared],
1783                    install_rpath : rootlibexecdir,
1784                    install : true,
1785                    install_dir : rootlibexecdir)
1786
1787         exe = executable('hostnamectl',
1788                          'src/hostname/hostnamectl.c',
1789                          include_directories : includes,
1790                          link_with : [libshared],
1791                          install_rpath : rootlibexecdir,
1792                          install : true)
1793         public_programs += [exe]
1794 endif
1795
1796 if conf.get('ENABLE_LOCALED') == 1
1797         if conf.get('HAVE_XKBCOMMON') == 1
1798                 # logind will load libxkbcommon.so dynamically on its own
1799                 deps = [libdl]
1800         else
1801                 deps = []
1802         endif
1803
1804         executable('systemd-localed',
1805                    systemd_localed_sources,
1806                    include_directories : includes,
1807                    link_with : [libshared],
1808                    dependencies : deps,
1809                    install_rpath : rootlibexecdir,
1810                    install : true,
1811                    install_dir : rootlibexecdir)
1812
1813         exe = executable('localectl',
1814                          localectl_sources,
1815                          include_directories : includes,
1816                          link_with : [libshared],
1817                          install_rpath : rootlibexecdir,
1818                          install : true)
1819         public_programs += [exe]
1820 endif
1821
1822 if conf.get('ENABLE_TIMEDATED') == 1
1823         executable('systemd-timedated',
1824                    'src/timedate/timedated.c',
1825                    include_directories : includes,
1826                    link_with : [libshared],
1827                    install_rpath : rootlibexecdir,
1828                    install : true,
1829                    install_dir : rootlibexecdir)
1830
1831         exe = executable('timedatectl',
1832                          'src/timedate/timedatectl.c',
1833                          include_directories : includes,
1834                          install_rpath : rootlibexecdir,
1835                          link_with : [libshared],
1836                          install : true)
1837         public_programs += [exe]
1838 endif
1839
1840 if conf.get('ENABLE_TIMESYNCD') == 1
1841         executable('systemd-timesyncd',
1842                    systemd_timesyncd_sources,
1843                    include_directories : includes,
1844                    link_with : [libshared],
1845                    dependencies : [threads,
1846                                    libm],
1847                    install_rpath : rootlibexecdir,
1848                    install : true,
1849                    install_dir : rootlibexecdir)
1850 endif
1851
1852 if conf.get('ENABLE_MACHINED') == 1
1853         executable('systemd-machined',
1854                    systemd_machined_sources,
1855                    include_directories : includes,
1856                    link_with : [libmachine_core,
1857                                 libshared],
1858                    install_rpath : rootlibexecdir,
1859                    install : true,
1860                    install_dir : rootlibexecdir)
1861
1862         exe = executable('machinectl',
1863                          'src/machine/machinectl.c',
1864                          include_directories : includes,
1865                          link_with : [libshared],
1866                          dependencies : [threads,
1867                                          libxz,
1868                                          liblz4],
1869                          install_rpath : rootlibexecdir,
1870                          install : true,
1871                          install_dir : rootbindir)
1872         public_programs += [exe]
1873 endif
1874
1875 if conf.get('ENABLE_IMPORTD') == 1
1876         executable('systemd-importd',
1877                    systemd_importd_sources,
1878                    include_directories : includes,
1879                    link_with : [libshared],
1880                    dependencies : [threads],
1881                    install_rpath : rootlibexecdir,
1882                    install : true,
1883                    install_dir : rootlibexecdir)
1884
1885         systemd_pull = executable('systemd-pull',
1886                                   systemd_pull_sources,
1887                                   include_directories : includes,
1888                                   link_with : [libshared],
1889                                   dependencies : [libcurl,
1890                                                   libz,
1891                                                   libbzip2,
1892                                                   libxz,
1893                                                   libgcrypt],
1894                                   install_rpath : rootlibexecdir,
1895                                   install : true,
1896                                   install_dir : rootlibexecdir)
1897
1898         systemd_import = executable('systemd-import',
1899                                     systemd_import_sources,
1900                                     include_directories : includes,
1901                                     link_with : [libshared],
1902                                     dependencies : [libcurl,
1903                                                     libz,
1904                                                     libbzip2,
1905                                                     libxz],
1906                                     install_rpath : rootlibexecdir,
1907                                     install : true,
1908                                     install_dir : rootlibexecdir)
1909
1910         systemd_export = executable('systemd-export',
1911                                     systemd_export_sources,
1912                                     include_directories : includes,
1913                                     link_with : [libshared],
1914                                     dependencies : [libcurl,
1915                                                     libz,
1916                                                     libbzip2,
1917                                                     libxz],
1918                                     install_rpath : rootlibexecdir,
1919                                     install : true,
1920                                     install_dir : rootlibexecdir)
1921         public_programs += [systemd_pull, systemd_import, systemd_export]
1922 endif
1923
1924 if conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_LIBCURL') == 1
1925         exe = executable('systemd-journal-upload',
1926                          systemd_journal_upload_sources,
1927                          include_directories : includes,
1928                          link_with : [libshared],
1929                          dependencies : [threads,
1930                                          libcurl,
1931                                          libgnutls,
1932                                          libxz,
1933                                          liblz4],
1934                          install_rpath : rootlibexecdir,
1935                          install : true,
1936                          install_dir : rootlibexecdir)
1937         public_programs += [exe]
1938 endif
1939
1940 if conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_MICROHTTPD') == 1
1941         s_j_remote = executable('systemd-journal-remote',
1942                                 systemd_journal_remote_sources,
1943                                 include_directories : includes,
1944                                 link_with : [libshared],
1945                                 dependencies : [threads,
1946                                                 libmicrohttpd,
1947                                                 libgnutls,
1948                                                 libxz,
1949                                                 liblz4],
1950                                 install_rpath : rootlibexecdir,
1951                                 install : true,
1952                                 install_dir : rootlibexecdir)
1953
1954         s_j_gatewayd = executable('systemd-journal-gatewayd',
1955                                   systemd_journal_gatewayd_sources,
1956                                   include_directories : includes,
1957                                   link_with : [libshared],
1958                                   dependencies : [threads,
1959                                                   libmicrohttpd,
1960                                                   libgnutls,
1961                                                   libxz,
1962                                                   liblz4],
1963                                   install_rpath : rootlibexecdir,
1964                                   install : true,
1965                                   install_dir : rootlibexecdir)
1966         public_programs += [s_j_remote, s_j_gatewayd]
1967 endif
1968
1969 if conf.get('ENABLE_COREDUMP') == 1
1970         executable('systemd-coredump',
1971                    systemd_coredump_sources,
1972                    include_directories : includes,
1973                    link_with : [libshared],
1974                    dependencies : [threads,
1975                                    libacl,
1976                                    libdw,
1977                                    libxz,
1978                                    liblz4],
1979                    install_rpath : rootlibexecdir,
1980                    install : true,
1981                    install_dir : rootlibexecdir)
1982
1983         exe = executable('coredumpctl',
1984                          coredumpctl_sources,
1985                          include_directories : includes,
1986                          link_with : [libshared],
1987                          dependencies : [threads,
1988                                          libxz,
1989                                          liblz4],
1990                          install_rpath : rootlibexecdir,
1991                          install : true)
1992         public_programs += [exe]
1993 endif
1994
1995 if conf.get('ENABLE_BINFMT') == 1
1996         exe = executable('systemd-binfmt',
1997                          'src/binfmt/binfmt.c',
1998                          include_directories : includes,
1999                          link_with : [libshared],
2000                          install_rpath : rootlibexecdir,
2001                          install : true,
2002                          install_dir : rootlibexecdir)
2003         public_programs += [exe]
2004
2005         meson.add_install_script('sh', '-c',
2006                                  mkdir_p.format(binfmtdir))
2007         meson.add_install_script('sh', '-c',
2008                                  mkdir_p.format(join_paths(sysconfdir, 'binfmt.d')))
2009 endif
2010
2011 if conf.get('ENABLE_VCONSOLE') == 1
2012         executable('systemd-vconsole-setup',
2013                    'src/vconsole/vconsole-setup.c',
2014                    include_directories : includes,
2015                    link_with : [libshared],
2016                    install_rpath : rootlibexecdir,
2017                    install : true,
2018                    install_dir : rootlibexecdir)
2019 endif
2020
2021 if conf.get('ENABLE_RANDOMSEED') == 1
2022         executable('systemd-random-seed',
2023                    'src/random-seed/random-seed.c',
2024                    include_directories : includes,
2025                    link_with : [libshared],
2026                    install_rpath : rootlibexecdir,
2027                    install : true,
2028                    install_dir : rootlibexecdir)
2029 endif
2030
2031 if conf.get('ENABLE_FIRSTBOOT') == 1
2032         executable('systemd-firstboot',
2033                    'src/firstboot/firstboot.c',
2034                    include_directories : includes,
2035                    link_with : [libshared],
2036                    dependencies : [libcrypt],
2037                    install_rpath : rootlibexecdir,
2038                    install : true,
2039                    install_dir : rootbindir)
2040 endif
2041
2042 executable('systemd-remount-fs',
2043            'src/remount-fs/remount-fs.c',
2044            'src/core/mount-setup.c',
2045            'src/core/mount-setup.h',
2046            include_directories : includes,
2047            link_with : [libshared],
2048            install_rpath : rootlibexecdir,
2049            install : true,
2050            install_dir : rootlibexecdir)
2051
2052 executable('systemd-machine-id-setup',
2053            'src/machine-id-setup/machine-id-setup-main.c',
2054            'src/core/machine-id-setup.c',
2055            'src/core/machine-id-setup.h',
2056            include_directories : includes,
2057            link_with : [libshared],
2058            install_rpath : rootlibexecdir,
2059            install : true,
2060            install_dir : rootbindir)
2061
2062 executable('systemd-fsck',
2063            'src/fsck/fsck.c',
2064            include_directories : includes,
2065            link_with : [libshared],
2066            install_rpath : rootlibexecdir,
2067            install : true,
2068            install_dir : rootlibexecdir)
2069
2070 executable('systemd-growfs',
2071            'src/partition/growfs.c',
2072            include_directories : includes,
2073            link_with : [libshared],
2074            dependencies : [libcryptsetup],
2075            install_rpath : rootlibexecdir,
2076            install : true,
2077            install_dir : rootlibexecdir)
2078
2079 executable('systemd-makefs',
2080            'src/partition/makefs.c',
2081            include_directories : includes,
2082            link_with : [libshared],
2083            install_rpath : rootlibexecdir,
2084            install : true,
2085            install_dir : rootlibexecdir)
2086
2087 executable('systemd-sleep',
2088            'src/sleep/sleep.c',
2089            include_directories : includes,
2090            link_with : [libshared],
2091            install_rpath : rootlibexecdir,
2092            install : true,
2093            install_dir : rootlibexecdir)
2094
2095 exe = executable('systemd-sysctl',
2096                  'src/sysctl/sysctl.c',
2097                  include_directories : includes,
2098                  link_with : [libshared],
2099                  install_rpath : rootlibexecdir,
2100                  install : true,
2101                  install_dir : rootlibexecdir)
2102 public_programs += [exe]
2103
2104 executable('systemd-ac-power',
2105            'src/ac-power/ac-power.c',
2106            include_directories : includes,
2107            link_with : [libshared],
2108            install_rpath : rootlibexecdir,
2109            install : true,
2110            install_dir : rootlibexecdir)
2111
2112 exe_name = 'systemd-dbus1-generator'
2113 exe = executable(exe_name,
2114                  'src/dbus1-generator/dbus1-generator.c',
2115                  include_directories : includes,
2116                  link_with : [libshared],
2117                  install_rpath : rootlibexecdir,
2118                  install : true,
2119                  install_dir : systemgeneratordir)
2120 meson.add_install_script(meson_make_symlink,
2121                          join_paths(systemgeneratordir, exe_name),
2122                          join_paths(usergeneratordir, exe_name))
2123
2124 exe = executable('systemd-detect-virt',
2125                  'src/detect-virt/detect-virt.c',
2126                  include_directories : includes,
2127                  link_with : [libshared],
2128                  install_rpath : rootlibexecdir,
2129                  install : true)
2130 public_programs += [exe]
2131
2132 exe = executable('systemd-delta',
2133                  'src/delta/delta.c',
2134                  include_directories : includes,
2135                  link_with : [libshared],
2136                  install_rpath : rootlibexecdir,
2137                  install : true)
2138 public_programs += [exe]
2139
2140 exe = executable('systemd-escape',
2141                  'src/escape/escape.c',
2142                  include_directories : includes,
2143                  link_with : [libshared],
2144                  install_rpath : rootlibexecdir,
2145                  install : true,
2146                  install_dir : rootbindir)
2147 public_programs += [exe]
2148
2149 exe = executable('systemd-notify',
2150                  'src/notify/notify.c',
2151                  include_directories : includes,
2152                  link_with : [libshared],
2153                  install_rpath : rootlibexecdir,
2154                  install : true,
2155                  install_dir : rootbindir)
2156 public_programs += [exe]
2157
2158 executable('systemd-volatile-root',
2159            'src/volatile-root/volatile-root.c',
2160            include_directories : includes,
2161            link_with : [libshared],
2162            install_rpath : rootlibexecdir,
2163            install : true,
2164            install_dir : rootlibexecdir)
2165
2166 executable('systemd-cgroups-agent',
2167            'src/cgroups-agent/cgroups-agent.c',
2168            include_directories : includes,
2169            link_with : [libshared],
2170            install_rpath : rootlibexecdir,
2171            install : true,
2172            install_dir : rootlibexecdir)
2173
2174 exe = executable('systemd-path',
2175                  'src/path/path.c',
2176                  include_directories : includes,
2177                  link_with : [libshared],
2178                  install_rpath : rootlibexecdir,
2179                  install : true)
2180 public_programs += [exe]
2181
2182 exe = executable('systemd-ask-password',
2183                  'src/ask-password/ask-password.c',
2184                  include_directories : includes,
2185                  link_with : [libshared],
2186                  install_rpath : rootlibexecdir,
2187                  install : true,
2188                  install_dir : rootbindir)
2189 public_programs += [exe]
2190
2191 executable('systemd-reply-password',
2192            'src/reply-password/reply-password.c',
2193            include_directories : includes,
2194            link_with : [libshared],
2195            install_rpath : rootlibexecdir,
2196            install : true,
2197            install_dir : rootlibexecdir)
2198
2199 exe = executable('systemd-tty-ask-password-agent',
2200                  'src/tty-ask-password-agent/tty-ask-password-agent.c',
2201                  include_directories : includes,
2202                  link_with : [libshared],
2203                  install_rpath : rootlibexecdir,
2204                  install : true,
2205                  install_dir : rootbindir)
2206 public_programs += [exe]
2207
2208 exe = executable('systemd-cgls',
2209                  'src/cgls/cgls.c',
2210                  include_directories : includes,
2211                  link_with : [libshared],
2212                  install_rpath : rootlibexecdir,
2213                  install : true)
2214 public_programs += [exe]
2215
2216 exe = executable('systemd-cgtop',
2217                  'src/cgtop/cgtop.c',
2218                  include_directories : includes,
2219                  link_with : [libshared],
2220                  install_rpath : rootlibexecdir,
2221                  install : true)
2222 public_programs += [exe]
2223
2224 executable('systemd-initctl',
2225            'src/initctl/initctl.c',
2226            include_directories : includes,
2227            link_with : [libshared],
2228            install_rpath : rootlibexecdir,
2229            install : true,
2230            install_dir : rootlibexecdir)
2231
2232 exe = executable('systemd-mount',
2233                  'src/mount/mount-tool.c',
2234                  include_directories : includes,
2235                  link_with : [libshared],
2236                  install_rpath : rootlibexecdir,
2237                  install : true)
2238 public_programs += [exe]
2239
2240 meson.add_install_script(meson_make_symlink,
2241                          'systemd-mount', join_paths(bindir, 'systemd-umount'))
2242
2243 exe = executable('systemd-run',
2244                  'src/run/run.c',
2245                  include_directories : includes,
2246                  link_with : [libshared],
2247                  install_rpath : rootlibexecdir,
2248                  install : true)
2249 public_programs += [exe]
2250
2251 exe = executable('systemd-stdio-bridge',
2252                  'src/stdio-bridge/stdio-bridge.c',
2253                  include_directories : includes,
2254                  link_with : [libshared],
2255                  install_rpath : rootlibexecdir,
2256                  install : true)
2257 public_programs += [exe]
2258
2259 exe = executable('busctl',
2260                  'src/busctl/busctl.c',
2261                  'src/busctl/busctl-introspect.c',
2262                  'src/busctl/busctl-introspect.h',
2263                  include_directories : includes,
2264                  link_with : [libshared],
2265                  install_rpath : rootlibexecdir,
2266                  install : true)
2267 public_programs += [exe]
2268
2269 if conf.get('ENABLE_SYSUSERS') == 1
2270         exe = executable('systemd-sysusers',
2271                          'src/sysusers/sysusers.c',
2272                          include_directories : includes,
2273                          link_with : [libshared],
2274                          install_rpath : rootlibexecdir,
2275                          install : true,
2276                          install_dir : rootbindir)
2277         public_programs += [exe]
2278 endif
2279
2280 if conf.get('ENABLE_TMPFILES') == 1
2281         exe = executable('systemd-tmpfiles',
2282                          'src/tmpfiles/tmpfiles.c',
2283                          include_directories : includes,
2284                          link_with : [libshared],
2285                          dependencies : [libacl],
2286                          install_rpath : rootlibexecdir,
2287                          install : true,
2288                          install_dir : rootbindir)
2289         public_programs += [exe]
2290
2291         test('test-systemd-tmpfiles',
2292              test_systemd_tmpfiles_py,
2293              args : exe.full_path())
2294         # https://github.com/mesonbuild/meson/issues/2681
2295 endif
2296
2297 if conf.get('ENABLE_HWDB') == 1
2298         exe = executable('systemd-hwdb',
2299                          'src/hwdb/hwdb.c',
2300                          'src/libsystemd/sd-hwdb/hwdb-internal.h',
2301                          include_directories : includes,
2302                          link_with : [libudev_static],
2303                          install_rpath : udev_rpath,
2304                          install : true,
2305                          install_dir : rootbindir)
2306         public_programs += [exe]
2307 endif
2308
2309 if conf.get('ENABLE_QUOTACHECK') == 1
2310         executable('systemd-quotacheck',
2311                    'src/quotacheck/quotacheck.c',
2312                    include_directories : includes,
2313                    link_with : [libshared],
2314                    install_rpath : rootlibexecdir,
2315                    install : true,
2316                    install_dir : rootlibexecdir)
2317 endif
2318
2319 exe = executable('systemd-socket-proxyd',
2320                  'src/socket-proxy/socket-proxyd.c',
2321                  include_directories : includes,
2322                  link_with : [libshared],
2323                  dependencies : [threads],
2324                  install_rpath : rootlibexecdir,
2325                  install : true,
2326                  install_dir : rootlibexecdir)
2327 public_programs += [exe]
2328
2329 exe = executable('systemd-udevd',
2330                  systemd_udevd_sources,
2331                  include_directories : includes,
2332                  c_args : ['-DLOG_REALM=LOG_REALM_UDEV'],
2333                  link_with : [libudev_core,
2334                               libsystemd_network,
2335                               libudev_static],
2336                  dependencies : [threads,
2337                                  libkmod,
2338                                  libidn,
2339                                  libacl,
2340                                  libblkid],
2341                  install_rpath : udev_rpath,
2342                  install : true,
2343                  install_dir : rootlibexecdir)
2344 public_programs += [exe]
2345
2346 exe = executable('udevadm',
2347                  udevadm_sources,
2348                  c_args : ['-DLOG_REALM=LOG_REALM_UDEV'],
2349                  include_directories : includes,
2350                  link_with : [libudev_core,
2351                               libsystemd_network,
2352                               libudev_static],
2353                  dependencies : [threads,
2354                                  libkmod,
2355                                  libidn,
2356                                  libacl,
2357                                  libblkid],
2358                  install_rpath : udev_rpath,
2359                  install : true,
2360                  install_dir : rootbindir)
2361 public_programs += [exe]
2362
2363 executable('systemd-shutdown',
2364            systemd_shutdown_sources,
2365            include_directories : includes,
2366            link_with : [libshared],
2367            install_rpath : rootlibexecdir,
2368            install : true,
2369            install_dir : rootlibexecdir)
2370
2371 executable('systemd-update-done',
2372            'src/update-done/update-done.c',
2373            include_directories : includes,
2374            link_with : [libshared],
2375            install_rpath : rootlibexecdir,
2376            install : true,
2377            install_dir : rootlibexecdir)
2378
2379 executable('systemd-update-utmp',
2380            'src/update-utmp/update-utmp.c',
2381            include_directories : includes,
2382            link_with : [libshared],
2383            dependencies : [libaudit],
2384            install_rpath : rootlibexecdir,
2385            install : true,
2386            install_dir : rootlibexecdir)
2387
2388 if conf.get('HAVE_KMOD') == 1
2389         executable('systemd-modules-load',
2390                    'src/modules-load/modules-load.c',
2391                    include_directories : includes,
2392                    link_with : [libshared],
2393                    dependencies : [libkmod],
2394                    install_rpath : rootlibexecdir,
2395                    install : true,
2396                    install_dir : rootlibexecdir)
2397
2398         meson.add_install_script('sh', '-c',
2399                                  mkdir_p.format(modulesloaddir))
2400         meson.add_install_script('sh', '-c',
2401                                  mkdir_p.format(join_paths(sysconfdir, 'modules-load.d')))
2402 endif
2403
2404 exe = executable('systemd-nspawn',
2405                  systemd_nspawn_sources,
2406                  'src/core/mount-setup.c', # FIXME: use a variable?
2407                  'src/core/mount-setup.h',
2408                  'src/core/loopback-setup.c',
2409                  'src/core/loopback-setup.h',
2410                  include_directories : [includes, include_directories('src/nspawn')],
2411                  link_with : [libshared],
2412                  dependencies : [libacl,
2413                                  libblkid,
2414                                  libseccomp,
2415                                  libselinux],
2416                  install_rpath : rootlibexecdir,
2417                  install : true)
2418 public_programs += [exe]
2419
2420 if conf.get('ENABLE_NETWORKD') == 1
2421         executable('systemd-networkd',
2422                    systemd_networkd_sources,
2423                    include_directories : includes,
2424                    link_with : [libnetworkd_core,
2425                                 libsystemd_network,
2426                                 libudev_static,
2427                                 libshared],
2428                    dependencies : [threads],
2429                    install_rpath : rootlibexecdir,
2430                    install : true,
2431                    install_dir : rootlibexecdir)
2432
2433         executable('systemd-networkd-wait-online',
2434                    systemd_networkd_wait_online_sources,
2435                    include_directories : includes,
2436                    link_with : [libnetworkd_core,
2437                                 libshared],
2438                    install_rpath : rootlibexecdir,
2439                    install : true,
2440                    install_dir : rootlibexecdir)
2441
2442         exe = executable('networkctl',
2443                    networkctl_sources,
2444                    include_directories : includes,
2445                    link_with : [libsystemd_network,
2446                               libshared],
2447                    install_rpath : rootlibexecdir,
2448                    install : true,
2449                    install_dir : rootbindir)
2450         public_programs += [exe]
2451 endif
2452
2453 executable('systemd-sulogin-shell',
2454            ['src/sulogin-shell/sulogin-shell.c'],
2455            include_directories : includes,
2456            link_with : [libshared],
2457            install_rpath : rootlibexecdir,
2458            install : true,
2459            install_dir : rootlibexecdir)
2460
2461 ############################################################
2462
2463 foreach tuple : tests
2464         sources = tuple[0]
2465         link_with = tuple[1].length() > 0 ? tuple[1] : [libshared]
2466         dependencies = tuple[2]
2467         condition = tuple.length() >= 4 ? tuple[3] : ''
2468         type = tuple.length() >= 5 ? tuple[4] : ''
2469         defs = tuple.length() >= 6 ? tuple[5] : []
2470         incs = tuple.length() >= 7 ? tuple[6] : includes
2471         timeout = 30
2472
2473         name = sources[0].split('/')[-1].split('.')[0]
2474         if type.startswith('timeout=')
2475                 timeout = type.split('=')[1].to_int()
2476                 type = ''
2477         endif
2478         if want_tests == 'false'
2479                 message('Not compiling @0@ because tests is set to false'.format(name))
2480         elif condition == '' or conf.get(condition) == 1
2481                 exe = executable(
2482                         name,
2483                         sources,
2484                         include_directories : incs,
2485                         link_with : link_with,
2486                         dependencies : dependencies,
2487                         c_args : defs,
2488                         install_rpath : rootlibexecdir,
2489                         install : install_tests,
2490                         install_dir : join_paths(testsdir, type))
2491
2492                 if type == 'manual'
2493                         message('@0@ is a manual test'.format(name))
2494                 elif type == 'unsafe' and want_tests != 'unsafe'
2495                         message('@0@ is an unsafe test'.format(name))
2496                 else
2497                         test(name, exe,
2498                              env : test_env,
2499                              timeout : timeout)
2500                 endif
2501         else
2502                 message('Not compiling @0@ because @1@ is not true'.format(name, condition))
2503         endif
2504 endforeach
2505
2506 test_libsystemd_sym = executable(
2507         'test-libsystemd-sym',
2508         test_libsystemd_sym_c,
2509         include_directories : includes,
2510         link_with : [libsystemd],
2511         install : install_tests,
2512         install_dir : testsdir)
2513 test('test-libsystemd-sym',
2514      test_libsystemd_sym)
2515
2516 test_libudev_sym = executable(
2517         'test-libudev-sym',
2518         test_libudev_sym_c,
2519         include_directories : includes,
2520         c_args : ['-Wno-deprecated-declarations'],
2521         link_with : [libudev],
2522         install : install_tests,
2523         install_dir : testsdir)
2524 test('test-libudev-sym',
2525      test_libudev_sym)
2526
2527 ############################################################
2528
2529 fuzzer_exes = []
2530
2531 foreach tuple : fuzzers
2532         sources = tuple[0]
2533         link_with = tuple[1].length() > 0 ? tuple[1] : [libshared]
2534         dependencies = tuple[2]
2535         defs = tuple.length() >= 4 ? tuple[3] : []
2536         incs = tuple.length() >= 5 ? tuple[4] : includes
2537
2538         if fuzzer_build
2539                 dependencies += fuzzing_engine
2540         else
2541                 sources += 'src/fuzz/fuzz-main.c'
2542         endif
2543
2544         name = sources[0].split('/')[-1].split('.')[0]
2545
2546         fuzzer_exes += executable(
2547                 name,
2548                 sources,
2549                 include_directories : [incs, include_directories('src/fuzz')],
2550                 link_with : link_with,
2551                 dependencies : dependencies,
2552                 c_args : defs,
2553                 install : false)
2554 endforeach
2555
2556 run_target('fuzzers',
2557         depends : fuzzer_exes,
2558         command : ['true'])
2559
2560 ############################################################
2561
2562 make_directive_index_py = find_program('tools/make-directive-index.py')
2563 make_man_index_py = find_program('tools/make-man-index.py')
2564 xml_helper_py = find_program('tools/xml_helper.py')
2565 hwdb_update_sh = find_program('tools/meson-hwdb-update.sh')
2566
2567 subdir('units')
2568 subdir('sysctl.d')
2569 subdir('sysusers.d')
2570 subdir('tmpfiles.d')
2571 subdir('presets')
2572 subdir('hwdb')
2573 subdir('network')
2574 subdir('man')
2575 subdir('shell-completion/bash')
2576 subdir('shell-completion/zsh')
2577 subdir('docs/sysvinit')
2578 subdir('docs/var-log')
2579
2580 # FIXME: figure out if the warning is true:
2581 # https://github.com/mesonbuild/meson/wiki/Reference-manual#install_subdir
2582 install_subdir('factory/etc',
2583                install_dir : factorydir)
2584
2585
2586 install_data('xorg/50-systemd-user.sh',
2587              install_dir : xinitrcdir)
2588 install_data('modprobe.d/systemd.conf',
2589              install_dir : modprobedir)
2590 install_data('README',
2591              'NEWS',
2592              'CODING_STYLE',
2593              'DISTRO_PORTING',
2594              'ENVIRONMENT.md',
2595              'LICENSE.GPL2',
2596              'LICENSE.LGPL2.1',
2597              'TRANSIENT-SETTINGS.md',
2598              'UIDS-GIDS.md',
2599              'src/libsystemd/sd-bus/GVARIANT-SERIALIZATION',
2600              install_dir : docdir)
2601
2602 meson.add_install_script('sh', '-c', mkdir_p.format(systemdstatedir))
2603 meson.add_install_script('sh', '-c', 'touch $DESTDIR@0@'.format(prefixdir))
2604
2605 ############################################################
2606
2607 meson_check_help = find_program('tools/meson-check-help.sh')
2608
2609 foreach exec : public_programs
2610         name = exec.full_path().split('/')[-1]
2611         test('check-help-' + name,
2612              meson_check_help,
2613              args : [exec.full_path()])
2614 endforeach
2615
2616 ############################################################
2617
2618 prev = ''
2619 foreach p : fuzz_regression_tests
2620         a = p.split('/')[-3]
2621         b = p.split('/')[-2]
2622         c = p.split('/')[-1]
2623
2624         if a == 'address'
2625                 build = sanitize_address
2626         else
2627                 error('unknown sanitizer @0@'.format(a))
2628         endif
2629
2630         name = '@1@:@0@'.format(a, b)
2631
2632         if name != prev
2633                 if want_tests == 'false'
2634                         message('Not compiling @0@ because tests is set to false'.format(name))
2635                 elif not sanitizers.contains(a)
2636                         message('Not compiling @0@ because @1@ sanitizer is not available'.format(name, a))
2637                 elif slow_tests
2638                         exe = custom_target(
2639                                 name,
2640                                 output : name,
2641                                 depends : build,
2642                                 command : [env, 'ln', '-fs',
2643                                            join_paths(build.full_path(), b),
2644                                            '@OUTPUT@'],
2645                                 build_by_default : true)
2646                 else
2647                         message('Not compiling @0@ because slow-tests is set to false'.format(name))
2648                 endif
2649         endif
2650         prev = name
2651
2652         if want_tests != 'false' and slow_tests
2653                 test(c, env, args : [exe.full_path(),
2654                                      join_paths(meson.source_root(),
2655                                                 'test/fuzz-regressions',
2656                                                 p)])
2657         endif
2658 endforeach
2659
2660 ############################################################
2661
2662 if git.found()
2663         all_files = run_command(
2664                 git,
2665                 ['--git-dir=@0@/.git'.format(meson.current_source_dir()),
2666                  'ls-files',
2667                  ':/*.[ch]'])
2668         all_files = files(all_files.stdout().split())
2669
2670         custom_target(
2671                 'tags',
2672                 output : 'tags',
2673                 command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.current_source_dir())] + all_files)
2674         custom_target(
2675                 'ctags',
2676                 output : 'ctags',
2677                 command : [env, 'ctags', '-o', '@0@/tags'.format(meson.current_source_dir())] + all_files)
2678 endif
2679
2680 if git.found()
2681         meson_git_contrib_sh = find_program('tools/meson-git-contrib.sh')
2682         run_target(
2683                 'git-contrib',
2684                 command : [meson_git_contrib_sh])
2685 endif
2686
2687 if git.found()
2688         git_head = run_command(
2689                 git,
2690                 ['--git-dir=@0@/.git'.format(meson.current_source_dir()),
2691                  'rev-parse', 'HEAD']).stdout().strip()
2692         git_head_short = run_command(
2693                 git,
2694                 ['--git-dir=@0@/.git'.format(meson.current_source_dir()),
2695                  'rev-parse', '--short=7', 'HEAD']).stdout().strip()
2696
2697         run_target(
2698                 'git-snapshot',
2699                 command : ['git', 'archive',
2700                            '-o', '@0@/systemd-@1@.tar.gz'.format(meson.current_source_dir(),
2701                                                                  git_head_short),
2702                            '--prefix', 'systemd-@0@/'.format(git_head),
2703                            'HEAD'])
2704 endif
2705
2706 ############################################################
2707
2708 meson_check_api_docs_sh = find_program('tools/meson-check-api-docs.sh')
2709 run_target(
2710         'check-api-docs',
2711         depends : [man, libsystemd, libudev],
2712         command : [meson_check_api_docs_sh, libsystemd.full_path(), libudev.full_path()])
2713
2714 ############################################################
2715
2716 status = [
2717         '@0@ @1@'.format(meson.project_name(), meson.project_version()),
2718
2719         'prefix directory:                  @0@'.format(prefixdir),
2720         'rootprefix directory:              @0@'.format(rootprefixdir),
2721         'sysconf directory:                 @0@'.format(sysconfdir),
2722         'include directory:                 @0@'.format(includedir),
2723         'lib directory:                     @0@'.format(libdir),
2724         'rootlib directory:                 @0@'.format(rootlibdir),
2725         'SysV init scripts:                 @0@'.format(sysvinit_path),
2726         'SysV rc?.d directories:            @0@'.format(sysvrcnd_path),
2727         'PAM modules directory:             @0@'.format(pamlibdir),
2728         'PAM configuration directory:       @0@'.format(pamconfdir),
2729         'RPM macros directory:              @0@'.format(rpmmacrosdir),
2730         'modprobe.d directory:              @0@'.format(modprobedir),
2731         'D-Bus policy directory:            @0@'.format(dbuspolicydir),
2732         'D-Bus session directory:           @0@'.format(dbussessionservicedir),
2733         'D-Bus system directory:            @0@'.format(dbussystemservicedir),
2734         'bash completions directory:        @0@'.format(bashcompletiondir),
2735         'zsh completions directory:         @0@'.format(zshcompletiondir),
2736         'extra start script:                @0@'.format(get_option('rc-local')),
2737         'extra stop script:                 @0@'.format(get_option('halt-local')),
2738         'debug shell:                       @0@ @ @1@'.format(get_option('debug-shell'),
2739                                                               get_option('debug-tty')),
2740         'TTY GID:                           @0@'.format(tty_gid),
2741         'users GID:                         @0@'.format(users_gid),
2742         'maximum system UID:                @0@'.format(system_uid_max),
2743         'maximum system GID:                @0@'.format(system_gid_max),
2744         'minimum dynamic UID:               @0@'.format(dynamic_uid_min),
2745         'maximum dynamic UID:               @0@'.format(dynamic_uid_max),
2746         'minimum container UID base:        @0@'.format(container_uid_base_min),
2747         'maximum container UID base:        @0@'.format(container_uid_base_max),
2748         '/dev/kvm access mode:              @0@'.format(get_option('dev-kvm-mode')),
2749         'render group access mode:          @0@'.format(get_option('group-render-mode')),
2750         'certificate root directory:        @0@'.format(get_option('certificate-root')),
2751         'support URL:                       @0@'.format(support_url),
2752         'nobody user name:                  @0@'.format(nobody_user),
2753         'nobody group name:                 @0@'.format(nobody_group),
2754         'fallback hostname:                 @0@'.format(get_option('fallback-hostname')),
2755         'symbolic gateway hostnames:        @0@'.format(', '.join(gateway_hostnames)),
2756
2757         'default DNSSEC mode:               @0@'.format(default_dnssec),
2758         'default cgroup hierarchy:          @0@'.format(default_hierarchy),
2759         'default KillUserProcesses setting: @0@'.format(kill_user_processes)]
2760
2761 alt_dns_servers = '\n                                            '.join(dns_servers.split(' '))
2762 alt_ntp_servers = '\n                                            '.join(ntp_servers.split(' '))
2763 status += [
2764         'default DNS servers:               @0@'.format(alt_dns_servers),
2765         'default NTP servers:               @0@'.format(alt_ntp_servers)]
2766
2767 alt_time_epoch = run_command('date', '-Is', '-u', '-d',
2768                              '@@0@'.format(time_epoch)).stdout().strip()
2769 status += [
2770         'time epoch:                        @0@ (@1@)'.format(time_epoch, alt_time_epoch)]
2771
2772 # TODO:
2773 # CFLAGS:   ${OUR_CFLAGS} ${CFLAGS}
2774 # CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
2775 # LDFLAGS:  ${OUR_LDFLAGS} ${LDFLAGS}
2776
2777 if conf.get('ENABLE_EFI') == 1
2778         status += [
2779                 'efi arch:                          @0@'.format(efi_arch)]
2780
2781         if have_gnu_efi
2782                 status += [
2783                         'EFI machine type:                  @0@'.format(EFI_MACHINE_TYPE_NAME),
2784                         'EFI CC                             @0@'.format(efi_cc),
2785                         'EFI lib directory:                 @0@'.format(efi_libdir),
2786                         'EFI lds directory:                 @0@'.format(efi_ldsdir),
2787                         'EFI include directory:             @0@'.format(efi_incdir)]
2788         endif
2789 endif
2790
2791 found = []
2792 missing = []
2793
2794 foreach tuple : [
2795         ['libcryptsetup'],
2796         ['PAM'],
2797         ['AUDIT'],
2798         ['IMA'],
2799         ['AppArmor'],
2800         ['SELinux'],
2801         ['SECCOMP'],
2802         ['SMACK'],
2803         ['zlib'],
2804         ['xz'],
2805         ['lz4'],
2806         ['bzip2'],
2807         ['ACL'],
2808         ['gcrypt'],
2809         ['qrencode'],
2810         ['microhttpd'],
2811         ['gnutls'],
2812         ['libcurl'],
2813         ['idn'],
2814         ['libidn2'],
2815         ['libidn'],
2816         ['nss-systemd'],
2817         ['libiptc'],
2818         ['elfutils'],
2819         ['binfmt'],
2820         ['vconsole'],
2821         ['quotacheck'],
2822         ['tmpfiles'],
2823         ['environment.d'],
2824         ['sysusers'],
2825         ['firstboot'],
2826         ['randomseed'],
2827         ['backlight'],
2828         ['rfkill'],
2829         ['logind'],
2830         ['machined'],
2831         ['importd'],
2832         ['hostnamed'],
2833         ['timedated'],
2834         ['timesyncd'],
2835         ['localed'],
2836         ['networkd'],
2837         ['resolve'],
2838         ['coredump'],
2839         ['polkit'],
2840         ['legacy pkla',      install_polkit_pkla],
2841         ['efi'],
2842         ['gnu-efi',          have_gnu_efi],
2843         ['kmod'],
2844         ['xkbcommon'],
2845         ['pcre2'],
2846         ['blkid'],
2847         ['dbus'],
2848         ['kdbus'],
2849         ['glib'],
2850         ['nss-myhostname',   conf.get('ENABLE_MYHOSTNAME') == 1],
2851         ['hwdb'],
2852         ['tpm'],
2853         ['man pages',        want_man],
2854         ['html pages',       want_html],
2855         ['man page indices', want_man and have_lxml],
2856         ['split /usr',       conf.get('HAVE_SPLIT_USR') == 1],
2857         ['SysV compat'],
2858         ['utmp'],
2859         ['ldconfig'],
2860         ['hibernate'],
2861         ['adm group',        get_option('adm-group')],
2862         ['wheel group',      get_option('wheel-group')],
2863         ['gshadow'],
2864         ['debug hashmap'],
2865         ['debug mmap cache'],
2866 ]
2867
2868         cond = tuple.get(1, '')
2869         if cond == ''
2870                 ident1 = 'HAVE_' + tuple[0].underscorify().to_upper()
2871                 ident2 = 'ENABLE_' + tuple[0].underscorify().to_upper()
2872                 cond = conf.get(ident1, 0) == 1 or conf.get(ident2, 0) == 1
2873         endif
2874         if cond
2875                 found += [tuple[0]]
2876         else
2877                 missing += [tuple[0]]
2878         endif
2879 endforeach
2880
2881 status += [
2882         '',
2883         'enabled features: @0@'.format(', '.join(found)),
2884         '',
2885         'disabled features: @0@'.format(', '.join(missing)),
2886         '']
2887 message('\n         '.join(status))
2888
2889 if rootprefixdir != rootprefix_default
2890         message('WARNING:\n' +
2891                 '        Note that the installation prefix was changed to "@0@".\n'.format(rootprefixdir) +
2892                 '        systemd used fixed names for unit file directories and other paths, so anything\n' +
2893                 '        except the default ("@0@") is strongly discouraged.'.format(rootprefix_default))
2894 endif