udev: String substitutions can be done in ENV, too
[systemd_ALT.git] / meson.build
blobff3b56fe089cfd13e700b10bb28652049c9cb141
1 # SPDX-License-Identifier: LGPL-2.1-or-later
3 project('systemd', 'c',
4         version : '254',
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.60.0',
14        )
16 libsystemd_version = '0.37.0'
17 libudev_version = '1.7.7'
19 conf = configuration_data()
20 conf.set_quoted('PROJECT_URL', 'https://systemd.io/')
21 conf.set('PROJECT_VERSION', meson.project_version(),
22          description : 'Numerical project version (used where a simple number is expected)')
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
26 project_source_root = meson.current_source_dir()
27 project_build_root = meson.current_build_dir()
28 relative_source_path = run_command('realpath',
29                                    '--relative-to=@0@'.format(project_build_root),
30                                    project_source_root,
31                                    check : true).stdout().strip()
32 conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path)
34 conf.set10('BUILD_MODE_DEVELOPER', get_option('mode') == 'developer',
35            description : 'tailor build to development or release builds')
36 verification = get_option('log-message-verification')
37 if verification == 'auto'
38         verification = conf.get('BUILD_MODE_DEVELOPER') == 1
39 else
40         verification = verification == 'true'
41 endif
42 conf.set10('LOG_MESSAGE_VERIFICATION', verification)
44 want_ossfuzz = get_option('oss-fuzz')
45 want_libfuzzer = get_option('llvm-fuzz')
46 if want_ossfuzz and want_libfuzzer
47         error('only one of oss-fuzz or llvm-fuzz can be specified')
48 endif
50 skip_deps = want_ossfuzz or get_option('skip-deps')
51 fuzzer_build = want_ossfuzz or want_libfuzzer
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).
56 conf.set10('FUZZ_USE_SIZE_LIMIT', fuzzer_build)
58 # We'll set this to '1' for EFI builds in a different place.
59 conf.set10('SD_BOOT', false)
61 # Create a title-less summary section early, so it ends up first in the output.
62 # More items are added later after they have been detected.
63 summary({'build mode' : get_option('mode')})
65 #####################################################################
67 # Try to install the git pre-commit hook
68 add_git_hook_sh = find_program('tools/add-git-hook.sh', required : false)
69 if add_git_hook_sh.found()
70         git_hook = run_command(add_git_hook_sh, check : false)
71         if git_hook.returncode() == 0
72                 message(git_hook.stdout().strip())
73         endif
74 endif
76 #####################################################################
78 fs = import('fs')
79 if get_option('split-usr') == 'auto'
80         split_usr = not fs.is_symlink('/bin')
81 else
82         split_usr = get_option('split-usr') == 'true'
83 endif
84 if split_usr
85         warning('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n'
86                 + '                    split-usr mode is going to be removed\n' +
87                 '\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
88 endif
89 conf.set10('HAVE_SPLIT_USR', split_usr,
90            description : '/usr/bin and /bin directories are separate')
92 if get_option('split-bin') == 'auto'
93         split_bin = not fs.is_symlink('/usr/sbin')
94 else
95         split_bin = get_option('split-bin') == 'true'
96 endif
97 conf.set10('HAVE_SPLIT_BIN', split_bin,
98            description : 'bin and sbin directories are separate')
100 rootprefixdir = get_option('rootprefix')
101 # Unusual rootprefixdir values are used by some distros
102 # (see https://github.com/systemd/systemd/pull/7461).
103 rootprefix_default = split_usr ? '/' : '/usr'
104 if rootprefixdir == ''
105         rootprefixdir = rootprefix_default
106 endif
107 rootprefixdir_noslash = rootprefixdir == '/' ? '' : rootprefixdir
109 have_standalone_binaries = get_option('standalone-binaries')
111 sysvinit_path = get_option('sysvinit-path')
112 sysvrcnd_path = get_option('sysvrcnd-path')
113 conf.set10('HAVE_SYSV_COMPAT', sysvinit_path != '' and sysvrcnd_path != '',
114            description : 'SysV init scripts and rcN.d links are supported')
115 conf.set10('CREATE_LOG_DIRS', get_option('create-log-dirs'))
117 if get_option('hibernate') and not get_option('initrd')
118         error('hibernate depends on initrd')
119 endif
121 conf.set10('BUMP_PROC_SYS_FS_FILE_MAX', get_option('bump-proc-sys-fs-file-max'))
122 conf.set10('BUMP_PROC_SYS_FS_NR_OPEN',  get_option('bump-proc-sys-fs-nr-open'))
123 conf.set('HIGH_RLIMIT_NOFILE',          512*1024)
125 # Meson ignores the preceding arguments when joining paths if an absolute
126 # component is encountered, so this should canonicalize various paths when they
127 # are absolute or relative.
128 prefixdir = get_option('prefix')
129 if not prefixdir.startswith('/')
130         error('Prefix is not absolute: "@0@"'.format(prefixdir))
131 endif
132 if prefixdir != rootprefixdir and rootprefixdir != '/' and not prefixdir.strip('/').startswith(rootprefixdir.strip('/') + '/')
133         error('Prefix is not below root prefix (now rootprefix=@0@ prefix=@1@)'.format(
134                 rootprefixdir, prefixdir))
135 endif
137 bindir = prefixdir / get_option('bindir')
138 libdir = prefixdir / get_option('libdir')
139 sysconfdir = prefixdir / get_option('sysconfdir')
140 includedir = prefixdir / get_option('includedir')
141 datadir = prefixdir / get_option('datadir')
142 localstatedir = '/' / get_option('localstatedir')
144 rootbindir = rootprefixdir / 'bin'
145 rootsbindir = rootprefixdir / (split_bin ? 'sbin' : 'bin')
146 rootlibexecdir = rootprefixdir / 'lib/systemd'
148 rootlibdir = get_option('rootlibdir')
149 if rootlibdir == ''
150         # This will be a relative path if libdir is in prefix.
151         rootlibdir = get_option('libdir')
152 endif
153 if not rootlibdir.startswith('/')
154         # If we have a relative path, add rootprefixdir to the front.
155         rootlibdir = rootprefixdir / rootlibdir
156 endif
157 rootpkglibdir = rootlibdir / 'systemd'
159 install_sysconfdir = get_option('install-sysconfdir') != 'false'
160 install_sysconfdir_samples = get_option('install-sysconfdir') == 'true'
161 # Dirs of external packages
162 pkgconfigdatadir = get_option('pkgconfigdatadir') != '' ? get_option('pkgconfigdatadir') : datadir / 'pkgconfig'
163 pkgconfiglibdir = get_option('pkgconfiglibdir') != '' ? get_option('pkgconfiglibdir') : libdir / 'pkgconfig'
164 polkitpolicydir = datadir / 'polkit-1/actions'
165 polkitrulesdir = datadir / 'polkit-1/rules.d'
166 polkitpkladir = localstatedir / 'lib/polkit-1/localauthority/10-vendor.d'
167 xinitrcdir = get_option('xinitrcdir') != '' ? get_option('xinitrcdir') : sysconfdir / 'X11/xinit/xinitrc.d'
168 rpmmacrosdir = get_option('rpmmacrosdir')
169 if rpmmacrosdir != 'no'
170         rpmmacrosdir = prefixdir / rpmmacrosdir
171 endif
172 modprobedir = rootprefixdir / 'lib/modprobe.d'
174 # Our own paths
175 pkgdatadir = datadir / 'systemd'
176 environmentdir = prefixdir / 'lib/environment.d'
177 pkgsysconfdir = sysconfdir / 'systemd'
178 userunitdir = prefixdir / 'lib/systemd/user'
179 userpresetdir = prefixdir / 'lib/systemd/user-preset'
180 tmpfilesdir = prefixdir / 'lib/tmpfiles.d'
181 usertmpfilesdir = prefixdir / 'share/user-tmpfiles.d'
182 sysusersdir = prefixdir / 'lib/sysusers.d'
183 sysctldir = prefixdir / 'lib/sysctl.d'
184 binfmtdir = prefixdir / 'lib/binfmt.d'
185 modulesloaddir = prefixdir / 'lib/modules-load.d'
186 networkdir = rootprefixdir / 'lib/systemd/network'
187 systemgeneratordir = rootlibexecdir / 'system-generators'
188 usergeneratordir = prefixdir / 'lib/systemd/user-generators'
189 systemenvgeneratordir = prefixdir / 'lib/systemd/system-environment-generators'
190 userenvgeneratordir = prefixdir / 'lib/systemd/user-environment-generators'
191 systemshutdowndir = rootlibexecdir / 'system-shutdown'
192 systemsleepdir = rootlibexecdir / 'system-sleep'
193 systemunitdir = rootprefixdir / 'lib/systemd/system'
194 systempresetdir = rootprefixdir / 'lib/systemd/system-preset'
195 udevlibexecdir = rootprefixdir / 'lib/udev'
196 udevrulesdir = udevlibexecdir / 'rules.d'
197 udevhwdbdir = udevlibexecdir / 'hwdb.d'
198 catalogdir = prefixdir / 'lib/systemd/catalog'
199 kerneldir = prefixdir / 'lib/kernel'
200 kernelinstalldir = kerneldir / 'install.d'
201 factorydir = datadir / 'factory'
202 bootlibdir = prefixdir / 'lib/systemd/boot/efi'
203 testsdir = prefixdir / 'lib/systemd/tests'
204 unittestsdir = testsdir / 'unit-tests'
205 testdata_dir = testsdir / 'testdata'
206 systemdstatedir = localstatedir / 'lib/systemd'
207 catalogstatedir = systemdstatedir / 'catalog'
208 randomseeddir = localstatedir / 'lib/systemd'
209 profiledir = rootlibexecdir / 'portable' / 'profile'
210 ntpservicelistdir = rootprefixdir / 'lib/systemd/ntp-units.d'
211 credstoredir = prefixdir / 'lib/credstore'
213 docdir = get_option('docdir')
214 if docdir == ''
215         docdir = datadir / 'doc/systemd'
216 endif
218 pamlibdir = get_option('pamlibdir')
219 if pamlibdir == ''
220         pamlibdir = rootlibdir / 'security'
221 endif
223 pamconfdir = get_option('pamconfdir')
224 if pamconfdir == ''
225         pamconfdir = prefixdir / 'lib/pam.d'
226 endif
228 libcryptsetup_plugins_dir = get_option('libcryptsetup-plugins-dir')
229 if libcryptsetup_plugins_dir == ''
230         libcryptsetup_plugins_dir = rootlibdir / 'cryptsetup'
231 endif
233 memory_accounting_default = get_option('memory-accounting-default')
234 status_unit_format_default = get_option('status-unit-format-default')
235 if status_unit_format_default == 'auto'
236         status_unit_format_default = conf.get('BUILD_MODE_DEVELOPER') == 1 ? 'name' : 'description'
237 endif
239 conf.set_quoted('BINFMT_DIR',                                 binfmtdir)
240 conf.set_quoted('BOOTLIBDIR',                                 bootlibdir)
241 conf.set_quoted('CATALOG_DATABASE',                           catalogstatedir / 'database')
242 conf.set_quoted('CERTIFICATE_ROOT',                           get_option('certificate-root'))
243 conf.set_quoted('DOC_DIR',                                    docdir)
244 conf.set_quoted('DOCUMENT_ROOT',                              pkgdatadir / 'gatewayd')
245 conf.set_quoted('ENVIRONMENT_DIR',                            environmentdir)
246 conf.set_quoted('INCLUDE_DIR',                                includedir)
247 conf.set_quoted('LIBDIR',                                     libdir)
248 conf.set_quoted('MODPROBE_DIR',                               modprobedir)
249 conf.set_quoted('MODULESLOAD_DIR',                            modulesloaddir)
250 conf.set_quoted('PKGSYSCONFDIR',                              pkgsysconfdir)
251 conf.set_quoted('POLKIT_AGENT_BINARY_PATH',                   bindir / 'pkttyagent')
252 conf.set_quoted('PREFIX',                                     prefixdir)
253 conf.set_quoted('RANDOM_SEED',                                randomseeddir / 'random-seed')
254 conf.set_quoted('RANDOM_SEED_DIR',                            randomseeddir)
255 conf.set_quoted('RC_LOCAL_PATH',                              get_option('rc-local'))
256 conf.set_quoted('ROOTBINDIR',                                 rootbindir)
257 conf.set_quoted('ROOTLIBDIR',                                 rootlibdir)
258 conf.set_quoted('ROOTLIBEXECDIR',                             rootlibexecdir)
259 conf.set_quoted('ROOTPREFIX',                                 rootprefixdir)
260 conf.set_quoted('ROOTPREFIX_NOSLASH',                         rootprefixdir_noslash)
261 conf.set_quoted('SYSCONF_DIR',                                sysconfdir)
262 conf.set_quoted('SYSCTL_DIR',                                 sysctldir)
263 conf.set_quoted('SYSTEMCTL_BINARY_PATH',                      rootbindir / 'systemctl')
264 conf.set_quoted('SYSTEMD_BINARY_PATH',                        rootlibexecdir / 'systemd')
265 conf.set_quoted('SYSTEMD_CATALOG_DIR',                        catalogdir)
266 conf.set_quoted('SYSTEMD_CGROUPS_AGENT_PATH',                 rootlibexecdir / 'systemd-cgroups-agent')
267 conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH',                    rootlibexecdir / 'systemd-cryptsetup')
268 conf.set_quoted('SYSTEMD_EXPORT_PATH',                        rootlibexecdir / 'systemd-export')
269 conf.set_quoted('SYSTEMD_FSCK_PATH',                          rootlibexecdir / 'systemd-fsck')
270 conf.set_quoted('SYSTEMD_GROWFS_PATH',                        rootlibexecdir / 'systemd-growfs')
271 conf.set_quoted('SYSTEMD_HOMEWORK_PATH',                      rootlibexecdir / 'systemd-homework')
272 conf.set_quoted('SYSTEMD_IMPORT_FS_PATH',                     rootlibexecdir / 'systemd-import-fs')
273 conf.set_quoted('SYSTEMD_IMPORT_PATH',                        rootlibexecdir / 'systemd-import')
274 conf.set_quoted('SYSTEMD_INTEGRITYSETUP_PATH',                rootlibexecdir / 'systemd-integritysetup')
275 conf.set_quoted('SYSTEMD_KBD_MODEL_MAP',                      pkgdatadir / 'kbd-model-map')
276 conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP',              pkgdatadir / 'language-fallback-map')
277 conf.set_quoted('SYSTEMD_MAKEFS_PATH',                        rootlibexecdir / 'systemd-makefs')
278 conf.set_quoted('SYSTEMD_PULL_PATH',                          rootlibexecdir / 'systemd-pull')
279 conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH',               rootlibexecdir / 'systemd-shutdown')
280 conf.set_quoted('SYSTEMD_TEST_DATA',                          testdata_dir)
281 conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', rootbindir / 'systemd-tty-ask-password-agent')
282 conf.set_quoted('SYSTEMD_UPDATE_HELPER_PATH',                 rootlibexecdir / 'systemd-update-helper')
283 conf.set_quoted('SYSTEMD_USERWORK_PATH',                      rootlibexecdir / 'systemd-userwork')
284 conf.set_quoted('SYSTEMD_VERITYSETUP_PATH',                   rootlibexecdir / 'systemd-veritysetup')
285 conf.set_quoted('SYSTEM_CONFIG_UNIT_DIR',                     pkgsysconfdir / 'system')
286 conf.set_quoted('SYSTEM_DATA_UNIT_DIR',                       systemunitdir)
287 conf.set_quoted('SYSTEM_ENV_GENERATOR_DIR',                   systemenvgeneratordir)
288 conf.set_quoted('SYSTEM_GENERATOR_DIR',                       systemgeneratordir)
289 conf.set_quoted('SYSTEM_PRESET_DIR',                          systempresetdir)
290 conf.set_quoted('SYSTEM_SHUTDOWN_PATH',                       systemshutdowndir)
291 conf.set_quoted('SYSTEM_SLEEP_PATH',                          systemsleepdir)
292 conf.set_quoted('SYSTEM_SYSVINIT_PATH',                       sysvinit_path)
293 conf.set_quoted('SYSTEM_SYSVRCND_PATH',                       sysvrcnd_path)
294 conf.set_quoted('SYSUSERS_DIR',                               sysusersdir)
295 conf.set_quoted('TMPFILES_DIR',                               tmpfilesdir)
296 conf.set_quoted('USER_TMPFILES_DIR',                          usertmpfilesdir)
297 conf.set_quoted('UDEVLIBEXECDIR',                             udevlibexecdir)
298 conf.set_quoted('UDEV_HWDB_DIR',                              udevhwdbdir)
299 conf.set_quoted('UDEV_RULES_DIR',                             udevrulesdir)
300 conf.set_quoted('USER_CONFIG_UNIT_DIR',                       pkgsysconfdir / 'user')
301 conf.set_quoted('USER_DATA_UNIT_DIR',                         userunitdir)
302 conf.set_quoted('USER_ENV_GENERATOR_DIR',                     userenvgeneratordir)
303 conf.set_quoted('USER_GENERATOR_DIR',                         usergeneratordir)
304 conf.set_quoted('USER_KEYRING_PATH',                          pkgsysconfdir / 'import-pubring.gpg')
305 conf.set_quoted('USER_PRESET_DIR',                            userpresetdir)
306 conf.set_quoted('VENDOR_KEYRING_PATH',                        rootlibexecdir / 'import-pubring.gpg')
308 conf.set('ANSI_OK_COLOR',                                     'ANSI_' + get_option('ok-color').underscorify().to_upper())
309 conf.set10('ENABLE_URLIFY',                                   get_option('urlify'))
310 conf.set10('ENABLE_FEXECVE',                                  get_option('fexecve'))
311 conf.set10('MEMORY_ACCOUNTING_DEFAULT',                       memory_accounting_default)
312 conf.set('STATUS_UNIT_FORMAT_DEFAULT',                        'STATUS_UNIT_FORMAT_' + status_unit_format_default.to_upper())
313 conf.set_quoted('STATUS_UNIT_FORMAT_DEFAULT_STR',             status_unit_format_default)
315 conf.set('DEFAULT_TIMEOUT_SEC',                               get_option('default-timeout-sec'))
316 conf.set('DEFAULT_USER_TIMEOUT_SEC',                          get_option('default-user-timeout-sec'))
317 conf.set('UPDATE_HELPER_USER_TIMEOUT_SEC',                    get_option('update-helper-user-timeout-sec'))
319 conf.set10('ENABLE_FIRST_BOOT_FULL_PRESET',                   get_option('first-boot-full-preset'))
321 #####################################################################
323 cc = meson.get_compiler('c')
324 userspace_c_args = []
325 userspace_c_ld_args = []
326 meson_build_sh = find_program('tools/meson-build.sh')
328 want_tests = get_option('tests')
329 slow_tests = want_tests != 'false' and get_option('slow-tests')
330 fuzz_tests = want_tests != 'false' and get_option('fuzz-tests')
331 install_tests = want_tests != 'false' and get_option('install-tests')
333 if add_languages('cpp', native : false, required : fuzzer_build)
334         #  Used only for tests
335         cxx = meson.get_compiler('cpp')
336         cxx_cmd = ' '.join(cxx.cmd_array())
337 else
338         cxx_cmd = ''
339 endif
341 if want_libfuzzer
342         fuzzing_engine = meson.get_compiler('cpp').find_library('Fuzzer', required : false)
343         if fuzzing_engine.found()
344                 userspace_c_args += '-fsanitize-coverage=trace-pc-guard,trace-cmp'
345         elif cc.has_argument('-fsanitize=fuzzer-no-link')
346                 userspace_c_args += '-fsanitize=fuzzer-no-link'
347         else
348                 error('Looks like neither libFuzzer nor -fsanitize=fuzzer-no-link is supported')
349         endif
350 elif want_ossfuzz
351         fuzzing_engine = meson.get_compiler('cpp').find_library('FuzzingEngine')
352 endif
354 # Those generate many false positives, and we do not want to change the code to
355 # avoid them.
356 basic_disabled_warnings = [
357         '-Wno-missing-field-initializers',
358         '-Wno-unused-parameter',
359         '-Wno-nonnull-compare',
362 possible_common_cc_flags = [
363         '-Warray-bounds',     # clang
364         '-Warray-bounds=2',
365         '-Wdate-time',
366         '-Wendif-labels',
367         '-Werror=format=2',
368         '-Werror=format-signedness',
369         '-Werror=implicit-function-declaration',
370         '-Werror=implicit-int',
371         '-Werror=incompatible-pointer-types',
372         '-Werror=int-conversion',
373         '-Werror=missing-declarations',
374         '-Werror=missing-prototypes',
375         '-Werror=overflow',
376         '-Werror=override-init',
377         '-Werror=return-type',
378         '-Werror=shift-count-overflow',
379         '-Werror=shift-overflow=2',
380         '-Werror=strict-flex-arrays',
381         '-Werror=undef',
382         '-Wfloat-equal',
383         # gperf prevents us from enabling this because it does not emit fallthrough
384         # attribute with clang.
385         #'-Wimplicit-fallthrough',
386         '-Wimplicit-fallthrough=5',
387         '-Winit-self',
388         '-Wlogical-op',
389         '-Wmissing-include-dirs',
390         '-Wmissing-noreturn',
391         '-Wnested-externs',
392         '-Wold-style-definition',
393         '-Wpointer-arith',
394         '-Wredundant-decls',
395         '-Wshadow',
396         '-Wstrict-aliasing=2',
397         '-Wstrict-prototypes',
398         '-Wsuggest-attribute=noreturn',
399         '-Wunused-function',
400         '-Wwrite-strings',
401         '-Wzero-length-bounds',
403         # negative arguments are correctly detected starting with meson 0.46.
404         '-Wno-error=#warnings',  # clang
405         '-Wno-string-plus-int',  # clang
407         '-fdiagnostics-show-option',
408         '-fno-common',
409         '-fstack-protector',
410         '-fstack-protector-strong',
411         '-fstrict-flex-arrays',
412         '--param=ssp-buffer-size=4',
415 possible_common_link_flags = [
416         '-fstack-protector',
419 c_args = get_option('c_args')
421 # Our json library does not support -ffinite-math-only, which is enabled by -Ofast or -ffast-math.
422 if (('-Ofast' in c_args or '-ffast-math' in c_args or '-ffinite-math-only' in c_args) and '-fno-finite-math-only' not in c_args)
423         error('-Ofast, -ffast-math, or -ffinite-math-only is specified in c_args.')
424 endif
426 # Disable -Wmaybe-uninitialized when compiling with -Os/-O1/-O3/etc. There are
427 # too many false positives with gcc >= 8. Effectively, we only test with -O0
428 # and -O2; this should be enough to catch most important cases without too much
429 # busywork. See https://github.com/systemd/systemd/pull/19226.
430 if cc.get_id() == 'gcc' and (not '02'.contains(get_option('optimization')) or
431                              cc.version().version_compare('<10') or
432                              '-Os' in c_args or
433                              '-O1' in c_args or
434                              '-O3' in c_args or
435                              '-Og' in c_args)
436         possible_common_cc_flags += '-Wno-maybe-uninitialized'
437 endif
439 # Disable -Wno-unused-result with gcc, see
440 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425.
441 if cc.get_id() == 'gcc'
442         possible_common_cc_flags += '-Wno-unused-result'
443 endif
445 # --as-needed and --no-undefined are provided by meson by default,
446 # run 'meson configure' to see what is enabled
447 possible_link_flags = [
448         '-Wl,--fatal-warnings',
449         '-Wl,-z,now',
450         '-Wl,-z,relro',
453 if get_option('b_sanitize') == 'none'
454         possible_link_flags += '-Wl,--warn-common'
455 endif
457 if cc.get_id() == 'clang'
458         possible_common_cc_flags += [
459                 '-Wno-typedef-redefinition',
460                 '-Wno-gnu-variable-sized-type-not-at-end',
461         ]
462 endif
464 if get_option('mode') == 'release'
465         # We could enable 'pattern' for developer mode, but that can interfere with
466         # valgrind and sanitizer builds. Also, clang does not zero-initialize unions,
467         # breaking some of our code (https://reviews.llvm.org/D68115).
468         possible_common_cc_flags += '-ftrivial-auto-var-init=zero'
469 endif
471 possible_cc_flags = [
472         '-fno-strict-aliasing',
473         '-fstrict-flex-arrays=1',
474         '-fvisibility=hidden',
477 if get_option('buildtype') != 'debug'
478         possible_cc_flags += [
479                 '-ffunction-sections',
480                 '-fdata-sections',
481         ]
483         possible_link_flags += '-Wl,--gc-sections'
484 endif
486 if get_option('mode') == 'developer'
487         possible_cc_flags += '-fno-omit-frame-pointer'
488 endif
490 add_project_arguments(
491         cc.get_supported_arguments(
492                 basic_disabled_warnings,
493                 possible_common_cc_flags
494         ),
495         language : 'c')
497 add_project_link_arguments(
498         cc.get_supported_link_arguments(possible_common_link_flags),
499         language : 'c')
501 userspace_c_args += cc.get_supported_arguments(possible_cc_flags)
502 userspace_c_ld_args += cc.get_supported_link_arguments(possible_link_flags)
504 have = cc.has_argument('-Wzero-length-bounds')
505 conf.set10('HAVE_ZERO_LENGTH_BOUNDS', have)
507 if cc.compiles('''
508    #include <time.h>
509    #include <inttypes.h>
510    typedef uint64_t usec_t;
511    usec_t now(clockid_t clock);
512    int main(void) {
513            struct timespec now;
514            return 0;
515    }
516 ''', args: '-Werror=shadow', name : '-Werror=shadow with local shadowing')
517         add_project_arguments('-Werror=shadow', language : 'c')
518 endif
520 if cxx_cmd != ''
521         add_project_arguments(cxx.get_supported_arguments(basic_disabled_warnings), language : 'cpp')
522 endif
524 cpp = ' '.join(cc.cmd_array()) + ' -E'
526 has_wstringop_truncation = cc.has_argument('-Wstringop-truncation')
528 #####################################################################
529 # compilation result tests
531 conf.set('_GNU_SOURCE', 1)
532 conf.set('__SANE_USERSPACE_TYPES__', true)
533 conf.set10('HAVE_WSTRINGOP_TRUNCATION', has_wstringop_truncation)
535 conf.set('SIZEOF_DEV_T', cc.sizeof('dev_t', prefix : '#include <sys/types.h>'))
536 conf.set('SIZEOF_INO_T', cc.sizeof('ino_t', prefix : '#include <sys/types.h>'))
537 conf.set('SIZEOF_RLIM_T', cc.sizeof('rlim_t', prefix : '#include <sys/resource.h>'))
538 conf.set('SIZEOF_TIME_T', cc.sizeof('time_t', prefix : '#include <sys/time.h>'))
539 conf.set('SIZEOF_TIMEX_MEMBER', cc.sizeof('typeof(((struct timex *)0)->freq)', prefix : '#include <sys/timex.h>'))
541 long_max = cc.compute_int(
542         'LONG_MAX',
543         prefix : '#include <limits.h>',
544         guess : 0x7FFFFFFFFFFFFFFF,
545         high : 0x7FFFFFFFFFFFFFFF)
546 assert(long_max > 100000)
547 conf.set_quoted('LONG_MAX_STR', '@0@'.format(long_max))
549 decl_headers = '''
550 #include <dirent.h>
551 #include <uchar.h>
552 #include <sys/mount.h>
553 #include <sys/stat.h>
556 foreach decl : ['char16_t',
557                 'char32_t',
558                 'struct mount_attr',
559                 'struct statx',
560                 'struct dirent64',
561                ]
563         # We get -1 if the size cannot be determined
564         have = cc.sizeof(decl, prefix : decl_headers, args : '-D_GNU_SOURCE') > 0
566         if decl == 'struct mount_attr'
567                 if have
568                         want_linux_fs_h = false
569                 else
570                         have = cc.sizeof(decl,
571                                          prefix : decl_headers + '#include <linux/fs.h>',
572                                          args : '-D_GNU_SOURCE') > 0
573                         want_linux_fs_h = have
574                 endif
575         endif
577         if decl == 'struct statx'
578                 if have
579                         want_linux_stat_h = false
580                 else
581                         have = cc.sizeof(decl,
582                                          prefix : decl_headers + '#include <linux/stat.h>',
583                                          args : '-D_GNU_SOURCE') > 0
584                         want_linux_stat_h = have
585                 endif
586         endif
588         conf.set10('HAVE_' + decl.underscorify().to_upper(), have)
589 endforeach
591 conf.set10('WANT_LINUX_STAT_H', want_linux_stat_h)
592 conf.set10('WANT_LINUX_FS_H', want_linux_fs_h)
594 foreach ident : ['secure_getenv', '__secure_getenv']
595         conf.set10('HAVE_' + ident.to_upper(), cc.has_function(ident))
596 endforeach
598 foreach ident : [
599         ['memfd_create',      '''#include <sys/mman.h>'''],
600         ['gettid',            '''#include <sys/types.h>
601                                  #include <unistd.h>'''],
602         ['pivot_root',        '''#include <stdlib.h>
603                                  #include <unistd.h>'''],     # no known header declares pivot_root
604         ['ioprio_get',        '''#include <sched.h>'''],      # no known header declares ioprio_get
605         ['ioprio_set',        '''#include <sched.h>'''],      # no known header declares ioprio_set
606         ['name_to_handle_at', '''#include <sys/types.h>
607                                  #include <sys/stat.h>
608                                  #include <fcntl.h>'''],
609         ['setns',             '''#include <sched.h>'''],
610         ['renameat2',         '''#include <stdio.h>
611                                  #include <fcntl.h>'''],
612         ['kcmp',              '''#include <linux/kcmp.h>'''],
613         ['keyctl',            '''#include <sys/types.h>
614                                  #include <keyutils.h>'''],
615         ['copy_file_range',   '''#include <sys/syscall.h>
616                                  #include <unistd.h>'''],
617         ['bpf',               '''#include <sys/syscall.h>
618                                  #include <unistd.h>'''],
619         ['statx',             '''#include <sys/types.h>
620                                  #include <sys/stat.h>
621                                  #include <unistd.h>'''],
622         ['explicit_bzero' ,   '''#include <string.h>'''],
623         ['reallocarray',      '''#include <stdlib.h>'''],
624         ['set_mempolicy',     '''#include <stdlib.h>
625                                  #include <unistd.h>'''],
626         ['get_mempolicy',     '''#include <stdlib.h>
627                                  #include <unistd.h>'''],
628         ['pidfd_send_signal', '''#include <stdlib.h>
629                                  #include <unistd.h>
630                                  #include <signal.h>
631                                  #include <sys/wait.h>'''],
632         ['pidfd_open',        '''#include <stdlib.h>
633                                  #include <unistd.h>
634                                  #include <signal.h>
635                                  #include <sys/wait.h>'''],
636         ['rt_sigqueueinfo',   '''#include <stdlib.h>
637                                  #include <unistd.h>
638                                  #include <signal.h>
639                                  #include <sys/wait.h>'''],
640         ['rt_tgsigqueueinfo', '''#include <stdlib.h>
641                                  #include <unistd.h>
642                                  #include <signal.h>
643                                  #include <sys/wait.h>'''],
644         ['mallinfo',          '''#include <malloc.h>'''],
645         ['mallinfo2',         '''#include <malloc.h>'''],
646         ['execveat',          '''#include <unistd.h>'''],
647         ['close_range',       '''#include <unistd.h>'''],
648         ['epoll_pwait2',      '''#include <sys/epoll.h>'''],
649         ['mount_setattr',     '''#include <sys/mount.h>'''],
650         ['move_mount',        '''#include <sys/mount.h>'''],
651         ['open_tree',         '''#include <sys/mount.h>'''],
652         ['fsopen',            '''#include <sys/mount.h>'''],
653         ['fsconfig',          '''#include <sys/mount.h>'''],
654         ['fsmount',           '''#include <sys/mount.h>'''],
655         ['getdents64',        '''#include <dirent.h>'''],
658         have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
659         conf.set10('HAVE_' + ident[0].to_upper(), have)
660 endforeach
662 if cc.has_function('getrandom', prefix : '''#include <sys/random.h>''', args : '-D_GNU_SOURCE')
663         conf.set10('USE_SYS_RANDOM_H', true)
664         conf.set10('HAVE_GETRANDOM', true)
665 else
666         have = cc.has_function('getrandom', prefix : '''#include <linux/random.h>''')
667         conf.set10('USE_SYS_RANDOM_H', false)
668         conf.set10('HAVE_GETRANDOM', have)
669 endif
671 #####################################################################
673 version_tag = get_option('version-tag')
674 if version_tag != ''
675         vcs_data = configuration_data()
676         vcs_data.set('VCS_TAG', version_tag)
677         version_h = configure_file(configuration : vcs_data,
678                                    input : 'src/version/version.h.in',
679                                    output : 'version.h')
680 else
681         vcs_tagger = [
682                 project_source_root + '/tools/meson-vcs-tag.sh',
683                 project_source_root,
684                 meson.project_version()]
686         version_h = vcs_tag(
687                 input : 'src/version/version.h.in',
688                 output : 'version.h',
689                 command: vcs_tagger)
690 endif
692 versiondep = declare_dependency(
693         sources: version_h,
694         include_directories : include_directories('.'))
696 shared_lib_tag = get_option('shared-lib-tag')
697 if shared_lib_tag == ''
698         shared_lib_tag = meson.project_version()
699 endif
701 sh = find_program('sh')
702 echo = find_program('echo')
703 sed = find_program('sed')
704 awk = find_program('awk')
705 stat = find_program('stat')
706 ln = find_program('ln')
707 git = find_program('git', required : false)
708 env = find_program('env')
709 rsync = find_program('rsync', required : false)
710 diff = find_program('diff')
711 find = find_program('find')
712 meson_make_symlink = project_source_root + '/tools/meson-make-symlink.sh'
714 mkdir_p = 'mkdir -p $DESTDIR/@0@'
715 mkdir_p_mode = 'mkdir -p $DESTDIR/@0@ -m @1@'
717 # If -Dxxx-path option is found, use that. Otherwise, check in $PATH,
718 # /usr/sbin, /sbin, and fall back to the default from middle column.
719 progs = [['quotaon',    '/usr/sbin/quotaon'    ],
720          ['quotacheck', '/usr/sbin/quotacheck' ],
721          ['kmod',       '/usr/bin/kmod'        ],
722          ['kexec',      '/usr/sbin/kexec'      ],
723          ['sulogin',    '/usr/sbin/sulogin'    ],
724          ['mount',      '/usr/bin/mount',      'MOUNT_PATH'],
725          ['umount',     '/usr/bin/umount',     'UMOUNT_PATH'],
726          ['loadkeys',   '/usr/bin/loadkeys',   'KBD_LOADKEYS'],
727          ['setfont',    '/usr/bin/setfont',    'KBD_SETFONT'],
728          ['nologin',    '/usr/sbin/nologin',   ],
729         ]
730 foreach prog : progs
731         path = get_option(prog[0] + '-path')
732         if path != ''
733                 message('Using @1@ for @0@'.format(prog[0], path))
734         else
735                 exe = find_program(prog[0],
736                                    '/usr/sbin/' + prog[0],
737                                    '/sbin/' + prog[0],
738                                    required: false)
739                 path = exe.found() ? exe.full_path() : prog[1]
740         endif
741         name = prog.length() > 2 ? prog[2] : prog[0].to_upper()
742         conf.set_quoted(name, path)
743 endforeach
745 conf.set_quoted('TELINIT', get_option('telinit-path'))
747 if run_command(ln, '--relative', '--help', check : false).returncode() != 0
748         error('ln does not support --relative (added in coreutils 8.16)')
749 endif
751 ############################################################
753 gperf = find_program('gperf')
755 gperf_test_format = '''
756 #include <string.h>
757 const char * in_word_set(const char *, @0@);
760 gperf_snippet = run_command(sh, '-c', 'echo foo,bar | "$1" -L ANSI-C', '_', gperf,
761                             check : true)
762 gperf_test = gperf_test_format.format('size_t', gperf_snippet.stdout())
763 if cc.compiles(gperf_test)
764         gperf_len_type = 'size_t'
765 else
766         gperf_test = gperf_test_format.format('unsigned', gperf_snippet.stdout())
767         if cc.compiles(gperf_test)
768                 gperf_len_type = 'unsigned'
769         else
770                 error('unable to determine gperf len type')
771         endif
772 endif
773 message('gperf len type is @0@'.format(gperf_len_type))
774 conf.set('GPERF_LEN_TYPE', gperf_len_type,
775          description : 'The type of gperf "len" parameter')
777 ############################################################
779 if not cc.has_header('sys/capability.h')
780         error('POSIX caps headers not found')
781 endif
782 foreach header : ['crypt.h',
783                   'linux/memfd.h',
784                   'linux/vm_sockets.h',
785                   'sys/auxv.h',
786                   'threads.h',
787                   'valgrind/memcheck.h',
788                   'valgrind/valgrind.h',
789                   'linux/time_types.h',
790                   'sys/sdt.h',
791                  ]
793         conf.set10('HAVE_' + header.underscorify().to_upper(),
794                    cc.has_header(header))
795 endforeach
797 ############################################################
799 fallback_hostname = get_option('fallback-hostname')
800 if fallback_hostname == '' or fallback_hostname[0] == '.' or fallback_hostname[0] == '-'
801         error('Invalid fallback-hostname configuration')
802         # A more extensive test is done in test-hostname-util. Let's catch
803         # the most obvious errors here so we don't fail with an assert later.
804 endif
805 conf.set_quoted('FALLBACK_HOSTNAME', fallback_hostname)
807 default_hierarchy = get_option('default-hierarchy')
808 conf.set_quoted('DEFAULT_HIERARCHY_NAME', default_hierarchy,
809                 description : 'default cgroup hierarchy as string')
810 if default_hierarchy == 'legacy'
811         conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_NONE')
812 elif default_hierarchy == 'hybrid'
813         conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_SYSTEMD')
814 else
815         conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL')
816 endif
818 extra_net_naming_schemes = []
819 extra_net_naming_map = []
820 foreach scheme: get_option('extra-net-naming-schemes').split(',')
821         if scheme != ''
822                 name = scheme.split('=')[0]
823                 value = scheme.split('=')[1]
824                 NAME = name.underscorify().to_upper()
825                 VALUE = []
826                 foreach field: value.split('+')
827                         VALUE += 'NAMING_' + field.underscorify().to_upper()
828                 endforeach
829                 extra_net_naming_schemes += 'NAMING_@0@ = @1@,'.format(NAME, '|'.join(VALUE))
830                 extra_net_naming_map += '{ "@0@", NAMING_@1@ },'.format(name, NAME)
831         endif
832 endforeach
833 conf.set('EXTRA_NET_NAMING_SCHEMES', ' '.join(extra_net_naming_schemes))
834 conf.set('EXTRA_NET_NAMING_MAP', ' '.join(extra_net_naming_map))
836 default_net_naming_scheme = get_option('default-net-naming-scheme')
837 conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme)
838 if default_net_naming_scheme != 'latest'
839         conf.set('_DEFAULT_NET_NAMING_SCHEME_TEST',
840                  'NAMING_' + default_net_naming_scheme.underscorify().to_upper())
841 endif
843 time_epoch = get_option('time-epoch')
844 if time_epoch <= 0
845         time_epoch = run_command(sh, '-c', 'echo "$SOURCE_DATE_EPOCH"', check : true).stdout().strip()
846         if time_epoch == '' and git.found() and fs.is_dir('.git')
847                 # If we're in a git repository, use the creation time of the latest git tag.
848                 latest_tag = run_command(git, 'describe', '--abbrev=0', '--tags',
849                                          check : false)
850                 if latest_tag.returncode() == 0
851                         time_epoch = run_command(
852                                 git, 'log', '--no-show-signature', '-1', '--format=%at',
853                                      latest_tag.stdout().strip(),
854                                 check : false).stdout()
855                 endif
856         endif
857         if time_epoch == ''
858                 NEWS = files('NEWS')
859                 time_epoch = run_command(stat, '-c', '%Y', NEWS,
860                                          check : true).stdout()
861         endif
862         time_epoch = time_epoch.strip().to_int()
863 endif
864 conf.set('TIME_EPOCH', time_epoch)
866 conf.set('CLOCK_VALID_RANGE_USEC_MAX', get_option('clock-valid-range-usec-max'))
868 default_user_shell = get_option('default-user-shell')
869 conf.set_quoted('DEFAULT_USER_SHELL',      default_user_shell)
870 conf.set_quoted('DEFAULT_USER_SHELL_NAME', fs.name(default_user_shell))
872 foreach tuple : [['system-alloc-uid-min', 'SYS_UID_MIN', 1],  # Also see login.defs(5).
873                  ['system-uid-max',       'SYS_UID_MAX', 999],
874                  ['system-alloc-gid-min', 'SYS_GID_MIN', 1],
875                  ['system-gid-max',       'SYS_GID_MAX', 999]]
876         v = get_option(tuple[0])
877         if v <= 0
878                 v = run_command(
879                         awk,
880                         '/^\s*@0@\s+/ { uid=$2 } END { print uid }'.format(tuple[1]),
881                         '/etc/login.defs',
882                         check : false).stdout().strip()
883                 if v == ''
884                         v = tuple[2]
885                 else
886                         v = v.to_int()
887                 endif
888         endif
889         conf.set(tuple[0].underscorify().to_upper(), v)
890 endforeach
891 if conf.get('SYSTEM_ALLOC_UID_MIN') >= conf.get('SYSTEM_UID_MAX')
892         error('Invalid uid allocation range')
893 endif
894 if conf.get('SYSTEM_ALLOC_GID_MIN') >= conf.get('SYSTEM_GID_MAX')
895         error('Invalid gid allocation range')
896 endif
898 dynamic_uid_min = get_option('dynamic-uid-min')
899 dynamic_uid_max = get_option('dynamic-uid-max')
900 conf.set('DYNAMIC_UID_MIN', dynamic_uid_min)
901 conf.set('DYNAMIC_UID_MAX', dynamic_uid_max)
903 container_uid_base_min = get_option('container-uid-base-min')
904 container_uid_base_max = get_option('container-uid-base-max')
905 conf.set('CONTAINER_UID_BASE_MIN', container_uid_base_min)
906 conf.set('CONTAINER_UID_BASE_MAX', container_uid_base_max)
908 nobody_user = get_option('nobody-user')
909 nobody_group = get_option('nobody-group')
911 if not meson.is_cross_build()
912         getent_result = run_command('getent', 'passwd', '65534', check : false)
913         if getent_result.returncode() == 0
914                 name = getent_result.stdout().split(':')[0]
915                 if name != nobody_user
916                         warning('\n' +
917                                 '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) +
918                                 'Your build will result in an user table setup that is incompatible with the local system.')
919                 endif
920         endif
921         id_result = run_command('id', '-u', nobody_user, check : false)
922         if id_result.returncode() == 0
923                 id = id_result.stdout().strip().to_int()
924                 if id != 65534
925                         warning('\n' +
926                                 '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) +
927                                 'Your build will result in an user table setup that is incompatible with the local system.')
928                 endif
929         endif
931         getent_result = run_command('getent', 'group', '65534', check : false)
932         if getent_result.returncode() == 0
933                 name = getent_result.stdout().split(':')[0]
934                 if name != nobody_group
935                         warning('\n' +
936                                 '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) +
937                                 'Your build will result in an group table setup that is incompatible with the local system.')
938                 endif
939         endif
940         id_result = run_command('id', '-g', nobody_group, check : false)
941         if id_result.returncode() == 0
942                 id = id_result.stdout().strip().to_int()
943                 if id != 65534
944                         warning('\n' +
945                                 '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) +
946                                 'Your build will result in an group table setup that is incompatible with the local system.')
947                 endif
948         endif
949 endif
950 if nobody_user != nobody_group and not (nobody_user == 'nobody' and nobody_group == 'nogroup')
951         warning('\n' +
952                 'The configured user name "@0@" and group name "@0@" of the nobody user/group are not equivalent.\n'.format(nobody_user, nobody_group) +
953                 'Please re-check that both "nobody-user" and "nobody-group" options are correctly set.')
954 endif
956 conf.set_quoted('NOBODY_USER_NAME', nobody_user)
957 conf.set_quoted('NOBODY_GROUP_NAME', nobody_group)
959 static_ugids = []
960 foreach option : ['adm-gid',
961                   'audio-gid',
962                   'cdrom-gid',
963                   'dialout-gid',
964                   'disk-gid',
965                   'input-gid',
966                   'kmem-gid',
967                   'kvm-gid',
968                   'lp-gid',
969                   'render-gid',
970                   'sgx-gid',
971                   'tape-gid',
972                   'tty-gid',
973                   'users-gid',
974                   'utmp-gid',
975                   'video-gid',
976                   'wheel-gid',
977                   'systemd-journal-gid',
978                   'systemd-network-uid',
979                   'systemd-resolve-uid',
980                   'systemd-timesync-uid']
981         name = option.underscorify().to_upper()
982         val = get_option(option)
984         # Ensure provided GID argument is numeric, otherwise fall back to default assignment
985         conf.set(name, val > 0 ? val : '-')
986         if val > 0
987                 static_ugids += '@0@:@1@'.format(option, val)
988         endif
989 endforeach
991 conf.set10('ENABLE_ADM_GROUP', get_option('adm-group'))
992 conf.set10('ENABLE_WHEEL_GROUP', get_option('wheel-group'))
994 dev_kvm_mode = get_option('dev-kvm-mode')
995 conf.set_quoted('DEV_KVM_MODE', dev_kvm_mode) # FIXME: convert to 0o… notation
996 conf.set10('DEV_KVM_UACCESS', dev_kvm_mode != '0666')
997 group_render_mode = get_option('group-render-mode')
998 conf.set_quoted('GROUP_RENDER_MODE', group_render_mode)
999 conf.set10('GROUP_RENDER_UACCESS', group_render_mode != '0666')
1001 kill_user_processes = get_option('default-kill-user-processes')
1002 conf.set10('KILL_USER_PROCESSES', kill_user_processes)
1004 dns_servers = get_option('dns-servers')
1005 conf.set_quoted('DNS_SERVERS', dns_servers)
1007 ntp_servers = get_option('ntp-servers')
1008 conf.set_quoted('NTP_SERVERS', ntp_servers)
1010 default_locale = get_option('default-locale')
1011 conf.set_quoted('SYSTEMD_DEFAULT_LOCALE', default_locale)
1013 nspawn_locale = get_option('nspawn-locale')
1014 conf.set_quoted('SYSTEMD_NSPAWN_LOCALE', nspawn_locale)
1016 default_keymap = get_option('default-keymap')
1017 if default_keymap == ''
1018         # We canonicalize empty keymap to '@kernel', as it makes the default value
1019         # in the factory provided /etc/vconsole.conf more obvious.
1020         default_keymap = '@kernel'
1021 endif
1022 conf.set_quoted('SYSTEMD_DEFAULT_KEYMAP', default_keymap)
1024 localegen_path = get_option('localegen-path')
1025 if localegen_path != ''
1026         conf.set_quoted('LOCALEGEN_PATH', localegen_path)
1027 endif
1028 conf.set10('HAVE_LOCALEGEN', localegen_path != '')
1030 conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
1032 service_watchdog = get_option('service-watchdog')
1033 watchdog_value = service_watchdog == '' ? '' : 'WatchdogSec=' + service_watchdog
1034 conf.set_quoted('SERVICE_WATCHDOG', watchdog_value)
1036 conf.set_quoted('SUSHELL', get_option('debug-shell'))
1037 conf.set_quoted('DEBUGTTY', get_option('debug-tty'))
1039 enable_debug_hashmap = false
1040 enable_debug_mmap_cache = false
1041 enable_debug_siphash = false
1042 foreach name : get_option('debug-extra')
1043         if name == 'hashmap'
1044                 enable_debug_hashmap = true
1045         elif name == 'mmap-cache'
1046                 enable_debug_mmap_cache = true
1047         elif name == 'siphash'
1048                 enable_debug_siphash = true
1049         else
1050                 message('unknown debug option "@0@", ignoring'.format(name))
1051         endif
1052 endforeach
1053 conf.set10('ENABLE_DEBUG_HASHMAP', enable_debug_hashmap)
1054 conf.set10('ENABLE_DEBUG_MMAP_CACHE', enable_debug_mmap_cache)
1055 conf.set10('ENABLE_DEBUG_SIPHASH', enable_debug_siphash)
1056 conf.set10('LOG_TRACE', get_option('log-trace'))
1058 default_user_path = get_option('user-path')
1059 if default_user_path != ''
1060         conf.set_quoted('DEFAULT_USER_PATH', default_user_path)
1061 endif
1063 #####################################################################
1065 threads = dependency('threads')
1066 librt = cc.find_library('rt')
1067 libm = cc.find_library('m')
1068 libdl = cc.find_library('dl')
1069 libcrypt = dependency('libcrypt', 'libxcrypt', required : false)
1070 if not libcrypt.found()
1071         # fallback to use find_library() if libcrypt is provided by glibc, e.g. for LibreELEC.
1072         libcrypt = cc.find_library('crypt')
1073 endif
1074 libcap = dependency('libcap')
1076 # On some architectures, libatomic is required. But on some installations,
1077 # it is found, but actual linking fails. So let's try to use it opportunistically.
1078 # If it is installed, but not needed, it will be dropped because of --as-needed.
1079 if cc.links('''int main(int argc, char **argv) { return 0; }''',
1080             args : '-latomic',
1081             name : 'libatomic')
1082         libatomic = declare_dependency(link_args : '-latomic')
1083 else
1084         libatomic = []
1085 endif
1087 crypt_header = conf.get('HAVE_CRYPT_H') == 1 ? '''#include <crypt.h>''' : '''#include <unistd.h>'''
1088 foreach ident : [
1089         ['crypt_ra',               crypt_header],
1090         ['crypt_preferred_method', crypt_header],
1091         ['crypt_gensalt_ra',       crypt_header]]
1093         have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE',
1094                                dependencies : libcrypt)
1095         conf.set10('HAVE_' + ident[0].to_upper(), have)
1096 endforeach
1098 want_bpf_framework = get_option('bpf-framework')
1099 bpf_compiler = get_option('bpf-compiler')
1100 bpf_framework_required = want_bpf_framework == 'true'
1102 libbpf_version_requirement = '>= 0.1.0'
1103 if bpf_compiler == 'gcc'
1104         libbpf_version_requirement = '>= 1.0.0'
1105 endif
1106 libbpf = dependency('libbpf', required : bpf_framework_required, version : libbpf_version_requirement)
1107 conf.set10('HAVE_LIBBPF', libbpf.found())
1109 bpftool_strip_version_requirement = '>= 5.13.0'
1110 if bpf_compiler == 'gcc'
1111         bpftool_strip_version_requirement = '>= 7.0.0'
1112 endif
1114 if want_bpf_framework == 'false' or not libbpf.found() or skip_deps
1115         conf.set10('BPF_FRAMEWORK', false)
1116 else
1117         clang_found = false
1118         clang_supports_bpf = false
1119         bpf_gcc_found = false
1120         bpftool_strip = false
1121         deps_found = false
1123         if bpf_compiler == 'clang'
1124                 # Support 'versioned' clang/llvm-strip binaries, as seen on Debian/Ubuntu
1125                 # (like clang-10/llvm-strip-10)
1126                 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')
1127                         r = find_program('clang', required : bpf_framework_required, version : '>= 10.0.0')
1128                         clang_found = r.found()
1129                         if clang_found
1130                                 clang = r.full_path()
1131                         endif
1132                 else
1133                         clang_found = true
1134                         clang = cc.cmd_array()
1135                 endif
1137                 if clang_found
1138                         # Check if 'clang -target bpf' is supported.
1139                         clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus', check : false).returncode() == 0
1140                 endif
1141         elif bpf_compiler == 'gcc'
1142                 bpf_gcc = find_program('bpf-gcc',
1143                                        'bpf-none-gcc',
1144                                        required : true,
1145                                        version : '>= 13.1.0')
1146                 bpf_gcc_found = bpf_gcc.found()
1147         endif
1149         if clang_supports_bpf or bpf_gcc_found
1150                 # Debian installs this in /usr/sbin/ which is not in $PATH.
1151                 # We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian.
1152                 # We use 'bpftool gen object' subcommand for bpftool strip, it was added by d80b2fcbe0a023619e0fc73112f2a02c2662f6ab (v5.13).
1153                 bpftool_strip_required = bpf_framework_required and bpf_compiler == 'gcc'
1154                 bpftool = find_program('bpftool',
1155                                        '/usr/sbin/bpftool',
1156                                        required : bpftool_strip_required,
1157                                        version : bpftool_strip_version_requirement)
1159                 if bpftool.found()
1160                         bpftool_strip = true
1161                         deps_found = true
1162                 elif bpf_compiler == 'clang'
1163                         # We require the 'bpftool gen skeleton' subcommand, it was added by 985ead416df39d6fe8e89580cc1db6aa273e0175 (v5.6).
1164                         bpftool = find_program('bpftool',
1165                                                '/usr/sbin/bpftool',
1166                                                required : bpf_framework_required,
1167                                                version : '>= 5.6.0')
1168                 endif
1170                 # We use `llvm-strip` as a fallback if `bpftool gen object` strip support is not available.
1171                 if not bpftool_strip and bpftool.found() and clang_supports_bpf
1172                         if not meson.is_cross_build()
1173                                 llvm_strip_bin = run_command(clang, '--print-prog-name', 'llvm-strip',
1174                                                              check : true).stdout().strip()
1175                         else
1176                                 llvm_strip_bin = 'llvm-strip'
1177                         endif
1178                         llvm_strip = find_program(llvm_strip_bin, required : bpf_framework_required, version : '>= 10.0.0')
1179                         deps_found = llvm_strip.found()
1180                 endif
1181         endif
1183         # Can build BPF program from source code in restricted C
1184         conf.set10('BPF_FRAMEWORK', deps_found)
1185 endif
1187 libmount = dependency('mount',
1188                       version : fuzzer_build ? '>= 0' : '>= 2.30')
1190 want_libfdisk = get_option('fdisk')
1191 if want_libfdisk != 'false' and not skip_deps
1192         libfdisk = dependency('fdisk',
1193                               version : '>= 2.32',
1194                               required : want_libfdisk == 'true')
1195         have = libfdisk.found()
1196 else
1197         have = false
1198         libfdisk = []
1199 endif
1200 conf.set10('HAVE_LIBFDISK', have)
1202 want_passwdqc = get_option('passwdqc')
1203 want_pwquality = get_option('pwquality')
1204 if want_passwdqc == 'true' and want_pwquality == 'true'
1205         error('passwdqc and pwquality cannot be requested simultaneously')
1206 endif
1208 if want_pwquality != 'false' and want_passwdqc != 'true' and not skip_deps
1209         libpwquality = dependency('pwquality',
1210                                   version : '>= 1.4.1',
1211                                   required : want_pwquality == 'true')
1212         have = libpwquality.found()
1213 else
1214         have = false
1215         libpwquality = []
1216 endif
1217 conf.set10('HAVE_PWQUALITY', have)
1219 if not have and want_passwdqc != 'false' and not skip_deps
1220         libpasswdqc = dependency('passwdqc',
1221                                  required : want_passwdqc == 'true')
1222         have = libpasswdqc.found()
1223 else
1224         have = false
1225         libpasswdqc = []
1226 endif
1227 conf.set10('HAVE_PASSWDQC', have)
1229 want_seccomp = get_option('seccomp')
1230 if want_seccomp != 'false' and not skip_deps
1231         libseccomp = dependency('libseccomp',
1232                                 version : '>= 2.3.1',
1233                                 required : want_seccomp == 'true')
1234         have = libseccomp.found()
1235 else
1236         have = false
1237         libseccomp = []
1238 endif
1239 conf.set10('HAVE_SECCOMP', have)
1241 want_selinux = get_option('selinux')
1242 if want_selinux != 'false' and not skip_deps
1243         libselinux = dependency('libselinux',
1244                                 version : '>= 2.1.9',
1245                                 required : want_selinux == 'true')
1246         have = libselinux.found()
1247 else
1248         have = false
1249         libselinux = []
1250 endif
1251 conf.set10('HAVE_SELINUX', have)
1253 want_apparmor = get_option('apparmor')
1254 if want_apparmor != 'false' and not skip_deps
1255         libapparmor = dependency('libapparmor',
1256                                  version : '>= 2.13',
1257                                  required : want_apparmor == 'true')
1258         have = libapparmor.found()
1259 else
1260         have = false
1261         libapparmor = []
1262 endif
1263 conf.set10('HAVE_APPARMOR', have)
1265 have = get_option('smack') and get_option('smack-run-label') != ''
1266 conf.set10('HAVE_SMACK_RUN_LABEL', have)
1267 if have
1268         conf.set_quoted('SMACK_RUN_LABEL', get_option('smack-run-label'))
1269 endif
1271 have = get_option('smack') and get_option('smack-default-process-label') != ''
1272 if have
1273         conf.set_quoted('SMACK_DEFAULT_PROCESS_LABEL', get_option('smack-default-process-label'))
1274 endif
1276 want_polkit = get_option('polkit')
1277 install_polkit = false
1278 install_polkit_pkla = false
1279 if want_polkit != 'false' and not skip_deps
1280         install_polkit = true
1282         libpolkit = dependency('polkit-gobject-1',
1283                                required : false)
1284         if libpolkit.found() and libpolkit.version().version_compare('< 0.106')
1285                 message('Old polkit detected, will install pkla files')
1286                 install_polkit_pkla = true
1287         endif
1288 endif
1289 conf.set10('ENABLE_POLKIT', install_polkit)
1291 want_acl = get_option('acl')
1292 if want_acl != 'false' and not skip_deps
1293         libacl = dependency('libacl', required : want_acl == 'true')
1294         have = libacl.found()
1295 else
1296         have = false
1297         libacl = []
1298 endif
1299 conf.set10('HAVE_ACL', have)
1301 want_audit = get_option('audit')
1302 if want_audit != 'false' and not skip_deps
1303         libaudit = dependency('audit', required : want_audit == 'true')
1304         have = libaudit.found()
1305 else
1306         have = false
1307         libaudit = []
1308 endif
1309 conf.set10('HAVE_AUDIT', have)
1311 want_blkid = get_option('blkid')
1312 if want_blkid != 'false' and not skip_deps
1313         libblkid = dependency('blkid', required : want_blkid == 'true')
1314         have = libblkid.found()
1316         conf.set10('HAVE_BLKID_PROBE_SET_HINT',
1317                    have and cc.has_function('blkid_probe_set_hint', dependencies : libblkid))
1318 else
1319         have = false
1320         libblkid = []
1321 endif
1322 conf.set10('HAVE_BLKID', have)
1324 want_kmod = get_option('kmod')
1325 if want_kmod != 'false' and not skip_deps
1326         libkmod = dependency('libkmod',
1327                              version : '>= 15',
1328                              required : want_kmod == 'true')
1329         have = libkmod.found()
1330 else
1331         have = false
1332         libkmod = []
1333 endif
1334 conf.set10('HAVE_KMOD', have)
1336 want_xenctrl = get_option('xenctrl')
1337 if want_xenctrl != 'false' and not skip_deps
1338         libxenctrl = dependency('xencontrol',
1339                                 version : '>= 4.9',
1340                                 required : want_xenctrl == 'true')
1341         have = libxenctrl.found()
1342 else
1343         have = false
1344         libxenctrl = []
1345 endif
1346 conf.set10('HAVE_XENCTRL', have)
1348 want_pam = get_option('pam')
1349 if want_pam != 'false' and not skip_deps
1350         libpam = dependency('pam', required : false)
1351         if not libpam.found()
1352                 # Debian older than bookworm and Ubuntu older than 22.10 do not provide the .pc file.
1353                 libpam = cc.find_library('pam', required : want_pam == 'true')
1354         endif
1355         libpam_misc = dependency('pam_misc', required : false)
1356         if not libpam_misc.found()
1357                 libpam_misc = cc.find_library('pam_misc', required : want_pam == 'true')
1358         endif
1359         have = libpam.found() and libpam_misc.found()
1360 else
1361         have = false
1362         libpam = []
1363         libpam_misc = []
1364 endif
1365 conf.set10('HAVE_PAM', have)
1367 want_microhttpd = get_option('microhttpd')
1368 if want_microhttpd != 'false' and not skip_deps
1369         libmicrohttpd = dependency('libmicrohttpd',
1370                                    version : '>= 0.9.33',
1371                                    required : want_microhttpd == 'true')
1372         have = libmicrohttpd.found()
1373 else
1374         have = false
1375         libmicrohttpd = []
1376 endif
1377 conf.set10('HAVE_MICROHTTPD', have)
1379 want_libcryptsetup = get_option('libcryptsetup')
1380 want_libcryptsetup_plugins = get_option('libcryptsetup-plugins')
1382 if want_libcryptsetup_plugins == 'true' and want_libcryptsetup == 'false'
1383         error('libcryptsetup-plugins can not be requested without libcryptsetup')
1384 endif
1386 if want_libcryptsetup != 'false' and not skip_deps
1387         libcryptsetup = dependency('libcryptsetup',
1388                                    version : want_libcryptsetup_plugins == 'true' ? '>= 2.4.0' : '>= 2.0.1',
1389                                    required : want_libcryptsetup == 'true' or want_libcryptsetup_plugins == 'true')
1390         have = libcryptsetup.found()
1392         foreach ident : ['crypt_set_metadata_size',
1393                          'crypt_activate_by_signed_key',
1394                          'crypt_token_max',
1395                          'crypt_reencrypt_init_by_passphrase',
1396                          'crypt_reencrypt',
1397                          'crypt_set_data_offset']
1398                 have_ident = have and cc.has_function(
1399                         ident,
1400                         prefix : '#include <libcryptsetup.h>',
1401                         dependencies : libcryptsetup)
1402                 conf.set10('HAVE_' + ident.to_upper(), have_ident)
1403         endforeach
1404 else
1405         have = false
1406         libcryptsetup = []
1407 endif
1408 conf.set10('HAVE_LIBCRYPTSETUP', have)
1410 if want_libcryptsetup_plugins != 'false' and not skip_deps
1411         have = (cc.has_function(
1412                         'crypt_activate_by_token_pin',
1413                         prefix : '#include <libcryptsetup.h>',
1414                         dependencies : libcryptsetup) and
1415                 cc.has_function(
1416                         'crypt_token_external_path',
1417                         prefix : '#include <libcryptsetup.h>',
1418                         dependencies : libcryptsetup))
1419 else
1420         have = false
1421 endif
1422 conf.set10('HAVE_LIBCRYPTSETUP_PLUGINS', have)
1424 want_libcurl = get_option('libcurl')
1425 if want_libcurl != 'false' and not skip_deps
1426         libcurl = dependency('libcurl',
1427                              version : '>= 7.32.0',
1428                              required : want_libcurl == 'true')
1429         have = libcurl.found()
1430 else
1431         have = false
1432         libcurl = []
1433 endif
1434 conf.set10('HAVE_LIBCURL', have)
1435 conf.set10('CURL_NO_OLDIES', conf.get('BUILD_MODE_DEVELOPER') == 1)
1437 want_libidn = get_option('libidn')
1438 want_libidn2 = get_option('libidn2')
1439 if want_libidn == 'true' and want_libidn2 == 'true'
1440         error('libidn and libidn2 cannot be requested simultaneously')
1441 endif
1443 if want_libidn2 != 'false' and want_libidn != 'true' and not skip_deps
1444         libidn = dependency('libidn2',
1445                             required : want_libidn2 == 'true')
1446         have = libidn.found()
1447 else
1448         have = false
1449         libidn = []
1450 endif
1451 conf.set10('HAVE_LIBIDN2', have)
1452 if not have and want_libidn != 'false' and not skip_deps
1453         # libidn is used for both libidn and libidn2 objects
1454         libidn = dependency('libidn',
1455                             required : want_libidn == 'true')
1456         have = libidn.found()
1457 else
1458         have = false
1459 endif
1460 conf.set10('HAVE_LIBIDN', have)
1462 want_libiptc = get_option('libiptc')
1463 if want_libiptc != 'false' and not skip_deps
1464         libiptc = dependency('libiptc',
1465                              required : want_libiptc == 'true')
1466         have = libiptc.found()
1467 else
1468         have = false
1469         libiptc = []
1470 endif
1471 conf.set10('HAVE_LIBIPTC', have)
1473 want_qrencode = get_option('qrencode')
1474 if want_qrencode != 'false' and not skip_deps
1475         libqrencode = dependency('libqrencode',
1476                                  version : '>= 3',
1477                                  required : want_qrencode == 'true')
1478         have = libqrencode.found()
1479 else
1480         have = false
1481         libqrencode = []
1482 endif
1483 conf.set10('HAVE_QRENCODE', have)
1485 want_gcrypt = get_option('gcrypt')
1486 if want_gcrypt != 'false' and not skip_deps
1487         libgcrypt = dependency('libgcrypt', required : want_gcrypt == 'true')
1488         libgpg_error = dependency('gpg-error', required : false)
1489         if not libgpg_error.found()
1490                 # CentOS 8 does not provide the .pc file.
1491                 libgpg_error = cc.find_library('gpg-error', required : want_gcrypt == 'true')
1492         endif
1493         have = libgcrypt.found() and libgpg_error.found()
1494 else
1495         have = false
1496 endif
1497 if not have
1498         # link to neither of the libs if one is not found
1499         libgcrypt = []
1500         libgpg_error = []
1501 endif
1502 conf.set10('HAVE_GCRYPT', have)
1504 want_gnutls = get_option('gnutls')
1505 if want_gnutls != 'false' and not skip_deps
1506         libgnutls = dependency('gnutls',
1507                                version : '>= 3.1.4',
1508                                required : want_gnutls == 'true')
1509         have = libgnutls.found()
1510 else
1511         have = false
1512         libgnutls = []
1513 endif
1514 conf.set10('HAVE_GNUTLS', have)
1516 want_openssl = get_option('openssl')
1517 if want_openssl != 'false' and not skip_deps
1518         libopenssl = dependency('openssl',
1519                                 version : '>= 1.1.0',
1520                                 required : want_openssl == 'true')
1521         have = libopenssl.found()
1522 else
1523         have = false
1524         libopenssl = []
1525 endif
1526 conf.set10('HAVE_OPENSSL', have)
1528 want_p11kit = get_option('p11kit')
1529 if want_p11kit != 'false' and not skip_deps
1530         libp11kit = dependency('p11-kit-1',
1531                                version : '>= 0.23.3',
1532                                required : want_p11kit == 'true')
1533         have = libp11kit.found()
1534         libp11kit_cflags = libp11kit.partial_dependency(includes: true, compile_args: true)
1535 else
1536         have = false
1537         libp11kit_cflags = []
1538         libp11kit = []
1539 endif
1540 conf.set10('HAVE_P11KIT', have)
1542 want_libfido2 = get_option('libfido2')
1543 if want_libfido2 != 'false' and not skip_deps
1544         if conf.get('HAVE_OPENSSL') == 1
1545                 libfido2 = dependency('libfido2',
1546                                       required : want_libfido2 == 'true')
1547                 have = libfido2.found()
1548         elif want_libfido2 == 'true'
1549                 error('libfido2=true requires openssl')
1550         else
1551                 have = false
1552                 libfido2 = []
1553         endif
1554 else
1555         have = false
1556         libfido2 = []
1557 endif
1558 conf.set10('HAVE_LIBFIDO2', have)
1560 want_tpm2 = get_option('tpm2')
1561 if want_tpm2 != 'false' and not skip_deps
1562         tpm2 = dependency('tss2-esys tss2-rc tss2-mu tss2-tcti-device',
1563                           required : want_tpm2 == 'true')
1564         have = tpm2.found()
1565         have_esys3 = tpm2.version().version_compare('>= 3.0.0')
1566 else
1567         have = false
1568         have_esys3 = false
1569         tpm2 = []
1570 endif
1571 conf.set10('HAVE_TPM2', have)
1572 conf.set10('HAVE_TSS2_ESYS3', have_esys3)
1574 want_elfutils = get_option('elfutils')
1575 if want_elfutils != 'false' and not skip_deps
1576         libdw = dependency('libdw',
1577                            required : want_elfutils == 'true')
1578         have = libdw.found()
1580         # New in elfutils 0.177
1581         conf.set10('HAVE_DWELF_ELF_E_MACHINE_STRING',
1582                    have and cc.has_function('dwelf_elf_e_machine_string', dependencies : libdw))
1583 else
1584         have = false
1585         libdw = []
1586 endif
1587 conf.set10('HAVE_ELFUTILS', have)
1589 want_zlib = get_option('zlib')
1590 if want_zlib != 'false' and not skip_deps
1591         libz = dependency('zlib',
1592                           required : want_zlib == 'true')
1593         have = libz.found()
1594 else
1595         have = false
1596         libz = []
1597 endif
1598 conf.set10('HAVE_ZLIB', have)
1600 want_bzip2 = get_option('bzip2')
1601 if want_bzip2 != 'false' and not skip_deps
1602         libbzip2 = dependency('bzip2', required : false)
1603         if not libbzip2.found()
1604                 # Debian and Ubuntu do not provide the .pc file.
1605                 libbzip2 = cc.find_library('bz2', required : want_bzip2 == 'true')
1606         endif
1607         have = libbzip2.found()
1608 else
1609         have = false
1610         libbzip2 = []
1611 endif
1612 conf.set10('HAVE_BZIP2', have)
1614 want_xz = get_option('xz')
1615 if want_xz != 'false' and not skip_deps
1616         libxz = dependency('liblzma',
1617                            required : want_xz == 'true')
1618         have_xz = libxz.found()
1619 else
1620         have_xz = false
1621         libxz = []
1622 endif
1623 conf.set10('HAVE_XZ', have_xz)
1625 want_lz4 = get_option('lz4')
1626 if want_lz4 != 'false' and not skip_deps
1627         liblz4 = dependency('liblz4',
1628                             version : '>= 1.3.0',
1629                             required : want_lz4 == 'true')
1630         have_lz4 = liblz4.found()
1631 else
1632         have_lz4 = false
1633         liblz4 = []
1634 endif
1635 conf.set10('HAVE_LZ4', have_lz4)
1637 want_zstd = get_option('zstd')
1638 if want_zstd != 'false' and not skip_deps
1639         libzstd = dependency('libzstd',
1640                              required : want_zstd == 'true',
1641                              version : '>= 1.4.0')
1642         have_zstd = libzstd.found()
1643 else
1644         have_zstd = false
1645         libzstd = []
1646 endif
1647 conf.set10('HAVE_ZSTD', have_zstd)
1649 conf.set10('HAVE_COMPRESSION', have_xz or have_lz4 or have_zstd)
1651 compression = get_option('default-compression')
1652 if compression == 'auto'
1653         if have_zstd
1654                 compression = 'zstd'
1655         elif have_lz4
1656                 compression = 'lz4'
1657         elif have_xz
1658                 compression = 'xz'
1659         else
1660                 compression = 'none'
1661         endif
1662 elif compression == 'zstd' and not have_zstd
1663         error('default-compression=zstd requires zstd')
1664 elif compression == 'lz4' and not have_lz4
1665         error('default-compression=lz4 requires lz4')
1666 elif compression == 'xz' and not have_xz
1667         error('default-compression=xz requires xz')
1668 endif
1669 conf.set('DEFAULT_COMPRESSION', 'COMPRESSION_@0@'.format(compression.to_upper()))
1671 want_xkbcommon = get_option('xkbcommon')
1672 if want_xkbcommon != 'false' and not skip_deps
1673         libxkbcommon = dependency('xkbcommon',
1674                                   version : '>= 0.3.0',
1675                                   required : want_xkbcommon == 'true')
1676         have = libxkbcommon.found()
1677 else
1678         have = false
1679         libxkbcommon = []
1680 endif
1681 conf.set10('HAVE_XKBCOMMON', have)
1683 want_pcre2 = get_option('pcre2')
1684 if want_pcre2 != 'false' and not skip_deps
1685         libpcre2 = dependency('libpcre2-8',
1686                               required : want_pcre2 == 'true')
1687         have = libpcre2.found()
1688 else
1689         have = false
1690         libpcre2 = []
1691 endif
1692 conf.set10('HAVE_PCRE2', have)
1694 want_glib = get_option('glib')
1695 if want_glib != 'false' and not skip_deps
1696         libglib =    dependency('glib-2.0',
1697                                 version : '>= 2.22.0',
1698                                 required : want_glib == 'true')
1699         libgobject = dependency('gobject-2.0',
1700                                 version : '>= 2.22.0',
1701                                 required : want_glib == 'true')
1702         libgio =     dependency('gio-2.0',
1703                                 required : want_glib == 'true')
1704         have = libglib.found() and libgobject.found() and libgio.found()
1705 else
1706         have = false
1707         libglib = []
1708         libgobject = []
1709         libgio = []
1710 endif
1711 conf.set10('HAVE_GLIB', have)
1713 want_dbus = get_option('dbus')
1714 if want_dbus != 'false' and not skip_deps
1715         libdbus = dependency('dbus-1',
1716                              version : '>= 1.3.2',
1717                              required : want_dbus == 'true')
1718         have = libdbus.found()
1719 else
1720         have = false
1721         libdbus = []
1722 endif
1723 conf.set10('HAVE_DBUS', have)
1725 dbusdatadir = datadir / 'dbus-1'
1726 if conf.get('HAVE_DBUS') == 1
1727         dbusdatadir = libdbus.get_variable(pkgconfig: 'datadir', default_value: datadir) / 'dbus-1'
1728 endif
1730 dbuspolicydir = get_option('dbuspolicydir')
1731 if dbuspolicydir == ''
1732         dbuspolicydir = dbusdatadir / 'system.d'
1733 endif
1735 dbussessionservicedir = get_option('dbussessionservicedir')
1736 if dbussessionservicedir == ''
1737         dbussessionservicedir = dbusdatadir / 'services'
1738         if conf.get('HAVE_DBUS') == 1
1739                 dbussessionservicedir = libdbus.get_variable(pkgconfig: 'session_bus_services_dir', default_value: dbussessionservicedir)
1740         endif
1741 endif
1743 dbussystemservicedir = get_option('dbussystemservicedir')
1744 if dbussystemservicedir == ''
1745         dbussystemservicedir = dbusdatadir / 'system-services'
1746         if conf.get('HAVE_DBUS') == 1
1747                 dbussystemservicedir = libdbus.get_variable(pkgconfig: 'system_bus_services_dir', default_value: dbussystemservicedir)
1748         endif
1749 endif
1751 dbus_interfaces_dir = get_option('dbus-interfaces-dir')
1752 if dbus_interfaces_dir == '' or dbus_interfaces_dir == 'yes'
1753         if meson.is_cross_build() and dbus_interfaces_dir != 'yes'
1754                 dbus_interfaces_dir = 'no'
1755                 warning('Exporting D-Bus interface XML files is disabled during cross build. Pass path or "yes" to force enable.')
1756         else
1757                 dbus_interfaces_dir = dbusdatadir / 'interfaces'
1758                 if conf.get('HAVE_DBUS') == 1
1759                         dbus_interfaces_dir = libdbus.get_variable(pkgconfig: 'interfaces_dir', default_value: dbus_interfaces_dir)
1760                 endif
1761         endif
1762 endif
1764 # We support one or the other. If gcrypt is available, we assume it's there to
1765 # be used, and use it in preference.
1766 opt = get_option('cryptolib')
1767 if opt == 'openssl' and conf.get('HAVE_OPENSSL') == 0
1768         error('openssl requested as the default cryptolib, but not available')
1769 endif
1770 conf.set10('PREFER_OPENSSL',
1771            opt == 'openssl' or (opt == 'auto' and conf.get('HAVE_OPENSSL') == 1 and conf.get('HAVE_GCRYPT') == 0))
1772 conf.set10('HAVE_OPENSSL_OR_GCRYPT',
1773            conf.get('HAVE_OPENSSL') == 1 or conf.get('HAVE_GCRYPT') == 1)
1774 lib_openssl_or_gcrypt = conf.get('PREFER_OPENSSL') == 1 ? [libopenssl] : [libgcrypt, libgpg_error]
1776 dns_over_tls = get_option('dns-over-tls')
1777 if dns_over_tls != 'false'
1778         if dns_over_tls == 'gnutls' and conf.get('PREFER_OPENSSL') == 1
1779                 error('Sorry, -Ddns-over-tls=gnutls is not supported when openssl is used as the cryptolib')
1780         endif
1782         if dns_over_tls == 'gnutls'
1783                 have_openssl = false
1784         else
1785                 have_openssl = conf.get('HAVE_OPENSSL') == 1
1786                 if dns_over_tls == 'openssl' and not have_openssl
1787                         error('DNS-over-TLS support was requested with openssl, but dependencies are not available')
1788                 endif
1789         endif
1790         if dns_over_tls == 'openssl' or have_openssl
1791                 have_gnutls = false
1792         else
1793                 have_gnutls = conf.get('HAVE_GNUTLS') == 1 and libgnutls.version().version_compare('>= 3.6.0')
1794                 if dns_over_tls != 'auto' and not have_gnutls
1795                         str = dns_over_tls == 'gnutls' ? ' with gnutls' : ''
1796                         error('DNS-over-TLS support was requested@0@, but dependencies are not available'.format(str))
1797                 endif
1798         endif
1799         have = have_gnutls or have_openssl
1800 else
1801         have = false
1802         have_gnutls = false
1803         have_openssl = false
1804 endif
1805 conf.set10('ENABLE_DNS_OVER_TLS', have)
1806 conf.set10('DNS_OVER_TLS_USE_GNUTLS', have_gnutls)
1807 conf.set10('DNS_OVER_TLS_USE_OPENSSL', have_openssl)
1809 default_dns_over_tls = get_option('default-dns-over-tls')
1810 if skip_deps
1811         default_dns_over_tls = 'no'
1812 endif
1813 if default_dns_over_tls != 'no' and conf.get('ENABLE_DNS_OVER_TLS') == 0
1814         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.')
1815         default_dns_over_tls = 'no'
1816 endif
1817 conf.set('DEFAULT_DNS_OVER_TLS_MODE',
1818          'DNS_OVER_TLS_' + default_dns_over_tls.underscorify().to_upper())
1819 conf.set_quoted('DEFAULT_DNS_OVER_TLS_MODE_STR', default_dns_over_tls)
1821 default_mdns = get_option('default-mdns')
1822 conf.set('DEFAULT_MDNS_MODE',
1823          'RESOLVE_SUPPORT_' + default_mdns.to_upper())
1824 conf.set_quoted('DEFAULT_MDNS_MODE_STR', default_mdns)
1826 default_llmnr = get_option('default-llmnr')
1827 conf.set('DEFAULT_LLMNR_MODE',
1828          'RESOLVE_SUPPORT_' + default_llmnr.to_upper())
1829 conf.set_quoted('DEFAULT_LLMNR_MODE_STR', default_llmnr)
1831 want_repart = get_option('repart')
1832 if want_repart != 'false'
1833         have = conf.get('HAVE_LIBFDISK') == 1
1834         if want_repart == 'true' and not have
1835                 error('repart support was requested, but dependencies are not available')
1836         endif
1837 else
1838         have = false
1839 endif
1840 conf.set10('ENABLE_REPART', have)
1842 default_dnssec = get_option('default-dnssec')
1843 if skip_deps
1844         default_dnssec = 'no'
1845 endif
1846 if default_dnssec != 'no' and conf.get('HAVE_OPENSSL_OR_GCRYPT') == 0
1847         message('default-dnssec cannot be set to yes or allow-downgrade openssl and gcrypt are disabled. Setting default-dnssec to no.')
1848         default_dnssec = 'no'
1849 endif
1850 conf.set('DEFAULT_DNSSEC_MODE',
1851          'DNSSEC_' + default_dnssec.underscorify().to_upper())
1852 conf.set_quoted('DEFAULT_DNSSEC_MODE_STR', default_dnssec)
1854 want_sysupdate = get_option('sysupdate')
1855 if want_sysupdate != 'false'
1856         have = (conf.get('HAVE_OPENSSL') == 1 and
1857                 conf.get('HAVE_LIBFDISK') == 1)
1858         if want_sysupdate == 'true' and not have
1859                 error('sysupdate support was requested, but dependencies are not available')
1860         endif
1861 else
1862         have = false
1863 endif
1864 conf.set10('ENABLE_SYSUPDATE', have)
1866 want_importd = get_option('importd')
1867 if want_importd != 'false'
1868         have = (conf.get('HAVE_LIBCURL') == 1 and
1869                 conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1 and
1870                 conf.get('HAVE_ZLIB') == 1 and
1871                 conf.get('HAVE_XZ') == 1)
1872         if want_importd == 'true' and not have
1873                 error('importd support was requested, but dependencies are not available')
1874         endif
1875 else
1876         have = false
1877 endif
1878 conf.set10('ENABLE_IMPORTD', have)
1880 want_homed = get_option('homed')
1881 if want_homed != 'false'
1882         have = (conf.get('HAVE_OPENSSL') == 1 and
1883                 conf.get('HAVE_LIBFDISK') == 1 and
1884                 conf.get('HAVE_LIBCRYPTSETUP') == 1)
1885         if want_homed == 'true' and not have
1886                 error('homed support was requested, but dependencies are not available')
1887         endif
1888 else
1889         have = false
1890 endif
1891 conf.set10('ENABLE_HOMED', have)
1893 have = have and conf.get('HAVE_PAM') == 1
1894 conf.set10('ENABLE_PAM_HOME', have)
1896 want_remote = get_option('remote')
1897 if want_remote != 'false'
1898         have_deps = [conf.get('HAVE_MICROHTTPD') == 1,
1899                      conf.get('HAVE_LIBCURL') == 1]
1900         # sd-j-remote requires µhttpd, and sd-j-upload requires libcurl, so
1901         # it's possible to build one without the other. Complain only if
1902         # support was explicitly requested. The auxiliary files like sysusers
1903         # config should be installed when any of the programs are built.
1904         if want_remote == 'true' and not (have_deps[0] and have_deps[1])
1905                 error('remote support was requested, but dependencies are not available')
1906         endif
1907         have = have_deps[0] or have_deps[1]
1908 else
1909         have = false
1910 endif
1911 conf.set10('ENABLE_REMOTE', have)
1913 foreach term : ['analyze',
1914                 'backlight',
1915                 'binfmt',
1916                 'compat-mutable-uid-boundaries',
1917                 'coredump',
1918                 'efi',
1919                 'environment-d',
1920                 'firstboot',
1921                 'gshadow',
1922                 'hibernate',
1923                 'hostnamed',
1924                 'hwdb',
1925                 'idn',
1926                 'ima',
1927                 'initrd',
1928                 'kernel-install',
1929                 'ldconfig',
1930                 'localed',
1931                 'logind',
1932                 'machined',
1933                 'networkd',
1934                 'nscd',
1935                 'nss-myhostname',
1936                 'nss-systemd',
1937                 'oomd',
1938                 'portabled',
1939                 'pstore',
1940                 'quotacheck',
1941                 'randomseed',
1942                 'resolve',
1943                 'rfkill',
1944                 'smack',
1945                 'sysext',
1946                 'sysusers',
1947                 'timedated',
1948                 'timesyncd',
1949                 'tmpfiles',
1950                 'tpm',
1951                 'userdb',
1952                 'utmp',
1953                 'vconsole',
1954                 'xdg-autostart']
1955         have = get_option(term)
1956         name = 'ENABLE_' + term.underscorify().to_upper()
1957         conf.set10(name, have)
1958 endforeach
1960 enable_sysusers = conf.get('ENABLE_SYSUSERS') == 1
1962 foreach tuple : [['nss-mymachines', 'machined'],
1963                  ['nss-resolve',    'resolve']]
1964         want = get_option(tuple[0])
1965         if want != 'false'
1966                 have = get_option(tuple[1])
1967                 if want == 'true' and not have
1968                         error('@0@ is requested but @1@ is disabled'.format(tuple[0], tuple[1]))
1969                 endif
1970         else
1971                 have = false
1972         endif
1973         name = 'ENABLE_' + tuple[0].underscorify().to_upper()
1974         conf.set10(name, have)
1975 endforeach
1977 enable_nss = false
1978 foreach term : ['ENABLE_NSS_MYHOSTNAME',
1979                 'ENABLE_NSS_MYMACHINES',
1980                 'ENABLE_NSS_RESOLVE',
1981                 'ENABLE_NSS_SYSTEMD']
1982         if conf.get(term) == 1
1983                 enable_nss = true
1984         endif
1985 endforeach
1986 conf.set10('ENABLE_NSS', enable_nss)
1988 conf.set10('ENABLE_TIMEDATECTL', get_option('timedated') or get_option('timesyncd'))
1990 conf.set10('SYSTEMD_SLOW_TESTS_DEFAULT', slow_tests)
1992 ############################################################
1994 tests = []
1995 simple_tests = []
1996 fuzzers = []
1997 simple_fuzzers = []
1998 catalogs = []
2000 ############################################################
2002 pymod = import('python')
2003 python = pymod.find_installation('python3', required : true, modules : ['jinja2'])
2004 python_39 = python.language_version().version_compare('>=3.9')
2006 ############################################################
2008 if conf.get('BPF_FRAMEWORK') == 1
2009         bpf_clang_flags = [
2010                 '-std=gnu11',
2011                 '-Wno-compare-distinct-pointer-types',
2012                 '-fno-stack-protector',
2013                 '-O2',
2014                 '-target',
2015                 'bpf',
2016                 '-g',
2017                 '-c',
2018         ]
2020         bpf_gcc_flags = [
2021                 '-std=gnu11',
2022                 '-fno-stack-protector',
2023                 '-O2',
2024                 '-mkernel=5.2',
2025                 '-mcpu=v3',
2026                 '-mco-re',
2027                 '-gbtf',
2028                 '-c',
2029         ]
2031         # Generate defines that are appropriate to tell the compiler what architecture
2032         # we're compiling for. By default we just map meson's cpu_family to __<cpu_family>__.
2033         # This dictionary contains the exceptions where this doesn't work.
2034         #
2035         # C.f. https://mesonbuild.com/Reference-tables.html#cpu-families
2036         # and src/basic/missing_syscall_def.h.
2037         cpu_arch_defines = {
2038                 'ppc'     : ['-D__powerpc__'],
2039                 'ppc64'   : ['-D__powerpc64__', '-D_CALL_ELF=2'],
2040                 'riscv32' : ['-D__riscv', '-D__riscv_xlen=32'],
2041                 'riscv64' : ['-D__riscv', '-D__riscv_xlen=64'],
2042                 'x86'     : ['-D__i386__'],
2044                 # For arm, assume hardware fp is available.
2045                 'arm'     : ['-D__arm__', '-D__ARM_PCS_VFP'],
2046         }
2048         bpf_arch_flags = cpu_arch_defines.get(host_machine.cpu_family(),
2049                                               ['-D__@0@__'.format(host_machine.cpu_family())])
2050         if bpf_compiler == 'gcc'
2051                 bpf_arch_flags += ['-m' + host_machine.endian() + '-endian']
2052         endif
2054         libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir')
2056         bpf_o_unstripped_cmd = []
2057         if bpf_compiler == 'clang'
2058                 bpf_o_unstripped_cmd += [
2059                         clang,
2060                         bpf_clang_flags,
2061                         bpf_arch_flags,
2062                 ]
2063         elif bpf_compiler == 'gcc'
2064                 bpf_o_unstripped_cmd += [
2065                         bpf_gcc,
2066                         bpf_gcc_flags,
2067                         bpf_arch_flags,
2068                 ]
2069         endif
2071         bpf_o_unstripped_cmd += ['-I.']
2073         if not meson.is_cross_build() and bpf_compiler == 'clang'
2074                 target_triplet_cmd = run_command('gcc', '-dumpmachine', check: false)
2075                 if target_triplet_cmd.returncode() == 0
2076                         target_triplet = target_triplet_cmd.stdout().strip()
2077                         bpf_o_unstripped_cmd += [
2078                                 '-isystem',
2079                                 '/usr/include/@0@'.format(target_triplet)
2080                         ]
2081                 endif
2082         endif
2084         bpf_o_unstripped_cmd += [
2085                 '-idirafter',
2086                 libbpf_include_dir,
2087                 '@INPUT@',
2088                 '-o',
2089                 '@OUTPUT@'
2090         ]
2092         if bpftool_strip
2093                 bpf_o_cmd = [
2094                         bpftool,
2095                         'gen',
2096                         'object',
2097                         '@OUTPUT@',
2098                         '@INPUT@'
2099                 ]
2100         elif bpf_compiler == 'clang'
2101                 bpf_o_cmd = [
2102                         llvm_strip,
2103                         '-g',
2104                         '@INPUT@',
2105                         '-o',
2106                         '@OUTPUT@'
2107                 ]
2108         endif
2110         skel_h_cmd = [
2111                 bpftool,
2112                 'gen',
2113                 'skeleton',
2114                 '@INPUT@'
2115         ]
2116 endif
2118 #####################################################################
2120 efi_arch = {
2121         'aarch64'     : 'aa64',
2122         'arm'         : 'arm',
2123         'loongarch32' : 'loongarch32',
2124         'loongarch64' : 'loongarch64',
2125         'riscv32'     : 'riscv32',
2126         'riscv64'     : 'riscv64',
2127         'x86_64'      : 'x64',
2128         'x86'         : 'ia32',
2129 }.get(host_machine.cpu_family(), '')
2131 if get_option('bootloader') != 'false' and efi_arch != ''
2132         conf.set_quoted('EFI_MACHINE_TYPE_NAME', efi_arch)
2133 elif get_option('bootloader') == 'false' and efi_arch != ''
2134         # Ensure that if the option is explicitly set to false, then no EFI code is built, including tests
2135         efi_arch = ''
2136 elif get_option('bootloader') == 'true' and efi_arch == ''
2137         error('EFI not supported for this arch.')
2138 endif
2140 efi_arch_alt = ''
2141 efi_cpu_family_alt = ''
2142 if efi_arch == 'x64' and cc.links('''
2143                 #include <limits.h>
2144                 int main(int argc, char *argv[]) {
2145                         return __builtin_popcount(argc - CHAR_MAX);
2146                 }''', args : ['-m32', '-march=i686'], name : '32bit build possible')
2147         efi_arch_alt = 'ia32'
2148         efi_cpu_family_alt = 'x86'
2149 endif
2151 have_pyelftools = pymod.find_installation('python3', required : false, modules : ['elftools']).found()
2152 if get_option('bootloader') == 'true' and not have_pyelftools
2153         error('EFI bootloader support requires pyelftools.')
2154 endif
2156 conf.set10(
2157         'ENABLE_BOOTLOADER',
2158         get_option('efi') and
2159         get_option('bootloader') in ['auto', 'true'] and
2160         efi_arch != '' and
2161         have_pyelftools,
2164 if get_option('ukify') == 'auto'
2165     want_ukify = python_39  and conf.get('ENABLE_BOOTLOADER') == 1
2166 elif get_option('ukify') == 'true' and (not python_39 or conf.get('ENABLE_BOOTLOADER') != 1)
2167     error('ukify requires Python >= 3.9 and -Dbootloader=true')
2168 else
2169     want_ukify = get_option('ukify') == 'true'
2170 endif
2171 conf.set10('ENABLE_UKIFY', want_ukify)
2173 ############################################################
2175 elf2efi_lds = project_source_root / 'tools/elf2efi.lds'
2176 elf2efi_py = find_program('tools/elf2efi.py')
2177 export_dbus_interfaces_py = find_program('tools/dbus_exporter.py')
2178 generate_gperfs = find_program('tools/generate-gperfs.py')
2179 make_autosuspend_rules_py = find_program('tools/make-autosuspend-rules.py')
2180 make_directive_index_py = find_program('tools/make-directive-index.py')
2181 make_man_index_py = find_program('tools/make-man-index.py')
2182 meson_render_jinja2 = find_program('tools/meson-render-jinja2.py')
2183 update_dbus_docs_py = find_program('tools/update-dbus-docs.py')
2184 update_hwdb_autosuspend_sh = find_program('tools/update-hwdb-autosuspend.sh')
2185 update_hwdb_sh = find_program('tools/update-hwdb.sh')
2186 update_man_rules_py = find_program('tools/update-man-rules.py')
2187 update_syscall_tables_sh = find_program('tools/update-syscall-tables.sh')
2188 xml_helper_py = find_program('tools/xml_helper.py')
2190 ############################################################
2192 if get_option('b_coverage')
2193         userspace_c_args += ['-include', 'src/basic/coverage.h']
2194 endif
2196 ############################################################
2198 config_h = configure_file(
2199         output : 'config.h',
2200         configuration : conf)
2202 userspace_c_args += ['-include', 'config.h']
2204 jinja2_cmdline = [meson_render_jinja2, config_h, version_h]
2206 userspace = declare_dependency(
2207         compile_args : userspace_c_args,
2208         link_args : userspace_c_ld_args,
2211 man_page_depends = []
2213 ############################################################
2215 # binaries that have --help and are intended for use by humans,
2216 # usually, but not always, installed in /bin.
2217 public_programs = []
2219 # D-Bus introspection XML export
2220 dbus_programs = []
2222 # A list of boot stubs. Required for testing of ukify.
2223 boot_stubs = []
2225 basic_includes = include_directories(
2226         'src/basic',
2227         'src/fundamental',
2228         'src/systemd',
2229         '.')
2231 libsystemd_includes = [basic_includes, include_directories(
2232         'src/libsystemd/sd-bus',
2233         'src/libsystemd/sd-device',
2234         'src/libsystemd/sd-event',
2235         'src/libsystemd/sd-hwdb',
2236         'src/libsystemd/sd-id128',
2237         'src/libsystemd/sd-journal',
2238         'src/libsystemd/sd-netlink',
2239         'src/libsystemd/sd-network',
2240         'src/libsystemd/sd-resolve')]
2242 includes = [libsystemd_includes, include_directories('src/shared')]
2244 subdir('po')
2245 subdir('catalog')
2246 subdir('src/fundamental')
2247 subdir('src/basic')
2248 subdir('src/libsystemd')
2249 subdir('src/shared')
2250 subdir('src/udev')
2251 subdir('src/libudev')
2252 subdir('src/cryptsetup/cryptsetup-tokens')
2254 libsystemd = shared_library(
2255         'systemd',
2256         version : libsystemd_version,
2257         include_directories : libsystemd_includes,
2258         link_args : ['-shared',
2259                      '-Wl,--version-script=' + libsystemd_sym_path],
2260         link_with : [libbasic,
2261                      libbasic_gcrypt,
2262                      libbasic_compress],
2263         link_whole : [libsystemd_static],
2264         dependencies : [librt,
2265                         threads,
2266                         userspace],
2267         link_depends : libsystemd_sym,
2268         install : true,
2269         install_tag: 'libsystemd',
2270         install_dir : rootlibdir)
2272 alias_target('libsystemd', libsystemd)
2274 install_libsystemd_static = static_library(
2275         'systemd',
2276         libsystemd_sources,
2277         basic_sources,
2278         basic_gcrypt_sources,
2279         basic_compress_sources,
2280         fundamental_sources,
2281         include_directories : libsystemd_includes,
2282         build_by_default : static_libsystemd != 'false',
2283         install : static_libsystemd != 'false',
2284         install_tag: 'libsystemd',
2285         install_dir : rootlibdir,
2286         pic : static_libsystemd_pic,
2287         dependencies : [libblkid,
2288                         libcap,
2289                         libdl,
2290                         libgcrypt,
2291                         liblz4,
2292                         libmount,
2293                         libopenssl,
2294                         librt,
2295                         libxz,
2296                         libzstd,
2297                         threads,
2298                         userspace,
2299                         versiondep],
2300         c_args : libsystemd_c_args + (static_libsystemd_pic ? [] : ['-fno-PIC']))
2302 libudev = shared_library(
2303         'udev',
2304         version : libudev_version,
2305         include_directories : includes,
2306         link_args : ['-shared',
2307                      '-Wl,--version-script=' + libudev_sym_path],
2308         link_with : [libsystemd_static, libshared_static],
2309         link_whole : libudev_basic,
2310         dependencies : [threads,
2311                         userspace],
2312         link_depends : libudev_sym,
2313         install : true,
2314         install_tag: 'libudev',
2315         install_dir : rootlibdir)
2317 alias_target('libudev', libudev)
2319 install_libudev_static = static_library(
2320         'udev',
2321         basic_sources,
2322         fundamental_sources,
2323         shared_sources,
2324         libsystemd_sources,
2325         libudev_sources,
2326         include_directories : includes,
2327         build_by_default : static_libudev != 'false',
2328         install : static_libudev != 'false',
2329         install_tag: 'libudev',
2330         install_dir : rootlibdir,
2331         link_depends : libudev_sym,
2332         dependencies : [libmount,
2333                         libshared_deps,
2334                         userspace,
2335                         versiondep],
2336         c_args : static_libudev_pic ? [] : ['-fno-PIC'],
2337         pic : static_libudev_pic)
2339 if conf.get('HAVE_LIBCRYPTSETUP_PLUGINS') == 1
2340         if conf.get('HAVE_TPM2') == 1
2341                 shared_library(
2342                         'cryptsetup-token-systemd-tpm2',
2343                         cryptsetup_token_systemd_tpm2_sources,
2344                         include_directories : includes,
2345                         link_args : ['-shared',
2346                                      '-Wl,--version-script=' + cryptsetup_token_sym_path],
2347                         link_with : [lib_cryptsetup_token_common,
2348                                      libshared],
2349                         dependencies : [libcryptsetup,
2350                                         tpm2,
2351                                         userspace,
2352                                         versiondep],
2353                         link_depends : cryptsetup_token_sym,
2354                         install_rpath : rootpkglibdir,
2355                         install : true,
2356                         install_dir : libcryptsetup_plugins_dir)
2357         endif
2359         if conf.get('HAVE_LIBFIDO2') == 1
2360                 shared_library(
2361                         'cryptsetup-token-systemd-fido2',
2362                         cryptsetup_token_systemd_fido2_sources,
2363                         include_directories : includes,
2364                         link_args : ['-shared',
2365                                      '-Wl,--version-script=' + cryptsetup_token_sym_path],
2366                         link_with : [lib_cryptsetup_token_common,
2367                                      libshared],
2368                         dependencies : [libcryptsetup,
2369                                         libfido2,
2370                                         userspace,
2371                                         versiondep],
2372                         link_depends : cryptsetup_token_sym,
2373                         install_rpath : rootpkglibdir,
2374                         install : true,
2375                         install_dir : libcryptsetup_plugins_dir)
2376         endif
2378         if conf.get('HAVE_P11KIT') == 1
2379                 shared_library(
2380                         'cryptsetup-token-systemd-pkcs11',
2381                         cryptsetup_token_systemd_pkcs11_sources,
2382                         include_directories : includes,
2383                         link_args : ['-shared',
2384                                      '-Wl,--version-script=' + cryptsetup_token_sym_path],
2385                         link_with : [lib_cryptsetup_token_common,
2386                                      libshared],
2387                         dependencies : [libcryptsetup,
2388                                         libp11kit,
2389                                         userspace,
2390                                         versiondep],
2391                         link_depends : cryptsetup_token_sym,
2392                         install_rpath : rootpkglibdir,
2393                         install : true,
2394                         install_dir : libcryptsetup_plugins_dir)
2395         endif
2396 endif
2398 ############################################################
2400 # systemd-analyze requires 'libcore'
2401 subdir('src/core')
2402 # systemd-journal-remote requires 'libjournal_core'
2403 subdir('src/journal')
2404 # systemd-networkd requires 'libsystemd_network'
2405 subdir('src/libsystemd-network')
2407 subdir('src/analyze')
2408 subdir('src/boot')
2409 subdir('src/boot/efi')
2410 subdir('src/busctl')
2411 subdir('src/coredump')
2412 subdir('src/cryptenroll')
2413 subdir('src/cryptsetup')
2414 subdir('src/home')
2415 subdir('src/hostname')
2416 subdir('src/import')
2417 subdir('src/journal-remote')
2418 subdir('src/kernel-install')
2419 subdir('src/locale')
2420 subdir('src/login')
2421 subdir('src/machine')
2422 subdir('src/network')
2423 subdir('src/nspawn')
2424 subdir('src/oom')
2425 subdir('src/partition')
2426 subdir('src/portable')
2427 subdir('src/pstore')
2428 subdir('src/resolve')
2429 subdir('src/rpm')
2430 subdir('src/shutdown')
2431 subdir('src/sysext')
2432 subdir('src/systemctl')
2433 subdir('src/sysupdate')
2434 subdir('src/timedate')
2435 subdir('src/timesync')
2436 subdir('src/tmpfiles')
2437 subdir('src/userdb')
2438 subdir('src/xdg-autostart-generator')
2440 subdir('src/systemd')
2442 subdir('src/test')
2443 subdir('src/fuzz')
2444 subdir('rules.d')
2445 subdir('test')
2446 subdir('src/ukify/test')  # needs to be last for test_env variable
2448 alias_target('devel', libsystemd_pc, libudev_pc, systemd_pc, udev_pc)
2450 ############################################################
2452 # only static linking apart from libdl, to make sure that the
2453 # module is linked to all libraries that it uses.
2454 test_dlopen = executable(
2455         'test-dlopen',
2456         test_dlopen_c,
2457         include_directories : includes,
2458         link_with : [libbasic],
2459         dependencies : [libdl,
2460                         userspace],
2461         build_by_default : want_tests != 'false')
2463 foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'],
2464                  ['systemd',    'ENABLE_NSS_SYSTEMD', ['nss-systemd.h', 'userdb-glue.c', 'userdb-glue.h']],
2465                  ['mymachines', 'ENABLE_NSS_MYMACHINES'],
2466                  ['resolve',    'ENABLE_NSS_RESOLVE', [], resolve_includes]]
2468         condition = tuple[1] == '' or conf.get(tuple[1]) == 1
2469         if condition
2470                 module = tuple[0]
2472                 sym = 'src/nss-@0@/nss-@0@.sym'.format(module)
2473                 version_script_arg = project_source_root / sym
2475                 sources = ['src/nss-@0@/nss-@0@.c'.format(module)]
2476                 if tuple.length() > 2
2477                         foreach s : tuple[2]
2478                                 sources += ['src/nss-@0@/@1@'.format(module, s)]
2479                         endforeach
2480                 endif
2482                 incs = tuple.length() > 3 ? tuple[3] : includes
2484                 nss = shared_library(
2485                         'nss_' + module,
2486                         sources,
2487                         version : '2',
2488                         include_directories : incs,
2489                         # Note that we link NSS modules with '-z nodelete' so that mempools never get orphaned
2490                         link_args : ['-Wl,-z,nodelete',
2491                                      '-shared',
2492                                      '-Wl,--version-script=' + version_script_arg],
2493                         link_with : [libsystemd_static,
2494                                      libshared_static,
2495                                      libbasic],
2496                         dependencies : [librt,
2497                                         threads,
2498                                         userspace],
2499                         link_depends : sym,
2500                         install : true,
2501                         install_tag : 'nss',
2502                         install_dir : rootlibdir)
2504                 # We cannot use shared_module because it does not support version suffix.
2505                 # Unfortunately shared_library insists on creating the symlink…
2506                 meson.add_install_script('sh', '-c',
2507                                          'rm $DESTDIR@0@/libnss_@1@.so'
2508                                          .format(rootlibdir, module),
2509                                          install_tag : 'nss'
2510                                          )
2512                 if want_tests != 'false'
2513                         test('dlopen-nss_' + module,
2514                              test_dlopen,
2515                              # path to dlopen must include a slash
2516                              args : nss.full_path(),
2517                              depends : nss)
2518                 endif
2519         endif
2520 endforeach
2522 ############################################################
2524 exe = executable(
2525         'systemd',
2526         systemd_sources,
2527         include_directories : includes,
2528         link_with : [libcore,
2529                      libshared],
2530         dependencies : [libseccomp,
2531                         userspace,
2532                         versiondep],
2533         install_rpath : rootpkglibdir,
2534         install : true,
2535         install_dir : rootlibexecdir)
2536 dbus_programs += exe
2537 public_programs += exe
2539 meson.add_install_script(meson_make_symlink,
2540                          rootlibexecdir / 'systemd',
2541                          rootsbindir / 'init')
2543 exe = executable(
2544         'systemd-analyze',
2545         systemd_analyze_sources,
2546         include_directories : core_includes,
2547         link_with : [libcore,
2548                      libshared],
2549         dependencies : [libseccomp,
2550                         userspace,
2551                         versiondep],
2552         install_rpath : rootpkglibdir,
2553         install : conf.get('ENABLE_ANALYZE') == 1)
2554 if conf.get('ENABLE_ANALYZE') == 1
2555         public_programs += exe
2556 endif
2558 if want_tests != 'false'
2559         test('test-compare-versions',
2560              test_compare_versions_sh,
2561              args : exe.full_path())
2562 endif
2564 executable(
2565         'systemd-journald',
2566         systemd_journald_sources,
2567         include_directories : includes,
2568         link_with : [libjournal_core,
2569                      libshared],
2570         dependencies : [liblz4,
2571                         libselinux,
2572                         libxz,
2573                         libzstd,
2574                         threads,
2575                         userspace,
2576                         versiondep],
2577         install_rpath : rootpkglibdir,
2578         install : true,
2579         install_dir : rootlibexecdir)
2581 public_programs += executable(
2582         'systemd-cat',
2583         systemd_cat_sources,
2584         include_directories : includes,
2585         link_with : [libjournal_core,
2586                      libshared],
2587         dependencies : [threads,
2588                         userspace,
2589                         versiondep],
2590         install_rpath : rootpkglibdir,
2591         install : true)
2593 if get_option('link-journalctl-shared')
2594         journalctl_link_with = [libshared]
2595 else
2596         journalctl_link_with = [libsystemd_static,
2597                                 libshared_static,
2598                                 libbasic_gcrypt]
2599 endif
2601 public_programs += executable(
2602         'journalctl',
2603         journalctl_sources,
2604         include_directories : includes,
2605         link_with : [journalctl_link_with],
2606         dependencies : [libdl,
2607                         liblz4,
2608                         libxz,
2609                         libzstd,
2610                         threads,
2611                         userspace,
2612                         versiondep],
2613         install_rpath : rootpkglibdir,
2614         install : true,
2615         install_dir : rootbindir)
2617 executable(
2618         'systemd-getty-generator',
2619         'src/getty-generator/getty-generator.c',
2620         include_directories : includes,
2621         link_with : [libshared],
2622         dependencies : userspace,
2623         install_rpath : rootpkglibdir,
2624         install : true,
2625         install_dir : systemgeneratordir)
2627 executable(
2628         'systemd-debug-generator',
2629         'src/debug-generator/debug-generator.c',
2630         include_directories : includes,
2631         link_with : [libshared],
2632         dependencies : userspace,
2633         install_rpath : rootpkglibdir,
2634         install : true,
2635         install_dir : systemgeneratordir)
2637 executable(
2638         'systemd-run-generator',
2639         'src/run-generator/run-generator.c',
2640         include_directories : includes,
2641         link_with : [libshared],
2642         dependencies : userspace,
2643         install_rpath : rootpkglibdir,
2644         install : true,
2645         install_dir : systemgeneratordir)
2647 exe = executable(
2648         'systemd-fstab-generator',
2649         'src/fstab-generator/fstab-generator.c',
2650         include_directories : includes,
2651         link_with : [libshared],
2652         dependencies : userspace,
2653         install_rpath : rootpkglibdir,
2654         install : true,
2655         install_dir : systemgeneratordir)
2657 meson.add_install_script(meson_make_symlink,
2658                          systemgeneratordir / 'systemd-fstab-generator',
2659                          rootlibexecdir / 'systemd-sysroot-fstab-check')
2661 if want_tests != 'false'
2662         test('test-fstab-generator',
2663              test_fstab_generator_sh,
2664              # https://github.com/mesonbuild/meson/issues/2681
2665              args : exe.full_path(),
2666              env : test_env,
2667              depends : exe)
2668 endif
2670 if conf.get('ENABLE_ENVIRONMENT_D') == 1
2671         executable(
2672                 '30-systemd-environment-d-generator',
2673                 'src/environment-d-generator/environment-d-generator.c',
2674                 include_directories : includes,
2675                 link_with : [libshared],
2676                 dependencies : userspace,
2677                 install_rpath : rootpkglibdir,
2678                 install : true,
2679                 install_dir : userenvgeneratordir)
2681         meson.add_install_script(meson_make_symlink,
2682                                  sysconfdir / 'environment',
2683                                  environmentdir / '99-environment.conf')
2684 endif
2686 if conf.get('ENABLE_HIBERNATE') == 1
2687         executable(
2688                 'systemd-hibernate-resume-generator',
2689                 'src/hibernate-resume/hibernate-resume-generator.c',
2690                 include_directories : includes,
2691                 link_with : [libshared],
2692                 dependencies : userspace,
2693                 install_rpath : rootpkglibdir,
2694                 install : true,
2695                 install_dir : systemgeneratordir)
2697         executable(
2698                 'systemd-hibernate-resume',
2699                 'src/hibernate-resume/hibernate-resume.c',
2700                 include_directories : includes,
2701                 link_with : [libshared],
2702                 dependencies : userspace,
2703                 install_rpath : rootpkglibdir,
2704                 install : true,
2705                 install_dir : rootlibexecdir)
2706 endif
2708 if conf.get('HAVE_BLKID') == 1
2709         executable(
2710                 'systemd-gpt-auto-generator',
2711                 'src/gpt-auto-generator/gpt-auto-generator.c',
2712                 include_directories : includes,
2713                 link_with : [libshared],
2714                 dependencies : [libblkid,
2715                                 userspace],
2716                 install_rpath : rootpkglibdir,
2717                 install : true,
2718                 install_dir : systemgeneratordir)
2720         public_programs += executable(
2721                 'systemd-dissect',
2722                 'src/dissect/dissect.c',
2723                 include_directories : includes,
2724                 link_with : [libshared],
2725                 dependencies : [userspace,
2726                                 versiondep],
2727                 install_rpath : rootpkglibdir,
2728                 install : true)
2730         meson.add_install_script(meson_make_symlink,
2731                                  bindir / 'systemd-dissect',
2732                                  rootsbindir / 'mount.ddi')
2733 endif
2735 if conf.get('ENABLE_RESOLVE') == 1
2736         dbus_programs += executable(
2737                 'systemd-resolved',
2738                 systemd_resolved_sources,
2739                 include_directories : resolve_includes,
2740                 link_with : [libshared,
2741                              libbasic_gcrypt,
2742                              libsystemd_resolve_core],
2743                 dependencies : [systemd_resolved_dependencies,
2744                                 userspace],
2745                 install_rpath : rootpkglibdir,
2746                 install : true,
2747                 install_dir : rootlibexecdir)
2749         public_programs += executable(
2750                 'resolvectl',
2751                 resolvectl_sources,
2752                 include_directories : includes,
2753                 link_with : [libshared,
2754                              libbasic_gcrypt,
2755                              libsystemd_resolve_core],
2756                 dependencies : [lib_openssl_or_gcrypt,
2757                                 libidn,
2758                                 libm,
2759                                 threads,
2760                                 userspace,
2761                                 versiondep],
2762                 install_rpath : rootpkglibdir,
2763                 install : true)
2765         meson.add_install_script(meson_make_symlink,
2766                                  bindir / 'resolvectl',
2767                                  rootsbindir / 'resolvconf')
2769         meson.add_install_script(meson_make_symlink,
2770                                  bindir / 'resolvectl',
2771                                  bindir / 'systemd-resolve')
2772 endif
2774 if conf.get('ENABLE_LOGIND') == 1
2775         dbus_programs += executable(
2776                 'systemd-logind',
2777                 systemd_logind_sources,
2778                 include_directories : includes,
2779                 link_with : [liblogind_core,
2780                              libshared],
2781                 dependencies : [libacl,
2782                                 threads,
2783                                 userspace,
2784                                 versiondep],
2785                 install_rpath : rootpkglibdir,
2786                 install : true,
2787                 install_dir : rootlibexecdir)
2789         public_programs += executable(
2790                 'loginctl',
2791                 loginctl_sources,
2792                 include_directories : includes,
2793                 link_with : [libshared],
2794                 dependencies : [liblz4,
2795                                 libxz,
2796                                 libzstd,
2797                                 threads,
2798                                 userspace,
2799                                 versiondep],
2800                 install_rpath : rootpkglibdir,
2801                 install : true,
2802                 install_dir : rootbindir)
2804         public_programs += executable(
2805                 'systemd-inhibit',
2806                 'src/login/inhibit.c',
2807                 include_directories : includes,
2808                 link_with : [libshared],
2809                 dependencies : [userspace,
2810                                 versiondep],
2811                 install_rpath : rootpkglibdir,
2812                 install : true,
2813                 install_dir : rootbindir)
2815         if conf.get('HAVE_PAM') == 1
2816                 version_script_arg = project_source_root / pam_systemd_sym
2817                 pam_systemd = shared_library(
2818                         'pam_systemd',
2819                         pam_systemd_c,
2820                         name_prefix : '',
2821                         include_directories : includes,
2822                         link_args : ['-shared',
2823                                      '-Wl,--version-script=' + version_script_arg],
2824                         link_with : [libsystemd_static,
2825                                      libshared_static],
2826                         dependencies : [libpam_misc,
2827                                         libpam,
2828                                         threads,
2829                                         userspace,
2830                                         versiondep],
2831                         link_depends : pam_systemd_sym,
2832                         install : true,
2833                         install_tag : 'pam',
2834                         install_dir : pamlibdir)
2836                 if want_tests != 'false'
2837                         test('dlopen-pam_systemd',
2838                              test_dlopen,
2839                              # path to dlopen must include a slash
2840                              args : pam_systemd.full_path(),
2841                              depends : pam_systemd)
2842                 endif
2843         endif
2845         executable(
2846                 'systemd-user-runtime-dir',
2847                 user_runtime_dir_sources,
2848                 include_directories : includes,
2849                 link_with : [libshared],
2850                 dependencies : userspace,
2851                 install_rpath : rootpkglibdir,
2852                 install : true,
2853                 install_dir : rootlibexecdir)
2854 endif
2856 if conf.get('HAVE_PAM') == 1
2857         executable(
2858                 'systemd-user-sessions',
2859                 'src/user-sessions/user-sessions.c',
2860                 include_directories : includes,
2861                 link_with : [libshared],
2862                 dependencies : userspace,
2863                 install_rpath : rootpkglibdir,
2864                 install : true,
2865                 install_dir : rootlibexecdir)
2866 endif
2868 if conf.get('HAVE_BLKID') == 1 and conf.get('ENABLE_BOOTLOADER') == 1
2869         if get_option('link-boot-shared')
2870                 boot_link_with = [libshared]
2871         else
2872                 boot_link_with = [libsystemd_static, libshared_static]
2873         endif
2875         exe = executable(
2876                 'bootctl',
2877                 bootctl_sources,
2878                 include_directories : includes,
2879                 link_with : [boot_link_with],
2880                 dependencies : [libblkid,
2881                                 userspace,
2882                                 versiondep],
2883                 install_rpath : rootpkglibdir,
2884                 install : true)
2885         public_programs += exe
2887         if want_tests != 'false'
2888                 test('test-bootctl-json',
2889                      test_bootctl_json_sh,
2890                      args : exe.full_path(),
2891                      depends : exe)
2892         endif
2894         public_programs += executable(
2895                 'systemd-bless-boot',
2896                 'src/boot/bless-boot.c',
2897                 include_directories : includes,
2898                 link_with : [boot_link_with],
2899                 dependencies : [libblkid,
2900                                 userspace,
2901                                 versiondep],
2902                 install_rpath : rootpkglibdir,
2903                 install : true,
2904                 install_dir : rootlibexecdir)
2906         executable(
2907                 'systemd-bless-boot-generator',
2908                 'src/boot/bless-boot-generator.c',
2909                 include_directories : includes,
2910                 link_with : [boot_link_with],
2911                 dependencies : userspace,
2912                 install_rpath : rootpkglibdir,
2913                 install : true,
2914                 install_dir : systemgeneratordir)
2916         if conf.get('HAVE_OPENSSL') == 1 and conf.get('HAVE_TPM2') == 1
2917                 executable(
2918                         'systemd-measure',
2919                         'src/boot/measure.c',
2920                         include_directories : includes,
2921                         link_with : [libshared],
2922                         dependencies : [libopenssl,
2923                                         userspace,
2924                                         versiondep],
2925                         install_rpath : rootpkglibdir,
2926                         install : true,
2927                         install_dir : rootlibexecdir)
2928                 executable(
2929                         'systemd-pcrphase',
2930                         'src/boot/pcrphase.c',
2931                         include_directories : includes,
2932                         link_with : [libshared],
2933                         dependencies : [libblkid,
2934                                         libopenssl,
2935                                         tpm2,
2936                                         userspace,
2937                                         versiondep],
2938                         install_rpath : rootpkglibdir,
2939                         install : true,
2940                         install_dir : rootlibexecdir)
2941         endif
2942 endif
2944 executable(
2945         'systemd-boot-check-no-failures',
2946         'src/boot/boot-check-no-failures.c',
2947         include_directories : includes,
2948         link_with : [libshared],
2949         dependencies : [libblkid,
2950                         userspace,
2951                         versiondep],
2952         install_rpath : rootpkglibdir,
2953         install : true,
2954         install_dir : rootlibexecdir)
2956 public_programs += executable(
2957         'systemd-socket-activate',
2958         'src/socket-activate/socket-activate.c',
2959         include_directories : includes,
2960         link_with : [libshared],
2961         dependencies : [threads,
2962                         userspace,
2963                         versiondep],
2964         install_rpath : rootpkglibdir,
2965         install : true)
2967 systemctl = executable(
2968         'systemctl',
2969         systemctl_sources,
2970         include_directories : includes,
2971         link_with : systemctl_link_with,
2972         dependencies : [libcap,
2973                         liblz4,
2974                         libselinux,
2975                         libxz,
2976                         libzstd,
2977                         threads,
2978                         userspace,
2979                         versiondep],
2980         install_rpath : rootpkglibdir,
2981         install : true,
2982         install_dir : rootbindir)
2983 public_programs += systemctl
2985 if conf.get('ENABLE_PORTABLED') == 1
2986         if get_option('link-portabled-shared')
2987                 portabled_link_with = [libshared]
2988         else
2989                 portabled_link_with = [libsystemd_static,
2990                                        libshared_static]
2991         endif
2993         dbus_programs += executable(
2994                 'systemd-portabled',
2995                 systemd_portabled_sources,
2996                 include_directories : includes,
2997                 link_with : [portabled_link_with],
2998                 dependencies : [libselinux,
2999                                 threads,
3000                                 userspace,
3001                                 versiondep],
3002                 install_rpath : rootpkglibdir,
3003                 install : true,
3004                 install_dir : rootlibexecdir)
3006         public_programs += executable(
3007                 'portablectl',
3008                 'src/portable/portablectl.c',
3009                 include_directories : includes,
3010                 link_with : [portabled_link_with],
3011                 dependencies : [threads,
3012                                 userspace,
3013                                 versiondep],
3014                 install_rpath : rootpkglibdir,
3015                 install : true,
3016                 install_dir : rootbindir)
3017 endif
3019 if conf.get('ENABLE_SYSEXT') == 1
3020         public_programs += executable(
3021                 'systemd-sysext',
3022                 systemd_sysext_sources,
3023                 include_directories : includes,
3024                 link_with : [libshared],
3025                 dependencies : [userspace,
3026                                 versiondep],
3027                 install_rpath : rootpkglibdir,
3028                 install : true,
3029                 install_dir : rootbindir)
3030 endif
3032 if conf.get('ENABLE_USERDB') == 1
3033         executable(
3034                 'systemd-userwork',
3035                 systemd_userwork_sources,
3036                 include_directories : includes,
3037                 link_with : [libshared],
3038                 dependencies : [threads,
3039                                 userspace,
3040                                 versiondep],
3041                 install_rpath : rootpkglibdir,
3042                 install : true,
3043                 install_dir : rootlibexecdir)
3045         executable(
3046                 'systemd-userdbd',
3047                 systemd_userdbd_sources,
3048                 include_directories : includes,
3049                 link_with : [libshared],
3050                 dependencies : [threads,
3051                                 userspace,
3052                                 versiondep],
3053                 install_rpath : rootpkglibdir,
3054                 install : true,
3055                 install_dir : rootlibexecdir)
3057         public_programs += executable(
3058                 'userdbctl',
3059                 userdbctl_sources,
3060                 include_directories : includes,
3061                 link_with : [libshared],
3062                 dependencies : [threads,
3063                                 userspace,
3064                                 versiondep],
3065                 install_rpath : rootpkglibdir,
3066                 install : true)
3067 endif
3069 if conf.get('ENABLE_HOMED') == 1
3070         executable(
3071                 'systemd-homework',
3072                 systemd_homework_sources,
3073                 include_directories : includes,
3074                 link_with : [libshared,
3075                              libshared_fdisk],
3076                 dependencies : [libblkid,
3077                                 libcrypt,
3078                                 libfdisk,
3079                                 libopenssl,
3080                                 libp11kit,
3081                                 threads,
3082                                 userspace,
3083                                 versiondep],
3084                 install_rpath : rootpkglibdir,
3085                 install : true,
3086                 install_dir : rootlibexecdir)
3088         dbus_programs += executable(
3089                 'systemd-homed',
3090                 systemd_homed_sources,
3091                 include_directories : home_includes,
3092                 link_with : [libshared],
3093                 dependencies : [libcrypt,
3094                                 libm,
3095                                 libopenssl,
3096                                 threads,
3097                                 userspace,
3098                                 versiondep],
3099                 install_rpath : rootpkglibdir,
3100                 install : true,
3101                 install_dir : rootlibexecdir)
3103         public_programs += executable(
3104                 'homectl',
3105                 homectl_sources,
3106                 include_directories : includes,
3107                 link_with : [libshared],
3108                 dependencies : [libcrypt,
3109                                 libdl,
3110                                 libopenssl,
3111                                 libp11kit,
3112                                 threads,
3113                                 userspace,
3114                                 versiondep],
3115                 install_rpath : rootpkglibdir,
3116                 install : true)
3118         if conf.get('HAVE_PAM') == 1
3119                 version_script_arg = project_source_root / pam_systemd_home_sym
3120                 pam_systemd_home = shared_library(
3121                         'pam_systemd_home',
3122                         pam_systemd_home_c,
3123                         name_prefix : '',
3124                         include_directories : includes,
3125                         link_args : ['-shared',
3126                                      '-Wl,--version-script=' + version_script_arg],
3127                         link_with : [libsystemd_static,
3128                                      libshared_static],
3129                         dependencies : [libcrypt,
3130                                         libpam_misc,
3131                                         libpam,
3132                                         threads,
3133                                         userspace,
3134                                         versiondep],
3135                         link_depends : pam_systemd_home_sym,
3136                         install : true,
3137                         install_tag : 'pam',
3138                         install_dir : pamlibdir)
3140                 if want_tests != 'false'
3141                         test('dlopen-pam_systemd_home',
3142                              test_dlopen,
3143                              # path to dlopen must include a slash
3144                              args : pam_systemd_home.full_path(),
3145                              depends : pam_systemd_home)
3146                 endif
3147         endif
3148 endif
3150 foreach alias : (['halt', 'poweroff', 'reboot', 'shutdown'] +
3151                  (conf.get('HAVE_SYSV_COMPAT') == 1 ? ['runlevel', 'telinit'] : []))
3152         meson.add_install_script(meson_make_symlink,
3153                                  rootbindir / 'systemctl',
3154                                  rootsbindir / alias)
3155 endforeach
3157 meson.add_install_script(meson_make_symlink,
3158                          rootbindir / 'udevadm',
3159                          rootlibexecdir / 'systemd-udevd')
3161 if conf.get('ENABLE_BACKLIGHT') == 1
3162         executable(
3163                 'systemd-backlight',
3164                 'src/backlight/backlight.c',
3165                 include_directories : includes,
3166                 link_with : [libshared],
3167                 dependencies : userspace,
3168                 install_rpath : rootpkglibdir,
3169                 install : true,
3170                 install_dir : rootlibexecdir)
3171 endif
3173 if conf.get('ENABLE_RFKILL') == 1
3174         executable(
3175                 'systemd-rfkill',
3176                 'src/rfkill/rfkill.c',
3177                 include_directories : includes,
3178                 link_with : [libshared],
3179                 dependencies : userspace,
3180                 install_rpath : rootpkglibdir,
3181                 install : true,
3182                 install_dir : rootlibexecdir)
3183 endif
3185 executable(
3186         'systemd-system-update-generator',
3187         'src/system-update-generator/system-update-generator.c',
3188         include_directories : includes,
3189         link_with : [libshared],
3190         dependencies : userspace,
3191         install_rpath : rootpkglibdir,
3192         install : true,
3193         install_dir : systemgeneratordir)
3195 if conf.get('HAVE_LIBCRYPTSETUP') == 1
3196         executable(
3197                 'systemd-cryptsetup',
3198                 systemd_cryptsetup_sources,
3199                 include_directories : includes,
3200                 link_with : [libshared],
3201                 dependencies : [libcryptsetup,
3202                                 libopenssl,
3203                                 libp11kit,
3204                                 userspace,
3205                                 versiondep],
3206                 install_rpath : rootpkglibdir,
3207                 install : true,
3208                 install_dir : rootlibexecdir)
3210         executable(
3211                 'systemd-cryptsetup-generator',
3212                 'src/cryptsetup/cryptsetup-generator.c',
3213                 include_directories : includes,
3214                 link_with : [libshared],
3215                 dependencies : userspace,
3216                 install_rpath : rootpkglibdir,
3217                 install : true,
3218                 install_dir : systemgeneratordir)
3220         executable(
3221                 'systemd-veritysetup',
3222                 'src/veritysetup/veritysetup.c',
3223                 include_directories : includes,
3224                 link_with : [libshared],
3225                 dependencies : [libcryptsetup,
3226                                 userspace,
3227                                 versiondep],
3228                 install_rpath : rootpkglibdir,
3229                 install : true,
3230                 install_dir : rootlibexecdir)
3232         executable(
3233                 'systemd-veritysetup-generator',
3234                 'src/veritysetup/veritysetup-generator.c',
3235                 include_directories : includes,
3236                 link_with : [libshared],
3237                 dependencies : [userspace,
3238                                 versiondep],
3239                 install_rpath : rootpkglibdir,
3240                 install : true,
3241                 install_dir : systemgeneratordir)
3243         public_programs += executable(
3244                 'systemd-cryptenroll',
3245                 systemd_cryptenroll_sources,
3246                 include_directories : includes,
3247                 link_with : [libshared],
3248                 dependencies : [libcryptsetup,
3249                                 libdl,
3250                                 libopenssl,
3251                                 libp11kit,
3252                                 userspace,
3253                                 versiondep],
3254                 install_rpath : rootpkglibdir,
3255                 install : true)
3257         executable(
3258                 'systemd-integritysetup',
3259                 ['src/integritysetup/integritysetup.c', 'src/integritysetup/integrity-util.c'],
3260                 include_directories : includes,
3261                 link_with : [libshared],
3262                 dependencies : [libcryptsetup,
3263                                 userspace,
3264                                 versiondep],
3265                 install_rpath : rootpkglibdir,
3266                 install : true,
3267                 install_dir : rootlibexecdir)
3269         executable(
3270                 'systemd-integritysetup-generator',
3271                 ['src/integritysetup/integritysetup-generator.c', 'src/integritysetup/integrity-util.c'],
3272                 include_directories : includes,
3273                 link_with : [libshared],
3274                 dependencies : userspace,
3275                 install_rpath : rootpkglibdir,
3276                 install : true,
3277                 install_dir : systemgeneratordir)
3278 endif
3280 if conf.get('HAVE_SYSV_COMPAT') == 1
3281         exe = executable(
3282                 'systemd-sysv-generator',
3283                 'src/sysv-generator/sysv-generator.c',
3284                 include_directories : includes,
3285                 link_with : [libshared],
3286                 dependencies : userspace,
3287                 install_rpath : rootpkglibdir,
3288                 install : true,
3289                 install_dir : systemgeneratordir)
3291         sysv_generator_test_py = find_program('test/sysv-generator-test.py')
3292         if want_tests != 'false'
3293                 test('sysv-generator-test',
3294                      sysv_generator_test_py,
3295                      depends : exe)
3296         endif
3298         executable(
3299                 'systemd-rc-local-generator',
3300                 'src/rc-local-generator/rc-local-generator.c',
3301                 include_directories : includes,
3302                 link_with : [libshared],
3303                 dependencies : userspace,
3304                 install_rpath : rootpkglibdir,
3305                 install : true,
3306                 install_dir : systemgeneratordir)
3307 endif
3309 if conf.get('ENABLE_XDG_AUTOSTART') == 1
3310         executable(
3311                 'systemd-xdg-autostart-generator',
3312                 systemd_xdg_autostart_generator_sources,
3313                 include_directories : includes,
3314                 link_with : [libshared],
3315                 dependencies : userspace,
3316                 install_rpath : rootpkglibdir,
3317                 install : true,
3318                 install_dir : usergeneratordir)
3320         executable(
3321                 'systemd-xdg-autostart-condition',
3322                 'src/xdg-autostart-generator/xdg-autostart-condition.c',
3323                 include_directories : includes,
3324                 link_with : [libshared],
3325                 dependencies : userspace,
3326                 install_rpath : rootpkglibdir,
3327                 install : true,
3328                 install_dir : rootlibexecdir)
3329 endif
3331 if conf.get('ENABLE_HOSTNAMED') == 1
3332         dbus_programs += executable(
3333                 'systemd-hostnamed',
3334                 'src/hostname/hostnamed.c',
3335                 include_directories : includes,
3336                 link_with : [libshared],
3337                 dependencies : userspace,
3338                 install_rpath : rootpkglibdir,
3339                 install : true,
3340                 install_dir : rootlibexecdir)
3342         public_programs += executable(
3343                 'hostnamectl',
3344                 'src/hostname/hostnamectl.c',
3345                 include_directories : includes,
3346                 link_with : [libshared],
3347                 dependencies : [userspace,
3348                                 versiondep],
3349                 install_rpath : rootpkglibdir,
3350                 install : true)
3351 endif
3353 if conf.get('ENABLE_LOCALED') == 1
3354         dbus_programs += executable(
3355                 'systemd-localed',
3356                 systemd_localed_sources,
3357                 include_directories : includes,
3358                 link_with : [libshared],
3359                 dependencies : libxkbcommon_deps +
3360                                [userspace,
3361                                 versiondep],
3362                 install_rpath : rootpkglibdir,
3363                 install : true,
3364                 install_dir : rootlibexecdir)
3366         public_programs += executable(
3367                 'localectl',
3368                 localectl_sources,
3369                 include_directories : includes,
3370                 link_with : [libshared],
3371                 dependencies : [userspace,
3372                                 versiondep],
3373                 install_rpath : rootpkglibdir,
3374                 install : true)
3375 endif
3377 if conf.get('ENABLE_TIMEDATED') == 1
3378         dbus_programs += executable(
3379                 'systemd-timedated',
3380                 'src/timedate/timedated.c',
3381                 include_directories : includes,
3382                 link_with : [libshared],
3383                 dependencies : userspace,
3384                 install_rpath : rootpkglibdir,
3385                 install : true,
3386                 install_dir : rootlibexecdir)
3387 endif
3389 if conf.get('ENABLE_TIMEDATECTL') == 1
3390         public_programs += executable(
3391                 'timedatectl',
3392                 'src/timedate/timedatectl.c',
3393                 include_directories : includes,
3394                 install_rpath : rootpkglibdir,
3395                 link_with : [libshared],
3396                 dependencies : [libm,
3397                                 userspace,
3398                                 versiondep],
3399                 install : true)
3400 endif
3402 if conf.get('ENABLE_TIMESYNCD') == 1
3403         executable(
3404                 'systemd-timesyncd',
3405                 systemd_timesyncd_sources,
3406                 include_directories : includes,
3407                 link_with : [libtimesyncd_core],
3408                 dependencies : [libm,
3409                                 threads,
3410                                 userspace,
3411                                 versiondep],
3412                 install_rpath : rootpkglibdir,
3413                 install : true,
3414                 install_dir : rootlibexecdir)
3416         executable(
3417                 'systemd-time-wait-sync',
3418                 'src/timesync/wait-sync.c',
3419                 include_directories : includes,
3420                 link_with : [libtimesyncd_core],
3421                 dependencies : userspace,
3422                 install_rpath : rootpkglibdir,
3423                 install : true,
3424                 install_dir : rootlibexecdir)
3425 endif
3427 if conf.get('ENABLE_MACHINED') == 1
3428         dbus_programs += executable(
3429                 'systemd-machined',
3430                 systemd_machined_sources,
3431                 include_directories : includes,
3432                 link_with : [libmachine_core,
3433                              libshared],
3434                 dependencies : userspace,
3435                 install_rpath : rootpkglibdir,
3436                 install : true,
3437                 install_dir : rootlibexecdir)
3439         public_programs += executable(
3440                 'machinectl',
3441                 'src/machine/machinectl.c',
3442                 include_directories : includes,
3443                 link_with : [libshared],
3444                 dependencies : [liblz4,
3445                                 libxz,
3446                                 libzstd,
3447                                 threads,
3448                                 userspace,
3449                                 versiondep],
3450                 install_rpath : rootpkglibdir,
3451                 install : true,
3452                 install_dir : rootbindir)
3453 endif
3455 if conf.get('ENABLE_IMPORTD') == 1
3456         dbus_programs += executable(
3457                 'systemd-importd',
3458                 systemd_importd_sources,
3459                 include_directories : includes,
3460                 link_with : [libshared],
3461                 dependencies : [threads,
3462                                 userspace,
3463                                 versiondep],
3464                 install_rpath : rootpkglibdir,
3465                 install : true,
3466                 install_dir : rootlibexecdir)
3468         systemd_pull = executable(
3469                 'systemd-pull',
3470                 systemd_pull_sources,
3471                 include_directories : includes,
3472                 link_with : [libshared,
3473                              lib_import_common],
3474                 dependencies : [lib_openssl_or_gcrypt,
3475                                 libbzip2,
3476                                 libcurl,
3477                                 libxz,
3478                                 libz,
3479                                 userspace,
3480                                 versiondep],
3481                 install_rpath : rootpkglibdir,
3482                 install : true,
3483                 install_dir : rootlibexecdir)
3485         systemd_import = executable(
3486                 'systemd-import',
3487                 systemd_import_sources,
3488                 include_directories : includes,
3489                 link_with : [libshared,
3490                              lib_import_common],
3491                 dependencies : [libbzip2,
3492                                 libcurl,
3493                                 libxz,
3494                                 libz,
3495                                 userspace,
3496                                 versiondep],
3497                 install_rpath : rootpkglibdir,
3498                 install : true,
3499                 install_dir : rootlibexecdir)
3501         systemd_import_fs = executable(
3502                 'systemd-import-fs',
3503                 systemd_import_fs_sources,
3504                 include_directories : includes,
3505                 link_with : [libshared,
3506                              lib_import_common],
3507                 dependencies : [userspace,
3508                                 versiondep],
3509                 install_rpath : rootpkglibdir,
3510                 install : true,
3511                 install_dir : rootlibexecdir)
3513         systemd_export = executable(
3514                 'systemd-export',
3515                 systemd_export_sources,
3516                 include_directories : includes,
3517                 link_with : [libshared,
3518                              lib_import_common],
3519                 dependencies : [libbzip2,
3520                                 libcurl,
3521                                 libxz,
3522                                 libz,
3523                                 userspace,
3524                                 versiondep],
3525                 install_rpath : rootpkglibdir,
3526                 install : true,
3527                 install_dir : rootlibexecdir)
3529         public_programs += [systemd_pull, systemd_import, systemd_import_fs, systemd_export]
3530 endif
3532 if conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_LIBCURL') == 1
3533         public_programs += executable(
3534                 'systemd-journal-upload',
3535                 systemd_journal_upload_sources,
3536                 include_directories : includes,
3537                 link_with : [libshared],
3538                 dependencies : [libcurl,
3539                                 libgnutls,
3540                                 liblz4,
3541                                 libxz,
3542                                 libzstd,
3543                                 threads,
3544                                 userspace,
3545                                 versiondep],
3546                 install_rpath : rootpkglibdir,
3547                 install : true,
3548                 install_dir : rootlibexecdir)
3549 endif
3551 if conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_MICROHTTPD') == 1
3552         public_programs += executable(
3553                 'systemd-journal-remote',
3554                 systemd_journal_remote_sources,
3555                 include_directories : journal_includes,
3556                 link_with : [libshared,
3557                              libsystemd_journal_remote],
3558                 dependencies : [libgnutls,
3559                                 liblz4,
3560                                 libmicrohttpd,
3561                                 libxz,
3562                                 libzstd,
3563                                 threads,
3564                                 userspace,
3565                                 versiondep],
3566                 install_rpath : rootpkglibdir,
3567                 install : true,
3568                 install_dir : rootlibexecdir)
3570         public_programs += executable(
3571                 'systemd-journal-gatewayd',
3572                 systemd_journal_gatewayd_sources,
3573                 include_directories : journal_includes,
3574                 link_with : [libshared],
3575                 dependencies : [libgnutls,
3576                                 liblz4,
3577                                 libmicrohttpd,
3578                                 libxz,
3579                                 libzstd,
3580                                 threads,
3581                                 userspace,
3582                                 versiondep],
3583                 install_rpath : rootpkglibdir,
3584                 install : true,
3585                 install_dir : rootlibexecdir)
3586 endif
3588 if conf.get('ENABLE_COREDUMP') == 1
3589         executable(
3590                 'systemd-coredump',
3591                 systemd_coredump_sources,
3592                 include_directories : includes,
3593                 link_with : [libshared,
3594                              libbasic_compress],
3595                 dependencies : [libacl,
3596                                 liblz4,
3597                                 libxz,
3598                                 libzstd,
3599                                 threads,
3600                                 userspace,
3601                                 versiondep],
3602                 install_rpath : rootpkglibdir,
3603                 install : true,
3604                 install_dir : rootlibexecdir)
3606         public_programs += executable(
3607                 'coredumpctl',
3608                 coredumpctl_sources,
3609                 include_directories : includes,
3610                 link_with : [libshared,
3611                              libbasic_compress],
3612                 dependencies : [liblz4,
3613                                 libxz,
3614                                 libzstd,
3615                                 threads,
3616                                 userspace,
3617                                 versiondep],
3618                 install_rpath : rootpkglibdir,
3619                 install : true)
3620 endif
3622 if conf.get('ENABLE_PSTORE') == 1
3623         executable(
3624                 'systemd-pstore',
3625                 systemd_pstore_sources,
3626                 include_directories : includes,
3627                 link_with : [libshared],
3628                 dependencies : [libacl,
3629                                 liblz4,
3630                                 libxz,
3631                                 libzstd,
3632                                 threads,
3633                                 userspace,
3634                                 versiondep],
3635                 install_rpath : rootpkglibdir,
3636                 install : true,
3637                 install_dir : rootlibexecdir)
3638 endif
3640 if conf.get('ENABLE_OOMD') == 1
3641         dbus_programs += executable('systemd-oomd',
3642                    systemd_oomd_sources,
3643                    include_directories : includes,
3644                    link_with : [libshared],
3645                    dependencies : [libatomic,
3646                                    userspace,
3647                                    versiondep],
3648                    install_rpath : rootpkglibdir,
3649                    install : true,
3650                    install_dir : rootlibexecdir)
3652         public_programs += executable(
3653                 'oomctl',
3654                 oomctl_sources,
3655                 include_directories : includes,
3656                 link_with : [libshared],
3657                 dependencies : [userspace,
3658                                 versiondep],
3659                 install_rpath : rootpkglibdir,
3660                 install : true)
3661 endif
3663 if conf.get('ENABLE_BINFMT') == 1
3664         public_programs += executable(
3665                 'systemd-binfmt',
3666                 'src/binfmt/binfmt.c',
3667                 include_directories : includes,
3668                 link_with : [libshared],
3669                 dependencies : [userspace,
3670                                 versiondep],
3671                 install_rpath : rootpkglibdir,
3672                 install : true,
3673                 install_dir : rootlibexecdir)
3675         meson.add_install_script('sh', '-c',
3676                                  mkdir_p.format(binfmtdir))
3677         if install_sysconfdir
3678                 meson.add_install_script('sh', '-c',
3679                                          mkdir_p.format(sysconfdir / 'binfmt.d'))
3680         endif
3681 endif
3683 if conf.get('ENABLE_SYSUPDATE') == 1
3684         exe = executable(
3685                 'systemd-sysupdate',
3686                 systemd_sysupdate_sources,
3687                 include_directories : includes,
3688                 link_with : [libshared,
3689                              libshared_fdisk],
3690                 dependencies : [libblkid,
3691                                 libfdisk,
3692                                 libopenssl,
3693                                 threads,
3694                                 userspace,
3695                                 versiondep],
3696                 install_rpath : rootpkglibdir,
3697                 install : true,
3698                 install_dir : rootlibexecdir)
3699         public_programs += exe
3700 endif
3702 if conf.get('ENABLE_VCONSOLE') == 1
3703         executable(
3704                 'systemd-vconsole-setup',
3705                 'src/vconsole/vconsole-setup.c',
3706                 include_directories : includes,
3707                 link_with : [libshared],
3708                 dependencies : userspace,
3709                 install_rpath : rootpkglibdir,
3710                 install : true,
3711                 install_dir : rootlibexecdir)
3712 endif
3714 if conf.get('ENABLE_RANDOMSEED') == 1
3715         executable(
3716                 'systemd-random-seed',
3717                 'src/random-seed/random-seed.c',
3718                 include_directories : includes,
3719                 link_with : [libshared],
3720                 dependencies : [userspace,
3721                                 versiondep],
3722                 install_rpath : rootpkglibdir,
3723                 install : true,
3724                 install_dir : rootlibexecdir)
3725 endif
3727 if conf.get('ENABLE_FIRSTBOOT') == 1
3728         public_programs += executable(
3729                 'systemd-firstboot',
3730                 'src/firstboot/firstboot.c',
3731                 include_directories : includes,
3732                 link_with : [libshared],
3733                 dependencies : [libcrypt,
3734                                 userspace,
3735                                 versiondep],
3736                 install_rpath : rootpkglibdir,
3737                 install : true,
3738                 install_dir : rootbindir)
3739 endif
3741 executable(
3742         'systemd-remount-fs',
3743         'src/remount-fs/remount-fs.c',
3744         include_directories : includes,
3745         link_with : [libshared],
3746         dependencies : [userspace,
3747                         versiondep],
3748         install_rpath : rootpkglibdir,
3749         install : true,
3750         install_dir : rootlibexecdir)
3752 executable(
3753         'systemd-machine-id-setup',
3754         'src/machine-id-setup/machine-id-setup-main.c',
3755         include_directories : includes,
3756         link_with : [libshared],
3757         dependencies : [userspace,
3758                         versiondep],
3759         install_rpath : rootpkglibdir,
3760         install : true,
3761         install_dir : rootbindir)
3763 executable(
3764         'systemd-fsck',
3765         'src/fsck/fsck.c',
3766         include_directories : includes,
3767         link_with : [libshared],
3768         dependencies : [userspace,
3769                         versiondep],
3770         install_rpath : rootpkglibdir,
3771         install : true,
3772         install_dir : rootlibexecdir)
3774 executable(
3775         'systemd-growfs',
3776         'src/partition/growfs.c',
3777         include_directories : includes,
3778         link_with : [libshared],
3779         dependencies : [userspace,
3780                         versiondep],
3781         install_rpath : rootpkglibdir,
3782         install : true,
3783         install_dir : rootlibexecdir)
3785 executable(
3786         'systemd-makefs',
3787         'src/partition/makefs.c',
3788         include_directories : includes,
3789         link_with : [libshared],
3790         dependencies : [userspace,
3791                         versiondep],
3792         install_rpath : rootpkglibdir,
3793         install : true,
3794         install_dir : rootlibexecdir)
3796 executable(
3797         'systemd-sleep',
3798         'src/sleep/sleep.c',
3799         include_directories : includes,
3800         link_with : [libshared],
3801         dependencies : [userspace,
3802                         versiondep],
3803         install_rpath : rootpkglibdir,
3804         install : true,
3805         install_dir : rootlibexecdir)
3807 if install_sysconfdir_samples
3808         install_data('src/sleep/sleep.conf',
3809                      install_dir : pkgsysconfdir)
3810 endif
3812 public_programs += executable(
3813         'systemd-sysctl',
3814         'src/sysctl/sysctl.c',
3815         include_directories : includes,
3816         link_with : [libshared],
3817         dependencies : [userspace,
3818                         versiondep],
3819         install_rpath : rootpkglibdir,
3820         install : true,
3821         install_dir : rootlibexecdir)
3823 public_programs += executable(
3824         'systemd-ac-power',
3825         'src/ac-power/ac-power.c',
3826         include_directories : includes,
3827         link_with : [libshared],
3828         dependencies : [userspace,
3829                         versiondep],
3830         install_rpath : rootpkglibdir,
3831         install : true)
3833 public_programs += executable(
3834         'systemd-detect-virt',
3835         'src/detect-virt/detect-virt.c',
3836         include_directories : includes,
3837         link_with : [libshared],
3838         dependencies : [userspace,
3839                         versiondep],
3840         install_rpath : rootpkglibdir,
3841         install : true)
3843 public_programs += executable(
3844         'systemd-delta',
3845         'src/delta/delta.c',
3846         include_directories : includes,
3847         link_with : [libshared],
3848         dependencies : [userspace,
3849                         versiondep],
3850         install_rpath : rootpkglibdir,
3851         install : true)
3853 public_programs += executable(
3854         'systemd-escape',
3855         'src/escape/escape.c',
3856         include_directories : includes,
3857         link_with : [libshared],
3858         dependencies : [userspace,
3859                         versiondep],
3860         install_rpath : rootpkglibdir,
3861         install : true,
3862         install_dir : rootbindir)
3864 public_programs += executable(
3865         'systemd-notify',
3866         'src/notify/notify.c',
3867         include_directories : includes,
3868         link_with : [libshared],
3869         dependencies : [userspace,
3870                         versiondep],
3871         install_rpath : rootpkglibdir,
3872         install : true,
3873         install_dir : rootbindir)
3875 public_programs += executable(
3876         'systemd-creds',
3877         'src/creds/creds.c',
3878         include_directories : includes,
3879         link_with : [libshared],
3880         dependencies : [threads,
3881                         libopenssl,
3882                         userspace,
3883                         versiondep],
3884         install_rpath : rootpkglibdir,
3885         install : true,
3886         install_dir : rootbindir)
3888 public_programs += executable(
3889         'systemd-battery-check',
3890         'src/battery-check/battery-check.c',
3891         include_directories : includes,
3892         link_with : [libshared],
3893         dependencies : [userspace, versiondep],
3894         install_rpath : rootpkglibdir,
3895         install_dir : rootlibexecdir,
3896         install : true)
3898 # Protecting files from the distro in /usr doesn't make sense since they can be trivially accessed otherwise,
3899 # so don't restrict the access mode in /usr. That doesn't apply to /etc, so we do restrict the access mode
3900 # there.
3901 meson.add_install_script('sh', '-c', mkdir_p.format(credstoredir))
3902 if install_sysconfdir
3903         # Keep in sync with tmpfiles.d/credstore.conf
3904         meson.add_install_script('sh', '-c', mkdir_p_mode.format(sysconfdir / 'credstore', '0700'))
3905         meson.add_install_script('sh', '-c', mkdir_p_mode.format(sysconfdir / 'credstore.encrypted', '0700'))
3906 endif
3908 executable(
3909         'systemd-volatile-root',
3910         'src/volatile-root/volatile-root.c',
3911         include_directories : includes,
3912         link_with : [libshared],
3913         dependencies : userspace,
3914         install_rpath : rootpkglibdir,
3915         install : conf.get('ENABLE_INITRD') == 1,
3916         install_dir : rootlibexecdir)
3918 executable(
3919         'systemd-cgroups-agent',
3920         'src/cgroups-agent/cgroups-agent.c',
3921         include_directories : includes,
3922         link_with : [libshared],
3923         dependencies : userspace,
3924         install_rpath : rootpkglibdir,
3925         install : true,
3926         install_dir : rootlibexecdir)
3928 systemd_id128 = executable(
3929         'systemd-id128',
3930         'src/id128/id128.c',
3931         include_directories : includes,
3932         link_with : [libshared],
3933         dependencies : [userspace,
3934                         versiondep],
3935         install_rpath : rootpkglibdir,
3936         install : true)
3937 public_programs += systemd_id128
3939 if want_tests != 'false'
3940         test('test-systemctl-enable',
3941              test_systemctl_enable_sh,
3942              # https://github.com/mesonbuild/meson/issues/2681
3943              args : [systemctl.full_path(),
3944                      systemd_id128.full_path()])
3945 endif
3947 public_programs += executable(
3948         'systemd-path',
3949         'src/path/path.c',
3950         include_directories : includes,
3951         link_with : [libshared],
3952         dependencies : [userspace,
3953                         versiondep],
3954         install_rpath : rootpkglibdir,
3955         install : true)
3957 public_programs += executable(
3958         'systemd-ask-password',
3959         'src/ask-password/ask-password.c',
3960         include_directories : includes,
3961         link_with : [libshared],
3962         dependencies : [userspace,
3963                         versiondep],
3964         install_rpath : rootpkglibdir,
3965         install : true,
3966         install_dir : rootbindir)
3968 executable(
3969         'systemd-reply-password',
3970         'src/reply-password/reply-password.c',
3971         include_directories : includes,
3972         link_with : [libshared],
3973         dependencies : userspace,
3974         install_rpath : rootpkglibdir,
3975         install : true,
3976         install_dir : rootlibexecdir)
3978 public_programs += executable(
3979         'systemd-tty-ask-password-agent',
3980         'src/tty-ask-password-agent/tty-ask-password-agent.c',
3981         include_directories : includes,
3982         link_with : [libshared],
3983         dependencies : [userspace,
3984                         versiondep],
3985         install_rpath : rootpkglibdir,
3986         install : true,
3987         install_dir : rootbindir)
3989 public_programs += executable(
3990         'systemd-cgls',
3991         'src/cgls/cgls.c',
3992         include_directories : includes,
3993         link_with : [libshared],
3994         dependencies : [userspace,
3995                         versiondep],
3996         install_rpath : rootpkglibdir,
3997         install : true)
3999 public_programs += executable(
4000         'systemd-cgtop',
4001         'src/cgtop/cgtop.c',
4002         include_directories : includes,
4003         link_with : [libshared],
4004         dependencies : [userspace,
4005                         versiondep],
4006         install_rpath : rootpkglibdir,
4007         install : true)
4009 executable(
4010         'systemd-initctl',
4011         'src/initctl/initctl.c',
4012         include_directories : includes,
4013         link_with : [libshared],
4014         dependencies : userspace,
4015         install_rpath : rootpkglibdir,
4016         install : (conf.get('HAVE_SYSV_COMPAT') == 1),
4017         install_dir : rootlibexecdir)
4019 public_programs += executable(
4020         'systemd-mount',
4021         'src/mount/mount-tool.c',
4022         include_directories : includes,
4023         link_with : [libshared],
4024         dependencies: [libmount,
4025                        userspace,
4026                        versiondep],
4027         install_rpath : rootpkglibdir,
4028         install : true)
4030 meson.add_install_script(meson_make_symlink,
4031                          'systemd-mount', bindir / 'systemd-umount')
4033 public_programs += executable(
4034         'systemd-run',
4035         'src/run/run.c',
4036         include_directories : includes,
4037         link_with : [libshared],
4038         dependencies : [userspace,
4039                         versiondep],
4040         install_rpath : rootpkglibdir,
4041         install : true)
4043 public_programs += executable(
4044         'systemd-stdio-bridge',
4045         'src/stdio-bridge/stdio-bridge.c',
4046         include_directories : includes,
4047         link_with : [libshared],
4048         dependencies : [userspace,
4049                         versiondep],
4050         install_rpath : rootpkglibdir,
4051         install : true)
4053 public_programs += executable(
4054         'busctl',
4055         busctl_sources,
4056         include_directories : includes,
4057         link_with : [libshared],
4058         dependencies : [userspace,
4059                         versiondep],
4060         install_rpath : rootpkglibdir,
4061         install : true)
4063 if enable_sysusers
4064         exe = executable(
4065                 'systemd-sysusers',
4066                 'src/sysusers/sysusers.c',
4067                 include_directories : includes,
4068                 link_with : [libshared],
4069                 dependencies : [userspace,
4070                                 versiondep],
4071                 install_rpath : rootpkglibdir,
4072                 install : true,
4073                 install_dir : rootbindir)
4074         public_programs += exe
4076         if want_tests != 'false'
4077                 test('test-sysusers',
4078                      test_sysusers_sh,
4079                      # https://github.com/mesonbuild/meson/issues/2681
4080                      args : exe.full_path())
4081         endif
4083         exe = executable(
4084                 'systemd-sysusers.standalone',
4085                 'src/sysusers/sysusers.c',
4086                 include_directories : includes,
4087                 c_args : '-DSTANDALONE',
4088                 link_with : [libshared_static,
4089                              libbasic,
4090                              libbasic_gcrypt,
4091                              libsystemd_static],
4092                 dependencies : [userspace,
4093                                 versiondep],
4094                 build_by_default: have_standalone_binaries,
4095                 install : have_standalone_binaries,
4096                 install_dir : rootbindir)
4097         if have_standalone_binaries
4098                 public_programs += exe
4100                 if want_tests != 'false'
4101                         test('test-sysusers.standalone',
4102                              test_sysusers_sh,
4103                              # https://github.com/mesonbuild/meson/issues/2681
4104                              args : exe.full_path())
4105                 endif
4106         endif
4107 endif
4109 if conf.get('ENABLE_TMPFILES') == 1
4110         exe = executable(
4111                 'systemd-tmpfiles',
4112                 systemd_tmpfiles_sources,
4113                 include_directories : includes,
4114                 link_with : [libshared],
4115                 dependencies : [libacl,
4116                                 userspace,
4117                                 versiondep],
4118                 install_rpath : rootpkglibdir,
4119                 install : true,
4120                 install_dir : rootbindir)
4121         public_programs += exe
4123         if want_tests != 'false'
4124                 test('test-systemd-tmpfiles',
4125                      test_systemd_tmpfiles_py,
4126                      # https://github.com/mesonbuild/meson/issues/2681
4127                      args : exe.full_path())
4128         endif
4130         exe = executable(
4131                 'systemd-tmpfiles.standalone',
4132                 systemd_tmpfiles_sources,
4133                 include_directories : includes,
4134                 c_args : '-DSTANDALONE',
4135                 link_with : [libshared_static,
4136                              libbasic,
4137                              libbasic_gcrypt,
4138                              libsystemd_static],
4139                 dependencies : [libacl,
4140                                 userspace,
4141                                 versiondep],
4142                 build_by_default: have_standalone_binaries,
4143                 install : have_standalone_binaries,
4144                 install_dir : rootbindir)
4145         if have_standalone_binaries
4146                 public_programs += exe
4148                 if want_tests != 'false'
4149                         test('test-systemd-tmpfiles.standalone',
4150                              test_systemd_tmpfiles_py,
4151                              # https://github.com/mesonbuild/meson/issues/2681
4152                              args : exe.full_path())
4153                 endif
4154         endif
4155 endif
4157 if conf.get('ENABLE_HWDB') == 1
4158         systemd_hwdb = executable(
4159                 'systemd-hwdb',
4160                 'src/hwdb/hwdb.c',
4161                 include_directories : includes,
4162                 link_with : udev_link_with,
4163                 dependencies : [userspace,
4164                                 versiondep],
4165                 install_rpath : udev_rpath,
4166                 install : true,
4167                 install_dir : rootbindir)
4168         public_programs += systemd_hwdb
4170         if want_tests != 'false'
4171                 test('hwdb-test',
4172                      hwdb_test_sh,
4173                      suite : 'dist',
4174                      args : [systemd_hwdb.full_path()],
4175                      timeout : 90)
4176         endif
4177 endif
4179 if conf.get('ENABLE_QUOTACHECK') == 1
4180         executable(
4181                 'systemd-quotacheck',
4182                 'src/quotacheck/quotacheck.c',
4183                 include_directories : includes,
4184                 link_with : [libshared],
4185                 dependencies : userspace,
4186                 install_rpath : rootpkglibdir,
4187                 install : true,
4188                 install_dir : rootlibexecdir)
4189 endif
4191 public_programs += executable(
4192         'systemd-socket-proxyd',
4193         'src/socket-proxy/socket-proxyd.c',
4194         include_directories : includes,
4195         link_with : [libshared],
4196         dependencies : [threads,
4197                         userspace,
4198                         versiondep],
4199         install_rpath : rootpkglibdir,
4200         install : true,
4201         install_dir : rootlibexecdir)
4203 udevadm = executable(
4204         'udevadm',
4205         udevadm_sources,
4206         include_directories : includes,
4207         link_with : [libudevd_core],
4208         dependencies : [libacl,
4209                         libblkid,
4210                         libidn,
4211                         libkmod,
4212                         threads,
4213                         userspace,
4214                         versiondep],
4215         install_rpath : udev_rpath,
4216         install : true,
4217         install_dir : rootbindir)
4218 public_programs += udevadm
4220 if want_tests != 'false'
4221         test('udev-rules-check',
4222              udevadm,
4223              suite : 'dist',
4224              args : ['verify', '--resolve-names=never', all_rules])
4225 endif
4227 if conf.get('ENABLE_REPART') == 1
4228         exe = executable(
4229                 'systemd-repart',
4230                 systemd_repart_sources,
4231                 include_directories : includes,
4232                 link_with : [libshared,
4233                              libshared_fdisk],
4234                 dependencies : [libblkid,
4235                                 libfdisk,
4236                                 libopenssl,
4237                                 threads,
4238                                 userspace,
4239                                 versiondep],
4240                 install_rpath : rootpkglibdir,
4241                 install : true,
4242                 install_dir : rootbindir)
4243         public_programs += exe
4245         exe = executable(
4246                 'systemd-repart.standalone',
4247                 systemd_repart_sources,
4248                 include_directories : includes,
4249                 c_args : '-DSTANDALONE',
4250                 link_with : [libshared_static,
4251                              libbasic,
4252                              libbasic_gcrypt,
4253                              libsystemd_static,
4254                              libshared_fdisk],
4255                 dependencies : [libblkid,
4256                                 libfdisk,
4257                                 libopenssl,
4258                                 threads,
4259                                 userspace,
4260                                 versiondep],
4261                 build_by_default: have_standalone_binaries,
4262                 install_rpath : rootpkglibdir,
4263                 install : have_standalone_binaries,
4264                 install_dir : rootbindir)
4265         if have_standalone_binaries
4266                 public_programs += exe
4267         endif
4268 endif
4270 executable(
4271         'systemd-shutdown',
4272         systemd_shutdown_sources,
4273         include_directories : includes,
4274         link_with : [libshared],
4275         dependencies : [libmount,
4276                         userspace,
4277                         versiondep],
4278         install_rpath : rootpkglibdir,
4279         install : true,
4280         install_dir : rootlibexecdir)
4282 executable(
4283         'systemd-shutdown.standalone',
4284         systemd_shutdown_sources,
4285         include_directories : includes,
4286         c_args : '-DSTANDALONE',
4287         link_with : [libshared_static,
4288                      libbasic,
4289                      libsystemd_static],
4290         dependencies : [libmount,
4291                         userspace,
4292                         versiondep],
4293         build_by_default: have_standalone_binaries,
4294         install_rpath : rootpkglibdir,
4295         install : have_standalone_binaries,
4296         install_dir : rootlibexecdir)
4298 executable(
4299         'systemd-update-done',
4300         'src/update-done/update-done.c',
4301         include_directories : includes,
4302         link_with : [libshared],
4303         dependencies : [userspace,
4304                         versiondep],
4305         install_rpath : rootpkglibdir,
4306         install : true,
4307         install_dir : rootlibexecdir)
4309 executable(
4310         'systemd-update-utmp',
4311         'src/update-utmp/update-utmp.c',
4312         include_directories : includes,
4313         link_with : [libshared],
4314         dependencies : [libaudit,
4315                         userspace,
4316                         versiondep],
4317         install_rpath : rootpkglibdir,
4318         install : (conf.get('ENABLE_UTMP') == 1),
4319         install_dir : rootlibexecdir)
4321 if conf.get('HAVE_KMOD') == 1
4322         executable(
4323                 'systemd-modules-load',
4324                 'src/modules-load/modules-load.c',
4325                 include_directories : includes,
4326                 link_with : [libshared],
4327                 dependencies : [libkmod,
4328                                 userspace,
4329                                 versiondep],
4330                 install_rpath : rootpkglibdir,
4331                 install : true,
4332                 install_dir : rootlibexecdir)
4334         meson.add_install_script('sh', '-c',
4335                                  mkdir_p.format(modulesloaddir))
4336         if install_sysconfdir
4337                 meson.add_install_script('sh', '-c',
4338                                          mkdir_p.format(sysconfdir / 'modules-load.d'))
4339         endif
4340 endif
4342 public_programs += executable(
4343         'systemd-nspawn',
4344         systemd_nspawn_sources,
4345         include_directories : includes,
4346         link_with : [libnspawn_core,
4347                      libshared],
4348         dependencies : [libblkid,
4349                         libseccomp,
4350                         userspace,
4351                         versiondep],
4352         install_rpath : rootpkglibdir,
4353         install : true)
4355 if conf.get('ENABLE_NETWORKD') == 1
4356         dbus_programs += executable(
4357                 'systemd-networkd',
4358                 systemd_networkd_sources,
4359                 include_directories : network_includes,
4360                 link_with : [libnetworkd_core,
4361                              libsystemd_network,
4362                              networkd_link_with],
4363                 dependencies : [threads,
4364                                 userspace,
4365                                 versiondep],
4366                 install_rpath : rootpkglibdir,
4367                 install : true,
4368                 install_dir : rootlibexecdir)
4370         public_programs += executable(
4371                 'systemd-networkd-wait-online',
4372                 systemd_networkd_wait_online_sources,
4373                 include_directories : includes,
4374                 link_with : [networkd_link_with],
4375                 dependencies : [userspace,
4376                                 versiondep],
4377                 install_rpath : rootpkglibdir,
4378                 install : true,
4379                 install_dir : rootlibexecdir)
4381         public_programs += executable(
4382                 'networkctl',
4383                 networkctl_sources,
4384                 include_directories : libsystemd_network_includes,
4385                 link_with : [libsystemd_network,
4386                              networkd_link_with],
4387                 dependencies : [userspace,
4388                                 versiondep],
4389                 install_rpath : rootpkglibdir,
4390                 install : true,
4391                 install_dir : rootbindir)
4392 endif
4394 exe = executable(
4395         'systemd-network-generator',
4396         network_generator_sources,
4397         include_directories : includes,
4398         link_with : [networkd_link_with],
4399         dependencies : [userspace,
4400                         versiondep],
4401         install_rpath : rootpkglibdir,
4402         install : true,
4403         install_dir : rootlibexecdir)
4405 if want_tests != 'false'
4406         test('test-network-generator-conversion',
4407              test_network_generator_conversion_sh,
4408              # https://github.com/mesonbuild/meson/issues/2681
4409              args : exe.full_path(),
4410              depends : exe)
4411 endif
4413 executable(
4414         'systemd-sulogin-shell',
4415         'src/sulogin-shell/sulogin-shell.c',
4416         include_directories : includes,
4417         link_with : [libshared],
4418         dependencies : [userspace,
4419                         versiondep],
4420         install_rpath : rootpkglibdir,
4421         install : true,
4422         install_dir : rootlibexecdir)
4424 kernel_install = executable(
4425         'kernel-install',
4426         'src/kernel-install/kernel-install.c',
4427         include_directories : includes,
4428         link_with : [libshared],
4429         dependencies : [userspace,
4430                         versiondep],
4431         install_rpath : rootpkglibdir,
4432         install : want_kernel_install,
4433         install_dir : bindir)
4434 public_programs += kernel_install
4436 ukify = custom_target(
4437         'ukify',
4438         input : 'src/ukify/ukify.py',
4439         output : 'ukify',
4440         command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
4441         install : want_ukify,
4442         install_mode : 'rwxr-xr-x',
4443         install_dir : rootlibexecdir)
4444 if want_ukify
4445         public_programs += ukify
4446 endif
4448 if want_tests != 'false' and want_kernel_install
4449         args = [kernel_install.full_path(), loaderentry_install.full_path(), uki_copy_install]
4450         deps = [kernel_install, loaderentry_install]
4451         if want_ukify and boot_stubs.length() > 0
4452                 args += [ukify.full_path(), ukify_install.full_path(), boot_stubs[0]]
4453                 deps += [ukify, ukify_install, boot_stubs[0]]
4454         endif
4456         test('test-kernel-install',
4457              test_kernel_install_sh,
4458              env : test_env,
4459              args : args,
4460              depends: deps)
4461 endif
4463 ############################################################
4465 runtest_env = custom_target(
4466         'systemd-runtest.env',
4467         output : 'systemd-runtest.env',
4468         command : [sh, '-c',
4469                    '{ echo SYSTEMD_TEST_DATA=@0@; echo SYSTEMD_CATALOG_DIR=@1@; } >@OUTPUT@'.format(
4470                            project_source_root / 'test',
4471                            project_build_root / 'catalog')],
4472         depends : catalogs,
4473         build_by_default : true)
4475 test_cflags = ['-DTEST_CODE=1']
4476 # We intentionally do not do inline initializations with definitions for a
4477 # bunch of _cleanup_ variables in tests, to ensure valgrind is triggered if we
4478 # use the variable unexpectedly. This triggers a lot of maybe-uninitialized
4479 # false positives when the combination of -O2 and -flto is used. Suppress them.
4480 if '-O2' in c_args and '-flto=auto' in c_args
4481         test_cflags += cc.first_supported_argument('-Wno-maybe-uninitialized')
4482 endif
4484 foreach test : simple_tests
4485         tests += { 'sources' : [test] }
4486 endforeach
4488 TESTS = {}
4489 foreach test : tests
4490         sources = test.get('sources')
4491         condition = test.get('condition', '')
4492         type = test.get('type', '')
4493         base = test.get('base', {})
4494         deps = [
4495                 base.get('dependencies', []),
4496                 test.get('dependencies', []),
4497                 versiondep,
4498         ]
4500         name = fs.name(sources[0])
4501         if not name.endswith('.cc')
4502                 deps += [userspace]
4503         endif
4504         name = fs.stem(name)
4506         suite = fs.name(fs.parent(sources[0])).replace('sd-', '')
4508         if condition != '' and conf.get(condition) == 0
4509                 message('Not compiling @0@ because @1@ is not true'.format(name, condition))
4510                 continue
4511         endif
4513         exe = executable(
4514                 name,
4515                 sources,
4516                 include_directories : [base.get('includes', []), test.get('includes', includes)],
4517                 link_with : [base.get('link_with', []), test.get('link_with', libshared)],
4518                 dependencies : deps,
4519                 c_args : [test_cflags, test.get('c_args', [])],
4520                 build_by_default : want_tests != 'false',
4521                 install_rpath : rootpkglibdir,
4522                 install : install_tests,
4523                 install_dir : unittestsdir / type,
4524                 link_depends : runtest_env)
4526         if type == 'manual'
4527                 message('@0@ is a manual test'.format(name))
4528         elif type == 'unsafe' and want_tests != 'unsafe'
4529                 message('@0@ is an unsafe test'.format(name))
4530         elif want_tests != 'false'
4531                 test(name, exe,
4532                      env : test_env,
4533                      timeout : test.get('timeout', 30),
4534                      suite : suite,
4535                      is_parallel : test.get('parallel', true))
4536         endif
4538         TESTS += { name : exe }
4539 endforeach
4541 exe = executable(
4542         'test-libsystemd-sym',
4543         test_libsystemd_sym_c,
4544         include_directories : includes,
4545         link_with : [libsystemd],
4546         dependencies : userspace,
4547         build_by_default : want_tests != 'false',
4548         install : install_tests,
4549         install_dir : unittestsdir)
4550 if want_tests != 'false'
4551         test('test-libsystemd-sym', exe)
4552 endif
4554 exe = executable(
4555         'test-libsystemd-static-sym',
4556         test_libsystemd_sym_c,
4557         include_directories : includes,
4558         link_with : [install_libsystemd_static],
4559         dependencies : [
4560                 # threads is already included in dependencies on the library,
4561                 # but does not seem to get propagated. Add here as a work-around.
4562                 threads,
4563                 userspace,
4564         ],
4565         build_by_default : want_tests != 'false' and static_libsystemd != 'false',
4566         install : install_tests and static_libsystemd != 'false',
4567         install_dir : unittestsdir)
4568 if want_tests != 'false' and static_libsystemd != 'false'
4569         test('test-libsystemd-static-sym', exe)
4570 endif
4572 exe = executable(
4573         'test-libudev-sym',
4574         test_libudev_sym_c,
4575         include_directories : libudev_includes,
4576         c_args : ['-Wno-deprecated-declarations'] + test_cflags,
4577         link_with : [libudev],
4578         dependencies : userspace,
4579         build_by_default : want_tests != 'false',
4580         install : install_tests,
4581         install_dir : unittestsdir)
4582 if want_tests != 'false'
4583         test('test-libudev-sym', exe)
4584 endif
4586 exe = executable(
4587         'test-libudev-static-sym',
4588         test_libudev_sym_c,
4589         include_directories : libudev_includes,
4590         c_args : ['-Wno-deprecated-declarations'] + test_cflags,
4591         link_with : [install_libudev_static],
4592         dependencies : userspace,
4593         build_by_default : want_tests != 'false' and static_libudev != 'false',
4594         install : install_tests and static_libudev != 'false',
4595         install_dir : unittestsdir)
4596 if want_tests != 'false' and static_libudev != 'false'
4597         test('test-libudev-static-sym', exe)
4598 endif
4600 if want_tests != 'false'
4601         exe = TESTS.get('udev-rule-runner')
4602         test('test-udev',
4603              test_udev_py,
4604              args : ['-v'],
4605              env : ['UDEV_RULE_RUNNER=' + exe.full_path()],
4606              depends : exe,
4607              timeout : 180)
4608 endif
4610 ############################################################
4612 foreach fuzzer : simple_fuzzers
4613         fuzzers += { 'sources' : [fuzzer] }
4614 endforeach
4616 fuzzer_exes = []
4618 foreach fuzzer : fuzzers
4619         sources = fuzzer.get('sources')
4620         base = fuzzer.get('base', {})
4621         dependencies = [base.get('dependencies', []), fuzzer.get('dependencies', [])]
4622         link_args = []
4624         if want_ossfuzz
4625                 dependencies += fuzzing_engine
4626         elif want_libfuzzer
4627                 if fuzzing_engine.found()
4628                         dependencies += fuzzing_engine
4629                 else
4630                         link_args += ['-fsanitize=fuzzer']
4631                 endif
4632         else
4633                 sources += files('src/fuzz/fuzz-main.c')
4634         endif
4635         sources += fuzz_generated_directives
4637         name = fs.stem(sources[0])
4639         exe = executable(
4640                 name,
4641                 sources,
4642                 include_directories : [
4643                         base.get('includes', []),
4644                         fuzzer.get('includes', includes),
4645                         include_directories('src/fuzz'),
4646                 ],
4647                 link_with : [base.get('link_with', []), fuzzer.get('link_with', libshared)],
4648                 dependencies : [
4649                         dependencies,
4650                         userspace,
4651                         versiondep,
4652                 ],
4653                 c_args : [test_cflags, fuzzer.get('c_args', [])],
4654                 link_args: link_args,
4655                 install : false,
4656                 build_by_default : fuzzer_build)
4657         fuzzer_exes += exe
4659         if want_tests != 'false' and name in fuzz_regression_tests
4660                 # Run the fuzz regression tests without any sanitizers enabled.
4661                 # Additional invocations with sanitizers may be added below.
4662                 foreach tuple : fuzz_regression_tests[name]
4663                         fuzz_dir = tuple[0]
4664                         fuzz_in = tuple[1]
4665                         test('@0@_@1@'.format(name, fuzz_in),
4666                              exe,
4667                              suite : 'fuzz',
4668                              args : [fuzz_dir != '' ? project_source_root / fuzz_dir / name / fuzz_in
4669                                                     : fuzz_generated_in_dir / '@0@_@1@'.format(name, fuzz_in)])
4670                 endforeach
4671         endif
4672 endforeach
4674 alias_target('fuzzers', fuzzer_exes)
4676 ############################################################
4678 subdir('docs/sysvinit')
4679 subdir('docs/var-log')
4680 subdir('hwdb.d')
4681 subdir('man')
4682 subdir('modprobe.d')
4683 subdir('network')
4684 subdir('presets')
4685 subdir('shell-completion/bash')
4686 subdir('shell-completion/zsh')
4687 subdir('sysctl.d')
4688 subdir('sysusers.d')
4689 subdir('tmpfiles.d')
4690 subdir('units')
4692 install_subdir('factory/etc',
4693                install_dir : factorydir)
4694 subdir('factory/templates')
4696 if install_sysconfdir
4697         install_data('xorg/50-systemd-user.sh',
4698                      install_dir : xinitrcdir)
4699 endif
4700 install_data('LICENSE.GPL2',
4701              'LICENSE.LGPL2.1',
4702              'NEWS',
4703              'README',
4704              'docs/CODING_STYLE.md',
4705              'docs/DISTRO_PORTING.md',
4706              'docs/ENVIRONMENT.md',
4707              'docs/HACKING.md',
4708              'docs/TRANSIENT-SETTINGS.md',
4709              'docs/TRANSLATORS.md',
4710              'docs/UIDS-GIDS.md',
4711              install_dir : docdir)
4713 install_subdir('LICENSES',
4714                install_dir : docdir)
4716 meson.add_install_script('sh', '-c', mkdir_p.format(systemdstatedir))
4717 meson.add_install_script('sh', '-c', 'touch $DESTDIR@0@'.format(prefixdir))
4719 ############################################################
4721 # Ensure that changes to the docs/ directory do not break the
4722 # basic Github pages build. But only run it in developer mode,
4723 # as it might be fragile due to changes in the tooling, and it is
4724 # not generally useful for users.
4725 jekyll = find_program('jekyll', required : false)
4726 if get_option('mode') == 'developer' and want_tests != 'false' and jekyll.found()
4727         test('github-pages',
4728              jekyll,
4729              suite : 'dist',
4730              args : ['build',
4731                      '--source', project_source_root / 'docs',
4732                      '--destination', project_build_root / '_site'])
4733 endif
4735 ############################################################
4737 check_help = find_program('tools/check-help.sh')
4738 check_version = find_program('tools/check-version.sh')
4740 foreach exec : public_programs
4741         name = fs.name(exec.full_path())
4742         if want_tests != 'false'
4743                 test('check-help-' + name,
4744                      check_help,
4745                      suite : 'dist',
4746                      args : exec.full_path(),
4747                      depends: exec)
4749                 test('check-version-' + name,
4750                      check_version,
4751                      suite : 'dist',
4752                      args : [exec.full_path(),
4753                              meson.project_version()],
4754                      depends: exec)
4755         endif
4756 endforeach
4758 # Enable tests for all supported sanitizers
4759 foreach tuple : fuzz_sanitizers
4760         sanitizer = tuple[0]
4761         build = tuple[1]
4763         if cc.has_link_argument('-fsanitize=@0@'.format(sanitizer))
4764                 foreach fuzzer, fuzz_ins : fuzz_regression_tests
4765                         name = '@0@:@1@'.format(fuzzer, sanitizer)
4766                         if want_tests == 'false'
4767                                 message('Not compiling @0@ because tests is set to false'.format(name))
4768                                 continue
4769                         endif
4770                         if not fuzz_tests
4771                                 message('Not compiling @0@ because fuzz-tests is set to false'.format(name))
4772                                 continue
4773                         endif
4774                         exe = custom_target(
4775                                 name,
4776                                 output : name,
4777                                 depends : [build] + fuzz_generated_directives,
4778                                 command : [ln, '-fs',
4779                                            build.full_path() / fuzzer,
4780                                            '@OUTPUT@'],
4781                                 build_by_default : true)
4783                         foreach tuple : fuzz_ins
4784                                 fuzz_dir = tuple[0]
4785                                 fuzz_in = tuple[1]
4787                                 test('@0@_@1@_@2@'.format(fuzzer, fuzz_in, sanitizer),
4788                                      env,
4789                                      suite : 'fuzz+san',
4790                                      env : ['UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1'],
4791                                      timeout : 60,
4792                                      args : [exe.full_path(),
4793                                              fuzz_dir != '' ? project_source_root / fuzz_dir / fuzzer / fuzz_in
4794                                                             : fuzz_generated_in_dir / '@0@_@1@'.format(fuzzer, fuzz_in)])
4795                         endforeach
4796                 endforeach
4797         endif
4798 endforeach
4800 ############################################################
4802 if git.found()
4803         all_files = run_command(
4804                 env, '-u', 'GIT_WORK_TREE',
4805                 git, '--git-dir=@0@/.git'.format(project_source_root),
4806                      'ls-files', ':/*.[ch]', ':/*.cc',
4807                 check : false)
4808         if all_files.returncode() == 0
4809                 all_files = files(all_files.stdout().split())
4811                 custom_target(
4812                         'tags',
4813                         output : 'tags',
4814                         command : [env, 'etags', '-o', '@0@/TAGS'.format(project_source_root)] + all_files)
4815                 run_target(
4816                         'ctags',
4817                         command : [env, 'ctags', '--tag-relative=never', '-o', '@0@/tags'.format(project_source_root)] + all_files)
4819                 ############################################
4821                 if want_tests != 'false' and conf.get('BUILD_MODE_DEVELOPER') == 1
4822                         test('check-includes',
4823                              files('tools/check-includes.py'),
4824                              args: all_files,
4825                              env : ['PROJECT_SOURCE_ROOT=@0@'.format(project_source_root)])
4826                 endif
4827         endif
4829         ####################################################
4831         git_contrib_sh = find_program('tools/git-contrib.sh')
4832         run_target(
4833                 'git-contrib',
4834                 command : [git_contrib_sh])
4836         ####################################################
4838         git_head = run_command(
4839                 git, '--git-dir=@0@/.git'.format(project_source_root),
4840                      'rev-parse', 'HEAD',
4841                 check : false).stdout().strip()
4842         git_head_short = run_command(
4843                 git, '--git-dir=@0@/.git'.format(project_source_root),
4844                      'rev-parse', '--short=7', 'HEAD',
4845                 check : false).stdout().strip()
4847         run_target(
4848                 'git-snapshot',
4849                 command : [git, 'archive',
4850                            '-o', '@0@/systemd-@1@.tar.gz'.format(project_source_root,
4851                                                                  git_head_short),
4852                            '--prefix', 'systemd-@0@/'.format(git_head),
4853                            'HEAD'])
4854 endif
4856 ############################################################
4858 check_api_docs_sh = find_program('tools/check-api-docs.sh')
4859 run_target(
4860         'check-api-docs',
4861         depends : [man, libsystemd, libudev],
4862         command : [check_api_docs_sh, libsystemd.full_path(), libudev.full_path()])
4864 alias_target('update-dbus-docs', update_dbus_docs)
4865 alias_target('update-man-rules', update_man_rules)
4867 if not meson.is_cross_build()
4868         custom_target(
4869                 'export-dbus-interfaces',
4870                 output : fs.name(dbus_interfaces_dir),
4871                 install : dbus_interfaces_dir != 'no',
4872                 install_dir : fs.parent(dbus_interfaces_dir),
4873                 command : [export_dbus_interfaces_py, '@OUTPUT@', dbus_programs])
4874 endif
4876 ############################################################
4878 alt_time_epoch = run_command('date', '-Is', '-u', '-d', '@@0@'.format(time_epoch),
4879                              check : true).stdout().strip()
4881 summary({
4882         'split /usr' :                      split_usr,
4883         'split bin-sbin' :                  split_bin,
4884         'prefix directory' :                prefixdir,
4885         'rootprefix directory' :            rootprefixdir,
4886         'sysconf directory' :               sysconfdir,
4887         'include directory' :               includedir,
4888         'lib directory' :                   libdir,
4889         'rootlib directory' :               rootlibdir,
4890         'SysV init scripts' :               sysvinit_path,
4891         'SysV rc?.d directories' :          sysvrcnd_path,
4892         'PAM modules directory' :           pamlibdir,
4893         'PAM configuration directory' :     pamconfdir,
4894         'libcryptsetup plugins directory' : libcryptsetup_plugins_dir,
4895         'RPM macros directory' :            rpmmacrosdir,
4896         'modprobe.d directory' :            modprobedir,
4897         'D-Bus policy directory' :          dbuspolicydir,
4898         'D-Bus session directory' :         dbussessionservicedir,
4899         'D-Bus system directory' :          dbussystemservicedir,
4900         'D-Bus interfaces directory' :      dbus_interfaces_dir,
4901         'bash completions directory' :      bashcompletiondir,
4902         'zsh completions directory' :       zshcompletiondir,
4903         'private shared lib version tag' :  shared_lib_tag,
4904         'extra start script' :              get_option('rc-local'),
4905         'debug shell' :                     '@0@ @ @1@'.format(get_option('debug-shell'),
4906                                                                get_option('debug-tty')),
4907         'system UIDs' :                     '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_UID_MAX'),
4908                                                                          conf.get('SYSTEM_ALLOC_UID_MIN')),
4909         'system GIDs' :                     '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
4910                                                                          conf.get('SYSTEM_ALLOC_GID_MIN')),
4911         'dynamic UIDs' :                    '@0@…@1@'.format(dynamic_uid_min, dynamic_uid_max),
4912         'container UID bases' :             '@0@…@1@'.format(container_uid_base_min, container_uid_base_max),
4913         'static UID/GID allocations' :      ' '.join(static_ugids),
4914         '/dev/kvm access mode' :            get_option('dev-kvm-mode'),
4915         'render group access mode' :        get_option('group-render-mode'),
4916         'certificate root directory' :      get_option('certificate-root'),
4917         'support URL' :                     support_url,
4918         'nobody user name' :                nobody_user,
4919         'nobody group name' :               nobody_group,
4920         'fallback hostname' :               get_option('fallback-hostname'),
4921         'default compression method' :      compression,
4922         'default DNSSEC mode' :             default_dnssec,
4923         'default DNS-over-TLS mode' :       default_dns_over_tls,
4924         'default mDNS mode' :               default_mdns,
4925         'default LLMNR mode' :              default_llmnr,
4926         'default DNS servers' :             dns_servers.split(' '),
4927         'default NTP servers' :             ntp_servers.split(' '),
4928         'default cgroup hierarchy' :        default_hierarchy,
4929         'default net.naming-scheme value' : default_net_naming_scheme,
4930         'default KillUserProcesses value' : kill_user_processes,
4931         'default locale' :                  default_locale,
4932         'default nspawn locale' :           nspawn_locale,
4933         'default status unit format' :      status_unit_format_default,
4934         'default user $PATH' :
4935                 default_user_path != '' ? default_user_path : '(same as system services)',
4936         'systemd service watchdog' :        service_watchdog == '' ? 'disabled' : service_watchdog,
4937         'time epoch' :                      '@0@ (@1@)'.format(time_epoch, alt_time_epoch)})
4939 # TODO:
4940 # CFLAGS:   ${OUR_CFLAGS} ${CFLAGS}
4941 # CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
4942 # LDFLAGS:  ${OUR_LDFLAGS} ${LDFLAGS}
4944 found = []
4945 missing = []
4947 foreach tuple : [
4948         # dependencies
4949         ['ACL'],
4950         ['AUDIT'],
4951         ['AppArmor'],
4952         ['IMA'],
4953         ['PAM'],
4954         ['SECCOMP'],
4955         ['SELinux'],
4956         ['SMACK'],
4957         ['blkid'],
4958         ['elfutils'],
4959         ['gcrypt'],
4960         ['gnutls'],
4961         ['libbpf'],
4962         ['libcryptsetup'],
4963         ['libcryptsetup-plugins'],
4964         ['libcurl'],
4965         ['libfdisk'],
4966         ['libfido2'],
4967         ['libidn'],
4968         ['libidn2'],
4969         ['libiptc'],
4970         ['microhttpd'],
4971         ['openssl'],
4972         ['p11kit'],
4973         ['passwdqc'],
4974         ['pcre2'],
4975         ['pwquality'],
4976         ['qrencode'],
4977         ['tpm2'],
4978         ['xkbcommon'],
4980         # compression libs
4981         ['zstd'],
4982         ['lz4'],
4983         ['xz'],
4984         ['zlib'],
4985         ['bzip2'],
4987         # components
4988         ['backlight'],
4989         ['binfmt'],
4990         ['bootloader'],
4991         ['bpf-framework',          conf.get('BPF_FRAMEWORK') == 1],
4992         ['coredump'],
4993         ['efi'],
4994         ['environment.d'],
4995         ['firstboot'],
4996         ['hibernate'],
4997         ['homed'],
4998         ['hostnamed'],
4999         ['hwdb'],
5000         ['importd'],
5001         ['initrd'],
5002         ['kernel-install'],
5003         ['localed'],
5004         ['logind'],
5005         ['machined'],
5006         ['networkd'],
5007         ['nss-myhostname'],
5008         ['nss-mymachines'],
5009         ['nss-resolve'],
5010         ['nss-systemd'],
5011         ['oomd'],
5012         ['portabled'],
5013         ['pstore'],
5014         ['quotacheck'],
5015         ['randomseed'],
5016         ['repart'],
5017         ['resolve'],
5018         ['rfkill'],
5019         ['sysext'],
5020         ['systemd-analyze',        conf.get('ENABLE_ANALYZE') == 1],
5021         ['sysupdate'],
5022         ['sysusers'],
5023         ['timedated'],
5024         ['timesyncd'],
5025         ['tmpfiles'],
5026         ['userdb'],
5027         ['vconsole'],
5028         ['xdg-autostart'],
5030         # optional features
5031         ['idn'],
5032         ['polkit'],
5033         ['nscd'],
5034         ['legacy-pkla',            install_polkit_pkla],
5035         ['kmod'],
5036         ['xenctrl'],
5037         ['dbus'],
5038         ['glib'],
5039         ['tpm'],
5040         ['man pages',              want_man],
5041         ['html pages',             want_html],
5042         ['man page indices',       want_man and have_lxml],
5043         ['SysV compat'],
5044         ['compat-mutable-uid-boundaries'],
5045         ['utmp'],
5046         ['ldconfig'],
5047         ['adm group',              get_option('adm-group')],
5048         ['wheel group',            get_option('wheel-group')],
5049         ['gshadow'],
5050         ['debug hashmap'],
5051         ['debug mmap cache'],
5052         ['debug siphash'],
5053         ['trace logging',          conf.get('LOG_TRACE') == 1],
5054         ['slow tests',             slow_tests],
5055         ['fuzz tests',             fuzz_tests],
5056         ['install tests',          install_tests],
5057         ['link-udev-shared',       get_option('link-udev-shared')],
5058         ['link-systemctl-shared',  get_option('link-systemctl-shared')],
5059         ['link-networkd-shared',   get_option('link-networkd-shared')],
5060         ['link-timesyncd-shared',  get_option('link-timesyncd-shared')],
5061         ['link-journalctl-shared', get_option('link-journalctl-shared')],
5062         ['link-boot-shared',       get_option('link-boot-shared')],
5063         ['link-portabled-shared',  get_option('link-portabled-shared')],
5064         ['first-boot-full-preset'],
5065         ['fexecve'],
5066         ['standalone-binaries',    get_option('standalone-binaries')],
5067         ['coverage',               get_option('b_coverage')],
5070         if tuple.length() >= 2
5071                 cond = tuple[1]
5072         else
5073                 ident1 = 'HAVE_' + tuple[0].underscorify().to_upper()
5074                 ident2 = 'ENABLE_' + tuple[0].underscorify().to_upper()
5075                 cond = conf.get(ident1, 0) == 1 or conf.get(ident2, 0) == 1
5076         endif
5077         if cond
5078                 found += tuple[0]
5079         else
5080                 missing += tuple[0]
5081         endif
5082 endforeach
5084 if static_libsystemd == 'false'
5085         missing += 'static-libsystemd'
5086 else
5087         found += 'static-libsystemd(@0@)'.format(static_libsystemd)
5088 endif
5090 if static_libudev == 'false'
5091         missing += 'static-libudev'
5092 else
5093         found += 'static-libudev(@0@)'.format(static_libudev)
5094 endif
5096 if conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1 and conf.get('PREFER_OPENSSL') == 1
5097         found += 'cryptolib(openssl)'
5098 elif conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1
5099         found += 'cryptolib(gcrypt)'
5100 else
5101         missing += 'cryptolib'
5102 endif
5104 if conf.get('DNS_OVER_TLS_USE_GNUTLS') == 1
5105         found += 'DNS-over-TLS(gnutls)'
5106 elif conf.get('DNS_OVER_TLS_USE_OPENSSL') == 1
5107         found += 'DNS-over-TLS(openssl)'
5108 else
5109         missing += 'DNS-over-TLS'
5110 endif
5112 summary({
5113         'enabled' :  ', '.join(found),
5114         'disabled' : ', '.join(missing)},
5115         section : 'Features')
5117 if rootprefixdir != rootprefix_default
5118         warning('\n' +
5119                 'Note that the installation prefix was changed to "@0@".\n'.format(rootprefixdir) +
5120                 'systemd used fixed names for unit file directories and other paths, so anything\n' +
5121                 'except the default ("@0@") is strongly discouraged.'.format(rootprefix_default))
5122 endif