1# SPDX-License-Identifier: LGPL-2.1-or-later
2
3project('systemd', 'c',
4        version : '251',
5        license : 'LGPLv2+',
6        default_options: [
7                'c_std=gnu11',
8                'prefix=/usr',
9                'sysconfdir=/etc',
10                'localstatedir=/var',
11                'warning_level=2',
12        ],
13        meson_version : '>= 0.53.2',
14       )
15
16libsystemd_version = '0.34.0'
17libudev_version = '1.7.4'
18
19conf = configuration_data()
20conf.set_quoted('PROJECT_URL', 'https://www.freedesktop.org/wiki/Software/systemd')
21conf.set('PROJECT_VERSION',    meson.project_version(),
22         description : 'Numerical project version (used where a simple number is expected)')
23
24# This is to be used instead of meson.source_root(), as the latter will return
25# the wrong result when systemd is being built as a meson subproject
26project_source_root = meson.current_source_dir()
27project_build_root = meson.current_build_dir()
28relative_source_path = run_command('realpath',
29                                   '--relative-to=@0@'.format(project_build_root),
30                                   project_source_root,
31                                   check : true).stdout().strip()
32conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path)
33
34conf.set10('BUILD_MODE_DEVELOPER', get_option('mode') == 'developer',
35           description : 'tailor build to development or release builds')
36verification = get_option('log-message-verification')
37if verification == 'auto'
38        verification = conf.get('BUILD_MODE_DEVELOPER') == 1
39else
40        verification = verification == 'true'
41endif
42conf.set10('LOG_MESSAGE_VERIFICATION', verification)
43
44want_ossfuzz = get_option('oss-fuzz')
45want_libfuzzer = get_option('llvm-fuzz')
46if want_ossfuzz and want_libfuzzer
47        error('only one of oss-fuzz or llvm-fuzz can be specified')
48endif
49
50skip_deps = want_ossfuzz or get_option('skip-deps')
51fuzzer_build = want_ossfuzz or want_libfuzzer
52
53# If we're building *not* for actual fuzzing, allow input samples of any size
54# (for testing and for reproduction of issues discovered with previously-higher
55# limits).
56conf.set10('FUZZ_USE_SIZE_LIMIT', fuzzer_build)
57
58# Create a title-less summary section early, so it ends up first in the output.
59# More items are added later after they have been detected.
60summary({'build mode' : get_option('mode')})
61
62#####################################################################
63
64# Try to install the git pre-commit hook
65add_git_hook_sh = find_program('tools/add-git-hook.sh', required : false)
66if add_git_hook_sh.found()
67        git_hook = run_command(add_git_hook_sh, check : false)
68        if git_hook.returncode() == 0
69                message(git_hook.stdout().strip())
70        endif
71endif
72
73#####################################################################
74
75fs = import('fs')
76if get_option('split-usr') == 'auto'
77        split_usr = not fs.is_symlink('/bin')
78else
79        split_usr = get_option('split-usr') == 'true'
80endif
81if split_usr
82        warning('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n'
83                + '                    split-usr mode is going to be removed\n' +
84                '\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
85endif
86conf.set10('HAVE_SPLIT_USR', split_usr,
87           description : '/usr/bin and /bin directories are separate')
88
89if get_option('split-bin') == 'auto'
90        split_bin = not fs.is_symlink('/usr/sbin')
91else
92        split_bin = get_option('split-bin') == 'true'
93endif
94conf.set10('HAVE_SPLIT_BIN', split_bin,
95           description : 'bin and sbin directories are separate')
96
97rootprefixdir = get_option('rootprefix')
98# Unusual rootprefixdir values are used by some distros
99# (see https://github.com/systemd/systemd/pull/7461).
100rootprefix_default = split_usr ? '/' : '/usr'
101if rootprefixdir == ''
102        rootprefixdir = rootprefix_default
103endif
104rootprefixdir_noslash = rootprefixdir == '/' ? '' : rootprefixdir
105
106have_standalone_binaries = get_option('standalone-binaries')
107
108sysvinit_path = get_option('sysvinit-path')
109sysvrcnd_path = get_option('sysvrcnd-path')
110conf.set10('HAVE_SYSV_COMPAT', sysvinit_path != '' and sysvrcnd_path != '',
111           description : 'SysV init scripts and rcN.d links are supported')
112conf.set10('CREATE_LOG_DIRS', get_option('create-log-dirs'))
113
114if get_option('hibernate') and not get_option('initrd')
115        error('hibernate depends on initrd')
116endif
117
118conf.set10('BUMP_PROC_SYS_FS_FILE_MAX', get_option('bump-proc-sys-fs-file-max'))
119conf.set10('BUMP_PROC_SYS_FS_NR_OPEN',  get_option('bump-proc-sys-fs-nr-open'))
120conf.set('HIGH_RLIMIT_NOFILE',          512*1024)
121
122# Meson ignores the preceding arguments when joining paths if an absolute
123# component is encountered, so this should canonicalize various paths when they
124# are absolute or relative.
125prefixdir = get_option('prefix')
126if not prefixdir.startswith('/')
127        error('Prefix is not absolute: "@0@"'.format(prefixdir))
128endif
129if prefixdir != rootprefixdir and rootprefixdir != '/' and not prefixdir.strip('/').startswith(rootprefixdir.strip('/') + '/')
130        error('Prefix is not below root prefix (now rootprefix=@0@ prefix=@1@)'.format(
131                rootprefixdir, prefixdir))
132endif
133
134bindir = prefixdir / get_option('bindir')
135libdir = prefixdir / get_option('libdir')
136sysconfdir = prefixdir / get_option('sysconfdir')
137includedir = prefixdir / get_option('includedir')
138datadir = prefixdir / get_option('datadir')
139localstatedir = '/' / get_option('localstatedir')
140
141rootbindir = rootprefixdir / 'bin'
142rootsbindir = rootprefixdir / (split_bin ? 'sbin' : 'bin')
143rootlibexecdir = rootprefixdir / 'lib/systemd'
144
145rootlibdir = get_option('rootlibdir')
146if rootlibdir == ''
147        rootlibdir = rootprefixdir / libdir.split('/')[-1]
148endif
149
150install_sysconfdir = get_option('install-sysconfdir') != 'false'
151install_sysconfdir_samples = get_option('install-sysconfdir') == 'true'
152# Dirs of external packages
153pkgconfigdatadir = get_option('pkgconfigdatadir') != '' ? get_option('pkgconfigdatadir') : datadir / 'pkgconfig'
154pkgconfiglibdir = get_option('pkgconfiglibdir') != '' ? get_option('pkgconfiglibdir') : libdir / 'pkgconfig'
155polkitpolicydir = datadir / 'polkit-1/actions'
156polkitrulesdir = datadir / 'polkit-1/rules.d'
157polkitpkladir = localstatedir / 'lib/polkit-1/localauthority/10-vendor.d'
158xinitrcdir = get_option('xinitrcdir') != '' ? get_option('xinitrcdir') : sysconfdir / 'X11/xinit/xinitrc.d'
159rpmmacrosdir = get_option('rpmmacrosdir')
160if rpmmacrosdir != 'no'
161        rpmmacrosdir = prefixdir / rpmmacrosdir
162endif
163modprobedir = rootprefixdir / 'lib/modprobe.d'
164
165# Our own paths
166pkgdatadir = datadir / 'systemd'
167environmentdir = prefixdir / 'lib/environment.d'
168pkgsysconfdir = sysconfdir / 'systemd'
169userunitdir = prefixdir / 'lib/systemd/user'
170userpresetdir = prefixdir / 'lib/systemd/user-preset'
171tmpfilesdir = prefixdir / 'lib/tmpfiles.d'
172sysusersdir = prefixdir / 'lib/sysusers.d'
173sysctldir = prefixdir / 'lib/sysctl.d'
174binfmtdir = prefixdir / 'lib/binfmt.d'
175modulesloaddir = prefixdir / 'lib/modules-load.d'
176networkdir = rootprefixdir / 'lib/systemd/network'
177pkgincludedir = includedir / 'systemd'
178systemgeneratordir = rootlibexecdir / 'system-generators'
179usergeneratordir = prefixdir / 'lib/systemd/user-generators'
180systemenvgeneratordir = prefixdir / 'lib/systemd/system-environment-generators'
181userenvgeneratordir = prefixdir / 'lib/systemd/user-environment-generators'
182systemshutdowndir = rootlibexecdir / 'system-shutdown'
183systemsleepdir = rootlibexecdir / 'system-sleep'
184systemunitdir = rootprefixdir / 'lib/systemd/system'
185systempresetdir = rootprefixdir / 'lib/systemd/system-preset'
186udevlibexecdir = rootprefixdir / 'lib/udev'
187udevrulesdir = udevlibexecdir / 'rules.d'
188udevhwdbdir = udevlibexecdir / 'hwdb.d'
189catalogdir = prefixdir / 'lib/systemd/catalog'
190kerneldir = prefixdir / 'lib/kernel'
191kernelinstalldir = kerneldir / 'install.d'
192factorydir = datadir / 'factory'
193bootlibdir = prefixdir / 'lib/systemd/boot/efi'
194testsdir = prefixdir / 'lib/systemd/tests'
195systemdstatedir = localstatedir / 'lib/systemd'
196catalogstatedir = systemdstatedir / 'catalog'
197randomseeddir = localstatedir / 'lib/systemd'
198profiledir = rootlibexecdir / 'portable' / 'profile'
199ntpservicelistdir = rootprefixdir / 'lib/systemd/ntp-units.d'
200
201docdir = get_option('docdir')
202if docdir == ''
203        docdir = datadir / 'doc/systemd'
204endif
205
206pamlibdir = get_option('pamlibdir')
207if pamlibdir == ''
208        pamlibdir = rootlibdir / 'security'
209endif
210
211pamconfdir = get_option('pamconfdir')
212if pamconfdir == ''
213        pamconfdir = prefixdir / 'lib/pam.d'
214endif
215
216libcryptsetup_plugins_dir = get_option('libcryptsetup-plugins-dir')
217if libcryptsetup_plugins_dir == ''
218        libcryptsetup_plugins_dir = rootlibdir / 'cryptsetup'
219endif
220
221memory_accounting_default = get_option('memory-accounting-default')
222status_unit_format_default = get_option('status-unit-format-default')
223
224conf.set_quoted('BINFMT_DIR',                                 binfmtdir)
225conf.set_quoted('BOOTLIBDIR',                                 bootlibdir)
226conf.set_quoted('CATALOG_DATABASE',                           catalogstatedir / 'database')
227conf.set_quoted('CERTIFICATE_ROOT',                           get_option('certificate-root'))
228conf.set_quoted('DOC_DIR',                                    docdir)
229conf.set_quoted('DOCUMENT_ROOT',                              pkgdatadir / 'gatewayd')
230conf.set_quoted('ENVIRONMENT_DIR',                            environmentdir)
231conf.set_quoted('INCLUDE_DIR',                                includedir)
232conf.set_quoted('LIBDIR',                                     libdir)
233conf.set_quoted('MODPROBE_DIR',                               modprobedir)
234conf.set_quoted('MODULESLOAD_DIR',                            modulesloaddir)
235conf.set_quoted('PKGSYSCONFDIR',                              pkgsysconfdir)
236conf.set_quoted('POLKIT_AGENT_BINARY_PATH',                   bindir / 'pkttyagent')
237conf.set_quoted('PREFIX',                                     prefixdir)
238conf.set_quoted('RANDOM_SEED',                                randomseeddir / 'random-seed')
239conf.set_quoted('RANDOM_SEED_DIR',                            randomseeddir)
240conf.set_quoted('RC_LOCAL_PATH',                              get_option('rc-local'))
241conf.set_quoted('ROOTBINDIR',                                 rootbindir)
242conf.set_quoted('ROOTLIBDIR',                                 rootlibdir)
243conf.set_quoted('ROOTLIBEXECDIR',                             rootlibexecdir)
244conf.set_quoted('ROOTPREFIX',                                 rootprefixdir)
245conf.set_quoted('ROOTPREFIX_NOSLASH',                         rootprefixdir_noslash)
246conf.set_quoted('SYSCONF_DIR',                                sysconfdir)
247conf.set_quoted('SYSCTL_DIR',                                 sysctldir)
248conf.set_quoted('SYSTEMCTL_BINARY_PATH',                      rootbindir / 'systemctl')
249conf.set_quoted('SYSTEMD_BINARY_PATH',                        rootlibexecdir / 'systemd')
250conf.set_quoted('SYSTEMD_CATALOG_DIR',                        catalogdir)
251conf.set_quoted('SYSTEMD_CGROUPS_AGENT_PATH',                 rootlibexecdir / 'systemd-cgroups-agent')
252conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH',                    rootlibexecdir / 'systemd-cryptsetup')
253conf.set_quoted('SYSTEMD_EXPORT_PATH',                        rootlibexecdir / 'systemd-export')
254conf.set_quoted('SYSTEMD_FSCK_PATH',                          rootlibexecdir / 'systemd-fsck')
255conf.set_quoted('SYSTEMD_GROWFS_PATH',                        rootlibexecdir / 'systemd-growfs')
256conf.set_quoted('SYSTEMD_HOMEWORK_PATH',                      rootlibexecdir / 'systemd-homework')
257conf.set_quoted('SYSTEMD_IMPORT_FS_PATH',                     rootlibexecdir / 'systemd-import-fs')
258conf.set_quoted('SYSTEMD_IMPORT_PATH',                        rootlibexecdir / 'systemd-import')
259conf.set_quoted('SYSTEMD_INTEGRITYSETUP_PATH',                rootlibexecdir / 'systemd-integritysetup')
260conf.set_quoted('SYSTEMD_KBD_MODEL_MAP',                      pkgdatadir / 'kbd-model-map')
261conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP',              pkgdatadir / 'language-fallback-map')
262conf.set_quoted('SYSTEMD_MAKEFS_PATH',                        rootlibexecdir / 'systemd-makefs')
263conf.set_quoted('SYSTEMD_PULL_PATH',                          rootlibexecdir / 'systemd-pull')
264conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH',               rootlibexecdir / 'systemd-shutdown')
265conf.set_quoted('SYSTEMD_TEST_DATA',                          testsdir / 'testdata')
266conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', rootbindir / 'systemd-tty-ask-password-agent')
267conf.set_quoted('SYSTEMD_UPDATE_HELPER_PATH',                 rootlibexecdir / 'systemd-update-helper')
268conf.set_quoted('SYSTEMD_USERWORK_PATH',                      rootlibexecdir / 'systemd-userwork')
269conf.set_quoted('SYSTEMD_VERITYSETUP_PATH',                   rootlibexecdir / 'systemd-veritysetup')
270conf.set_quoted('SYSTEM_CONFIG_UNIT_DIR',                     pkgsysconfdir / 'system')
271conf.set_quoted('SYSTEM_DATA_UNIT_DIR',                       systemunitdir)
272conf.set_quoted('SYSTEM_ENV_GENERATOR_DIR',                   systemenvgeneratordir)
273conf.set_quoted('SYSTEM_GENERATOR_DIR',                       systemgeneratordir)
274conf.set_quoted('SYSTEM_PRESET_DIR',                          systempresetdir)
275conf.set_quoted('SYSTEM_SHUTDOWN_PATH',                       systemshutdowndir)
276conf.set_quoted('SYSTEM_SLEEP_PATH',                          systemsleepdir)
277conf.set_quoted('SYSTEM_SYSVINIT_PATH',                       sysvinit_path)
278conf.set_quoted('SYSTEM_SYSVRCND_PATH',                       sysvrcnd_path)
279conf.set_quoted('SYSUSERS_DIR',                               sysusersdir)
280conf.set_quoted('TMPFILES_DIR',                               tmpfilesdir)
281conf.set_quoted('UDEVLIBEXECDIR',                             udevlibexecdir)
282conf.set_quoted('UDEV_HWDB_DIR',                              udevhwdbdir)
283conf.set_quoted('UDEV_RULES_DIR',                             udevrulesdir)
284conf.set_quoted('UPDATE_HELPER_USER_TIMEOUT',                 get_option('update-helper-user-timeout'))
285conf.set_quoted('USER_CONFIG_UNIT_DIR',                       pkgsysconfdir / 'user')
286conf.set_quoted('USER_DATA_UNIT_DIR',                         userunitdir)
287conf.set_quoted('USER_ENV_GENERATOR_DIR',                     userenvgeneratordir)
288conf.set_quoted('USER_GENERATOR_DIR',                         usergeneratordir)
289conf.set_quoted('USER_KEYRING_PATH',                          pkgsysconfdir / 'import-pubring.gpg')
290conf.set_quoted('USER_PRESET_DIR',                            userpresetdir)
291conf.set_quoted('VENDOR_KEYRING_PATH',                        rootlibexecdir / 'import-pubring.gpg')
292
293conf.set('ANSI_OK_COLOR',                                     'ANSI_' + get_option('ok-color').underscorify().to_upper())
294conf.set10('ENABLE_URLIFY',                                   get_option('urlify'))
295conf.set10('ENABLE_FEXECVE',                                  get_option('fexecve'))
296conf.set10('MEMORY_ACCOUNTING_DEFAULT',                       memory_accounting_default)
297conf.set('STATUS_UNIT_FORMAT_DEFAULT',                        'STATUS_UNIT_FORMAT_' + status_unit_format_default.to_upper())
298conf.set_quoted('STATUS_UNIT_FORMAT_DEFAULT_STR',             status_unit_format_default)
299
300#####################################################################
301
302cc = meson.get_compiler('c')
303pkgconfig = import('pkgconfig')
304meson_build_sh = find_program('tools/meson-build.sh')
305
306want_tests = get_option('tests')
307slow_tests = want_tests != 'false' and get_option('slow-tests')
308fuzz_tests = want_tests != 'false' and get_option('fuzz-tests')
309install_tests = get_option('install-tests')
310
311if add_languages('cpp', required : fuzzer_build)
312        #  Used only for tests
313        cxx = meson.get_compiler('cpp')
314        cxx_cmd = ' '.join(cxx.cmd_array())
315else
316        cxx_cmd = ''
317endif
318
319if want_libfuzzer
320        fuzzing_engine = meson.get_compiler('cpp').find_library('Fuzzer', required : false)
321        if fuzzing_engine.found()
322                add_project_arguments('-fsanitize-coverage=trace-pc-guard,trace-cmp', language : 'c')
323        elif cc.has_argument('-fsanitize=fuzzer-no-link')
324                add_project_arguments('-fsanitize=fuzzer-no-link', language : 'c')
325        else
326                error('Looks like neither libFuzzer nor -fsanitize=fuzzer-no-link is supported')
327        endif
328elif want_ossfuzz
329        fuzzing_engine = meson.get_compiler('cpp').find_library('FuzzingEngine')
330endif
331
332# Those generate many false positives, and we do not want to change the code to
333# avoid them.
334basic_disabled_warnings = [
335        '-Wno-format-signedness',
336        '-Wno-missing-field-initializers',
337        '-Wno-unused-parameter',
338]
339
340possible_common_cc_flags = [
341        '-Wdate-time',
342        '-Wendif-labels',
343        '-Werror=format=2',
344        '-Werror=implicit-function-declaration',
345        '-Werror=incompatible-pointer-types',
346        '-Werror=int-conversion',
347        '-Werror=overflow',
348        '-Werror=override-init',
349        '-Werror=return-type',
350        '-Werror=shift-count-overflow',
351        '-Werror=shift-overflow=2',
352        '-Werror=undef',
353        '-Wfloat-equal',
354        '-Wimplicit-fallthrough=5',
355        '-Winit-self',
356        '-Wlogical-op',
357        '-Wmissing-include-dirs',
358        '-Wmissing-noreturn',
359        '-Wnested-externs',
360        '-Wold-style-definition',
361        '-Wpointer-arith',
362        '-Wredundant-decls',
363        '-Wshadow',
364        '-Wstrict-aliasing=2',
365        '-Wstrict-prototypes',
366        '-Wsuggest-attribute=noreturn',
367        '-Wunused-function',
368        '-Wwrite-strings',
369
370        # negative arguments are correctly detected starting with meson 0.46.
371        '-Wno-error=#warnings',  # clang
372        '-Wno-string-plus-int',  # clang
373]
374
375c_args = get_option('c_args')
376
377# Disable -Wmaybe-uninitialized when compiling with -Os/-O1/-O3/etc. There are
378# too many false positives with gcc >= 8. Effectively, we only test with -O0
379# and -O2; this should be enough to catch most important cases without too much
380# busywork. See https://github.com/systemd/systemd/pull/19226.
381if cc.get_id() == 'gcc' and (not '02'.contains(get_option('optimization')) or
382                             cc.version().version_compare('<10') or
383                             '-Os' in c_args or
384                             '-O1' in c_args or
385                             '-O3' in c_args or
386                             '-Og' in c_args)
387        possible_common_cc_flags += '-Wno-maybe-uninitialized'
388endif
389
390# Disable -Wno-unused-result with gcc, see
391# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425.
392if cc.get_id() == 'gcc'
393        possible_common_cc_flags += '-Wno-unused-result'
394endif
395
396# --as-needed and --no-undefined are provided by meson by default,
397# run 'meson configure' to see what is enabled
398possible_link_flags = [
399        '-Wl,--fatal-warnings',
400        '-Wl,-z,now',
401        '-Wl,-z,relro',
402        '-fstack-protector',
403]
404
405if get_option('b_sanitize') == 'none'
406        possible_link_flags += '-Wl,--warn-common'
407endif
408
409if cc.get_id() == 'clang'
410        possible_common_cc_flags += [
411                '-Wno-typedef-redefinition',
412                '-Wno-gnu-variable-sized-type-not-at-end',
413        ]
414endif
415
416possible_cc_flags = possible_common_cc_flags + [
417        '-Werror=missing-declarations',
418        '-Werror=missing-prototypes',
419        '-fdiagnostics-show-option',
420        '-fno-common',
421        '-fno-strict-aliasing',
422        '-fstack-protector',
423        '-fstack-protector-strong',
424        '-fvisibility=hidden',
425        '--param=ssp-buffer-size=4',
426]
427
428if get_option('buildtype') != 'debug'
429        possible_cc_flags += [
430                '-ffunction-sections',
431                '-fdata-sections',
432        ]
433
434        possible_link_flags += '-Wl,--gc-sections'
435endif
436
437add_project_arguments(cc.get_supported_arguments(basic_disabled_warnings), language : 'c')
438add_project_arguments(cc.get_supported_arguments(possible_cc_flags), language : 'c')
439add_project_link_arguments(cc.get_supported_link_arguments(possible_link_flags), language : 'c')
440
441have = cc.has_argument('-Wzero-length-bounds')
442conf.set10('HAVE_ZERO_LENGTH_BOUNDS', have)
443
444if cc.compiles('''
445   #include <time.h>
446   #include <inttypes.h>
447   typedef uint64_t usec_t;
448   usec_t now(clockid_t clock);
449   int main(void) {
450           struct timespec now;
451           return 0;
452   }
453''', args: '-Werror=shadow', name : '-Werror=shadow with local shadowing')
454        add_project_arguments('-Werror=shadow', language : 'c')
455endif
456
457if cxx_cmd != ''
458        add_project_arguments(cxx.get_supported_arguments(basic_disabled_warnings), language : 'cpp')
459endif
460
461cpp = ' '.join(cc.cmd_array()) + ' -E'
462
463has_wstringop_truncation = cc.has_argument('-Wstringop-truncation')
464
465#####################################################################
466# compilation result tests
467
468conf.set('_GNU_SOURCE', true)
469conf.set('__SANE_USERSPACE_TYPES__', true)
470conf.set10('HAVE_WSTRINGOP_TRUNCATION', has_wstringop_truncation)
471
472conf.set('SIZEOF_DEV_T', cc.sizeof('dev_t', prefix : '#include <sys/types.h>'))
473conf.set('SIZEOF_INO_T', cc.sizeof('ino_t', prefix : '#include <sys/types.h>'))
474conf.set('SIZEOF_TIME_T', cc.sizeof('time_t', prefix : '#include <sys/time.h>'))
475conf.set('SIZEOF_RLIM_T', cc.sizeof('rlim_t', prefix : '#include <sys/resource.h>'))
476conf.set('SIZEOF_TIMEX_MEMBER', cc.sizeof('typeof(((struct timex *)0)->freq)', prefix : '#include <sys/timex.h>'))
477
478decl_headers = '''
479#include <uchar.h>
480#include <sys/mount.h>
481#include <sys/stat.h>
482#include <linux/fs.h>
483'''
484
485foreach decl : ['char16_t',
486                'char32_t',
487                'struct mount_attr',
488                'struct statx',
489               ]
490
491        # We get -1 if the size cannot be determined
492        have = cc.sizeof(decl, prefix : decl_headers, args : '-D_GNU_SOURCE') > 0
493
494        if decl == 'struct statx'
495                if have
496                        want_linux_stat_h = false
497                else
498                        have = cc.sizeof(decl,
499                                         prefix : decl_headers + '#include <linux/stat.h>',
500                                         args : '-D_GNU_SOURCE') > 0
501                        want_linux_stat_h = have
502                endif
503        endif
504
505        conf.set10('HAVE_' + decl.underscorify().to_upper(), have)
506endforeach
507
508conf.set10('WANT_LINUX_STAT_H', want_linux_stat_h)
509
510foreach ident : ['secure_getenv', '__secure_getenv']
511        conf.set10('HAVE_' + ident.to_upper(), cc.has_function(ident))
512endforeach
513
514foreach ident : [
515        ['memfd_create',      '''#include <sys/mman.h>'''],
516        ['gettid',            '''#include <sys/types.h>
517                                 #include <unistd.h>'''],
518        ['pivot_root',        '''#include <stdlib.h>
519                                 #include <unistd.h>'''],     # no known header declares pivot_root
520        ['ioprio_get',        '''#include <sched.h>'''],      # no known header declares ioprio_get
521        ['ioprio_set',        '''#include <sched.h>'''],      # no known header declares ioprio_set
522        ['name_to_handle_at', '''#include <sys/types.h>
523                                 #include <sys/stat.h>
524                                 #include <fcntl.h>'''],
525        ['setns',             '''#include <sched.h>'''],
526        ['renameat2',         '''#include <stdio.h>
527                                 #include <fcntl.h>'''],
528        ['kcmp',              '''#include <linux/kcmp.h>'''],
529        ['keyctl',            '''#include <sys/types.h>
530                                 #include <keyutils.h>'''],
531        ['copy_file_range',   '''#include <sys/syscall.h>
532                                 #include <unistd.h>'''],
533        ['bpf',               '''#include <sys/syscall.h>
534                                 #include <unistd.h>'''],
535        ['statx',             '''#include <sys/types.h>
536                                 #include <sys/stat.h>
537                                 #include <unistd.h>'''],
538        ['explicit_bzero' ,   '''#include <string.h>'''],
539        ['reallocarray',      '''#include <stdlib.h>'''],
540        ['set_mempolicy',     '''#include <stdlib.h>
541                                 #include <unistd.h>'''],
542        ['get_mempolicy',     '''#include <stdlib.h>
543                                 #include <unistd.h>'''],
544        ['pidfd_send_signal', '''#include <stdlib.h>
545                                 #include <unistd.h>
546                                 #include <signal.h>
547                                 #include <sys/wait.h>'''],
548        ['pidfd_open',        '''#include <stdlib.h>
549                                 #include <unistd.h>
550                                 #include <signal.h>
551                                 #include <sys/wait.h>'''],
552        ['rt_sigqueueinfo',   '''#include <stdlib.h>
553                                 #include <unistd.h>
554                                 #include <signal.h>
555                                 #include <sys/wait.h>'''],
556        ['mallinfo',          '''#include <malloc.h>'''],
557        ['mallinfo2',         '''#include <malloc.h>'''],
558        ['execveat',          '''#include <unistd.h>'''],
559        ['close_range',       '''#include <unistd.h>'''],
560        ['epoll_pwait2',      '''#include <sys/epoll.h>'''],
561        ['mount_setattr',     '''#include <sys/mount.h>'''],
562        ['move_mount',        '''#include <sys/mount.h>'''],
563        ['open_tree',         '''#include <sys/mount.h>'''],
564        ['getdents64',        '''#include <dirent.h>'''],
565]
566
567        have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
568        conf.set10('HAVE_' + ident[0].to_upper(), have)
569endforeach
570
571if cc.has_function('getrandom', prefix : '''#include <sys/random.h>''', args : '-D_GNU_SOURCE')
572        conf.set10('USE_SYS_RANDOM_H', true)
573        conf.set10('HAVE_GETRANDOM', true)
574else
575        have = cc.has_function('getrandom', prefix : '''#include <linux/random.h>''')
576        conf.set10('USE_SYS_RANDOM_H', false)
577        conf.set10('HAVE_GETRANDOM', have)
578endif
579
580#####################################################################
581
582version_tag = get_option('version-tag')
583if version_tag != ''
584        vcs_data = configuration_data()
585        vcs_data.set('VCS_TAG', version_tag)
586        version_h = configure_file(configuration : vcs_data,
587                                   input : 'src/version/version.h.in',
588                                   output : 'version.h')
589else
590        vcs_tagger = [
591                project_source_root + '/tools/meson-vcs-tag.sh',
592                project_source_root,
593                meson.project_version()]
594
595        version_h = vcs_tag(
596                input : 'src/version/version.h.in',
597                output : 'version.h',
598                command: vcs_tagger)
599endif
600
601versiondep = declare_dependency(sources: version_h)
602
603shared_lib_tag = get_option('shared-lib-tag')
604if shared_lib_tag == ''
605        shared_lib_tag = meson.project_version()
606endif
607
608sh = find_program('sh')
609echo = find_program('echo')
610sed = find_program('sed')
611awk = find_program('awk')
612stat = find_program('stat')
613ln = find_program('ln')
614git = find_program('git', required : false)
615env = find_program('env')
616perl = find_program('perl', required : false)
617rsync = find_program('rsync', required : false)
618meson_make_symlink = project_source_root + '/tools/meson-make-symlink.sh'
619
620mkdir_p = 'mkdir -p $DESTDIR/@0@'
621
622# If -Dxxx-path option is found, use that. Otherwise, check in $PATH,
623# /usr/sbin, /sbin, and fall back to the default from middle column.
624progs = [['quotaon',    '/usr/sbin/quotaon'    ],
625         ['quotacheck', '/usr/sbin/quotacheck' ],
626         ['kmod',       '/usr/bin/kmod'        ],
627         ['kexec',      '/usr/sbin/kexec'      ],
628         ['sulogin',    '/usr/sbin/sulogin'    ],
629         ['mount',      '/usr/bin/mount',      'MOUNT_PATH'],
630         ['umount',     '/usr/bin/umount',     'UMOUNT_PATH'],
631         ['loadkeys',   '/usr/bin/loadkeys',   'KBD_LOADKEYS'],
632         ['setfont',    '/usr/bin/setfont',    'KBD_SETFONT'],
633         ['nologin',    '/usr/sbin/nologin',   ],
634        ]
635foreach prog : progs
636        path = get_option(prog[0] + '-path')
637        if path != ''
638                message('Using @1@ for @0@'.format(prog[0], path))
639        else
640                exe = find_program(prog[0],
641                                   '/usr/sbin/' + prog[0],
642                                   '/sbin/' + prog[0],
643                                   required: false)
644                path = exe.found() ? exe.path() : prog[1]
645        endif
646        name = prog.length() > 2 ? prog[2] : prog[0].to_upper()
647        conf.set_quoted(name, path)
648endforeach
649
650conf.set_quoted('TELINIT', get_option('telinit-path'))
651
652if run_command(ln, '--relative', '--help', check : false).returncode() != 0
653        error('ln does not support --relative (added in coreutils 8.16)')
654endif
655
656############################################################
657
658python = find_program('python3')
659if run_command(python, '-c', 'import jinja2', check : false).returncode() != 0
660        error('python3 jinja2 missing')
661endif
662
663############################################################
664
665gperf = find_program('gperf')
666
667gperf_test_format = '''
668#include <string.h>
669const char * in_word_set(const char *, @0@);
670@1@
671'''
672gperf_snippet = run_command(sh, '-c', 'echo foo,bar | "$1" -L ANSI-C', '_', gperf,
673                            check : true)
674gperf_test = gperf_test_format.format('size_t', gperf_snippet.stdout())
675if cc.compiles(gperf_test)
676        gperf_len_type = 'size_t'
677else
678        gperf_test = gperf_test_format.format('unsigned', gperf_snippet.stdout())
679        if cc.compiles(gperf_test)
680                gperf_len_type = 'unsigned'
681        else
682                error('unable to determine gperf len type')
683        endif
684endif
685message('gperf len type is @0@'.format(gperf_len_type))
686conf.set('GPERF_LEN_TYPE', gperf_len_type,
687         description : 'The type of gperf "len" parameter')
688
689############################################################
690
691if not cc.has_header('sys/capability.h')
692        error('POSIX caps headers not found')
693endif
694foreach header : ['crypt.h',
695                  'linux/memfd.h',
696                  'linux/vm_sockets.h',
697                  'sys/auxv.h',
698                  'valgrind/memcheck.h',
699                  'valgrind/valgrind.h',
700                  'linux/time_types.h',
701                  'sys/sdt.h',
702                 ]
703
704        conf.set10('HAVE_' + header.underscorify().to_upper(),
705                   cc.has_header(header))
706endforeach
707
708############################################################
709
710fallback_hostname = get_option('fallback-hostname')
711if fallback_hostname == '' or fallback_hostname[0] == '.' or fallback_hostname[0] == '-'
712        error('Invalid fallback-hostname configuration')
713        # A more extensive test is done in test-hostname-util. Let's catch
714        # the most obvious errors here so we don't fail with an assert later.
715endif
716conf.set_quoted('FALLBACK_HOSTNAME', fallback_hostname)
717
718default_hierarchy = get_option('default-hierarchy')
719conf.set_quoted('DEFAULT_HIERARCHY_NAME', default_hierarchy,
720                description : 'default cgroup hierarchy as string')
721if default_hierarchy == 'legacy'
722        conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_NONE')
723elif default_hierarchy == 'hybrid'
724        conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_SYSTEMD')
725else
726        conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL')
727endif
728
729extra_net_naming_schemes = []
730extra_net_naming_map = []
731foreach scheme: get_option('extra-net-naming-schemes').split(',')
732        if scheme != ''
733                name = scheme.split('=')[0]
734                value = scheme.split('=')[1]
735                NAME = name.underscorify().to_upper()
736                VALUE = []
737                foreach field: value.split('+')
738                        VALUE += 'NAMING_' + field.underscorify().to_upper()
739                endforeach
740                extra_net_naming_schemes += 'NAMING_@0@ = @1@,'.format(NAME, '|'.join(VALUE))
741                extra_net_naming_map += '{ "@0@", NAMING_@1@ },'.format(name, NAME)
742        endif
743endforeach
744conf.set('EXTRA_NET_NAMING_SCHEMES', ' '.join(extra_net_naming_schemes))
745conf.set('EXTRA_NET_NAMING_MAP', ' '.join(extra_net_naming_map))
746
747default_net_naming_scheme = get_option('default-net-naming-scheme')
748conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme)
749if default_net_naming_scheme != 'latest'
750        conf.set('_DEFAULT_NET_NAMING_SCHEME_TEST',
751                 'NAMING_' + default_net_naming_scheme.underscorify().to_upper())
752endif
753
754time_epoch = get_option('time-epoch')
755if time_epoch == -1
756        time_epoch = run_command(sh, '-c', 'echo "$SOURCE_DATE_EPOCH"', check : true).stdout().strip()
757        if time_epoch == '' and git.found() and fs.exists('.git')
758                # If we're in a git repository, use the creation time of the latest git tag.
759                latest_tag = run_command(git, 'describe', '--abbrev=0', '--tags',
760                                         check : false)
761                if latest_tag.returncode() == 0
762                        time_epoch = run_command(
763                                git, 'log', '--no-show-signature', '-1', '--format=%at',
764                                     latest_tag.stdout().strip(),
765                                check : false).stdout()
766                endif
767        endif
768        if time_epoch == ''
769                NEWS = files('NEWS')
770                time_epoch = run_command(stat, '-c', '%Y', NEWS,
771                                         check : true).stdout()
772        endif
773        time_epoch = time_epoch.to_int()
774endif
775conf.set('TIME_EPOCH', time_epoch)
776
777conf.set('CLOCK_VALID_RANGE_USEC_MAX', get_option('clock-valid-range-usec-max'))
778
779default_user_shell = get_option('default-user-shell')
780conf.set_quoted('DEFAULT_USER_SHELL',      default_user_shell)
781conf.set_quoted('DEFAULT_USER_SHELL_NAME', fs.name(default_user_shell))
782
783foreach tuple : [['system-alloc-uid-min', 'SYS_UID_MIN', 1],  # Also see login.defs(5).
784                 ['system-uid-max',       'SYS_UID_MAX', 999],
785                 ['system-alloc-gid-min', 'SYS_GID_MIN', 1],
786                 ['system-gid-max',       'SYS_GID_MAX', 999]]
787        v = get_option(tuple[0])
788        if v == -1
789                v = run_command(
790                        awk,
791                        '/^\s*@0@\s+/ { uid=$2 } END { print uid }'.format(tuple[1]),
792                        '/etc/login.defs',
793                        check : false).stdout().strip()
794                if v == ''
795                        v = tuple[2]
796                else
797                        v = v.to_int()
798                endif
799        endif
800        conf.set(tuple[0].underscorify().to_upper(), v)
801endforeach
802if conf.get('SYSTEM_ALLOC_UID_MIN') >= conf.get('SYSTEM_UID_MAX')
803        error('Invalid uid allocation range')
804endif
805if conf.get('SYSTEM_ALLOC_GID_MIN') >= conf.get('SYSTEM_GID_MAX')
806        error('Invalid gid allocation range')
807endif
808
809dynamic_uid_min = get_option('dynamic-uid-min')
810dynamic_uid_max = get_option('dynamic-uid-max')
811conf.set('DYNAMIC_UID_MIN', dynamic_uid_min)
812conf.set('DYNAMIC_UID_MAX', dynamic_uid_max)
813
814container_uid_base_min = get_option('container-uid-base-min')
815container_uid_base_max = get_option('container-uid-base-max')
816conf.set('CONTAINER_UID_BASE_MIN', container_uid_base_min)
817conf.set('CONTAINER_UID_BASE_MAX', container_uid_base_max)
818
819nobody_user = get_option('nobody-user')
820nobody_group = get_option('nobody-group')
821
822if not meson.is_cross_build()
823        getent_result = run_command('getent', 'passwd', '65534', check : false)
824        if getent_result.returncode() == 0
825                name = getent_result.stdout().split(':')[0]
826                if name != nobody_user
827                        warning('\n' +
828                                '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) +
829                                'Your build will result in an user table setup that is incompatible with the local system.')
830                endif
831        endif
832        id_result = run_command('id', '-u', nobody_user, check : false)
833        if id_result.returncode() == 0
834                id = id_result.stdout().to_int()
835                if id != 65534
836                        warning('\n' +
837                                '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) +
838                                'Your build will result in an user table setup that is incompatible with the local system.')
839                endif
840        endif
841
842        getent_result = run_command('getent', 'group', '65534', check : false)
843        if getent_result.returncode() == 0
844                name = getent_result.stdout().split(':')[0]
845                if name != nobody_group
846                        warning('\n' +
847                                '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) +
848                                'Your build will result in an group table setup that is incompatible with the local system.')
849                endif
850        endif
851        id_result = run_command('id', '-g', nobody_group, check : false)
852        if id_result.returncode() == 0
853                id = id_result.stdout().to_int()
854                if id != 65534
855                        warning('\n' +
856                                'The local group with the configured group name "@0@" of the nobody group does not have GID 65534 (it has @1@).\n'.format(nobody_group, id) +
857                                'Your build will result in an group table setup that is incompatible with the local system.')
858                endif
859        endif
860endif
861if nobody_user != nobody_group and not (nobody_user == 'nobody' and nobody_group == 'nogroup')
862        warning('\n' +
863                'The configured user name "@0@" and group name "@0@" of the nobody user/group are not equivalent.\n'.format(nobody_user, nobody_group) +
864                'Please re-check that both "nobody-user" and "nobody-group" options are correctly set.')
865endif
866
867conf.set_quoted('NOBODY_USER_NAME', nobody_user)
868conf.set_quoted('NOBODY_GROUP_NAME', nobody_group)
869
870static_ugids = []
871foreach option : ['adm-gid',
872                  'audio-gid',
873                  'cdrom-gid',
874                  'dialout-gid',
875                  'disk-gid',
876                  'input-gid',
877                  'kmem-gid',
878                  'kvm-gid',
879                  'lp-gid',
880                  'render-gid',
881                  'sgx-gid',
882                  'tape-gid',
883                  'tty-gid',
884                  'users-gid',
885                  'utmp-gid',
886                  'video-gid',
887                  'wheel-gid',
888                  'systemd-journal-gid',
889                  'systemd-network-uid',
890                  'systemd-resolve-uid',
891                  'systemd-timesync-uid']
892        name = option.underscorify().to_upper()
893        val = get_option(option)
894
895        # Ensure provided GID argument is numeric, otherwise fall back to default assignment
896        conf.set(name, val >= 0 ? val : '-')
897        if val >= 0
898                static_ugids += '@0@:@1@'.format(option, val)
899        endif
900endforeach
901
902conf.set10('ENABLE_ADM_GROUP', get_option('adm-group'))
903conf.set10('ENABLE_WHEEL_GROUP', get_option('wheel-group'))
904
905dev_kvm_mode = get_option('dev-kvm-mode')
906conf.set_quoted('DEV_KVM_MODE', dev_kvm_mode) # FIXME: convert to 0o… notation
907conf.set10('DEV_KVM_UACCESS', dev_kvm_mode != '0666')
908group_render_mode = get_option('group-render-mode')
909conf.set_quoted('GROUP_RENDER_MODE', group_render_mode)
910conf.set10('GROUP_RENDER_UACCESS', group_render_mode != '0666')
911
912kill_user_processes = get_option('default-kill-user-processes')
913conf.set10('KILL_USER_PROCESSES', kill_user_processes)
914
915dns_servers = get_option('dns-servers')
916conf.set_quoted('DNS_SERVERS', dns_servers)
917
918ntp_servers = get_option('ntp-servers')
919conf.set_quoted('NTP_SERVERS', ntp_servers)
920
921default_locale = get_option('default-locale')
922if default_locale == ''
923        if not meson.is_cross_build()
924                choose_default_locale_sh = find_program('tools/choose-default-locale.sh')
925                default_locale = run_command(choose_default_locale_sh,
926                                             check : true).stdout().strip()
927        else
928                default_locale = 'C.UTF-8'
929        endif
930endif
931conf.set_quoted('SYSTEMD_DEFAULT_LOCALE', default_locale)
932
933localegen_path = get_option('localegen-path')
934if localegen_path != ''
935        conf.set_quoted('LOCALEGEN_PATH', localegen_path)
936endif
937conf.set10('HAVE_LOCALEGEN', localegen_path != '')
938
939conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
940
941service_watchdog = get_option('service-watchdog')
942watchdog_value = service_watchdog == '' ? '' : 'WatchdogSec=' + service_watchdog
943conf.set_quoted('SERVICE_WATCHDOG', watchdog_value)
944
945conf.set_quoted('SUSHELL', get_option('debug-shell'))
946conf.set_quoted('DEBUGTTY', get_option('debug-tty'))
947
948enable_debug_hashmap = false
949enable_debug_mmap_cache = false
950enable_debug_siphash = false
951foreach name : get_option('debug-extra')
952        if name == 'hashmap'
953                enable_debug_hashmap = true
954        elif name == 'mmap-cache'
955                enable_debug_mmap_cache = true
956        elif name == 'siphash'
957                enable_debug_siphash = true
958        else
959                message('unknown debug option "@0@", ignoring'.format(name))
960        endif
961endforeach
962conf.set10('ENABLE_DEBUG_HASHMAP', enable_debug_hashmap)
963conf.set10('ENABLE_DEBUG_MMAP_CACHE', enable_debug_mmap_cache)
964conf.set10('ENABLE_DEBUG_SIPHASH', enable_debug_siphash)
965
966conf.set10('VALGRIND', get_option('valgrind'))
967conf.set10('LOG_TRACE', get_option('log-trace'))
968
969default_user_path = get_option('user-path')
970if default_user_path != ''
971        conf.set_quoted('DEFAULT_USER_PATH', default_user_path)
972endif
973
974
975#####################################################################
976
977threads = dependency('threads')
978librt = cc.find_library('rt')
979libm = cc.find_library('m')
980libdl = cc.find_library('dl')
981libcrypt = cc.find_library('crypt')
982
983crypt_header = conf.get('HAVE_CRYPT_H') == 1 ? '''#include <crypt.h>''' : '''#include <unistd.h>'''
984foreach ident : [
985        ['crypt_ra',               crypt_header],
986        ['crypt_preferred_method', crypt_header],
987        ['crypt_gensalt_ra',       crypt_header]]
988
989        have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE',
990                               dependencies : libcrypt)
991        conf.set10('HAVE_' + ident[0].to_upper(), have)
992endforeach
993
994libcap = dependency('libcap', required : false)
995if not libcap.found()
996        # Compat with Ubuntu 14.04 which ships libcap w/o .pc file
997        libcap = cc.find_library('cap')
998endif
999
1000want_bpf_framework = get_option('bpf-framework')
1001bpf_framework_required = want_bpf_framework == 'true'
1002
1003libbpf = dependency('libbpf', required : bpf_framework_required, version : '>= 0.2')
1004conf.set10('HAVE_LIBBPF', libbpf.found())
1005
1006if want_bpf_framework == 'false' or not libbpf.found() or skip_deps
1007        conf.set10('BPF_FRAMEWORK', false)
1008else
1009        # Support 'versioned' clang/llvm-strip binaries, as seen on Debian/Ubuntu
1010        # (like clang-10/llvm-strip-10)
1011        if meson.is_cross_build() or cc.get_id() != 'clang' or cc.cmd_array()[0].contains('afl-clang') or cc.cmd_array()[0].contains('hfuzz-clang')
1012                r = find_program('clang', required : bpf_framework_required, version : '>= 10.0.0')
1013                clang_found = r.found()
1014                if clang_found
1015                        clang = r.path()
1016                endif
1017                # Assume that the required flags are supported by the found clang.
1018                clang_supports_flags = clang_found
1019        else
1020                clang_found = true
1021                clang = cc.cmd_array()
1022                clang_supports_flags = cc.has_argument('-Wno-compare-distinct-pointer-types')
1023        endif
1024
1025        if clang_found
1026                # Check if 'clang -target bpf' is supported.
1027                clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus', check : false).returncode() == 0
1028        else
1029                clang_supports_bpf = false
1030        endif
1031
1032        # Debian installs this in /usr/sbin/ which is not in $PATH.
1033        # We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian.
1034        # We use 'bpftool gen' subcommand, it was added by 985ead416df39d6fe8e89580cc1db6aa273e0175 (v5.6).
1035        bpftool = find_program('bpftool',
1036                               '/usr/sbin/bpftool',
1037                               required : false,
1038                               version : '>= 5.13.0')
1039
1040        if bpftool.found()
1041                bpftool_strip = true
1042        else
1043                bpftool_strip = false
1044                bpftool = find_program('bpftool',
1045                                       '/usr/sbin/bpftool',
1046                                       required : bpf_framework_required,
1047                                       version : '>= 5.6.0')
1048        endif
1049
1050        if not bpftool_strip
1051                if not meson.is_cross_build() and clang_found
1052                        llvm_strip_bin = run_command(clang, '--print-prog-name', 'llvm-strip',
1053                                                     check : true).stdout().strip()
1054                else
1055                        llvm_strip_bin = 'llvm-strip'
1056                endif
1057                llvm_strip = find_program(llvm_strip_bin, required : bpf_framework_required, version : '>= 10.0.0')
1058        endif
1059
1060        deps_found = clang_found and clang_supports_bpf and clang_supports_flags and (bpftool_strip or llvm_strip.found()) and bpftool.found()
1061
1062        # Can build BPF program from source code in restricted C
1063        conf.set10('BPF_FRAMEWORK', deps_found)
1064endif
1065
1066libmount = dependency('mount',
1067                      version : fuzzer_build ? '>= 0' : '>= 2.30')
1068
1069want_libfdisk = get_option('fdisk')
1070if want_libfdisk != 'false' and not skip_deps
1071        libfdisk = dependency('fdisk',
1072                              version : '>= 2.32',
1073                              required : want_libfdisk == 'true')
1074        have = libfdisk.found()
1075else
1076        have = false
1077        libfdisk = []
1078endif
1079conf.set10('HAVE_LIBFDISK', have)
1080
1081want_pwquality = get_option('pwquality')
1082if want_pwquality != 'false' and not skip_deps
1083        libpwquality = dependency('pwquality', required : want_pwquality == 'true')
1084        have = libpwquality.found()
1085else
1086        have = false
1087        libpwquality = []
1088endif
1089conf.set10('HAVE_PWQUALITY', have)
1090
1091want_seccomp = get_option('seccomp')
1092if want_seccomp != 'false' and not skip_deps
1093        libseccomp = dependency('libseccomp',
1094                                version : '>= 2.3.1',
1095                                required : want_seccomp == 'true')
1096        have = libseccomp.found()
1097else
1098        have = false
1099        libseccomp = []
1100endif
1101conf.set10('HAVE_SECCOMP', have)
1102
1103want_selinux = get_option('selinux')
1104if want_selinux != 'false' and not skip_deps
1105        libselinux = dependency('libselinux',
1106                                version : '>= 2.1.9',
1107                                required : want_selinux == 'true')
1108        have = libselinux.found()
1109else
1110        have = false
1111        libselinux = []
1112endif
1113conf.set10('HAVE_SELINUX', have)
1114
1115want_apparmor = get_option('apparmor')
1116if want_apparmor != 'false' and not skip_deps
1117        libapparmor = dependency('libapparmor',
1118                                 version : '>= 2.13',
1119                                 required : want_apparmor == 'true')
1120        have = libapparmor.found()
1121else
1122        have = false
1123        libapparmor = []
1124endif
1125conf.set10('HAVE_APPARMOR', have)
1126
1127have = get_option('smack') and get_option('smack-run-label') != ''
1128conf.set10('HAVE_SMACK_RUN_LABEL', have)
1129if have
1130        conf.set_quoted('SMACK_RUN_LABEL', get_option('smack-run-label'))
1131endif
1132
1133want_polkit = get_option('polkit')
1134install_polkit = false
1135install_polkit_pkla = false
1136if want_polkit != 'false' and not skip_deps
1137        install_polkit = true
1138
1139        libpolkit = dependency('polkit-gobject-1',
1140                               required : false)
1141        if libpolkit.found() and libpolkit.version().version_compare('< 0.106')
1142                message('Old polkit detected, will install pkla files')
1143                install_polkit_pkla = true
1144        endif
1145endif
1146conf.set10('ENABLE_POLKIT', install_polkit)
1147
1148want_acl = get_option('acl')
1149if want_acl != 'false' and not skip_deps
1150        libacl = cc.find_library('acl', required : want_acl == 'true')
1151        have = libacl.found()
1152else
1153        have = false
1154        libacl = []
1155endif
1156conf.set10('HAVE_ACL', have)
1157
1158want_audit = get_option('audit')
1159if want_audit != 'false' and not skip_deps
1160        libaudit = dependency('audit', required : want_audit == 'true')
1161        have = libaudit.found()
1162else
1163        have = false
1164        libaudit = []
1165endif
1166conf.set10('HAVE_AUDIT', have)
1167
1168want_blkid = get_option('blkid')
1169if want_blkid != 'false' and not skip_deps
1170        libblkid = dependency('blkid', required : want_blkid == 'true')
1171        have = libblkid.found()
1172
1173        conf.set10('HAVE_BLKID_PROBE_SET_HINT',
1174                   have and cc.has_function('blkid_probe_set_hint', dependencies : libblkid))
1175else
1176        have = false
1177        libblkid = []
1178endif
1179conf.set10('HAVE_BLKID', have)
1180
1181want_kmod = get_option('kmod')
1182if want_kmod != 'false' and not skip_deps
1183        libkmod = dependency('libkmod',
1184                             version : '>= 15',
1185                             required : want_kmod == 'true')
1186        have = libkmod.found()
1187else
1188        have = false
1189        libkmod = []
1190endif
1191conf.set10('HAVE_KMOD', have)
1192
1193want_pam = get_option('pam')
1194if want_pam != 'false' and not skip_deps
1195        libpam = cc.find_library('pam', required : want_pam == 'true')
1196        libpam_misc = cc.find_library('pam_misc', required : want_pam == 'true')
1197        have = libpam.found() and libpam_misc.found()
1198else
1199        have = false
1200        libpam = []
1201        libpam_misc = []
1202endif
1203conf.set10('HAVE_PAM', have)
1204
1205want_microhttpd = get_option('microhttpd')
1206if want_microhttpd != 'false' and not skip_deps
1207        libmicrohttpd = dependency('libmicrohttpd',
1208                                   version : '>= 0.9.33',
1209                                   required : want_microhttpd == 'true')
1210        have = libmicrohttpd.found()
1211else
1212        have = false
1213        libmicrohttpd = []
1214endif
1215conf.set10('HAVE_MICROHTTPD', have)
1216
1217want_libcryptsetup = get_option('libcryptsetup')
1218want_libcryptsetup_plugins = get_option('libcryptsetup-plugins')
1219
1220if want_libcryptsetup_plugins == 'true' and want_libcryptsetup == 'false'
1221        error('libcryptsetup-plugins can not be requested without libcryptsetup')
1222endif
1223
1224if want_libcryptsetup != 'false' and not skip_deps
1225        libcryptsetup = dependency('libcryptsetup',
1226                                   version : want_libcryptsetup_plugins == 'true' ? '>= 2.4.0' : '>= 2.0.1',
1227                                   required : want_libcryptsetup == 'true' or want_libcryptsetup_plugins == 'true')
1228        have = libcryptsetup.found()
1229
1230        foreach ident : ['crypt_set_metadata_size',
1231                         'crypt_activate_by_signed_key',
1232                         'crypt_token_max']
1233                have_ident = have and cc.has_function(
1234                        ident,
1235                        prefix : '#include <libcryptsetup.h>',
1236                        dependencies : libcryptsetup)
1237                conf.set10('HAVE_' + ident.to_upper(), have_ident)
1238        endforeach
1239else
1240        have = false
1241        libcryptsetup = []
1242endif
1243conf.set10('HAVE_LIBCRYPTSETUP', have)
1244
1245if want_libcryptsetup_plugins != 'false' and not skip_deps
1246        have = (cc.has_function(
1247                        'crypt_activate_by_token_pin',
1248                        prefix : '#include <libcryptsetup.h>',
1249                        dependencies : libcryptsetup) and
1250                cc.has_function(
1251                        'crypt_token_external_path',
1252                        prefix : '#include <libcryptsetup.h>',
1253                        dependencies : libcryptsetup))
1254else
1255        have = false
1256endif
1257conf.set10('HAVE_LIBCRYPTSETUP_PLUGINS', have)
1258
1259want_libcurl = get_option('libcurl')
1260if want_libcurl != 'false' and not skip_deps
1261        libcurl = dependency('libcurl',
1262                             version : '>= 7.32.0',
1263                             required : want_libcurl == 'true')
1264        have = libcurl.found()
1265else
1266        have = false
1267        libcurl = []
1268endif
1269conf.set10('HAVE_LIBCURL', have)
1270conf.set10('CURL_NO_OLDIES', conf.get('BUILD_MODE_DEVELOPER') == 1)
1271
1272want_libidn = get_option('libidn')
1273want_libidn2 = get_option('libidn2')
1274if want_libidn == 'true' and want_libidn2 == 'true'
1275        error('libidn and libidn2 cannot be requested simultaneously')
1276endif
1277
1278if want_libidn2 != 'false' and want_libidn != 'true' and not skip_deps
1279        libidn = dependency('libidn2',
1280                            required : want_libidn2 == 'true')
1281        have = libidn.found()
1282else
1283        have = false
1284        libidn = []
1285endif
1286conf.set10('HAVE_LIBIDN2', have)
1287if not have and want_libidn != 'false' and not skip_deps
1288        # libidn is used for both libidn and libidn2 objects
1289        libidn = dependency('libidn',
1290                            required : want_libidn == 'true')
1291        have = libidn.found()
1292else
1293        have = false
1294endif
1295conf.set10('HAVE_LIBIDN', have)
1296
1297want_libiptc = get_option('libiptc')
1298if want_libiptc != 'false' and not skip_deps
1299        libiptc = dependency('libiptc',
1300                             required : want_libiptc == 'true')
1301        have = libiptc.found()
1302else
1303        have = false
1304        libiptc = []
1305endif
1306conf.set10('HAVE_LIBIPTC', have)
1307
1308want_qrencode = get_option('qrencode')
1309if want_qrencode != 'false' and not skip_deps
1310        libqrencode = dependency('libqrencode',
1311                                 version : '>= 4',
1312                                 required : want_qrencode == 'true')
1313        have = libqrencode.found()
1314else
1315        have = false
1316        libqrencode = []
1317endif
1318conf.set10('HAVE_QRENCODE', have)
1319
1320want_gcrypt = get_option('gcrypt')
1321if want_gcrypt != 'false' and not skip_deps
1322        libgcrypt = cc.find_library('gcrypt', required : want_gcrypt == 'true')
1323        libgpg_error = cc.find_library('gpg-error', required : want_gcrypt == 'true')
1324        have = libgcrypt.found() and libgpg_error.found()
1325else
1326        have = false
1327endif
1328if not have
1329        # link to neither of the libs if one is not found
1330        libgcrypt = []
1331        libgpg_error = []
1332endif
1333conf.set10('HAVE_GCRYPT', have)
1334
1335want_gnutls = get_option('gnutls')
1336if want_gnutls != 'false' and not skip_deps
1337        libgnutls = dependency('gnutls',
1338                               version : '>= 3.1.4',
1339                               required : want_gnutls == 'true')
1340        have = libgnutls.found()
1341else
1342        have = false
1343        libgnutls = []
1344endif
1345conf.set10('HAVE_GNUTLS', have)
1346
1347want_openssl = get_option('openssl')
1348if want_openssl != 'false' and not skip_deps
1349        libopenssl = dependency('openssl',
1350                                version : '>= 1.1.0',
1351                                required : want_openssl == 'true')
1352        have = libopenssl.found()
1353else
1354        have = false
1355        libopenssl = []
1356endif
1357conf.set10('HAVE_OPENSSL', have)
1358
1359want_p11kit = get_option('p11kit')
1360if want_p11kit != 'false' and not skip_deps
1361        libp11kit = dependency('p11-kit-1',
1362                               version : '>= 0.23.3',
1363                               required : want_p11kit == 'true')
1364        have = libp11kit.found()
1365else
1366        have = false
1367        libp11kit = []
1368endif
1369conf.set10('HAVE_P11KIT', have)
1370
1371want_libfido2 = get_option('libfido2')
1372if want_libfido2 != 'false' and not skip_deps
1373        libfido2 = dependency('libfido2',
1374                              required : want_libfido2 == 'true')
1375        have = libfido2.found()
1376else
1377        have = false
1378        libfido2 = []
1379endif
1380conf.set10('HAVE_LIBFIDO2', have)
1381
1382want_tpm2 = get_option('tpm2')
1383if want_tpm2 != 'false' and not skip_deps
1384        tpm2 = dependency('tss2-esys tss2-rc tss2-mu',
1385                          required : want_tpm2 == 'true')
1386        have = tpm2.found()
1387else
1388        have = false
1389        tpm2 = []
1390endif
1391conf.set10('HAVE_TPM2', have)
1392
1393want_elfutils = get_option('elfutils')
1394if want_elfutils != 'false' and not skip_deps
1395        libdw = dependency('libdw',
1396                           required : want_elfutils == 'true')
1397        have = libdw.found()
1398
1399        # New in elfutils 0.177
1400        conf.set10('HAVE_DWELF_ELF_E_MACHINE_STRING',
1401                   have and cc.has_function('dwelf_elf_e_machine_string', dependencies : libdw))
1402else
1403        have = false
1404        libdw = []
1405endif
1406conf.set10('HAVE_ELFUTILS', have)
1407
1408want_zlib = get_option('zlib')
1409if want_zlib != 'false' and not skip_deps
1410        libz = dependency('zlib',
1411                          required : want_zlib == 'true')
1412        have = libz.found()
1413else
1414        have = false
1415        libz = []
1416endif
1417conf.set10('HAVE_ZLIB', have)
1418
1419want_bzip2 = get_option('bzip2')
1420if want_bzip2 != 'false' and not skip_deps
1421        libbzip2 = cc.find_library('bz2',
1422                                   required : want_bzip2 == 'true')
1423        have = libbzip2.found()
1424else
1425        have = false
1426        libbzip2 = []
1427endif
1428conf.set10('HAVE_BZIP2', have)
1429
1430want_xz = get_option('xz')
1431if want_xz != 'false' and not skip_deps
1432        libxz = dependency('liblzma',
1433                           required : want_xz == 'true')
1434        have_xz = libxz.found()
1435else
1436        have_xz = false
1437        libxz = []
1438endif
1439conf.set10('HAVE_XZ', have_xz)
1440
1441want_lz4 = get_option('lz4')
1442if want_lz4 != 'false' and not skip_deps
1443        liblz4 = dependency('liblz4',
1444                            version : '>= 1.3.0',
1445                            required : want_lz4 == 'true')
1446        have_lz4 = liblz4.found()
1447else
1448        have_lz4 = false
1449        liblz4 = []
1450endif
1451conf.set10('HAVE_LZ4', have_lz4)
1452
1453want_zstd = get_option('zstd')
1454if want_zstd != 'false' and not skip_deps
1455        libzstd = dependency('libzstd',
1456                             required : want_zstd == 'true',
1457                             version : '>= 1.4.0')
1458        have_zstd = libzstd.found()
1459else
1460        have_zstd = false
1461        libzstd = []
1462endif
1463conf.set10('HAVE_ZSTD', have_zstd)
1464
1465conf.set10('HAVE_COMPRESSION', have_xz or have_lz4 or have_zstd)
1466
1467compression = get_option('default-compression')
1468if compression == 'auto'
1469        if have_zstd
1470                compression = 'zstd'
1471        elif have_lz4
1472                compression = 'lz4'
1473        elif have_xz
1474                compression = 'xz'
1475        else
1476                compression = 'none'
1477        endif
1478elif compression == 'zstd' and not have_zstd
1479        error('default-compression=zstd requires zstd')
1480elif compression == 'lz4' and not have_lz4
1481        error('default-compression=lz4 requires lz4')
1482elif compression == 'xz' and not have_xz
1483        error('default-compression=xz requires xz')
1484endif
1485conf.set('DEFAULT_COMPRESSION', 'COMPRESSION_@0@'.format(compression.to_upper()))
1486
1487want_xkbcommon = get_option('xkbcommon')
1488if want_xkbcommon != 'false' and not skip_deps
1489        libxkbcommon = dependency('xkbcommon',
1490                                  version : '>= 0.3.0',
1491                                  required : want_xkbcommon == 'true')
1492        have = libxkbcommon.found()
1493else
1494        have = false
1495        libxkbcommon = []
1496endif
1497conf.set10('HAVE_XKBCOMMON', have)
1498
1499want_pcre2 = get_option('pcre2')
1500if want_pcre2 != 'false'
1501        libpcre2 = dependency('libpcre2-8',
1502                              required : want_pcre2 == 'true')
1503        have = libpcre2.found()
1504else
1505        have = false
1506        libpcre2 = []
1507endif
1508conf.set10('HAVE_PCRE2', have)
1509
1510want_glib = get_option('glib')
1511if want_glib != 'false' and not skip_deps
1512        libglib =    dependency('glib-2.0',
1513                                version : '>= 2.22.0',
1514                                required : want_glib == 'true')
1515        libgobject = dependency('gobject-2.0',
1516                                version : '>= 2.22.0',
1517                                required : want_glib == 'true')
1518        libgio =     dependency('gio-2.0',
1519                                required : want_glib == 'true')
1520        have = libglib.found() and libgobject.found() and libgio.found()
1521else
1522        have = false
1523        libglib = []
1524        libgobject = []
1525        libgio = []
1526endif
1527conf.set10('HAVE_GLIB', have)
1528
1529want_dbus = get_option('dbus')
1530if want_dbus != 'false' and not skip_deps
1531        libdbus = dependency('dbus-1',
1532                             version : '>= 1.3.2',
1533                             required : want_dbus == 'true')
1534        have = libdbus.found()
1535else
1536        have = false
1537        libdbus = []
1538endif
1539conf.set10('HAVE_DBUS', have)
1540
1541dbusdatadir = datadir / 'dbus-1'
1542if conf.get('HAVE_DBUS') == 1
1543        dbusdatadir = libdbus.get_variable(pkgconfig: 'datadir', default_value: datadir) / 'dbus-1'
1544endif
1545
1546dbuspolicydir = get_option('dbuspolicydir')
1547if dbuspolicydir == ''
1548        dbuspolicydir = dbusdatadir / 'system.d'
1549endif
1550
1551dbussessionservicedir = get_option('dbussessionservicedir')
1552if dbussessionservicedir == ''
1553        dbussessionservicedir = dbusdatadir / 'services'
1554        if conf.get('HAVE_DBUS') == 1
1555                dbussessionservicedir = libdbus.get_variable(pkgconfig: 'session_bus_services_dir', default_value: dbussessionservicedir)
1556        endif
1557endif
1558
1559dbussystemservicedir = get_option('dbussystemservicedir')
1560if dbussystemservicedir == ''
1561        dbussystemservicedir = dbusdatadir / 'system-services'
1562        if conf.get('HAVE_DBUS') == 1
1563                dbussystemservicedir = libdbus.get_variable(pkgconfig: 'system_bus_services_dir', default_value: dbussystemservicedir)
1564        endif
1565endif
1566
1567dbus_interfaces_dir = get_option('dbus-interfaces-dir')
1568if dbus_interfaces_dir == '' or dbus_interfaces_dir == 'yes'
1569        if meson.is_cross_build() and dbus_interfaces_dir != 'yes'
1570                dbus_interfaces_dir = 'no'
1571                warning('Exporting D-Bus interface XML files is disabled during cross build. Pass path or "yes" to force enable.')
1572        else
1573                dbus_interfaces_dir = dbusdatadir / 'interfaces'
1574                if conf.get('HAVE_DBUS') == 1
1575                        dbus_interfaces_dir = libdbus.get_variable(pkgconfig: 'interfaces_dir', default_value: dbus_interfaces_dir)
1576                endif
1577        endif
1578endif
1579
1580# We support one or the other. If gcrypt is available, we assume it's there to
1581# be used, and use it in preference.
1582opt = get_option('cryptolib')
1583if opt == 'openssl' and conf.get('HAVE_OPENSSL') == 0
1584        error('openssl requested as the default cryptolib, but not available')
1585endif
1586conf.set10('PREFER_OPENSSL',
1587           opt == 'openssl' or (opt == 'auto' and conf.get('HAVE_OPENSSL') == 1 and conf.get('HAVE_GCRYPT') == 0))
1588conf.set10('HAVE_OPENSSL_OR_GCRYPT',
1589           conf.get('HAVE_OPENSSL') == 1 or conf.get('HAVE_GCRYPT') == 1)
1590lib_openssl_or_gcrypt = conf.get('PREFER_OPENSSL') == 1 ? [libopenssl] : [libgcrypt, libgpg_error]
1591
1592dns_over_tls = get_option('dns-over-tls')
1593if dns_over_tls != 'false'
1594        if dns_over_tls == 'gnutls' and conf.get('PREFER_OPENSSL') == 1
1595                error('Sorry, -Ddns-over-tls=gnutls is not supported when openssl is used as the cryptolib')
1596        endif
1597
1598        if dns_over_tls == 'openssl' or conf.get('PREFER_OPENSSL') == 1
1599                have_gnutls = false
1600        else
1601                have_gnutls = (conf.get('HAVE_GNUTLS') == 1 and libgnutls.version().version_compare('>= 3.6.0'))
1602                if dns_over_tls == 'gnutls' and not have_gnutls
1603                        error('DNS-over-TLS support was requested with gnutls, but dependencies are not available')
1604                endif
1605        endif
1606        if dns_over_tls == 'gnutls' or have_gnutls
1607                have_openssl = false
1608        else
1609                have_openssl = conf.get('HAVE_OPENSSL') == 1
1610                if dns_over_tls != 'auto' and not have_openssl
1611                        str = dns_over_tls == 'openssl' ? ' with openssl' : ''
1612                        error('DNS-over-TLS support was requested@0@, but dependencies are not available'.format(str))
1613                endif
1614        endif
1615        have = have_gnutls or have_openssl
1616else
1617        have = false
1618        have_gnutls = false
1619        have_openssl = false
1620endif
1621conf.set10('ENABLE_DNS_OVER_TLS', have)
1622conf.set10('DNS_OVER_TLS_USE_GNUTLS', have_gnutls)
1623conf.set10('DNS_OVER_TLS_USE_OPENSSL', have_openssl)
1624
1625default_dns_over_tls = get_option('default-dns-over-tls')
1626if skip_deps
1627        default_dns_over_tls = 'no'
1628endif
1629if default_dns_over_tls != 'no' and conf.get('ENABLE_DNS_OVER_TLS') == 0
1630        message('default-dns-over-tls cannot be enabled or set to opportunistic when DNS-over-TLS support is disabled. Setting default-dns-over-tls to no.')
1631        default_dns_over_tls = 'no'
1632endif
1633conf.set('DEFAULT_DNS_OVER_TLS_MODE',
1634         'DNS_OVER_TLS_' + default_dns_over_tls.underscorify().to_upper())
1635conf.set_quoted('DEFAULT_DNS_OVER_TLS_MODE_STR', default_dns_over_tls)
1636
1637default_mdns = get_option('default-mdns')
1638conf.set('DEFAULT_MDNS_MODE',
1639         'RESOLVE_SUPPORT_' + default_mdns.to_upper())
1640conf.set_quoted('DEFAULT_MDNS_MODE_STR', default_mdns)
1641
1642default_llmnr = get_option('default-llmnr')
1643conf.set('DEFAULT_LLMNR_MODE',
1644         'RESOLVE_SUPPORT_' + default_llmnr.to_upper())
1645conf.set_quoted('DEFAULT_LLMNR_MODE_STR', default_llmnr)
1646
1647want_repart = get_option('repart')
1648if want_repart != 'false'
1649        have = conf.get('HAVE_LIBFDISK') == 1
1650        if want_repart == 'true' and not have
1651                error('repart support was requested, but dependencies are not available')
1652        endif
1653else
1654        have = false
1655endif
1656conf.set10('ENABLE_REPART', have)
1657
1658default_dnssec = get_option('default-dnssec')
1659if skip_deps
1660        default_dnssec = 'no'
1661endif
1662if default_dnssec != 'no' and conf.get('HAVE_OPENSSL_OR_GCRYPT') == 0
1663        message('default-dnssec cannot be set to yes or allow-downgrade openssl and gcrypt are disabled. Setting default-dnssec to no.')
1664        default_dnssec = 'no'
1665endif
1666conf.set('DEFAULT_DNSSEC_MODE',
1667         'DNSSEC_' + default_dnssec.underscorify().to_upper())
1668conf.set_quoted('DEFAULT_DNSSEC_MODE_STR', default_dnssec)
1669
1670want_sysupdate = get_option('sysupdate')
1671if want_sysupdate != 'false'
1672        have = (conf.get('HAVE_OPENSSL') == 1 and
1673                conf.get('HAVE_LIBFDISK') == 1)
1674        if want_sysupdate == 'true' and not have
1675                error('sysupdate support was requested, but dependencies are not available')
1676        endif
1677else
1678        have = false
1679endif
1680conf.set10('ENABLE_SYSUPDATE', have)
1681
1682want_importd = get_option('importd')
1683if want_importd != 'false'
1684        have = (conf.get('HAVE_LIBCURL') == 1 and
1685                conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1 and
1686                conf.get('HAVE_ZLIB') == 1 and
1687                conf.get('HAVE_XZ') == 1)
1688        if want_importd == 'true' and not have
1689                error('importd support was requested, but dependencies are not available')
1690        endif
1691else
1692        have = false
1693endif
1694conf.set10('ENABLE_IMPORTD', have)
1695
1696want_kernel_install = get_option('kernel-install')
1697conf.set10('ENABLE_KERNEL_INSTALL', want_kernel_install)
1698
1699want_homed = get_option('homed')
1700if want_homed != 'false'
1701        have = (conf.get('HAVE_OPENSSL') == 1 and
1702                conf.get('HAVE_LIBFDISK') == 1 and
1703                conf.get('HAVE_LIBCRYPTSETUP') == 1)
1704        if want_homed == 'true' and not have
1705                error('homed support was requested, but dependencies are not available')
1706        endif
1707else
1708        have = false
1709endif
1710conf.set10('ENABLE_HOMED', have)
1711
1712have = have and conf.get('HAVE_PAM') == 1
1713conf.set10('ENABLE_PAM_HOME', have)
1714
1715have = get_option('oomd')
1716conf.set10('ENABLE_OOMD', have)
1717
1718want_remote = get_option('remote')
1719if want_remote != 'false'
1720        have_deps = [conf.get('HAVE_MICROHTTPD') == 1,
1721                     conf.get('HAVE_LIBCURL') == 1]
1722        # sd-j-remote requires µhttpd, and sd-j-upload requires libcurl, so
1723        # it's possible to build one without the other. Complain only if
1724        # support was explicitly requested. The auxiliary files like sysusers
1725        # config should be installed when any of the programs are built.
1726        if want_remote == 'true' and not (have_deps[0] and have_deps[1])
1727                error('remote support was requested, but dependencies are not available')
1728        endif
1729        have = have_deps[0] or have_deps[1]
1730else
1731        have = false
1732endif
1733conf.set10('ENABLE_REMOTE', have)
1734
1735foreach term : ['analyze',
1736                'backlight',
1737                'binfmt',
1738                'coredump',
1739                'efi',
1740                'environment-d',
1741                'firstboot',
1742                'gshadow',
1743                'hibernate',
1744                'hostnamed',
1745                'hwdb',
1746                'idn',
1747                'ima',
1748                'initrd',
1749                'compat-mutable-uid-boundaries',
1750                'nscd',
1751                'ldconfig',
1752                'localed',
1753                'logind',
1754                'machined',
1755                'networkd',
1756                'nss-myhostname',
1757                'nss-systemd',
1758                'portabled',
1759                'sysext',
1760                'pstore',
1761                'quotacheck',
1762                'randomseed',
1763                'resolve',
1764                'rfkill',
1765                'smack',
1766                'sysusers',
1767                'timedated',
1768                'timesyncd',
1769                'tmpfiles',
1770                'tpm',
1771                'userdb',
1772                'utmp',
1773                'vconsole',
1774                'xdg-autostart']
1775        have = get_option(term)
1776        name = 'ENABLE_' + term.underscorify().to_upper()
1777        conf.set10(name, have)
1778endforeach
1779
1780enable_sysusers = conf.get('ENABLE_SYSUSERS') == 1
1781
1782foreach tuple : [['nss-mymachines', 'machined'],
1783                 ['nss-resolve',    'resolve']]
1784        want = get_option(tuple[0])
1785        if want != 'false'
1786                have = get_option(tuple[1])
1787                if want == 'true' and not have
1788                        error('@0@ is requested but @1@ is disabled'.format(tuple[0], tuple[1]))
1789                endif
1790        else
1791                have = false
1792        endif
1793        name = 'ENABLE_' + tuple[0].underscorify().to_upper()
1794        conf.set10(name, have)
1795endforeach
1796
1797enable_nss = false
1798foreach term : ['ENABLE_NSS_MYHOSTNAME',
1799                'ENABLE_NSS_MYMACHINES',
1800                'ENABLE_NSS_RESOLVE',
1801                'ENABLE_NSS_SYSTEMD']
1802        if conf.get(term) == 1
1803                enable_nss = true
1804        endif
1805endforeach
1806conf.set10('ENABLE_NSS', enable_nss)
1807
1808conf.set10('ENABLE_TIMEDATECTL', get_option('timedated') or get_option('timesyncd'))
1809
1810conf.set10('SYSTEMD_SLOW_TESTS_DEFAULT', slow_tests)
1811
1812############################################################
1813
1814tests = []
1815fuzzers = []
1816catalogs = []
1817
1818############################################################
1819
1820# Include these now as they provide gnu-efi detection.
1821subdir('src/fundamental')
1822subdir('src/boot/efi')
1823
1824############################################################
1825
1826generate_gperfs = find_program('tools/generate-gperfs.py')
1827make_autosuspend_rules_py = find_program('tools/make-autosuspend-rules.py')
1828make_directive_index_py = find_program('tools/make-directive-index.py')
1829make_man_index_py = find_program('tools/make-man-index.py')
1830meson_render_jinja2 = find_program('tools/meson-render-jinja2.py')
1831update_dbus_docs_py = find_program('tools/update-dbus-docs.py')
1832update_man_rules_py = find_program('tools/update-man-rules.py')
1833update_hwdb_sh = find_program('tools/update-hwdb.sh')
1834update_hwdb_autosuspend_sh = find_program('tools/update-hwdb-autosuspend.sh')
1835update_syscall_tables_sh = find_program('tools/update-syscall-tables.sh')
1836xml_helper_py = find_program('tools/xml_helper.py')
1837export_dbus_interfaces_py = find_program('tools/dbus_exporter.py')
1838
1839############################################################
1840
1841if get_option('b_coverage')
1842        add_project_arguments('-include', 'src/basic/coverage.h', language : 'c')
1843endif
1844
1845############################################################
1846
1847config_h = configure_file(
1848        output : 'config.h',
1849        configuration : conf)
1850
1851add_project_arguments('-include', 'config.h', language : 'c')
1852
1853jinja2_cmdline = [meson_render_jinja2, config_h, version_h]
1854
1855############################################################
1856
1857# binaries that have --help and are intended for use by humans,
1858# usually, but not always, installed in /bin.
1859public_programs = []
1860
1861# D-Bus introspection XML export
1862dbus_programs = []
1863
1864basic_includes = include_directories(
1865        'src/basic',
1866        'src/fundamental',
1867        'src/systemd',
1868        '.')
1869
1870libsystemd_includes = [basic_includes, include_directories(
1871        'src/libsystemd/sd-bus',
1872        'src/libsystemd/sd-device',
1873        'src/libsystemd/sd-event',
1874        'src/libsystemd/sd-hwdb',
1875        'src/libsystemd/sd-id128',
1876        'src/libsystemd/sd-journal',
1877        'src/libsystemd/sd-netlink',
1878        'src/libsystemd/sd-network',
1879        'src/libsystemd/sd-resolve')]
1880
1881includes = [libsystemd_includes, include_directories('src/shared')]
1882
1883subdir('po')
1884subdir('catalog')
1885subdir('src/basic')
1886subdir('src/libsystemd')
1887subdir('src/shared')
1888subdir('src/udev')
1889subdir('src/libudev')
1890subdir('src/cryptsetup/cryptsetup-tokens')
1891
1892libsystemd = shared_library(
1893        'systemd',
1894        disable_mempool_c,
1895        version : libsystemd_version,
1896        include_directories : libsystemd_includes,
1897        link_args : ['-shared',
1898                     '-Wl,--version-script=' + libsystemd_sym_path],
1899        link_with : [libbasic,
1900                     libbasic_gcrypt,
1901                     libbasic_compress],
1902        link_whole : [libsystemd_static],
1903        dependencies : [threads,
1904                        librt],
1905        link_depends : libsystemd_sym,
1906        install : true,
1907        install_tag: 'libsystemd',
1908        install_dir : rootlibdir)
1909
1910install_libsystemd_static = static_library(
1911        'systemd',
1912        libsystemd_sources,
1913        basic_sources,
1914        basic_gcrypt_sources,
1915        basic_compress_sources,
1916        fundamental_sources,
1917        disable_mempool_c,
1918        include_directories : libsystemd_includes,
1919        build_by_default : static_libsystemd != 'false',
1920        install : static_libsystemd != 'false',
1921        install_tag: 'libsystemd',
1922        install_dir : rootlibdir,
1923        pic : static_libsystemd_pic,
1924        dependencies : [threads,
1925                        librt,
1926                        libxz,
1927                        libzstd,
1928                        liblz4,
1929                        libdl,
1930                        libcap,
1931                        libblkid,
1932                        libmount,
1933                        libgcrypt,
1934                        libopenssl],
1935        c_args : libsystemd_c_args + (static_libsystemd_pic ? [] : ['-fno-PIC']))
1936
1937libudev = shared_library(
1938        'udev',
1939        disable_mempool_c,
1940        version : libudev_version,
1941        include_directories : includes,
1942        link_args : ['-shared',
1943                     '-Wl,--version-script=' + libudev_sym_path],
1944        link_with : [libsystemd_static, libshared_static],
1945        link_whole : libudev_basic,
1946        dependencies : [threads],
1947        link_depends : libudev_sym,
1948        install : true,
1949        install_tag: 'libudev',
1950        install_dir : rootlibdir)
1951
1952install_libudev_static = static_library(
1953        'udev',
1954        basic_sources,
1955        fundamental_sources,
1956        shared_sources,
1957        libsystemd_sources,
1958        libudev_sources,
1959        disable_mempool_c,
1960        include_directories : includes,
1961        build_by_default : static_libudev != 'false',
1962        install : static_libudev != 'false',
1963        install_tag: 'libudev',
1964        install_dir : rootlibdir,
1965        link_depends : libudev_sym,
1966        dependencies : libshared_deps + [libmount],
1967        c_args : static_libudev_pic ? [] : ['-fno-PIC'],
1968        pic : static_libudev_pic)
1969
1970if conf.get('HAVE_LIBCRYPTSETUP_PLUGINS') == 1
1971        if conf.get('HAVE_TPM2') == 1
1972                cryptsetup_token_systemd_tpm2 = shared_library(
1973                        'cryptsetup-token-systemd-tpm2',
1974                        cryptsetup_token_systemd_tpm2_sources,
1975                        include_directories : includes,
1976                        link_args : ['-shared',
1977                                     '-Wl,--version-script=' + cryptsetup_token_sym_path],
1978                        link_with : [lib_cryptsetup_token_common,
1979                                     libshared],
1980                        dependencies : [libcryptsetup,
1981                                        tpm2,
1982                                        versiondep],
1983                        link_depends : cryptsetup_token_sym,
1984                        install_rpath : rootlibexecdir,
1985                        install : true,
1986                        install_dir : libcryptsetup_plugins_dir)
1987        endif
1988
1989        if conf.get('HAVE_LIBFIDO2') == 1
1990                cryptsetup_token_systemd_fido2 = shared_library(
1991                        'cryptsetup-token-systemd-fido2',
1992                        cryptsetup_token_systemd_fido2_sources,
1993                        include_directories : includes,
1994                        link_args : ['-shared',
1995                                     '-Wl,--version-script=' + cryptsetup_token_sym_path],
1996                        link_with : [lib_cryptsetup_token_common,
1997                                     libshared],
1998                        dependencies : [libcryptsetup,
1999                                        libfido2,
2000                                        versiondep],
2001                        link_depends : cryptsetup_token_sym,
2002                        install_rpath : rootlibexecdir,
2003                        install : true,
2004                        install_dir : libcryptsetup_plugins_dir)
2005        endif
2006
2007        if conf.get('HAVE_P11KIT') == 1
2008                cryptsetup_token_systemd_pkcs11 = shared_library(
2009                        'cryptsetup-token-systemd-pkcs11',
2010                        cryptsetup_token_systemd_pkcs11_sources,
2011                        include_directories : includes,
2012                        link_args : ['-shared',
2013                                     '-Wl,--version-script=' + cryptsetup_token_sym_path],
2014                        link_with : [lib_cryptsetup_token_common,
2015                                     libshared],
2016                        dependencies : [libcryptsetup,
2017                                        libp11kit,
2018                                        versiondep],
2019                        link_depends : cryptsetup_token_sym,
2020                        install_rpath : rootlibexecdir,
2021                        install : true,
2022                        install_dir : libcryptsetup_plugins_dir)
2023        endif
2024endif
2025
2026############################################################
2027
2028# systemd-analyze requires 'libcore'
2029subdir('src/core')
2030# systemd-journal-remote requires 'libjournal_core'
2031subdir('src/journal')
2032# systemd-networkd requires 'libsystemd_network'
2033subdir('src/libsystemd-network')
2034
2035subdir('src/analyze')
2036subdir('src/busctl')
2037subdir('src/coredump')
2038subdir('src/cryptenroll')
2039subdir('src/cryptsetup')
2040subdir('src/home')
2041subdir('src/hostname')
2042subdir('src/import')
2043subdir('src/journal-remote')
2044subdir('src/kernel-install')
2045subdir('src/locale')
2046subdir('src/login')
2047subdir('src/machine')
2048subdir('src/network')
2049subdir('src/nspawn')
2050subdir('src/oom')
2051subdir('src/partition')
2052subdir('src/portable')
2053subdir('src/pstore')
2054subdir('src/resolve')
2055subdir('src/rpm')
2056subdir('src/shutdown')
2057subdir('src/sysext')
2058subdir('src/systemctl')
2059subdir('src/sysupdate')
2060subdir('src/timedate')
2061subdir('src/timesync')
2062subdir('src/tmpfiles')
2063subdir('src/userdb')
2064subdir('src/xdg-autostart-generator')
2065
2066subdir('src/systemd')
2067
2068subdir('src/test')
2069subdir('src/fuzz')
2070subdir('rules.d')
2071subdir('test')
2072
2073############################################################
2074
2075# only static linking apart from libdl, to make sure that the
2076# module is linked to all libraries that it uses.
2077test_dlopen = executable(
2078        'test-dlopen',
2079        test_dlopen_c,
2080        disable_mempool_c,
2081        include_directories : includes,
2082        link_with : [libbasic],
2083        dependencies : [libdl],
2084        build_by_default : want_tests != 'false')
2085
2086foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'],
2087                 ['systemd',    'ENABLE_NSS_SYSTEMD', ['nss-systemd.h', 'userdb-glue.c', 'userdb-glue.h']],
2088                 ['mymachines', 'ENABLE_NSS_MYMACHINES'],
2089                 ['resolve',    'ENABLE_NSS_RESOLVE', [], resolve_includes]]
2090
2091        condition = tuple[1] == '' or conf.get(tuple[1]) == 1
2092        if condition
2093                module = tuple[0]
2094
2095                sym = 'src/nss-@0@/nss-@0@.sym'.format(module)
2096                version_script_arg = project_source_root / sym
2097
2098                sources = ['src/nss-@0@/nss-@0@.c'.format(module)]
2099                if tuple.length() > 2
2100                        foreach s : tuple[2]
2101                                sources += ['src/nss-@0@/@1@'.format(module, s)]
2102                        endforeach
2103                endif
2104
2105                incs = tuple.length() > 3 ? tuple[3] : includes
2106
2107                nss = shared_library(
2108                        'nss_' + module,
2109                        sources,
2110                        disable_mempool_c,
2111                        version : '2',
2112                        include_directories : incs,
2113                        # Note that we link NSS modules with '-z nodelete' so that mempools never get orphaned
2114                        link_args : ['-Wl,-z,nodelete',
2115                                     '-shared',
2116                                     '-Wl,--version-script=' + version_script_arg],
2117                        link_with : [libsystemd_static,
2118                                     libshared_static,
2119                                     libbasic],
2120                        dependencies : [threads,
2121                                        librt],
2122                        link_depends : sym,
2123                        install : true,
2124                        install_tag : 'nss',
2125                        install_dir : rootlibdir)
2126
2127                # We cannot use shared_module because it does not support version suffix.
2128                # Unfortunately shared_library insists on creating the symlink…
2129                meson.add_install_script('sh', '-c',
2130                                         'rm $DESTDIR@0@/libnss_@1@.so'
2131                                         .format(rootlibdir, module),
2132                                         install_tag : 'nss'
2133                                         )
2134
2135                if want_tests != 'false'
2136                        test('dlopen-nss_' + module,
2137                             test_dlopen,
2138                             # path to dlopen must include a slash
2139                             args : nss.full_path(),
2140                             depends : nss)
2141                endif
2142        endif
2143endforeach
2144
2145############################################################
2146
2147exe = executable(
2148        'systemd',
2149        systemd_sources,
2150        include_directories : includes,
2151        link_with : [libcore,
2152                     libshared],
2153        dependencies : [versiondep,
2154                        libseccomp],
2155        install_rpath : rootlibexecdir,
2156        install : true,
2157        install_dir : rootlibexecdir)
2158dbus_programs += exe
2159public_programs += exe
2160
2161meson.add_install_script(meson_make_symlink,
2162                         rootlibexecdir / 'systemd',
2163                         rootsbindir / 'init')
2164
2165public_programs += executable(
2166        'systemd-analyze',
2167        systemd_analyze_sources,
2168        include_directories : core_includes,
2169        link_with : [libcore,
2170                     libshared],
2171        dependencies : [versiondep,
2172                        libseccomp],
2173        install_rpath : rootlibexecdir,
2174        install : conf.get('ENABLE_ANALYZE'))
2175
2176executable(
2177        'systemd-journald',
2178        systemd_journald_sources,
2179        include_directories : includes,
2180        link_with : [libjournal_core,
2181                     libshared],
2182        dependencies : [threads,
2183                        libxz,
2184                        liblz4,
2185                        libselinux,
2186                        libzstd],
2187        install_rpath : rootlibexecdir,
2188        install : true,
2189        install_dir : rootlibexecdir)
2190
2191public_programs += executable(
2192        'systemd-cat',
2193        systemd_cat_sources,
2194        include_directories : includes,
2195        link_with : [libjournal_core,
2196                     libshared],
2197        dependencies : [threads],
2198        install_rpath : rootlibexecdir,
2199        install : true)
2200
2201public_programs += executable(
2202        'journalctl',
2203        journalctl_sources,
2204        include_directories : includes,
2205        link_with : [libshared],
2206        dependencies : [threads,
2207                        libdl,
2208                        libxz,
2209                        liblz4,
2210                        libzstd,
2211                        libdl],
2212        install_rpath : rootlibexecdir,
2213        install : true,
2214        install_dir : rootbindir)
2215
2216executable(
2217        'systemd-getty-generator',
2218        'src/getty-generator/getty-generator.c',
2219        include_directories : includes,
2220        link_with : [libshared],
2221        install_rpath : rootlibexecdir,
2222        install : true,
2223        install_dir : systemgeneratordir)
2224
2225executable(
2226        'systemd-debug-generator',
2227        'src/debug-generator/debug-generator.c',
2228        include_directories : includes,
2229        link_with : [libshared],
2230        install_rpath : rootlibexecdir,
2231        install : true,
2232        install_dir : systemgeneratordir)
2233
2234executable(
2235        'systemd-run-generator',
2236        'src/run-generator/run-generator.c',
2237        include_directories : includes,
2238        link_with : [libshared],
2239        install_rpath : rootlibexecdir,
2240        install : true,
2241        install_dir : systemgeneratordir)
2242
2243exe = executable(
2244        'systemd-fstab-generator',
2245        'src/fstab-generator/fstab-generator.c',
2246        include_directories : includes,
2247        link_with : [libshared],
2248        install_rpath : rootlibexecdir,
2249        install : true,
2250        install_dir : systemgeneratordir)
2251
2252if want_tests != 'false'
2253        test('test-fstab-generator',
2254             test_fstab_generator_sh,
2255             # https://github.com/mesonbuild/meson/issues/2681
2256             args : exe.full_path(),
2257             depends : exe)
2258endif
2259
2260if conf.get('ENABLE_ENVIRONMENT_D') == 1
2261        executable(
2262                '30-systemd-environment-d-generator',
2263                'src/environment-d-generator/environment-d-generator.c',
2264                include_directories : includes,
2265                link_with : [libshared],
2266                install_rpath : rootlibexecdir,
2267                install : true,
2268                install_dir : userenvgeneratordir)
2269
2270        meson.add_install_script(meson_make_symlink,
2271                                 sysconfdir / 'environment',
2272                                 environmentdir / '99-environment.conf')
2273endif
2274
2275if conf.get('ENABLE_HIBERNATE') == 1
2276        executable(
2277                'systemd-hibernate-resume-generator',
2278                'src/hibernate-resume/hibernate-resume-generator.c',
2279                include_directories : includes,
2280                link_with : [libshared],
2281                install_rpath : rootlibexecdir,
2282                install : true,
2283                install_dir : systemgeneratordir)
2284
2285        executable(
2286                'systemd-hibernate-resume',
2287                'src/hibernate-resume/hibernate-resume.c',
2288                include_directories : includes,
2289                link_with : [libshared],
2290                install_rpath : rootlibexecdir,
2291                install : true,
2292                install_dir : rootlibexecdir)
2293endif
2294
2295if conf.get('HAVE_BLKID') == 1
2296        executable(
2297                'systemd-gpt-auto-generator',
2298                'src/gpt-auto-generator/gpt-auto-generator.c',
2299                include_directories : includes,
2300                link_with : [libshared],
2301                dependencies : libblkid,
2302                install_rpath : rootlibexecdir,
2303                install : true,
2304                install_dir : systemgeneratordir)
2305
2306        public_programs += executable(
2307                'systemd-dissect',
2308                'src/dissect/dissect.c',
2309                include_directories : includes,
2310                link_with : [libshared],
2311                install_rpath : rootlibexecdir,
2312                install : true)
2313endif
2314
2315if conf.get('ENABLE_RESOLVE') == 1
2316        dbus_programs += executable(
2317                'systemd-resolved',
2318                systemd_resolved_sources,
2319                include_directories : resolve_includes,
2320                link_with : [libshared,
2321                             libbasic_gcrypt,
2322                             libsystemd_resolve_core],
2323                dependencies : systemd_resolved_dependencies,
2324                install_rpath : rootlibexecdir,
2325                install : true,
2326                install_dir : rootlibexecdir)
2327
2328        public_programs += executable(
2329                'resolvectl',
2330                resolvectl_sources,
2331                include_directories : includes,
2332                link_with : [libshared,
2333                             libbasic_gcrypt,
2334                             libsystemd_resolve_core],
2335                dependencies : [threads,
2336                                lib_openssl_or_gcrypt,
2337                                libm,
2338                                libidn],
2339                install_rpath : rootlibexecdir,
2340                install : true)
2341
2342        meson.add_install_script(meson_make_symlink,
2343                                 bindir / 'resolvectl',
2344                                 rootsbindir / 'resolvconf')
2345
2346        meson.add_install_script(meson_make_symlink,
2347                                 bindir / 'resolvectl',
2348                                 bindir / 'systemd-resolve')
2349endif
2350
2351if conf.get('ENABLE_LOGIND') == 1
2352        dbus_programs += executable(
2353                'systemd-logind',
2354                systemd_logind_sources,
2355                include_directories : includes,
2356                link_with : [liblogind_core,
2357                             libshared],
2358                dependencies : [threads,
2359                                libacl],
2360                install_rpath : rootlibexecdir,
2361                install : true,
2362                install_dir : rootlibexecdir)
2363
2364        public_programs += executable(
2365                'loginctl',
2366                loginctl_sources,
2367                include_directories : includes,
2368                link_with : [libshared],
2369                dependencies : [threads,
2370                                liblz4,
2371                                libxz,
2372                                libzstd],
2373                install_rpath : rootlibexecdir,
2374                install : true,
2375                install_dir : rootbindir)
2376
2377        public_programs += executable(
2378                'systemd-inhibit',
2379                'src/login/inhibit.c',
2380                include_directories : includes,
2381                link_with : [libshared],
2382                install_rpath : rootlibexecdir,
2383                install : true,
2384                install_dir : rootbindir)
2385
2386        if conf.get('HAVE_PAM') == 1
2387                version_script_arg = project_source_root / pam_systemd_sym
2388                pam_systemd = shared_library(
2389                        'pam_systemd',
2390                        pam_systemd_c,
2391                        name_prefix : '',
2392                        include_directories : includes,
2393                        link_args : ['-shared',
2394                                     '-Wl,--version-script=' + version_script_arg],
2395                        link_with : [libsystemd_static,
2396                                     libshared_static],
2397                        dependencies : [threads,
2398                                        libpam,
2399                                        libpam_misc],
2400                        link_depends : pam_systemd_sym,
2401                        install : true,
2402                        install_tag : 'pam',
2403                        install_dir : pamlibdir)
2404
2405                if want_tests != 'false'
2406                        test('dlopen-pam_systemd',
2407                             test_dlopen,
2408                             # path to dlopen must include a slash
2409                             args : pam_systemd.full_path(),
2410                             depends : pam_systemd)
2411                endif
2412        endif
2413
2414        executable(
2415                'systemd-user-runtime-dir',
2416                user_runtime_dir_sources,
2417                include_directories : includes,
2418                link_with : [libshared],
2419                install_rpath : rootlibexecdir,
2420                install : true,
2421                install_dir : rootlibexecdir)
2422endif
2423
2424if conf.get('HAVE_PAM') == 1
2425        executable(
2426                'systemd-user-sessions',
2427                'src/user-sessions/user-sessions.c',
2428                include_directories : includes,
2429                link_with : [libshared],
2430                install_rpath : rootlibexecdir,
2431                install : true,
2432                install_dir : rootlibexecdir)
2433endif
2434
2435if conf.get('HAVE_BLKID') == 1 and conf.get('HAVE_GNU_EFI') == 1
2436        if get_option('link-boot-shared')
2437                boot_link_with = [libshared]
2438        else
2439                boot_link_with = [libsystemd_static, libshared_static]
2440        endif
2441
2442        public_programs += executable(
2443                'bootctl',
2444                'src/boot/bootctl.c',
2445                include_directories : includes,
2446                link_with : [boot_link_with],
2447                dependencies : [libblkid],
2448                install_rpath : rootlibexecdir,
2449                install : true)
2450
2451        public_programs += executable(
2452                'systemd-bless-boot',
2453                'src/boot/bless-boot.c',
2454                include_directories : includes,
2455                link_with : [boot_link_with],
2456                dependencies : [libblkid],
2457                install_rpath : rootlibexecdir,
2458                install : true,
2459                install_dir : rootlibexecdir)
2460
2461        executable(
2462                'systemd-bless-boot-generator',
2463                'src/boot/bless-boot-generator.c',
2464                include_directories : includes,
2465                link_with : [boot_link_with],
2466                install_rpath : rootlibexecdir,
2467                install : true,
2468                install_dir : systemgeneratordir)
2469endif
2470
2471executable(
2472        'systemd-boot-check-no-failures',
2473        'src/boot/boot-check-no-failures.c',
2474        include_directories : includes,
2475        link_with : [libshared],
2476        dependencies : [libblkid],
2477        install_rpath : rootlibexecdir,
2478        install : true,
2479        install_dir : rootlibexecdir)
2480
2481public_programs += executable(
2482        'systemd-socket-activate',
2483        'src/activate/activate.c',
2484        include_directories : includes,
2485        link_with : [libshared],
2486        dependencies : [threads],
2487        install_rpath : rootlibexecdir,
2488        install : true)
2489
2490systemctl = executable(
2491        'systemctl',
2492        systemctl_sources,
2493        include_directories : includes,
2494        link_with : systemctl_link_with,
2495        dependencies : [threads,
2496                        libcap,
2497                        libselinux,
2498                        libxz,
2499                        liblz4,
2500                        libzstd],
2501        install_rpath : rootlibexecdir,
2502        install : true,
2503        install_dir : rootbindir)
2504public_programs += systemctl
2505
2506if conf.get('ENABLE_PORTABLED') == 1
2507        dbus_programs += executable(
2508                'systemd-portabled',
2509                systemd_portabled_sources,
2510                include_directories : includes,
2511                link_with : [libshared],
2512                dependencies : [threads, libselinux],
2513                install_rpath : rootlibexecdir,
2514                install : true,
2515                install_dir : rootlibexecdir)
2516
2517        public_programs += executable(
2518                'portablectl',
2519                'src/portable/portablectl.c',
2520                include_directories : includes,
2521                link_with : [libshared],
2522                dependencies : [threads],
2523                install_rpath : rootlibexecdir,
2524                install : true,
2525                install_dir : rootbindir)
2526endif
2527
2528if conf.get('ENABLE_SYSEXT') == 1
2529        public_programs += executable(
2530                'systemd-sysext',
2531                systemd_sysext_sources,
2532                include_directories : includes,
2533                link_with : [libshared],
2534                install_rpath : rootlibexecdir,
2535                install : true,
2536                install_dir : rootbindir)
2537endif
2538
2539if conf.get('ENABLE_USERDB') == 1
2540        executable(
2541                'systemd-userwork',
2542                systemd_userwork_sources,
2543                include_directories : includes,
2544                link_with : [libshared],
2545                dependencies : [threads],
2546                install_rpath : rootlibexecdir,
2547                install : true,
2548                install_dir : rootlibexecdir)
2549
2550        executable(
2551                'systemd-userdbd',
2552                systemd_userdbd_sources,
2553                include_directories : includes,
2554                link_with : [libshared],
2555                dependencies : [threads],
2556                install_rpath : rootlibexecdir,
2557                install : true,
2558                install_dir : rootlibexecdir)
2559
2560        public_programs += executable(
2561                'userdbctl',
2562                userdbctl_sources,
2563                include_directories : includes,
2564                link_with : [libshared],
2565                dependencies : [threads],
2566                install_rpath : rootlibexecdir,
2567                install : true,
2568                install_dir : rootbindir)
2569endif
2570
2571if conf.get('ENABLE_HOMED') == 1
2572        executable(
2573                'systemd-homework',
2574                systemd_homework_sources,
2575                include_directories : includes,
2576                link_with : [libshared],
2577                dependencies : [threads,
2578                                libblkid,
2579                                libcrypt,
2580                                libopenssl,
2581                                libfdisk,
2582                                libp11kit],
2583                install_rpath : rootlibexecdir,
2584                install : true,
2585                install_dir : rootlibexecdir)
2586
2587        dbus_programs += executable(
2588                'systemd-homed',
2589                systemd_homed_sources,
2590                include_directories : home_includes,
2591                link_with : [libshared],
2592                dependencies : [threads,
2593                                libcrypt,
2594                                libopenssl,
2595                                libm],
2596                install_rpath : rootlibexecdir,
2597                install : true,
2598                install_dir : rootlibexecdir)
2599
2600        public_programs += executable(
2601                'homectl',
2602                homectl_sources,
2603                include_directories : includes,
2604                link_with : [libshared],
2605                dependencies : [threads,
2606                                libcrypt,
2607                                libopenssl,
2608                                libp11kit,
2609                                libdl],
2610                install_rpath : rootlibexecdir,
2611                install : true,
2612                install_dir : rootbindir)
2613
2614        if conf.get('HAVE_PAM') == 1
2615                version_script_arg = project_source_root / pam_systemd_home_sym
2616                pam_systemd = shared_library(
2617                        'pam_systemd_home',
2618                        pam_systemd_home_c,
2619                        name_prefix : '',
2620                        include_directories : includes,
2621                        link_args : ['-shared',
2622                                     '-Wl,--version-script=' + version_script_arg],
2623                        link_with : [libsystemd_static,
2624                                     libshared_static],
2625                        dependencies : [threads,
2626                                        libpam,
2627                                        libpam_misc,
2628                                        libcrypt],
2629                        link_depends : pam_systemd_home_sym,
2630                        install : true,
2631                        install_tag : 'pam',
2632                        install_dir : pamlibdir)
2633        endif
2634endif
2635
2636foreach alias : (['halt', 'poweroff', 'reboot', 'shutdown'] +
2637                 (conf.get('HAVE_SYSV_COMPAT') == 1 ? ['runlevel', 'telinit'] : []))
2638        meson.add_install_script(meson_make_symlink,
2639                                 rootbindir / 'systemctl',
2640                                 rootsbindir / alias)
2641endforeach
2642
2643meson.add_install_script(meson_make_symlink,
2644                         rootbindir / 'udevadm',
2645                         rootlibexecdir / 'systemd-udevd')
2646
2647if conf.get('ENABLE_BACKLIGHT') == 1
2648        executable(
2649                'systemd-backlight',
2650                'src/backlight/backlight.c',
2651                include_directories : includes,
2652                link_with : [libshared],
2653                install_rpath : rootlibexecdir,
2654                install : true,
2655                install_dir : rootlibexecdir)
2656endif
2657
2658if conf.get('ENABLE_RFKILL') == 1
2659        executable(
2660                'systemd-rfkill',
2661                'src/rfkill/rfkill.c',
2662                include_directories : includes,
2663                link_with : [libshared],
2664                install_rpath : rootlibexecdir,
2665                install : true,
2666                install_dir : rootlibexecdir)
2667endif
2668
2669executable(
2670        'systemd-system-update-generator',
2671        'src/system-update-generator/system-update-generator.c',
2672        include_directories : includes,
2673        link_with : [libshared],
2674        install_rpath : rootlibexecdir,
2675        install : true,
2676        install_dir : systemgeneratordir)
2677
2678if conf.get('HAVE_LIBCRYPTSETUP') == 1
2679        executable(
2680                'systemd-cryptsetup',
2681                systemd_cryptsetup_sources,
2682                include_directories : includes,
2683                link_with : [libshared],
2684                dependencies : [libcryptsetup,
2685                                libp11kit],
2686                install_rpath : rootlibexecdir,
2687                install : true,
2688                install_dir : rootlibexecdir)
2689
2690        executable(
2691                'systemd-cryptsetup-generator',
2692                'src/cryptsetup/cryptsetup-generator.c',
2693                include_directories : includes,
2694                link_with : [libshared],
2695                install_rpath : rootlibexecdir,
2696                install : true,
2697                install_dir : systemgeneratordir)
2698
2699        executable(
2700                'systemd-veritysetup',
2701                'src/veritysetup/veritysetup.c',
2702                include_directories : includes,
2703                link_with : [libshared],
2704                dependencies : [libcryptsetup],
2705                install_rpath : rootlibexecdir,
2706                install : true,
2707                install_dir : rootlibexecdir)
2708
2709        executable(
2710                'systemd-veritysetup-generator',
2711                'src/veritysetup/veritysetup-generator.c',
2712                include_directories : includes,
2713                link_with : [libshared],
2714                install_rpath : rootlibexecdir,
2715                install : true,
2716                install_dir : systemgeneratordir)
2717
2718        public_programs += executable(
2719                'systemd-cryptenroll',
2720                systemd_cryptenroll_sources,
2721                include_directories : includes,
2722                link_with : [libshared],
2723                dependencies : [libcryptsetup,
2724                                libdl,
2725                                libopenssl,
2726                                libp11kit],
2727                install_rpath : rootlibexecdir,
2728                install : true)
2729
2730        executable(
2731                'systemd-integritysetup',
2732                ['src/integritysetup/integritysetup.c', 'src/integritysetup/integrity-util.c'],
2733                include_directories : includes,
2734                link_with : [libshared],
2735                dependencies : [libcryptsetup],
2736                install_rpath : rootlibexecdir,
2737                install : true,
2738                install_dir : rootlibexecdir)
2739
2740        executable(
2741                'systemd-integritysetup-generator',
2742                ['src/integritysetup/integritysetup-generator.c', 'src/integritysetup/integrity-util.c'],
2743                include_directories : includes,
2744                link_with : [libshared],
2745                install_rpath : rootlibexecdir,
2746                install : true,
2747                install_dir : systemgeneratordir)
2748endif
2749
2750if conf.get('HAVE_SYSV_COMPAT') == 1
2751        exe = executable(
2752                'systemd-sysv-generator',
2753                'src/sysv-generator/sysv-generator.c',
2754                include_directories : includes,
2755                link_with : [libshared],
2756                install_rpath : rootlibexecdir,
2757                install : true,
2758                install_dir : systemgeneratordir)
2759
2760        sysv_generator_test_py = find_program('test/sysv-generator-test.py')
2761        if want_tests != 'false'
2762                test('sysv-generator-test',
2763                     sysv_generator_test_py,
2764                     depends : exe)
2765        endif
2766
2767        executable(
2768                'systemd-rc-local-generator',
2769                'src/rc-local-generator/rc-local-generator.c',
2770                include_directories : includes,
2771                link_with : [libshared],
2772                install_rpath : rootlibexecdir,
2773                install : true,
2774                install_dir : systemgeneratordir)
2775endif
2776
2777if conf.get('ENABLE_XDG_AUTOSTART') == 1
2778        executable(
2779                'systemd-xdg-autostart-generator',
2780                systemd_xdg_autostart_generator_sources,
2781                include_directories : includes,
2782                link_with : [libshared],
2783                install_rpath : rootlibexecdir,
2784                install : true,
2785                install_dir : usergeneratordir)
2786
2787        executable(
2788                'systemd-xdg-autostart-condition',
2789                'src/xdg-autostart-generator/xdg-autostart-condition.c',
2790                include_directories : includes,
2791                link_with : [libshared],
2792                install_rpath : rootlibexecdir,
2793                install : true,
2794                install_dir : rootlibexecdir)
2795endif
2796
2797if conf.get('ENABLE_HOSTNAMED') == 1
2798        dbus_programs += executable(
2799                'systemd-hostnamed',
2800                'src/hostname/hostnamed.c',
2801                include_directories : includes,
2802                link_with : [libshared],
2803                install_rpath : rootlibexecdir,
2804                install : true,
2805                install_dir : rootlibexecdir)
2806
2807        public_programs += executable(
2808                'hostnamectl',
2809                'src/hostname/hostnamectl.c',
2810                include_directories : includes,
2811                link_with : [libshared],
2812                install_rpath : rootlibexecdir,
2813                install : true)
2814endif
2815
2816if conf.get('ENABLE_LOCALED') == 1
2817        if conf.get('HAVE_XKBCOMMON') == 1
2818                # logind will load libxkbcommon.so dynamically on its own, but we still
2819                # need to specify where the headers are
2820                deps = [libdl, libxkbcommon.partial_dependency(compile_args: true)]
2821        else
2822                deps = []
2823        endif
2824
2825        dbus_programs += executable(
2826                'systemd-localed',
2827                systemd_localed_sources,
2828                include_directories : includes,
2829                link_with : [libshared],
2830                dependencies : deps,
2831                install_rpath : rootlibexecdir,
2832                install : true,
2833                install_dir : rootlibexecdir)
2834
2835        public_programs += executable(
2836                'localectl',
2837                localectl_sources,
2838                include_directories : includes,
2839                link_with : [libshared],
2840                install_rpath : rootlibexecdir,
2841                install : true)
2842endif
2843
2844if conf.get('ENABLE_TIMEDATED') == 1
2845        dbus_programs += executable(
2846                'systemd-timedated',
2847                'src/timedate/timedated.c',
2848                include_directories : includes,
2849                link_with : [libshared],
2850                install_rpath : rootlibexecdir,
2851                install : true,
2852                install_dir : rootlibexecdir)
2853endif
2854
2855if conf.get('ENABLE_TIMEDATECTL') == 1
2856        public_programs += executable(
2857                'timedatectl',
2858                'src/timedate/timedatectl.c',
2859                include_directories : includes,
2860                install_rpath : rootlibexecdir,
2861                link_with : [libshared],
2862                dependencies : [libm],
2863                install : true)
2864endif
2865
2866if conf.get('ENABLE_TIMESYNCD') == 1
2867        executable(
2868                'systemd-timesyncd',
2869                systemd_timesyncd_sources,
2870                include_directories : includes,
2871                link_with : [libtimesyncd_core],
2872                dependencies : [threads,
2873                                libm],
2874                install_rpath : rootlibexecdir,
2875                install : true,
2876                install_dir : rootlibexecdir)
2877
2878        executable(
2879                'systemd-time-wait-sync',
2880                'src/timesync/wait-sync.c',
2881                include_directories : includes,
2882                link_with : [libtimesyncd_core],
2883                install_rpath : rootlibexecdir,
2884                install : true,
2885                install_dir : rootlibexecdir)
2886endif
2887
2888if conf.get('ENABLE_MACHINED') == 1
2889        dbus_programs += executable(
2890                'systemd-machined',
2891                systemd_machined_sources,
2892                include_directories : includes,
2893                link_with : [libmachine_core,
2894                             libshared],
2895                install_rpath : rootlibexecdir,
2896                install : true,
2897                install_dir : rootlibexecdir)
2898
2899        public_programs += executable(
2900                'machinectl',
2901                'src/machine/machinectl.c',
2902                include_directories : includes,
2903                link_with : [libshared],
2904                dependencies : [threads,
2905                                libxz,
2906                                liblz4,
2907                                libzstd],
2908                install_rpath : rootlibexecdir,
2909                install : true,
2910                install_dir : rootbindir)
2911endif
2912
2913if conf.get('ENABLE_IMPORTD') == 1
2914        dbus_programs += executable(
2915                'systemd-importd',
2916                systemd_importd_sources,
2917                include_directories : includes,
2918                link_with : [libshared],
2919                dependencies : [threads],
2920                install_rpath : rootlibexecdir,
2921                install : true,
2922                install_dir : rootlibexecdir)
2923
2924        systemd_pull = executable(
2925                'systemd-pull',
2926                systemd_pull_sources,
2927                include_directories : includes,
2928                link_with : [libshared,
2929                             lib_import_common],
2930                dependencies : [versiondep,
2931                                libcurl,
2932                                lib_openssl_or_gcrypt,
2933                                libz,
2934                                libbzip2,
2935                                libxz],
2936                install_rpath : rootlibexecdir,
2937                install : true,
2938                install_dir : rootlibexecdir)
2939
2940        systemd_import = executable(
2941                'systemd-import',
2942                systemd_import_sources,
2943                include_directories : includes,
2944                link_with : [libshared,
2945                             lib_import_common],
2946                dependencies : [libcurl,
2947                                libz,
2948                                libbzip2,
2949                                libxz],
2950                install_rpath : rootlibexecdir,
2951                install : true,
2952                install_dir : rootlibexecdir)
2953
2954        systemd_import_fs = executable(
2955                'systemd-import-fs',
2956                systemd_import_fs_sources,
2957                include_directories : includes,
2958                link_with : [libshared,
2959                             lib_import_common],
2960                install_rpath : rootlibexecdir,
2961                install : true,
2962                install_dir : rootlibexecdir)
2963
2964        systemd_export = executable(
2965                'systemd-export',
2966                systemd_export_sources,
2967                include_directories : includes,
2968                link_with : [libshared,
2969                             lib_import_common],
2970                dependencies : [libcurl,
2971                                libz,
2972                                libbzip2,
2973                                libxz],
2974                install_rpath : rootlibexecdir,
2975                install : true,
2976                install_dir : rootlibexecdir)
2977
2978        public_programs += [systemd_pull, systemd_import, systemd_import_fs, systemd_export]
2979endif
2980
2981if conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_LIBCURL') == 1
2982        public_programs += executable(
2983                'systemd-journal-upload',
2984                systemd_journal_upload_sources,
2985                include_directories : includes,
2986                link_with : [libshared],
2987                dependencies : [versiondep,
2988                                threads,
2989                                libcurl,
2990                                libgnutls,
2991                                libxz,
2992                                liblz4,
2993                                libzstd],
2994                install_rpath : rootlibexecdir,
2995                install : true,
2996                install_dir : rootlibexecdir)
2997endif
2998
2999if conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_MICROHTTPD') == 1
3000        public_programs += executable(
3001                'systemd-journal-remote',
3002                systemd_journal_remote_sources,
3003                include_directories : journal_includes,
3004                link_with : [libshared,
3005                             libsystemd_journal_remote],
3006                dependencies : [threads,
3007                                libmicrohttpd,
3008                                libgnutls,
3009                                libxz,
3010                                liblz4,
3011                                libzstd],
3012                install_rpath : rootlibexecdir,
3013                install : true,
3014                install_dir : rootlibexecdir)
3015
3016        public_programs += executable(
3017                'systemd-journal-gatewayd',
3018                systemd_journal_gatewayd_sources,
3019                include_directories : journal_includes,
3020                link_with : [libshared],
3021                dependencies : [threads,
3022                                libmicrohttpd,
3023                                libgnutls,
3024                                libxz,
3025                                liblz4,
3026                                libzstd],
3027                install_rpath : rootlibexecdir,
3028                install : true,
3029                install_dir : rootlibexecdir)
3030endif
3031
3032if conf.get('ENABLE_COREDUMP') == 1
3033        executable(
3034                'systemd-coredump',
3035                systemd_coredump_sources,
3036                include_directories : includes,
3037                link_with : [libshared,
3038                             libbasic_compress],
3039                dependencies : [threads,
3040                                libacl,
3041                                libxz,
3042                                liblz4,
3043                                libzstd],
3044                install_rpath : rootlibexecdir,
3045                install : true,
3046                install_dir : rootlibexecdir)
3047
3048        public_programs += executable(
3049                'coredumpctl',
3050                coredumpctl_sources,
3051                include_directories : includes,
3052                link_with : [libshared,
3053                             libbasic_compress],
3054                dependencies : [threads,
3055                                libxz,
3056                                liblz4,
3057                                libzstd],
3058                install_rpath : rootlibexecdir,
3059                install : true)
3060endif
3061
3062if conf.get('ENABLE_PSTORE') == 1
3063        executable(
3064                'systemd-pstore',
3065                systemd_pstore_sources,
3066                include_directories : includes,
3067                link_with : [libshared],
3068                dependencies : [threads,
3069                                libacl,
3070                                libxz,
3071                                liblz4,
3072                                libzstd],
3073                install_rpath : rootlibexecdir,
3074                install : true,
3075                install_dir : rootlibexecdir)
3076endif
3077
3078if conf.get('ENABLE_OOMD') == 1
3079        dbus_programs += executable('systemd-oomd',
3080                   systemd_oomd_sources,
3081                   include_directories : includes,
3082                   link_with : [libshared],
3083                   dependencies : [],
3084                   install_rpath : rootlibexecdir,
3085                   install : true,
3086                   install_dir : rootlibexecdir)
3087
3088        public_programs += executable(
3089                'oomctl',
3090                oomctl_sources,
3091                include_directories : includes,
3092                link_with : [libshared],
3093                dependencies : [],
3094                install_rpath : rootlibexecdir,
3095                install : true)
3096endif
3097
3098if conf.get('ENABLE_BINFMT') == 1
3099        public_programs += executable(
3100                'systemd-binfmt',
3101                'src/binfmt/binfmt.c',
3102                include_directories : includes,
3103                link_with : [libshared],
3104                install_rpath : rootlibexecdir,
3105                install : true,
3106                install_dir : rootlibexecdir)
3107
3108        meson.add_install_script('sh', '-c',
3109                                 mkdir_p.format(binfmtdir))
3110        if install_sysconfdir
3111                meson.add_install_script('sh', '-c',
3112                                         mkdir_p.format(sysconfdir / 'binfmt.d'))
3113        endif
3114endif
3115
3116if conf.get('ENABLE_SYSUPDATE') == 1
3117        exe = executable(
3118                'systemd-sysupdate',
3119                systemd_sysupdate_sources,
3120                include_directories : includes,
3121                link_with : [libshared],
3122                dependencies : [threads,
3123                                libblkid,
3124                                libfdisk,
3125                                libopenssl],
3126                install_rpath : rootlibexecdir,
3127                install : true,
3128                install_dir : rootlibexecdir)
3129        public_programs += exe
3130endif
3131
3132if conf.get('ENABLE_VCONSOLE') == 1
3133        executable(
3134                'systemd-vconsole-setup',
3135                'src/vconsole/vconsole-setup.c',
3136                include_directories : includes,
3137                link_with : [libshared],
3138                install_rpath : rootlibexecdir,
3139                install : true,
3140                install_dir : rootlibexecdir)
3141endif
3142
3143if conf.get('ENABLE_RANDOMSEED') == 1
3144        executable(
3145                'systemd-random-seed',
3146                'src/random-seed/random-seed.c',
3147                include_directories : includes,
3148                link_with : [libshared],
3149                install_rpath : rootlibexecdir,
3150                install : true,
3151                install_dir : rootlibexecdir)
3152endif
3153
3154if conf.get('ENABLE_FIRSTBOOT') == 1
3155        public_programs += executable(
3156                'systemd-firstboot',
3157                'src/firstboot/firstboot.c',
3158                include_directories : includes,
3159                link_with : [libshared],
3160                dependencies : [libcrypt],
3161                install_rpath : rootlibexecdir,
3162                install : true,
3163                install_dir : rootbindir)
3164endif
3165
3166executable(
3167        'systemd-remount-fs',
3168        'src/remount-fs/remount-fs.c',
3169        include_directories : includes,
3170        link_with : [libshared],
3171        install_rpath : rootlibexecdir,
3172        install : true,
3173        install_dir : rootlibexecdir)
3174
3175executable(
3176        'systemd-machine-id-setup',
3177        'src/machine-id-setup/machine-id-setup-main.c',
3178        include_directories : includes,
3179        link_with : [libshared],
3180        install_rpath : rootlibexecdir,
3181        install : true,
3182        install_dir : rootbindir)
3183
3184executable(
3185        'systemd-fsck',
3186        'src/fsck/fsck.c',
3187        include_directories : includes,
3188        link_with : [libshared],
3189        install_rpath : rootlibexecdir,
3190        install : true,
3191        install_dir : rootlibexecdir)
3192
3193executable('systemd-growfs',
3194           'src/partition/growfs.c',
3195           include_directories : includes,
3196           link_with : [libshared],
3197           install_rpath : rootlibexecdir,
3198           install : true,
3199           install_dir : rootlibexecdir)
3200
3201executable(
3202        'systemd-makefs',
3203        'src/partition/makefs.c',
3204        include_directories : includes,
3205        link_with : [libshared],
3206        install_rpath : rootlibexecdir,
3207        install : true,
3208        install_dir : rootlibexecdir)
3209
3210executable(
3211        'systemd-sleep',
3212        'src/sleep/sleep.c',
3213        include_directories : includes,
3214        link_with : [libshared],
3215        install_rpath : rootlibexecdir,
3216        install : true,
3217        install_dir : rootlibexecdir)
3218
3219if install_sysconfdir_samples
3220        install_data('src/sleep/sleep.conf',
3221                     install_dir : pkgsysconfdir)
3222endif
3223
3224public_programs += executable(
3225        'systemd-sysctl',
3226        'src/sysctl/sysctl.c',
3227        include_directories : includes,
3228        link_with : [libshared],
3229        install_rpath : rootlibexecdir,
3230        install : true,
3231        install_dir : rootlibexecdir)
3232
3233executable(
3234        'systemd-ac-power',
3235        'src/ac-power/ac-power.c',
3236        include_directories : includes,
3237        link_with : [libshared],
3238        install_rpath : rootlibexecdir,
3239        install : true,
3240        install_dir : rootlibexecdir)
3241
3242public_programs += executable(
3243        'systemd-detect-virt',
3244        'src/detect-virt/detect-virt.c',
3245        include_directories : includes,
3246        link_with : [libshared],
3247        install_rpath : rootlibexecdir,
3248        install : true)
3249
3250public_programs += executable(
3251        'systemd-delta',
3252        'src/delta/delta.c',
3253        include_directories : includes,
3254        link_with : [libshared],
3255        install_rpath : rootlibexecdir,
3256        install : true)
3257
3258public_programs += executable(
3259        'systemd-escape',
3260        'src/escape/escape.c',
3261        include_directories : includes,
3262        link_with : [libshared],
3263        install_rpath : rootlibexecdir,
3264        install : true,
3265        install_dir : rootbindir)
3266
3267public_programs += executable(
3268        'systemd-notify',
3269        'src/notify/notify.c',
3270        include_directories : includes,
3271        link_with : [libshared],
3272        install_rpath : rootlibexecdir,
3273        install : true,
3274        install_dir : rootbindir)
3275
3276public_programs += executable(
3277        'systemd-creds',
3278        'src/creds/creds.c',
3279        include_directories : includes,
3280        link_with : [libshared],
3281        dependencies : [threads,
3282                        libopenssl],
3283        install_rpath : rootlibexecdir,
3284        install : true,
3285        install_dir : rootbindir)
3286
3287executable(
3288        'systemd-volatile-root',
3289        'src/volatile-root/volatile-root.c',
3290        include_directories : includes,
3291        link_with : [libshared],
3292        install_rpath : rootlibexecdir,
3293        install : conf.get('ENABLE_INITRD') == 1,
3294        install_dir : rootlibexecdir)
3295
3296executable(
3297        'systemd-cgroups-agent',
3298        'src/cgroups-agent/cgroups-agent.c',
3299        include_directories : includes,
3300        link_with : [libshared],
3301        install_rpath : rootlibexecdir,
3302        install : true,
3303        install_dir : rootlibexecdir)
3304
3305systemd_id128 = executable(
3306        'systemd-id128',
3307        'src/id128/id128.c',
3308        include_directories : includes,
3309        link_with : [libshared],
3310        install_rpath : rootlibexecdir,
3311        install : true)
3312public_programs += systemd_id128
3313
3314if want_tests != 'false'
3315        test('test-systemctl-enable',
3316             test_systemctl_enable_sh,
3317             # https://github.com/mesonbuild/meson/issues/2681
3318             args : [systemctl.full_path(),
3319                     systemd_id128.full_path()])
3320endif
3321
3322public_programs += executable(
3323        'systemd-path',
3324        'src/path/path.c',
3325        include_directories : includes,
3326        link_with : [libshared],
3327        install_rpath : rootlibexecdir,
3328        install : true)
3329
3330public_programs += executable(
3331        'systemd-ask-password',
3332        'src/ask-password/ask-password.c',
3333        include_directories : includes,
3334        link_with : [libshared],
3335        install_rpath : rootlibexecdir,
3336        install : true,
3337        install_dir : rootbindir)
3338
3339executable(
3340        'systemd-reply-password',
3341        'src/reply-password/reply-password.c',
3342        include_directories : includes,
3343        link_with : [libshared],
3344        install_rpath : rootlibexecdir,
3345        install : true,
3346        install_dir : rootlibexecdir)
3347
3348public_programs += executable(
3349        'systemd-tty-ask-password-agent',
3350        'src/tty-ask-password-agent/tty-ask-password-agent.c',
3351        include_directories : includes,
3352        link_with : [libshared],
3353        install_rpath : rootlibexecdir,
3354        install : true,
3355        install_dir : rootbindir)
3356
3357public_programs += executable(
3358        'systemd-cgls',
3359        'src/cgls/cgls.c',
3360        include_directories : includes,
3361        link_with : [libshared],
3362        install_rpath : rootlibexecdir,
3363        install : true)
3364
3365public_programs += executable(
3366        'systemd-cgtop',
3367        'src/cgtop/cgtop.c',
3368        include_directories : includes,
3369        link_with : [libshared],
3370        install_rpath : rootlibexecdir,
3371        install : true)
3372
3373executable(
3374        'systemd-initctl',
3375        'src/initctl/initctl.c',
3376        include_directories : includes,
3377        link_with : [libshared],
3378        install_rpath : rootlibexecdir,
3379        install : (conf.get('HAVE_SYSV_COMPAT') == 1),
3380        install_dir : rootlibexecdir)
3381
3382public_programs += executable(
3383        'systemd-mount',
3384        'src/mount/mount-tool.c',
3385        include_directories : includes,
3386        link_with : [libshared],
3387        dependencies: [libmount],
3388        install_rpath : rootlibexecdir,
3389        install : true)
3390
3391meson.add_install_script(meson_make_symlink,
3392                         'systemd-mount', bindir / 'systemd-umount')
3393
3394public_programs += executable(
3395        'systemd-run',
3396        'src/run/run.c',
3397        include_directories : includes,
3398        link_with : [libshared],
3399        install_rpath : rootlibexecdir,
3400        install : true)
3401
3402public_programs += executable(
3403        'systemd-stdio-bridge',
3404        'src/stdio-bridge/stdio-bridge.c',
3405        include_directories : includes,
3406        link_with : [libshared],
3407        dependencies : [versiondep],
3408        install_rpath : rootlibexecdir,
3409        install : true)
3410
3411public_programs += executable(
3412        'busctl',
3413        busctl_sources,
3414        include_directories : includes,
3415        link_with : [libshared],
3416        dependencies : [versiondep],
3417        install_rpath : rootlibexecdir,
3418        install : true)
3419
3420if enable_sysusers
3421        exe = executable(
3422                'systemd-sysusers',
3423                'src/sysusers/sysusers.c',
3424                include_directories : includes,
3425                link_with : [libshared],
3426                install_rpath : rootlibexecdir,
3427                install : true,
3428                install_dir : rootbindir)
3429        public_programs += exe
3430
3431        if want_tests != 'false'
3432                test('test-sysusers',
3433                     test_sysusers_sh,
3434                     # https://github.com/mesonbuild/meson/issues/2681
3435                     args : exe.full_path())
3436        endif
3437
3438        if have_standalone_binaries
3439                exe = executable(
3440                        'systemd-sysusers.standalone',
3441                        'src/sysusers/sysusers.c',
3442                        include_directories : includes,
3443                        c_args : '-DSTANDALONE',
3444                        link_with : [libshared_static,
3445                                     libbasic,
3446                                     libbasic_gcrypt,
3447                                     libsystemd_static],
3448                        install : true,
3449                        install_dir : rootbindir)
3450                public_programs += exe
3451
3452                if want_tests != 'false'
3453                        test('test-sysusers.standalone',
3454                             test_sysusers_sh,
3455                             # https://github.com/mesonbuild/meson/issues/2681
3456                             args : exe.full_path())
3457                endif
3458        endif
3459endif
3460
3461if conf.get('ENABLE_TMPFILES') == 1
3462        exe = executable(
3463                'systemd-tmpfiles',
3464                systemd_tmpfiles_sources,
3465                include_directories : includes,
3466                link_with : [libshared],
3467                dependencies : [libacl],
3468                install_rpath : rootlibexecdir,
3469                install : true,
3470                install_dir : rootbindir)
3471        public_programs += exe
3472
3473        if want_tests != 'false'
3474                test('test-systemd-tmpfiles',
3475                     test_systemd_tmpfiles_py,
3476                     # https://github.com/mesonbuild/meson/issues/2681
3477                     args : exe.full_path())
3478        endif
3479
3480        if have_standalone_binaries
3481                exe = executable(
3482                        'systemd-tmpfiles.standalone',
3483                        systemd_tmpfiles_sources,
3484                        include_directories : includes,
3485                        c_args : '-DSTANDALONE',
3486                        link_with : [libshared_static,
3487                                     libbasic,
3488                                     libbasic_gcrypt,
3489                                     libsystemd_static],
3490                        dependencies : [libacl],
3491                        install : true,
3492                        install_dir : rootbindir)
3493                public_programs += exe
3494
3495                if want_tests != 'false'
3496                        test('test-systemd-tmpfiles.standalone',
3497                             test_systemd_tmpfiles_py,
3498                             # https://github.com/mesonbuild/meson/issues/2681
3499                             args : exe.full_path())
3500                endif
3501        endif
3502endif
3503
3504if conf.get('ENABLE_HWDB') == 1
3505        systemd_hwdb = executable(
3506                'systemd-hwdb',
3507                'src/hwdb/hwdb.c',
3508                include_directories : includes,
3509                link_with : udev_link_with,
3510                install_rpath : udev_rpath,
3511                install : true,
3512                install_dir : rootbindir)
3513        public_programs += systemd_hwdb
3514
3515        if want_tests != 'false'
3516                test('hwdb-test',
3517                     hwdb_test_sh,
3518                     suite : 'dist-check',
3519                     args : [systemd_hwdb.full_path()],
3520                     timeout : 90)
3521        endif
3522endif
3523
3524if conf.get('ENABLE_QUOTACHECK') == 1
3525        executable(
3526                'systemd-quotacheck',
3527                'src/quotacheck/quotacheck.c',
3528                include_directories : includes,
3529                link_with : [libshared],
3530                install_rpath : rootlibexecdir,
3531                install : true,
3532                install_dir : rootlibexecdir)
3533endif
3534
3535public_programs += executable(
3536        'systemd-socket-proxyd',
3537        'src/socket-proxy/socket-proxyd.c',
3538        include_directories : includes,
3539        link_with : [libshared],
3540        dependencies : [threads],
3541        install_rpath : rootlibexecdir,
3542        install : true,
3543        install_dir : rootlibexecdir)
3544
3545udevadm = executable(
3546        'udevadm',
3547        udevadm_sources,
3548        include_directories : includes,
3549        link_with : [libudevd_core],
3550        dependencies : [versiondep,
3551                        threads,
3552                        libkmod,
3553                        libidn,
3554                        libacl,
3555                        libblkid],
3556        install_rpath : udev_rpath,
3557        install : true,
3558        install_dir : rootbindir)
3559public_programs += udevadm
3560
3561if conf.get('ENABLE_REPART') == 1
3562        exe = executable(
3563                'systemd-repart',
3564                systemd_repart_sources,
3565                include_directories : includes,
3566                link_with : [libshared],
3567                dependencies : [threads,
3568                                libblkid,
3569                                libfdisk],
3570                install_rpath : rootlibexecdir,
3571                install : true,
3572                install_dir : rootbindir)
3573        public_programs += exe
3574
3575        if want_tests != 'false'
3576                test('test-repart',
3577                     test_repart_sh,
3578                     args : [exe.full_path(), udevadm.full_path()])
3579        endif
3580endif
3581
3582executable(
3583        'systemd-shutdown',
3584        systemd_shutdown_sources,
3585        include_directories : includes,
3586        link_with : [libshared],
3587        dependencies : [libmount],
3588        install_rpath : rootlibexecdir,
3589        install : true,
3590        install_dir : rootlibexecdir)
3591
3592executable(
3593        'systemd-update-done',
3594        'src/update-done/update-done.c',
3595        include_directories : includes,
3596        link_with : [libshared],
3597        install_rpath : rootlibexecdir,
3598        install : true,
3599        install_dir : rootlibexecdir)
3600
3601executable(
3602        'systemd-update-utmp',
3603        'src/update-utmp/update-utmp.c',
3604        include_directories : includes,
3605        link_with : [libshared],
3606        dependencies : [libaudit],
3607        install_rpath : rootlibexecdir,
3608        install : (conf.get('ENABLE_UTMP') == 1),
3609        install_dir : rootlibexecdir)
3610
3611if conf.get('HAVE_KMOD') == 1
3612        executable(
3613                'systemd-modules-load',
3614                'src/modules-load/modules-load.c',
3615                include_directories : includes,
3616                link_with : [libshared],
3617                dependencies : [libkmod],
3618                install_rpath : rootlibexecdir,
3619                install : true,
3620                install_dir : rootlibexecdir)
3621
3622        meson.add_install_script('sh', '-c',
3623                                 mkdir_p.format(modulesloaddir))
3624        if install_sysconfdir
3625                meson.add_install_script('sh', '-c',
3626                                         mkdir_p.format(sysconfdir / 'modules-load.d'))
3627        endif
3628endif
3629
3630public_programs += executable(
3631        'systemd-nspawn',
3632        systemd_nspawn_sources,
3633        include_directories : includes,
3634        link_with : [libnspawn_core,
3635                     libshared],
3636        dependencies : [libblkid,
3637                        libseccomp],
3638        install_rpath : rootlibexecdir,
3639        install : true)
3640
3641if conf.get('ENABLE_NETWORKD') == 1
3642        dbus_programs += executable(
3643                'systemd-networkd',
3644                systemd_networkd_sources,
3645                include_directories : network_includes,
3646                link_with : [libnetworkd_core,
3647                             libsystemd_network,
3648                             networkd_link_with],
3649                dependencies : [threads],
3650                install_rpath : rootlibexecdir,
3651                install : true,
3652                install_dir : rootlibexecdir)
3653
3654        public_programs += executable(
3655                'systemd-networkd-wait-online',
3656                systemd_networkd_wait_online_sources,
3657                include_directories : includes,
3658                link_with : [networkd_link_with],
3659                install_rpath : rootlibexecdir,
3660                install : true,
3661                install_dir : rootlibexecdir)
3662
3663        public_programs += executable(
3664                'networkctl',
3665                networkctl_sources,
3666                include_directories : libsystemd_network_includes,
3667                link_with : [libsystemd_network,
3668                             networkd_link_with],
3669                install_rpath : rootlibexecdir,
3670                install : true,
3671                install_dir : rootbindir)
3672endif
3673
3674exe = executable(
3675        'systemd-network-generator',
3676        network_generator_sources,
3677        include_directories : includes,
3678        link_with : [networkd_link_with],
3679        install_rpath : rootlibexecdir,
3680        install : true,
3681        install_dir : rootlibexecdir)
3682
3683if want_tests != 'false'
3684        test('test-network-generator-conversion',
3685             test_network_generator_conversion_sh,
3686             # https://github.com/mesonbuild/meson/issues/2681
3687             args : exe.full_path(),
3688             depends : exe)
3689endif
3690
3691executable(
3692        'systemd-sulogin-shell',
3693        'src/sulogin-shell/sulogin-shell.c',
3694        include_directories : includes,
3695        link_with : [libshared],
3696        install_rpath : rootlibexecdir,
3697        install : true,
3698        install_dir : rootlibexecdir)
3699
3700public_programs += custom_target(
3701        'kernel-install',
3702        input : kernel_install_in,
3703        output : 'kernel-install',
3704        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
3705        install : want_kernel_install,
3706        install_mode : 'rwxr-xr-x',
3707        install_dir : bindir)
3708
3709############################################################
3710
3711runtest_env = custom_target(
3712        'systemd-runtest.env',
3713        output : 'systemd-runtest.env',
3714        command : [sh, '-c',
3715                   '{ echo SYSTEMD_TEST_DATA=@0@; echo SYSTEMD_CATALOG_DIR=@1@; } >@OUTPUT@'.format(
3716                           project_source_root / 'test',
3717                           project_build_root / 'catalog')],
3718        depends : catalogs,
3719        build_by_default : true)
3720
3721test_cflags = ['-DTEST_CODE=1']
3722# We intentionally do not do inline initializations with definitions for a
3723# bunch of _cleanup_ variables in tests, to ensure valgrind is triggered if we
3724# use the variable unexpectedly. This triggers a lot of maybe-uninitialized
3725# false positives when the combination of -O2 and -flto is used. Suppress them.
3726if '-O2' in c_args and '-flto=auto' in c_args
3727        test_cflags += cc.first_supported_argument('-Wno-maybe-uninitialized')
3728endif
3729
3730foreach tuple : tests
3731        sources = tuple[0]
3732        link_with = tuple.length() > 1 and tuple[1].length() > 0 ? tuple[1] : [libshared]
3733        dependencies = tuple.length() > 2 ? tuple[2] : []
3734        incs = tuple.length() > 3 and tuple[3].length() > 0 ? tuple[3] : includes
3735        condition = tuple.length() > 4 ? tuple[4] : ''
3736        type = tuple.length() > 5 ? tuple[5] : ''
3737        defs = tuple.length() > 6 ? tuple[6] : []
3738        defs += test_cflags
3739        parallel = tuple.length() > 7 ? tuple[7] : true
3740        timeout = 30
3741
3742        # FIXME: Use fs.stem() with meson >= 0.54.0
3743        name = '@0@'.format(sources[0]).split('/')[-1].split('.')[0]
3744        if type.startswith('timeout=')
3745                timeout = type.split('=')[1].to_int()
3746                type = ''
3747        endif
3748
3749        if condition == '' or conf.get(condition) == 1
3750                exe = executable(
3751                        name,
3752                        sources,
3753                        include_directories : incs,
3754                        link_with : link_with,
3755                        dependencies : [versiondep,
3756                                        dependencies],
3757                        c_args : defs,
3758                        build_by_default : want_tests != 'false',
3759                        install_rpath : rootlibexecdir,
3760                        install : install_tests,
3761                        install_dir : testsdir / type,
3762                        link_depends : runtest_env)
3763
3764                if type == 'manual'
3765                        message('@0@ is a manual test'.format(name))
3766                elif type == 'unsafe' and want_tests != 'unsafe'
3767                        message('@0@ is an unsafe test'.format(name))
3768                elif want_tests != 'false'
3769                        test(name, exe,
3770                             env : test_env,
3771                             timeout : timeout)
3772                endif
3773        else
3774                message('Not compiling @0@ because @1@ is not true'.format(name, condition))
3775        endif
3776endforeach
3777
3778exe = executable(
3779        'test-libsystemd-sym',
3780        test_libsystemd_sym_c,
3781        include_directories : includes,
3782        link_with : [libsystemd],
3783        build_by_default : want_tests != 'false',
3784        install : install_tests,
3785        install_dir : testsdir)
3786if want_tests != 'false'
3787        test('test-libsystemd-sym', exe)
3788endif
3789
3790exe = executable(
3791        'test-libsystemd-static-sym',
3792        test_libsystemd_sym_c,
3793        include_directories : includes,
3794        link_with : [install_libsystemd_static],
3795        dependencies : [threads], # threads is already included in dependencies on the library,
3796                                  # but does not seem to get propagated. Add here as a work-around.
3797        build_by_default : want_tests != 'false' and static_libsystemd_pic,
3798        install : install_tests and static_libsystemd_pic,
3799        install_dir : testsdir)
3800if want_tests != 'false' and static_libsystemd_pic
3801        test('test-libsystemd-static-sym', exe)
3802endif
3803
3804exe = executable(
3805        'test-libudev-sym',
3806        test_libudev_sym_c,
3807        include_directories : libudev_includes,
3808        c_args : ['-Wno-deprecated-declarations'] + test_cflags,
3809        link_with : [libudev],
3810        build_by_default : want_tests != 'false',
3811        install : install_tests,
3812        install_dir : testsdir)
3813if want_tests != 'false'
3814        test('test-libudev-sym', exe)
3815endif
3816
3817exe = executable(
3818        'test-libudev-static-sym',
3819        test_libudev_sym_c,
3820        include_directories : libudev_includes,
3821        c_args : ['-Wno-deprecated-declarations'] + test_cflags,
3822        link_with : [install_libudev_static],
3823        build_by_default : want_tests != 'false' and static_libudev_pic,
3824        install : install_tests and static_libudev_pic,
3825        install_dir : testsdir)
3826if want_tests != 'false' and static_libudev_pic
3827        test('test-libudev-static-sym', exe)
3828endif
3829
3830############################################################
3831
3832fuzzer_exes = []
3833
3834foreach tuple : fuzzers
3835        sources = tuple[0]
3836        link_with = tuple.length() > 1 and tuple[1].length() > 0 ? tuple[1] : [libshared]
3837        dependencies = tuple.length() > 2 ? tuple[2] : []
3838        incs = tuple.length() > 3 and tuple[3].length() > 0 ? tuple[3] : includes
3839        defs = tuple.length() > 4 ? tuple[4] : []
3840        link_args = []
3841
3842        if want_ossfuzz
3843                dependencies += fuzzing_engine
3844        elif want_libfuzzer
3845                if fuzzing_engine.found()
3846                        dependencies += fuzzing_engine
3847                else
3848                        link_args += ['-fsanitize=fuzzer']
3849                endif
3850        else
3851                sources += 'src/fuzz/fuzz-main.c'
3852        endif
3853
3854        # FIXME: Use fs.stem() with meson >= 0.54.0
3855        name = '@0@'.format(sources[0]).split('/')[-1].split('.')[0]
3856
3857        exe = executable(
3858                name,
3859                sources,
3860                include_directories : [incs, include_directories('src/fuzz')],
3861                link_with : link_with,
3862                dependencies : dependencies,
3863                c_args : defs + test_cflags,
3864                link_args: link_args,
3865                install : false,
3866                build_by_default : fuzzer_build)
3867        fuzzer_exes += exe
3868
3869        if want_tests != 'false'
3870                # Run the fuzz regression tests without any sanitizers enabled.
3871                # Additional invocations with sanitizers may be added below.
3872                foreach p : fuzz_regression_tests
3873                        b = p.split('/')[-2]
3874                        c = p.split('/')[-1]
3875
3876                        if b == name
3877                                test('@0@_@1@'.format(b, c),
3878                                     exe,
3879                                     suite : 'fuzzers',
3880                                     args : [project_source_root / p])
3881                        endif
3882                endforeach
3883        endif
3884endforeach
3885
3886alias_target('fuzzers', fuzzer_exes)
3887
3888############################################################
3889
3890subdir('modprobe.d')
3891subdir('sysctl.d')
3892subdir('sysusers.d')
3893subdir('tmpfiles.d')
3894subdir('hwdb.d')
3895subdir('units')
3896subdir('presets')
3897subdir('network')
3898subdir('man')
3899subdir('shell-completion/bash')
3900subdir('shell-completion/zsh')
3901subdir('docs/sysvinit')
3902subdir('docs/var-log')
3903
3904install_subdir('factory/etc',
3905               install_dir : factorydir)
3906subdir('factory/templates')
3907
3908if install_sysconfdir
3909        install_data('xorg/50-systemd-user.sh',
3910                     install_dir : xinitrcdir)
3911endif
3912install_data('LICENSE.GPL2',
3913             'LICENSE.LGPL2.1',
3914             'NEWS',
3915             'README',
3916             'docs/CODING_STYLE.md',
3917             'docs/DISTRO_PORTING.md',
3918             'docs/ENVIRONMENT.md',
3919             'docs/HACKING.md',
3920             'docs/TRANSIENT-SETTINGS.md',
3921             'docs/TRANSLATORS.md',
3922             'docs/UIDS-GIDS.md',
3923             'docs/GVARIANT-SERIALIZATION.md',
3924             install_dir : docdir)
3925
3926install_subdir('LICENSES',
3927               install_dir : docdir)
3928
3929meson.add_install_script('sh', '-c', mkdir_p.format(systemdstatedir))
3930meson.add_install_script('sh', '-c', 'touch $DESTDIR@0@'.format(prefixdir))
3931
3932############################################################
3933
3934# Ensure that changes to the docs/ directory do not break the
3935# basic Github pages build. But only run it in developer mode,
3936# as it might be fragile due to changes in the tooling, and it is
3937# not generally useful for users.
3938jekyll = find_program('jekyll', required : false)
3939if get_option('mode') == 'developer' and want_tests != 'false' and jekyll.found()
3940        test('github-pages',
3941             jekyll,
3942             suite : 'dist-check',
3943             args : ['build',
3944                     '--source', project_source_root / 'docs',
3945                     '--destination', project_build_root / '_site'])
3946endif
3947
3948############################################################
3949
3950check_help = find_program('tools/check-help.sh')
3951check_version = find_program('tools/check-version.sh')
3952
3953foreach exec : public_programs
3954        name = exec.full_path().split('/')[-1]
3955        if want_tests != 'false'
3956                test('check-help-' + name,
3957                     check_help,
3958                     suite : 'dist-check',
3959                     args : exec.full_path(),
3960                     depends: exec)
3961
3962                test('check-version-' + name,
3963                     check_version,
3964                     suite : 'dist-check',
3965                     args : [exec.full_path(),
3966                             meson.project_version()],
3967                     depends: exec)
3968        endif
3969endforeach
3970
3971############################################################
3972
3973check_directives_sh = find_program('tools/check-directives.sh')
3974
3975if want_tests != 'false'
3976        test('check-directives',
3977             check_directives_sh,
3978             suite : 'dist-check',
3979             args : [project_source_root, project_build_root])
3980endif
3981
3982############################################################
3983
3984# Enable tests for all supported sanitizers
3985foreach tuple : sanitizers
3986        sanitizer = tuple[0]
3987        build = tuple[1]
3988
3989        if cc.has_link_argument('-fsanitize=@0@'.format(sanitizer))
3990                prev = ''
3991                foreach p : fuzz_regression_tests
3992                        b = p.split('/')[-2]
3993                        c = p.split('/')[-1]
3994
3995                        name = '@0@:@1@'.format(b, sanitizer)
3996
3997                        if name != prev
3998                                if want_tests == 'false'
3999                                        message('Not compiling @0@ because tests is set to false'.format(name))
4000                                elif fuzz_tests
4001                                        exe = custom_target(
4002                                                name,
4003                                                output : name,
4004                                                depends : build,
4005                                                command : [ln, '-fs',
4006                                                           build.full_path() / b,
4007                                                           '@OUTPUT@'],
4008                                                build_by_default : true)
4009                                else
4010                                        message('Not compiling @0@ because fuzz-tests is set to false'.format(name))
4011                                endif
4012                        endif
4013                        prev = name
4014
4015                        if fuzz_tests
4016                                test('@0@_@1@_@2@'.format(b, c, sanitizer),
4017                                     env,
4018                                     suite : 'fuzz+san',
4019                                     env : ['UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1'],
4020                                     timeout : 60,
4021                                     args : [exe.full_path(),
4022                                             project_source_root / p])
4023                        endif
4024                endforeach
4025        endif
4026endforeach
4027
4028
4029############################################################
4030
4031if git.found()
4032        all_files = run_command(
4033                env, '-u', 'GIT_WORK_TREE',
4034                git, '--git-dir=@0@/.git'.format(project_source_root),
4035                     'ls-files', ':/*.[ch]',
4036                check : false)
4037        if all_files.returncode() == 0
4038                all_files = files(all_files.stdout().split())
4039
4040                custom_target(
4041                        'tags',
4042                        output : 'tags',
4043                        command : [env, 'etags', '-o', '@0@/TAGS'.format(project_source_root)] + all_files)
4044                run_target(
4045                        'ctags',
4046                        command : [env, 'ctags', '--tag-relative=never', '-o', '@0@/tags'.format(project_source_root)] + all_files)
4047        endif
4048endif
4049
4050if git.found()
4051        git_contrib_sh = find_program('tools/git-contrib.sh')
4052        run_target(
4053                'git-contrib',
4054                command : [git_contrib_sh])
4055endif
4056
4057if git.found()
4058        git_head = run_command(
4059                git, '--git-dir=@0@/.git'.format(project_source_root),
4060                     'rev-parse', 'HEAD',
4061                check : false).stdout().strip()
4062        git_head_short = run_command(
4063                git, '--git-dir=@0@/.git'.format(project_source_root),
4064                     'rev-parse', '--short=7', 'HEAD',
4065                check : false).stdout().strip()
4066
4067        run_target(
4068                'git-snapshot',
4069                command : [git, 'archive',
4070                           '-o', '@0@/systemd-@1@.tar.gz'.format(project_source_root,
4071                                                                 git_head_short),
4072                           '--prefix', 'systemd-@0@/'.format(git_head),
4073                           'HEAD'])
4074endif
4075
4076############################################################
4077
4078check_api_docs_sh = find_program('tools/check-api-docs.sh')
4079run_target(
4080        'check-api-docs',
4081        depends : [man, libsystemd, libudev],
4082        command : [check_api_docs_sh, libsystemd.full_path(), libudev.full_path()])
4083
4084alias_target('update-dbus-docs', update_dbus_docs)
4085alias_target('update-man-rules', update_man_rules)
4086
4087if not meson.is_cross_build()
4088        custom_target(
4089                'export-dbus-interfaces',
4090                output : fs.name(dbus_interfaces_dir),
4091                install : dbus_interfaces_dir != 'no',
4092                install_dir : fs.parent(dbus_interfaces_dir),
4093                command : [export_dbus_interfaces_py, '@OUTPUT@', dbus_programs])
4094endif
4095
4096############################################################
4097
4098alt_time_epoch = run_command('date', '-Is', '-u', '-d', '@@0@'.format(time_epoch),
4099                             check : true).stdout().strip()
4100
4101summary({
4102        'split /usr' :                      split_usr,
4103        'split bin-sbin' :                  split_bin,
4104        'prefix directory' :                prefixdir,
4105        'rootprefix directory' :            rootprefixdir,
4106        'sysconf directory' :               sysconfdir,
4107        'include directory' :               includedir,
4108        'lib directory' :                   libdir,
4109        'rootlib directory' :               rootlibdir,
4110        'SysV init scripts' :               sysvinit_path,
4111        'SysV rc?.d directories' :          sysvrcnd_path,
4112        'PAM modules directory' :           pamlibdir,
4113        'PAM configuration directory' :     pamconfdir,
4114        'libcryptsetup plugins directory' : libcryptsetup_plugins_dir,
4115        'RPM macros directory' :            rpmmacrosdir,
4116        'modprobe.d directory' :            modprobedir,
4117        'D-Bus policy directory' :          dbuspolicydir,
4118        'D-Bus session directory' :         dbussessionservicedir,
4119        'D-Bus system directory' :          dbussystemservicedir,
4120        'D-Bus interfaces directory' :      dbus_interfaces_dir,
4121        'bash completions directory' :      bashcompletiondir,
4122        'zsh completions directory' :       zshcompletiondir,
4123        'private shared lib version tag' :  shared_lib_tag,
4124        'extra start script' :              get_option('rc-local'),
4125        'debug shell' :                     '@0@ @ @1@'.format(get_option('debug-shell'),
4126                                                               get_option('debug-tty')),
4127        'system UIDs' :                     '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_UID_MAX'),
4128                                                                         conf.get('SYSTEM_ALLOC_UID_MIN')),
4129        'system GIDs' :                     '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
4130                                                                         conf.get('SYSTEM_ALLOC_GID_MIN')),
4131        'dynamic UIDs' :                    '@0@…@1@'.format(dynamic_uid_min, dynamic_uid_max),
4132        'container UID bases' :             '@0@…@1@'.format(container_uid_base_min, container_uid_base_max),
4133        'static UID/GID allocations' :      ' '.join(static_ugids),
4134        '/dev/kvm access mode' :            get_option('dev-kvm-mode'),
4135        'render group access mode' :        get_option('group-render-mode'),
4136        'certificate root directory' :      get_option('certificate-root'),
4137        'support URL' :                     support_url,
4138        'nobody user name' :                nobody_user,
4139        'nobody group name' :               nobody_group,
4140        'fallback hostname' :               get_option('fallback-hostname'),
4141        'default compression method' :      compression,
4142        'default DNSSEC mode' :             default_dnssec,
4143        'default DNS-over-TLS mode' :       default_dns_over_tls,
4144        'default mDNS mode' :               default_mdns,
4145        'default LLMNR mode' :              default_llmnr,
4146        'default DNS servers' :             dns_servers.split(' '),
4147        'default NTP servers' :             ntp_servers.split(' '),
4148        'default cgroup hierarchy' :        default_hierarchy,
4149        'default net.naming-scheme value' : default_net_naming_scheme,
4150        'default KillUserProcesses value' : kill_user_processes,
4151        'default locale' :                  default_locale,
4152        'default user $PATH' :
4153                default_user_path != '' ? default_user_path : '(same as system services)',
4154        'systemd service watchdog' :        service_watchdog == '' ? 'disabled' : service_watchdog,
4155        'time epoch' :                      '@0@ (@1@)'.format(time_epoch, alt_time_epoch)})
4156
4157# TODO:
4158# CFLAGS:   ${OUR_CFLAGS} ${CFLAGS}
4159# CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
4160# LDFLAGS:  ${OUR_LDFLAGS} ${LDFLAGS}
4161
4162found = []
4163missing = []
4164
4165foreach tuple : [
4166        # dependencies
4167        ['ACL'],
4168        ['AUDIT'],
4169        ['AppArmor'],
4170        ['IMA'],
4171        ['PAM'],
4172        ['SECCOMP'],
4173        ['SELinux'],
4174        ['SMACK'],
4175        ['blkid'],
4176        ['elfutils'],
4177        ['gcrypt'],
4178        ['gnutls'],
4179        ['libbpf'],
4180        ['libcryptsetup'],
4181        ['libcryptsetup-plugins'],
4182        ['libcurl'],
4183        ['libfdisk'],
4184        ['libfido2'],
4185        ['libidn'],
4186        ['libidn2'],
4187        ['libiptc'],
4188        ['microhttpd'],
4189        ['openssl'],
4190        ['p11kit'],
4191        ['pcre2'],
4192        ['pwquality'],
4193        ['qrencode'],
4194        ['tpm2'],
4195        ['xkbcommon'],
4196
4197        # compression libs
4198        ['zstd'],
4199        ['lz4'],
4200        ['xz'],
4201        ['zlib'],
4202        ['bzip2'],
4203
4204        # components
4205        ['backlight'],
4206        ['binfmt'],
4207        ['bpf-framework',         conf.get('BPF_FRAMEWORK') == 1],
4208        ['coredump'],
4209        ['environment.d'],
4210        ['efi'],
4211        ['gnu-efi'],
4212        ['firstboot'],
4213        ['hibernate'],
4214        ['homed'],
4215        ['hostnamed'],
4216        ['hwdb'],
4217        ['importd'],
4218        ['initrd'],
4219        ['kernel-install'],
4220        ['localed'],
4221        ['logind'],
4222        ['machined'],
4223        ['networkd'],
4224        ['nss-myhostname'],
4225        ['nss-mymachines'],
4226        ['nss-resolve'],
4227        ['nss-systemd'],
4228        ['oomd'],
4229        ['portabled'],
4230        ['pstore'],
4231        ['quotacheck'],
4232        ['randomseed'],
4233        ['repart'],
4234        ['resolve'],
4235        ['rfkill'],
4236        ['sysext'],
4237        ['systemd-analyze',       conf.get('ENABLE_ANALYZE') == 1],
4238        ['sysupdate'],
4239        ['sysusers'],
4240        ['timedated'],
4241        ['timesyncd'],
4242        ['tmpfiles'],
4243        ['userdb'],
4244        ['vconsole'],
4245        ['xdg-autostart'],
4246
4247        # optional features
4248        ['idn'],
4249        ['polkit'],
4250        ['nscd'],
4251        ['legacy-pkla',           install_polkit_pkla],
4252        ['kmod'],
4253        ['dbus'],
4254        ['glib'],
4255        ['tpm'],
4256        ['man pages',             want_man],
4257        ['html pages',            want_html],
4258        ['man page indices',      want_man and have_lxml],
4259        ['SysV compat'],
4260        ['compat-mutable-uid-boundaries'],
4261        ['utmp'],
4262        ['ldconfig'],
4263        ['adm group',             get_option('adm-group')],
4264        ['wheel group',           get_option('wheel-group')],
4265        ['gshadow'],
4266        ['debug hashmap'],
4267        ['debug mmap cache'],
4268        ['debug siphash'],
4269        ['valgrind',              conf.get('VALGRIND') == 1],
4270        ['trace logging',         conf.get('LOG_TRACE') == 1],
4271        ['install tests',         install_tests],
4272        ['link-udev-shared',      get_option('link-udev-shared')],
4273        ['link-systemctl-shared', get_option('link-systemctl-shared')],
4274        ['link-networkd-shared',  get_option('link-networkd-shared')],
4275        ['link-timesyncd-shared', get_option('link-timesyncd-shared')],
4276        ['link-boot-shared',      get_option('link-boot-shared')],
4277        ['fexecve'],
4278        ['standalone-binaries',   get_option('standalone-binaries')],
4279        ['coverage',              get_option('b_coverage')],
4280]
4281
4282        if tuple.length() >= 2
4283                cond = tuple[1]
4284        else
4285                ident1 = 'HAVE_' + tuple[0].underscorify().to_upper()
4286                ident2 = 'ENABLE_' + tuple[0].underscorify().to_upper()
4287                cond = conf.get(ident1, 0) == 1 or conf.get(ident2, 0) == 1
4288        endif
4289        if cond
4290                found += tuple[0]
4291        else
4292                missing += tuple[0]
4293        endif
4294endforeach
4295
4296if static_libsystemd == 'false'
4297        missing += 'static-libsystemd'
4298else
4299        found += 'static-libsystemd(@0@)'.format(static_libsystemd)
4300endif
4301
4302if static_libudev == 'false'
4303        missing += 'static-libudev'
4304else
4305        found += 'static-libudev(@0@)'.format(static_libudev)
4306endif
4307
4308if conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1 and conf.get('PREFER_OPENSSL') == 1
4309        found += 'cryptolib(openssl)'
4310elif conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1
4311        found += 'cryptolib(gcrypt)'
4312else
4313        missing += 'cryptolib'
4314endif
4315
4316if conf.get('DNS_OVER_TLS_USE_GNUTLS') == 1
4317        found += 'DNS-over-TLS(gnutls)'
4318elif conf.get('DNS_OVER_TLS_USE_OPENSSL') == 1
4319        found += 'DNS-over-TLS(openssl)'
4320else
4321        missing += 'DNS-over-TLS'
4322endif
4323
4324summary({
4325        'enabled' :  ', '.join(found),
4326        'disabled' : ', '.join(missing)},
4327        section : 'Features')
4328
4329if rootprefixdir != rootprefix_default
4330        warning('\n' +
4331                'Note that the installation prefix was changed to "@0@".\n'.format(rootprefixdir) +
4332                'systemd used fixed names for unit file directories and other paths, so anything\n' +
4333                'except the default ("@0@") is strongly discouraged.'.format(rootprefix_default))
4334endif
4335