]> git.ipfire.org Git - thirdparty/systemd.git/blame - meson.build
test-64-udev-storage: partition disk inside testcase - testcase_multipath_basic_failover
[thirdparty/systemd.git] / meson.build
CommitLineData
db9ecf05 1# SPDX-License-Identifier: LGPL-2.1-or-later
3a726fcd 2
5c23128d 3project('systemd', 'c',
ea2a57be 4 version : files('meson.version'),
5c23128d
ZJS
5 license : 'LGPLv2+',
6 default_options: [
2b2dbcbb 7 'c_std=gnu11',
37efbbd8
ZJS
8 'prefix=/usr',
9 'sysconfdir=/etc',
10 'localstatedir=/var',
827ca909 11 'warning_level=2',
5c23128d 12 ],
35c035a1 13 meson_version : '>= 0.60.0',
5c23128d
ZJS
14 )
15
e37f3a12
LB
16libsystemd_version = '0.38.0'
17libudev_version = '1.7.8'
56d50ab1 18
5c23128d 19conf = configuration_data()
a8c03388 20conf.set_quoted('PROJECT_URL', 'https://systemd.io/')
ea2a57be 21conf.set('PROJECT_VERSION', meson.project_version().split('~')[0],
6ffeca8c 22 description : 'Numerical project version (used where a simple number is expected)')
ea2a57be 23conf.set_quoted('PROJECT_VERSION_FULL', meson.project_version(), description : 'Full project version')
5c23128d 24
1485aacb
DC
25# This is to be used instead of meson.source_root(), as the latter will return
26# the wrong result when systemd is being built as a meson subproject
27project_source_root = meson.current_source_dir()
81e06775 28project_build_root = meson.current_build_dir()
a0b15b41 29relative_source_path = run_command('realpath',
81e06775 30 '--relative-to=@0@'.format(project_build_root),
e92777d2
ZJS
31 project_source_root,
32 check : true).stdout().strip()
a0b15b41 33conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path)
1485aacb 34
47350c5f
ZJS
35conf.set10('BUILD_MODE_DEVELOPER', get_option('mode') == 'developer',
36 description : 'tailor build to development or release builds')
2b84d628 37
1e73a64a
JJ
38feature = get_option('log-message-verification')
39if feature.auto()
40 have = conf.get('BUILD_MODE_DEVELOPER') == 1
011a03a3 41else
1e73a64a 42 have = feature.enabled()
011a03a3 43endif
1e73a64a 44conf.set10('LOG_MESSAGE_VERIFICATION', have)
839bdf25 45
c09edc79
ZJS
46want_ossfuzz = get_option('oss-fuzz')
47want_libfuzzer = get_option('llvm-fuzz')
c29537f3 48if want_ossfuzz and want_libfuzzer
6b8d32ea 49 error('only one of oss-fuzz or llvm-fuzz can be specified')
c09edc79 50endif
87ac55a1 51
6b8d32ea 52fuzzer_build = want_ossfuzz or want_libfuzzer
c09edc79 53
c4f883b7
ZJS
54# If we're building *not* for actual fuzzing, allow input samples of any size
55# (for testing and for reproduction of issues discovered with previously-higher
56# limits).
57conf.set10('FUZZ_USE_SIZE_LIMIT', fuzzer_build)
58
493cd503
ZJS
59# We'll set this to '1' for EFI builds in a different place.
60conf.set10('SD_BOOT', false)
61
3f871f12
ZJS
62# Create a title-less summary section early, so it ends up first in the output.
63# More items are added later after they have been detected.
64summary({'build mode' : get_option('mode')})
65
5c23128d
ZJS
66#####################################################################
67
003c8879 68# Try to install the git pre-commit hook
6233a769
DDM
69git_setup_sh = find_program('tools/git-setup.sh', required : false)
70if git_setup_sh.found()
71 git_hook = run_command(git_setup_sh, check : false)
e2d612a8
ZJS
72 if git_hook.returncode() == 0
73 message(git_hook.stdout().strip())
74 endif
003c8879
ZJS
75endif
76
77#####################################################################
78
4cf8a609 79fs = import('fs')
157baa87 80if get_option('split-bin') == 'auto'
4cf8a609 81 split_bin = not fs.is_symlink('/usr/sbin')
157baa87
ZJS
82else
83 split_bin = get_option('split-bin') == 'true'
84endif
671f0f8d
ZJS
85conf.set10('HAVE_SPLIT_BIN', split_bin,
86 description : 'bin and sbin directories are separate')
157baa87 87
8ef8f3d5
FB
88have_standalone_binaries = get_option('standalone-binaries')
89
5c23128d
ZJS
90sysvinit_path = get_option('sysvinit-path')
91sysvrcnd_path = get_option('sysvrcnd-path')
348b4437 92conf.set10('HAVE_SYSV_COMPAT', sysvinit_path != '' and sysvrcnd_path != '',
349cc4a5 93 description : 'SysV init scripts and rcN.d links are supported')
6fe23ff3 94conf.set10('CREATE_LOG_DIRS', get_option('create-log-dirs'))
5c23128d 95
cdf7ad38
NL
96if get_option('hibernate') and not get_option('initrd')
97 error('hibernate depends on initrd')
98endif
99
a8b627aa
LP
100conf.set10('BUMP_PROC_SYS_FS_FILE_MAX', get_option('bump-proc-sys-fs-file-max'))
101conf.set10('BUMP_PROC_SYS_FS_NR_OPEN', get_option('bump-proc-sys-fs-nr-open'))
09dad04c 102conf.set('HIGH_RLIMIT_NOFILE', 512*1024)
a8b627aa 103
fce9abb2
ZJS
104# Meson ignores the preceding arguments when joining paths if an absolute
105# component is encountered, so this should canonicalize various paths when they
106# are absolute or relative.
5c23128d
ZJS
107prefixdir = get_option('prefix')
108if not prefixdir.startswith('/')
37efbbd8 109 error('Prefix is not absolute: "@0@"'.format(prefixdir))
5c23128d 110endif
d895e10a 111
b0d3095f 112prefixdir_noslash = '/' + prefixdir.strip('/')
fce9abb2 113bindir = prefixdir / get_option('bindir')
b0d3095f 114sbindir = prefixdir / (split_bin ? 'sbin' : 'bin')
9289e093 115sbin_to_bin = split_bin ? '../bin/' : ''
fce9abb2
ZJS
116libdir = prefixdir / get_option('libdir')
117sysconfdir = prefixdir / get_option('sysconfdir')
118includedir = prefixdir / get_option('includedir')
119datadir = prefixdir / get_option('datadir')
120localstatedir = '/' / get_option('localstatedir')
5c23128d 121
b0d3095f
LB
122libexecdir = prefixdir / 'lib/systemd'
123pkglibdir = libdir / 'systemd'
5c23128d 124
225d08b8
JT
125install_sysconfdir = get_option('install-sysconfdir') != 'false'
126install_sysconfdir_samples = get_option('install-sysconfdir') == 'true'
5c23128d 127# Dirs of external packages
fce9abb2
ZJS
128pkgconfigdatadir = get_option('pkgconfigdatadir') != '' ? get_option('pkgconfigdatadir') : datadir / 'pkgconfig'
129pkgconfiglibdir = get_option('pkgconfiglibdir') != '' ? get_option('pkgconfiglibdir') : libdir / 'pkgconfig'
130polkitpolicydir = datadir / 'polkit-1/actions'
131polkitrulesdir = datadir / 'polkit-1/rules.d'
132polkitpkladir = localstatedir / 'lib/polkit-1/localauthority/10-vendor.d'
133xinitrcdir = get_option('xinitrcdir') != '' ? get_option('xinitrcdir') : sysconfdir / 'X11/xinit/xinitrc.d'
8a38aac3
YW
134rpmmacrosdir = get_option('rpmmacrosdir')
135if rpmmacrosdir != 'no'
fce9abb2 136 rpmmacrosdir = prefixdir / rpmmacrosdir
8a38aac3 137endif
b0d3095f 138modprobedir = prefixdir / 'lib/modprobe.d'
5c23128d
ZJS
139
140# Our own paths
fce9abb2
ZJS
141pkgdatadir = datadir / 'systemd'
142environmentdir = prefixdir / 'lib/environment.d'
143pkgsysconfdir = sysconfdir / 'systemd'
144userunitdir = prefixdir / 'lib/systemd/user'
145userpresetdir = prefixdir / 'lib/systemd/user-preset'
146tmpfilesdir = prefixdir / 'lib/tmpfiles.d'
107795a7 147usertmpfilesdir = prefixdir / 'share/user-tmpfiles.d'
fce9abb2
ZJS
148sysusersdir = prefixdir / 'lib/sysusers.d'
149sysctldir = prefixdir / 'lib/sysctl.d'
150binfmtdir = prefixdir / 'lib/binfmt.d'
151modulesloaddir = prefixdir / 'lib/modules-load.d'
b0d3095f
LB
152networkdir = prefixdir / 'lib/systemd/network'
153systemgeneratordir = libexecdir / 'system-generators'
fce9abb2
ZJS
154usergeneratordir = prefixdir / 'lib/systemd/user-generators'
155systemenvgeneratordir = prefixdir / 'lib/systemd/system-environment-generators'
156userenvgeneratordir = prefixdir / 'lib/systemd/user-environment-generators'
b0d3095f
LB
157systemshutdowndir = libexecdir / 'system-shutdown'
158systemsleepdir = libexecdir / 'system-sleep'
159systemunitdir = prefixdir / 'lib/systemd/system'
160systempresetdir = prefixdir / 'lib/systemd/system-preset'
161udevlibexecdir = prefixdir / 'lib/udev'
fce9abb2
ZJS
162udevrulesdir = udevlibexecdir / 'rules.d'
163udevhwdbdir = udevlibexecdir / 'hwdb.d'
164catalogdir = prefixdir / 'lib/systemd/catalog'
641e2124 165kerneldir = prefixdir / 'lib/kernel'
166kernelinstalldir = kerneldir / 'install.d'
fce9abb2
ZJS
167factorydir = datadir / 'factory'
168bootlibdir = prefixdir / 'lib/systemd/boot/efi'
169testsdir = prefixdir / 'lib/systemd/tests'
26c2b302 170unittestsdir = testsdir / 'unit-tests'
539ee7ab 171testdata_dir = testsdir / 'testdata'
fce9abb2
ZJS
172systemdstatedir = localstatedir / 'lib/systemd'
173catalogstatedir = systemdstatedir / 'catalog'
174randomseeddir = localstatedir / 'lib/systemd'
b0d3095f 175profiledir = libexecdir / 'portable' / 'profile'
a121b331 176repartdefinitionsdir = libexecdir / 'repart/definitions'
b0d3095f 177ntpservicelistdir = prefixdir / 'lib/systemd/ntp-units.d'
24039e12 178credstoredir = prefixdir / 'lib/credstore'
8e35338d 179pcrlockdir = prefixdir / 'lib/pcrlock.d'
eb981a5b 180mimepackagesdir = prefixdir / 'share/mime/packages'
5c23128d 181
6495361c
FB
182configfiledir = get_option('configfiledir')
183if configfiledir == ''
184 configfiledir= sysconfdir
185endif
186pkgconfigfiledir = configfiledir / 'systemd'
187
75aaade1
TB
188docdir = get_option('docdir')
189if docdir == ''
fce9abb2 190 docdir = datadir / 'doc/systemd'
75aaade1
TB
191endif
192
5c23128d
ZJS
193pamlibdir = get_option('pamlibdir')
194if pamlibdir == ''
b0d3095f 195 pamlibdir = libdir / 'security'
5c23128d
ZJS
196endif
197
198pamconfdir = get_option('pamconfdir')
199if pamconfdir == ''
fce9abb2 200 pamconfdir = prefixdir / 'lib/pam.d'
5c23128d
ZJS
201endif
202
0abd510f
LP
203sshconfdir = get_option('sshconfdir')
204if sshconfdir == ''
205 sshconfdir = sysconfdir / 'ssh/ssh_config.d'
206endif
207
7e360799
LP
208sshdconfdir = get_option('sshdconfdir')
209if sshdconfdir == ''
210 sshdconfdir = sysconfdir / 'ssh/sshd_config.d'
211endif
212
5360b10f
LP
213sshdprivsepdir = get_option('sshdprivsepdir')
214conf.set10('CREATE_SSHDPRIVSEPDIR', sshdprivsepdir != 'no' and not sshdprivsepdir.startswith('/usr/'))
215conf.set('SSHDPRIVSEPDIR', sshdprivsepdir, description : 'SSH privilege separation directory')
216
d1ae38d8
OK
217libcryptsetup_plugins_dir = get_option('libcryptsetup-plugins-dir')
218if libcryptsetup_plugins_dir == ''
b0d3095f 219 libcryptsetup_plugins_dir = libdir / 'cryptsetup'
d1ae38d8
OK
220endif
221
444d5863 222memory_accounting_default = get_option('memory-accounting-default')
36cf4507 223status_unit_format_default = get_option('status-unit-format-default')
819c0dcb
ZJS
224if status_unit_format_default == 'auto'
225 status_unit_format_default = conf.get('BUILD_MODE_DEVELOPER') == 1 ? 'name' : 'description'
226endif
444d5863 227
b0d3095f 228conf.set_quoted('BINDIR', bindir)
491bf10c
ZJS
229conf.set_quoted('BINFMT_DIR', binfmtdir)
230conf.set_quoted('BOOTLIBDIR', bootlibdir)
fce9abb2 231conf.set_quoted('CATALOG_DATABASE', catalogstatedir / 'database')
491bf10c 232conf.set_quoted('CERTIFICATE_ROOT', get_option('certificate-root'))
6fe23ff3 233conf.set_quoted('DOC_DIR', docdir)
fce9abb2 234conf.set_quoted('DOCUMENT_ROOT', pkgdatadir / 'gatewayd')
491bf10c
ZJS
235conf.set_quoted('ENVIRONMENT_DIR', environmentdir)
236conf.set_quoted('INCLUDE_DIR', includedir)
237conf.set_quoted('LIBDIR', libdir)
b0d3095f 238conf.set_quoted('LIBEXECDIR', libexecdir)
5248a0c5 239conf.set_quoted('KERNEL_INSTALL_DIR', kernelinstalldir)
491bf10c
ZJS
240conf.set_quoted('MODPROBE_DIR', modprobedir)
241conf.set_quoted('MODULESLOAD_DIR', modulesloaddir)
5c23128d 242conf.set_quoted('PKGSYSCONFDIR', pkgsysconfdir)
fce9abb2 243conf.set_quoted('POLKIT_AGENT_BINARY_PATH', bindir / 'pkttyagent')
491bf10c 244conf.set_quoted('PREFIX', prefixdir)
b0d3095f 245conf.set_quoted('PREFIX_NOSLASH', prefixdir_noslash)
fce9abb2 246conf.set_quoted('RANDOM_SEED', randomseeddir / 'random-seed')
491bf10c 247conf.set_quoted('RANDOM_SEED_DIR', randomseeddir)
452d2dfd 248conf.set_quoted('RC_LOCAL_PATH', get_option('rc-local'))
0abd510f 249conf.set_quoted('SSHCONFDIR', sshconfdir)
7e360799 250conf.set_quoted('SSHDCONFDIR', sshdconfdir)
491bf10c
ZJS
251conf.set_quoted('SYSCONF_DIR', sysconfdir)
252conf.set_quoted('SYSCTL_DIR', sysctldir)
b0d3095f
LB
253conf.set_quoted('SYSTEMCTL_BINARY_PATH', bindir / 'systemctl')
254conf.set_quoted('SYSTEMD_BINARY_PATH', libexecdir / 'systemd')
bb5232b6 255conf.set_quoted('SYSTEMD_EXECUTOR_BINARY_PATH', libexecdir / 'systemd-executor')
491bf10c 256conf.set_quoted('SYSTEMD_CATALOG_DIR', catalogdir)
b0d3095f 257conf.set_quoted('SYSTEMD_CGROUPS_AGENT_PATH', libexecdir / 'systemd-cgroups-agent')
fb8d67cd 258conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH', bindir / 'systemd-cryptsetup')
b0d3095f
LB
259conf.set_quoted('SYSTEMD_EXPORT_PATH', libexecdir / 'systemd-export')
260conf.set_quoted('SYSTEMD_FSCK_PATH', libexecdir / 'systemd-fsck')
261conf.set_quoted('SYSTEMD_GROWFS_PATH', libexecdir / 'systemd-growfs')
262conf.set_quoted('SYSTEMD_HOMEWORK_PATH', libexecdir / 'systemd-homework')
263conf.set_quoted('SYSTEMD_IMPORT_FS_PATH', libexecdir / 'systemd-import-fs')
264conf.set_quoted('SYSTEMD_IMPORT_PATH', libexecdir / 'systemd-import')
265conf.set_quoted('SYSTEMD_INTEGRITYSETUP_PATH', libexecdir / 'systemd-integritysetup')
fce9abb2
ZJS
266conf.set_quoted('SYSTEMD_KBD_MODEL_MAP', pkgdatadir / 'kbd-model-map')
267conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP', pkgdatadir / 'language-fallback-map')
b0d3095f
LB
268conf.set_quoted('SYSTEMD_MAKEFS_PATH', libexecdir / 'systemd-makefs')
269conf.set_quoted('SYSTEMD_PULL_PATH', libexecdir / 'systemd-pull')
270conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH', libexecdir / 'systemd-shutdown')
539ee7ab 271conf.set_quoted('SYSTEMD_TEST_DATA', testdata_dir)
b0d3095f
LB
272conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', bindir / 'systemd-tty-ask-password-agent')
273conf.set_quoted('SYSTEMD_UPDATE_HELPER_PATH', libexecdir / 'systemd-update-helper')
274conf.set_quoted('SYSTEMD_USERWORK_PATH', libexecdir / 'systemd-userwork')
702a52f4 275conf.set_quoted('SYSTEMD_MOUNTWORK_PATH', libexecdir / 'systemd-mountwork')
8aee931e 276conf.set_quoted('SYSTEMD_NSRESOURCEWORK_PATH', libexecdir / 'systemd-nsresourcework')
b0d3095f 277conf.set_quoted('SYSTEMD_VERITYSETUP_PATH', libexecdir / 'systemd-veritysetup')
fce9abb2 278conf.set_quoted('SYSTEM_CONFIG_UNIT_DIR', pkgsysconfdir / 'system')
491bf10c 279conf.set_quoted('SYSTEM_DATA_UNIT_DIR', systemunitdir)
96d33e4a 280conf.set_quoted('SYSTEM_ENV_GENERATOR_DIR', systemenvgeneratordir)
491bf10c
ZJS
281conf.set_quoted('SYSTEM_GENERATOR_DIR', systemgeneratordir)
282conf.set_quoted('SYSTEM_PRESET_DIR', systempresetdir)
5c23128d
ZJS
283conf.set_quoted('SYSTEM_SHUTDOWN_PATH', systemshutdowndir)
284conf.set_quoted('SYSTEM_SLEEP_PATH', systemsleepdir)
491bf10c
ZJS
285conf.set_quoted('SYSTEM_SYSVINIT_PATH', sysvinit_path)
286conf.set_quoted('SYSTEM_SYSVRCND_PATH', sysvrcnd_path)
835cf75a
ZJS
287conf.set_quoted('SYSUSERS_DIR', sysusersdir)
288conf.set_quoted('TMPFILES_DIR', tmpfilesdir)
107795a7 289conf.set_quoted('USER_TMPFILES_DIR', usertmpfilesdir)
5c23128d 290conf.set_quoted('UDEVLIBEXECDIR', udevlibexecdir)
491bf10c
ZJS
291conf.set_quoted('UDEV_HWDB_DIR', udevhwdbdir)
292conf.set_quoted('UDEV_RULES_DIR', udevrulesdir)
fce9abb2 293conf.set_quoted('USER_CONFIG_UNIT_DIR', pkgsysconfdir / 'user')
491bf10c
ZJS
294conf.set_quoted('USER_DATA_UNIT_DIR', userunitdir)
295conf.set_quoted('USER_ENV_GENERATOR_DIR', userenvgeneratordir)
296conf.set_quoted('USER_GENERATOR_DIR', usergeneratordir)
fce9abb2 297conf.set_quoted('USER_KEYRING_PATH', pkgsysconfdir / 'import-pubring.gpg')
491bf10c 298conf.set_quoted('USER_PRESET_DIR', userpresetdir)
b0d3095f 299conf.set_quoted('VENDOR_KEYRING_PATH', libexecdir / 'import-pubring.gpg')
491bf10c
ZJS
300
301conf.set('ANSI_OK_COLOR', 'ANSI_' + get_option('ok-color').underscorify().to_upper())
e5d86ebe 302conf.set10('ENABLE_URLIFY', get_option('urlify'))
491bf10c 303conf.set10('ENABLE_FEXECVE', get_option('fexecve'))
30538ff1 304conf.set10('MEMORY_ACCOUNTING_DEFAULT', memory_accounting_default)
36cf4507 305conf.set('STATUS_UNIT_FORMAT_DEFAULT', 'STATUS_UNIT_FORMAT_' + status_unit_format_default.to_upper())
e11a25ca 306conf.set_quoted('STATUS_UNIT_FORMAT_DEFAULT_STR', status_unit_format_default)
5c23128d 307
e4c7b5f5
ZJS
308conf.set('DEFAULT_TIMEOUT_SEC', get_option('default-timeout-sec'))
309conf.set('DEFAULT_USER_TIMEOUT_SEC', get_option('default-user-timeout-sec'))
310conf.set('UPDATE_HELPER_USER_TIMEOUT_SEC', get_option('update-helper-user-timeout-sec'))
311
22330352 312conf.set10('ENABLE_FIRST_BOOT_FULL_PRESET', get_option('first-boot-full-preset'))
93651582 313
5c23128d
ZJS
314#####################################################################
315
316cc = meson.get_compiler('c')
92148283
JJ
317userspace_c_args = []
318userspace_c_ld_args = []
b68dfb9e 319meson_build_sh = find_program('tools/meson-build.sh')
5c23128d 320
d3da291e
ZJS
321want_tests = get_option('tests')
322slow_tests = want_tests != 'false' and get_option('slow-tests')
c56463fd 323fuzz_tests = want_tests != 'false' and get_option('fuzz-tests')
311efaae 324install_tests = want_tests != 'false' and get_option('install-tests')
d3da291e 325
daf4e78e 326if add_languages('cpp', native : false, required : fuzzer_build)
3b2bdd62 327 # Used only for tests
e9f4f566
ZJS
328 cxx = meson.get_compiler('cpp')
329 cxx_cmd = ' '.join(cxx.cmd_array())
1b2acaa7 330else
9b0ca019 331 cxx_cmd = ''
94e2523b
ZJS
332endif
333
31e57a35 334if want_libfuzzer
9c5c4677
EV
335 fuzzing_engine = meson.get_compiler('cpp').find_library('Fuzzer', required : false)
336 if fuzzing_engine.found()
92148283 337 userspace_c_args += '-fsanitize-coverage=trace-pc-guard,trace-cmp'
9c5c4677 338 elif cc.has_argument('-fsanitize=fuzzer-no-link')
92148283 339 userspace_c_args += '-fsanitize=fuzzer-no-link'
9c5c4677
EV
340 else
341 error('Looks like neither libFuzzer nor -fsanitize=fuzzer-no-link is supported')
342 endif
c09edc79 343elif want_ossfuzz
7db7d5b7
JR
344 fuzzing_engine = meson.get_compiler('cpp').find_library('FuzzingEngine')
345endif
346
e9f4f566
ZJS
347# Those generate many false positives, and we do not want to change the code to
348# avoid them.
349basic_disabled_warnings = [
e9f4f566 350 '-Wno-missing-field-initializers',
505ab9dd 351 '-Wno-unused-parameter',
b59bce30 352 '-Wno-nonnull-compare',
e9f4f566 353]
e9f4f566 354
65267363 355possible_common_cc_flags = [
fc568837
ZJS
356 '-Warray-bounds', # clang
357 '-Warray-bounds=2',
505ab9dd
YW
358 '-Wdate-time',
359 '-Wendif-labels',
360 '-Werror=format=2',
a4ea5d19 361 '-Werror=format-signedness',
505ab9dd 362 '-Werror=implicit-function-declaration',
a0d613ec 363 '-Werror=implicit-int',
505ab9dd 364 '-Werror=incompatible-pointer-types',
ebbb1e36 365 '-Werror=int-conversion',
0b482b37
JJ
366 '-Werror=missing-declarations',
367 '-Werror=missing-prototypes',
505ab9dd 368 '-Werror=overflow',
48c67fdf 369 '-Werror=override-init',
505ab9dd
YW
370 '-Werror=return-type',
371 '-Werror=shift-count-overflow',
372 '-Werror=shift-overflow=2',
6405afda 373 '-Werror=strict-flex-arrays',
30a4ddff 374 '-Werror=undef',
505ab9dd 375 '-Wfloat-equal',
c0f5d58c
JJ
376 # gperf prevents us from enabling this because it does not emit fallthrough
377 # attribute with clang.
378 #'-Wimplicit-fallthrough',
505ab9dd
YW
379 '-Wimplicit-fallthrough=5',
380 '-Winit-self',
30a4ddff
YW
381 '-Wlogical-op',
382 '-Wmissing-include-dirs',
505ab9dd
YW
383 '-Wmissing-noreturn',
384 '-Wnested-externs',
30a4ddff
YW
385 '-Wold-style-definition',
386 '-Wpointer-arith',
30a4ddff 387 '-Wredundant-decls',
30a4ddff 388 '-Wshadow',
30a4ddff 389 '-Wstrict-aliasing=2',
505ab9dd
YW
390 '-Wstrict-prototypes',
391 '-Wsuggest-attribute=noreturn',
054ed430 392 '-Wunused-function',
30a4ddff 393 '-Wwrite-strings',
31560245 394 '-Wzero-length-bounds',
bf7efeb1
FB
395
396 # negative arguments are correctly detected starting with meson 0.46.
eed33623
ZJS
397 '-Wno-error=#warnings', # clang
398 '-Wno-string-plus-int', # clang
fc568837 399
0b482b37
JJ
400 '-fdiagnostics-show-option',
401 '-fno-common',
48e1b2c2
JJ
402 '-fstack-protector',
403 '-fstack-protector-strong',
fc568837 404 '-fstrict-flex-arrays',
48e1b2c2
JJ
405 '--param=ssp-buffer-size=4',
406]
407
408possible_common_link_flags = [
409 '-fstack-protector',
30a4ddff
YW
410]
411
b528a628
ZJS
412c_args = get_option('c_args')
413
60f97fee 414# Our json library does not support -ffinite-math-only, which is enabled by -Ofast or -ffast-math.
53403091 415if (('-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)
60f97fee
YW
416 error('-Ofast, -ffast-math, or -ffinite-math-only is specified in c_args.')
417endif
418
a17e5478 419# Disable -Wmaybe-uninitialized when compiling with -Os/-O1/-O3/etc. There are
68c98a41
ZJS
420# too many false positives with gcc >= 8. Effectively, we only test with -O0
421# and -O2; this should be enough to catch most important cases without too much
422# busywork. See https://github.com/systemd/systemd/pull/19226.
423if cc.get_id() == 'gcc' and (not '02'.contains(get_option('optimization')) or
b528a628
ZJS
424 cc.version().version_compare('<10') or
425 '-Os' in c_args or
426 '-O1' in c_args or
427 '-O3' in c_args or
428 '-Og' in c_args)
65267363 429 possible_common_cc_flags += '-Wno-maybe-uninitialized'
68c98a41
ZJS
430endif
431
bc2a4af2
ZJS
432# Disable -Wno-unused-result with gcc, see
433# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425.
434if cc.get_id() == 'gcc'
435 possible_common_cc_flags += '-Wno-unused-result'
436endif
437
30a4ddff 438# --as-needed and --no-undefined are provided by meson by default,
9247df5a 439# run 'meson configure' to see what is enabled
30a4ddff 440possible_link_flags = [
42e3bb35 441 '-Wl,--fatal-warnings',
30a4ddff 442 '-Wl,-z,now',
42e3bb35 443 '-Wl,-z,relro',
30a4ddff 444]
5c23128d 445
42e3bb35
JJ
446if get_option('b_sanitize') == 'none'
447 possible_link_flags += '-Wl,--warn-common'
448endif
449
30a4ddff 450if cc.get_id() == 'clang'
65267363 451 possible_common_cc_flags += [
30a4ddff
YW
452 '-Wno-typedef-redefinition',
453 '-Wno-gnu-variable-sized-type-not-at-end',
454 ]
455endif
456
1a4e3927
JJ
457if get_option('mode') == 'release'
458 # We could enable 'pattern' for developer mode, but that can interfere with
459 # valgrind and sanitizer builds. Also, clang does not zero-initialize unions,
460 # breaking some of our code (https://reviews.llvm.org/D68115).
461 possible_common_cc_flags += '-ftrivial-auto-var-init=zero'
462endif
463
92148283 464possible_cc_flags = [
16e09d51 465 '-fno-strict-aliasing',
afd8e1d9 466 '-fstrict-flex-arrays=1',
16e09d51 467 '-fvisibility=hidden',
16e09d51
YW
468]
469
30a4ddff 470if get_option('buildtype') != 'debug'
16e09d51 471 possible_cc_flags += [
30a4ddff
YW
472 '-ffunction-sections',
473 '-fdata-sections',
474 ]
475
476 possible_link_flags += '-Wl,--gc-sections'
477endif
478
82390022
DDM
479if get_option('mode') == 'developer'
480 possible_cc_flags += '-fno-omit-frame-pointer'
481endif
482
92148283
JJ
483add_project_arguments(
484 cc.get_supported_arguments(
485 basic_disabled_warnings,
486 possible_common_cc_flags
487 ),
488 language : 'c')
489
48e1b2c2
JJ
490add_project_link_arguments(
491 cc.get_supported_link_arguments(possible_common_link_flags),
492 language : 'c')
493
92148283
JJ
494userspace_c_args += cc.get_supported_arguments(possible_cc_flags)
495userspace_c_ld_args += cc.get_supported_link_arguments(possible_link_flags)
30a4ddff 496
94c0c5b7
ZJS
497have = cc.has_argument('-Wzero-length-bounds')
498conf.set10('HAVE_ZERO_LENGTH_BOUNDS', have)
499
9e70f2f8 500if cc.compiles('''
5c23128d
ZJS
501 #include <time.h>
502 #include <inttypes.h>
503 typedef uint64_t usec_t;
504 usec_t now(clockid_t clock);
505 int main(void) {
506 struct timespec now;
507 return 0;
508 }
38c1c96d 509''', args: '-Werror=shadow', name : '-Werror=shadow with local shadowing')
37efbbd8 510 add_project_arguments('-Werror=shadow', language : 'c')
5c23128d
ZJS
511endif
512
e9f4f566
ZJS
513if cxx_cmd != ''
514 add_project_arguments(cxx.get_supported_arguments(basic_disabled_warnings), language : 'cpp')
515endif
516
465104b4 517cpp = ' '.join(cc.cmd_array() + get_option('c_args')) + ' -E'
9cc0e6e9 518
6695c200
ZJS
519has_wstringop_truncation = cc.has_argument('-Wstringop-truncation')
520
5c23128d
ZJS
521#####################################################################
522# compilation result tests
523
78103450 524conf.set('_GNU_SOURCE', 1)
2c201c21 525conf.set('__SANE_USERSPACE_TYPES__', true)
6695c200 526conf.set10('HAVE_WSTRINGOP_TRUNCATION', has_wstringop_truncation)
5c23128d 527
5c23128d
ZJS
528conf.set('SIZEOF_DEV_T', cc.sizeof('dev_t', prefix : '#include <sys/types.h>'))
529conf.set('SIZEOF_INO_T', cc.sizeof('ino_t', prefix : '#include <sys/types.h>'))
5c23128d 530conf.set('SIZEOF_RLIM_T', cc.sizeof('rlim_t', prefix : '#include <sys/resource.h>'))
84d953e8 531conf.set('SIZEOF_TIME_T', cc.sizeof('time_t', prefix : '#include <sys/time.h>'))
3112d756 532conf.set('SIZEOF_TIMEX_MEMBER', cc.sizeof('typeof(((struct timex *)0)->freq)', prefix : '#include <sys/timex.h>'))
5c23128d 533
2736a0c6 534long_max = cc.compute_int(
535 'LONG_MAX',
536 prefix : '#include <limits.h>',
537 guess : 0x7FFFFFFFFFFFFFFF,
538 high : 0x7FFFFFFFFFFFFFFF)
a5fac1df
ZJS
539assert(long_max > 100000)
540conf.set_quoted('LONG_MAX_STR', '@0@'.format(long_max))
541
5c23128d 542decl_headers = '''
eb292969 543#include <dirent.h>
5c23128d 544#include <uchar.h>
84e8edec 545#include <sys/mount.h>
4c2e1b39 546#include <sys/stat.h>
5c23128d 547'''
5c23128d
ZJS
548
549foreach decl : ['char16_t',
550 'char32_t',
84e8edec 551 'struct mount_attr',
4c2e1b39 552 'struct statx',
eb292969 553 'struct dirent64',
5c23128d 554 ]
2c201c21
ZJS
555
556 # We get -1 if the size cannot be determined
9c869d08
ZJS
557 have = cc.sizeof(decl, prefix : decl_headers, args : '-D_GNU_SOURCE') > 0
558
3657d3a0
RH
559 if decl == 'struct mount_attr'
560 if have
561 want_linux_fs_h = false
562 else
563 have = cc.sizeof(decl,
564 prefix : decl_headers + '#include <linux/fs.h>',
565 args : '-D_GNU_SOURCE') > 0
566 want_linux_fs_h = have
567 endif
568 endif
569
9c869d08
ZJS
570 if decl == 'struct statx'
571 if have
572 want_linux_stat_h = false
573 else
574 have = cc.sizeof(decl,
575 prefix : decl_headers + '#include <linux/stat.h>',
576 args : '-D_GNU_SOURCE') > 0
577 want_linux_stat_h = have
578 endif
579 endif
580
349cc4a5 581 conf.set10('HAVE_' + decl.underscorify().to_upper(), have)
5c23128d
ZJS
582endforeach
583
9c869d08 584conf.set10('WANT_LINUX_STAT_H', want_linux_stat_h)
3657d3a0 585conf.set10('WANT_LINUX_FS_H', want_linux_fs_h)
75720bff 586
5c23128d 587foreach ident : ['secure_getenv', '__secure_getenv']
349cc4a5 588 conf.set10('HAVE_' + ident.to_upper(), cc.has_function(ident))
5c23128d
ZJS
589endforeach
590
591foreach ident : [
85db59b7 592 ['memfd_create', '''#include <sys/mman.h>'''],
7b961e40
LP
593 ['gettid', '''#include <sys/types.h>
594 #include <unistd.h>'''],
c21566d9
AM
595 ['fchmodat2', '''#include <stdlib.h>
596 #include <fcntl.h>'''], # no known header declares fchmodat2
3c042add
LP
597 ['pivot_root', '''#include <stdlib.h>
598 #include <unistd.h>'''], # no known header declares pivot_root
51fe206f
ZJS
599 ['ioprio_get', '''#include <sched.h>'''], # no known header declares ioprio_get
600 ['ioprio_set', '''#include <sched.h>'''], # no known header declares ioprio_set
85db59b7 601 ['name_to_handle_at', '''#include <sys/types.h>
37efbbd8
ZJS
602 #include <sys/stat.h>
603 #include <fcntl.h>'''],
85db59b7 604 ['setns', '''#include <sched.h>'''],
2acfd0ff
LP
605 ['renameat2', '''#include <stdio.h>
606 #include <fcntl.h>'''],
37efbbd8
ZJS
607 ['kcmp', '''#include <linux/kcmp.h>'''],
608 ['keyctl', '''#include <sys/types.h>
609 #include <keyutils.h>'''],
85db59b7 610 ['copy_file_range', '''#include <sys/syscall.h>
37efbbd8 611 #include <unistd.h>'''],
71e5200f
DM
612 ['bpf', '''#include <sys/syscall.h>
613 #include <unistd.h>'''],
4c2e1b39
LP
614 ['statx', '''#include <sys/types.h>
615 #include <sys/stat.h>
616 #include <unistd.h>'''],
aa484f35 617 ['explicit_bzero' , '''#include <string.h>'''],
5bb20fd3 618 ['reallocarray', '''#include <stdlib.h>'''],
b070c7c0
MS
619 ['set_mempolicy', '''#include <stdlib.h>
620 #include <unistd.h>'''],
621 ['get_mempolicy', '''#include <stdlib.h>
622 #include <unistd.h>'''],
5f152f43
LP
623 ['pidfd_send_signal', '''#include <stdlib.h>
624 #include <unistd.h>
625 #include <signal.h>
626 #include <sys/wait.h>'''],
627 ['pidfd_open', '''#include <stdlib.h>
628 #include <unistd.h>
629 #include <signal.h>
630 #include <sys/wait.h>'''],
5ead4e85
LP
631 ['rt_sigqueueinfo', '''#include <stdlib.h>
632 #include <unistd.h>
633 #include <signal.h>
634 #include <sys/wait.h>'''],
a5421953
DDM
635 ['rt_tgsigqueueinfo', '''#include <stdlib.h>
636 #include <unistd.h>
637 #include <signal.h>
638 #include <sys/wait.h>'''],
4b6f74f5 639 ['mallinfo', '''#include <malloc.h>'''],
1885169c 640 ['mallinfo2', '''#include <malloc.h>'''],
8939eeae 641 ['execveat', '''#include <unistd.h>'''],
441e0fdb 642 ['close_range', '''#include <unistd.h>'''],
420297c9 643 ['epoll_pwait2', '''#include <sys/epoll.h>'''],
84e8edec
LP
644 ['mount_setattr', '''#include <sys/mount.h>'''],
645 ['move_mount', '''#include <sys/mount.h>'''],
646 ['open_tree', '''#include <sys/mount.h>'''],
1c265fcd
DDM
647 ['fsopen', '''#include <sys/mount.h>'''],
648 ['fsconfig', '''#include <sys/mount.h>'''],
34a9da0d 649 ['fsmount', '''#include <sys/mount.h>'''],
aab35b1e 650 ['getdents64', '''#include <dirent.h>'''],
2e106312 651 ['pidfd_spawn', '''#include <spawn.h>'''],
37efbbd8
ZJS
652]
653
85db59b7 654 have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
4b9545f1 655 conf.set10('HAVE_' + ident[0].to_upper(), have)
5c23128d
ZJS
656endforeach
657
85db59b7 658if cc.has_function('getrandom', prefix : '''#include <sys/random.h>''', args : '-D_GNU_SOURCE')
349cc4a5 659 conf.set10('USE_SYS_RANDOM_H', true)
4b9545f1 660 conf.set10('HAVE_GETRANDOM', true)
4984c8be
ZJS
661else
662 have = cc.has_function('getrandom', prefix : '''#include <linux/random.h>''')
349cc4a5 663 conf.set10('USE_SYS_RANDOM_H', false)
4b9545f1 664 conf.set10('HAVE_GETRANDOM', have)
4984c8be
ZJS
665endif
666
5c23128d
ZJS
667#####################################################################
668
0f4c4f38
ZJS
669sh = find_program('sh')
670echo = find_program('echo')
5c23128d 671sed = find_program('sed')
5c23128d 672awk = find_program('awk')
5c23128d 673stat = find_program('stat')
0f4c4f38 674ln = find_program('ln')
d68b342b 675git = find_program('git', required : false)
b68dfb9e 676env = find_program('env')
0f4c4f38 677rsync = find_program('rsync', required : false)
4d56d084 678diff = find_program('diff')
d9081eb0 679find = find_program('find')
5c23128d 680
9289e093 681ln_s = ln.full_path() + ' -frsT -- "${DESTDIR:-}@0@" "${DESTDIR:-}@1@"'
94e75a54 682
9247df5a 683# If -Dxxx-path option is found, use that. Otherwise, check in $PATH,
5c23128d 684# /usr/sbin, /sbin, and fall back to the default from middle column.
2fa645f1 685progs = [['quotaon', '/usr/sbin/quotaon' ],
5c23128d 686 ['quotacheck', '/usr/sbin/quotacheck' ],
5c23128d
ZJS
687 ['kmod', '/usr/bin/kmod' ],
688 ['kexec', '/usr/sbin/kexec' ],
689 ['sulogin', '/usr/sbin/sulogin' ],
690 ['mount', '/usr/bin/mount', 'MOUNT_PATH'],
691 ['umount', '/usr/bin/umount', 'UMOUNT_PATH'],
692 ['loadkeys', '/usr/bin/loadkeys', 'KBD_LOADKEYS'],
693 ['setfont', '/usr/bin/setfont', 'KBD_SETFONT'],
6db90462 694 ['nologin', '/usr/sbin/nologin', ],
5c23128d
ZJS
695 ]
696foreach prog : progs
37efbbd8
ZJS
697 path = get_option(prog[0] + '-path')
698 if path != ''
699 message('Using @1@ for @0@'.format(prog[0], path))
700 else
701 exe = find_program(prog[0],
702 '/usr/sbin/' + prog[0],
703 '/sbin/' + prog[0],
704 required: false)
573c0dc1 705 path = exe.found() ? exe.full_path() : prog[1]
37efbbd8
ZJS
706 endif
707 name = prog.length() > 2 ? prog[2] : prog[0].to_upper()
708 conf.set_quoted(name, path)
5c23128d
ZJS
709endforeach
710
e92777d2 711if run_command(ln, '--relative', '--help', check : false).returncode() != 0
cd001016 712 error('ln does not support --relative (added in coreutils 8.16)')
1276a9f6 713endif
5c23128d 714
e6267e83 715#####################################################################
5c23128d
ZJS
716
717gperf = find_program('gperf')
718
719gperf_test_format = '''
720#include <string.h>
721const char * in_word_set(const char *, @0@);
722@1@
723'''
ac3eda34 724gperf_snippet = run_command(sh, '-c', 'echo foo,bar | "$1" -L ANSI-C', '_', gperf,
e92777d2 725 check : true)
5c23128d
ZJS
726gperf_test = gperf_test_format.format('size_t', gperf_snippet.stdout())
727if cc.compiles(gperf_test)
37efbbd8 728 gperf_len_type = 'size_t'
5c23128d 729else
37efbbd8
ZJS
730 gperf_test = gperf_test_format.format('unsigned', gperf_snippet.stdout())
731 if cc.compiles(gperf_test)
732 gperf_len_type = 'unsigned'
733 else
734 error('unable to determine gperf len type')
735 endif
5c23128d
ZJS
736endif
737message('gperf len type is @0@'.format(gperf_len_type))
37efbbd8
ZJS
738conf.set('GPERF_LEN_TYPE', gperf_len_type,
739 description : 'The type of gperf "len" parameter')
5c23128d 740
e6267e83 741#####################################################################
5c23128d
ZJS
742
743if not cc.has_header('sys/capability.h')
37efbbd8 744 error('POSIX caps headers not found')
5c23128d 745endif
9f555bba 746foreach header : ['crypt.h',
7258971b 747 'linux/ioprio.h',
5c23128d 748 'linux/memfd.h',
7258971b 749 'linux/time_types.h',
5c23128d 750 'linux/vm_sockets.h',
af8786b1 751 'sys/auxv.h',
7258971b 752 'sys/sdt.h',
5545f336 753 'threads.h',
5c23128d
ZJS
754 'valgrind/memcheck.h',
755 'valgrind/valgrind.h',
756 ]
2c201c21 757
349cc4a5
ZJS
758 conf.set10('HAVE_' + header.underscorify().to_upper(),
759 cc.has_header(header))
5c23128d
ZJS
760endforeach
761
e6267e83 762#####################################################################
5c23128d 763
eef4b800
ZJS
764fallback_hostname = get_option('fallback-hostname')
765if fallback_hostname == '' or fallback_hostname[0] == '.' or fallback_hostname[0] == '-'
766 error('Invalid fallback-hostname configuration')
767 # A more extensive test is done in test-hostname-util. Let's catch
768 # the most obvious errors here so we don't fail with an assert later.
769endif
770conf.set_quoted('FALLBACK_HOSTNAME', fallback_hostname)
771
681cb84a
ZJS
772extra_net_naming_schemes = []
773extra_net_naming_map = []
774foreach scheme: get_option('extra-net-naming-schemes').split(',')
775 if scheme != ''
776 name = scheme.split('=')[0]
777 value = scheme.split('=')[1]
778 NAME = name.underscorify().to_upper()
779 VALUE = []
780 foreach field: value.split('+')
781 VALUE += 'NAMING_' + field.underscorify().to_upper()
782 endforeach
783 extra_net_naming_schemes += 'NAMING_@0@ = @1@,'.format(NAME, '|'.join(VALUE))
784 extra_net_naming_map += '{ "@0@", NAMING_@1@ },'.format(name, NAME)
785 endif
786endforeach
787conf.set('EXTRA_NET_NAMING_SCHEMES', ' '.join(extra_net_naming_schemes))
788conf.set('EXTRA_NET_NAMING_MAP', ' '.join(extra_net_naming_map))
789
06da5c63 790default_net_naming_scheme = get_option('default-net-naming-scheme')
386256e6
ZJS
791conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme,
792 description : 'Default naming scheme as a string')
77faadfd 793if default_net_naming_scheme != 'latest'
386256e6
ZJS
794 conf.set('_DEFAULT_NET_NAMING_SCHEME',
795 'NAMING_' + default_net_naming_scheme.underscorify().to_upper(),
796 description : 'Default naming scheme as a constant')
77faadfd 797endif
06da5c63 798
5c23128d 799time_epoch = get_option('time-epoch')
a36be3e5 800if time_epoch <= 0
e92777d2 801 time_epoch = run_command(sh, '-c', 'echo "$SOURCE_DATE_EPOCH"', check : true).stdout().strip()
edd84b8e 802 if time_epoch == '' and git.found() and fs.is_dir('.git')
bd190899 803 # If we're in a git repository, use the creation time of the latest git tag.
e92777d2
ZJS
804 latest_tag = run_command(git, 'describe', '--abbrev=0', '--tags',
805 check : false)
806 if latest_tag.returncode() == 0
807 time_epoch = run_command(
808 git, 'log', '--no-show-signature', '-1', '--format=%at',
809 latest_tag.stdout().strip(),
810 check : false).stdout()
811 endif
0390b094
ZJS
812 endif
813 if time_epoch == ''
6dbf352c 814 NEWS = files('NEWS')
e92777d2
ZJS
815 time_epoch = run_command(stat, '-c', '%Y', NEWS,
816 check : true).stdout()
6dbf352c 817 endif
89cdbe1f 818 time_epoch = time_epoch.strip().to_int()
5c23128d 819endif
5c23128d
ZJS
820conf.set('TIME_EPOCH', time_epoch)
821
b10abe4b
EI
822conf.set('CLOCK_VALID_RANGE_USEC_MAX', get_option('clock-valid-range-usec-max'))
823
53350c7b 824default_user_shell = get_option('default-user-shell')
825conf.set_quoted('DEFAULT_USER_SHELL', default_user_shell)
826conf.set_quoted('DEFAULT_USER_SHELL_NAME', fs.name(default_user_shell))
827
fc1a5d1a
ZJS
828foreach tuple : [['system-alloc-uid-min', 'SYS_UID_MIN', 1], # Also see login.defs(5).
829 ['system-uid-max', 'SYS_UID_MAX', 999],
830 ['system-alloc-gid-min', 'SYS_GID_MIN', 1],
831 ['system-gid-max', 'SYS_GID_MAX', 999]]
832 v = get_option(tuple[0])
a36be3e5 833 if v <= 0
fc1a5d1a
ZJS
834 v = run_command(
835 awk,
836 '/^\s*@0@\s+/ { uid=$2 } END { print uid }'.format(tuple[1]),
e92777d2
ZJS
837 '/etc/login.defs',
838 check : false).stdout().strip()
fc1a5d1a
ZJS
839 if v == ''
840 v = tuple[2]
841 else
842 v = v.to_int()
843 endif
2f62cf35 844 endif
fc1a5d1a 845 conf.set(tuple[0].underscorify().to_upper(), v)
fc1a5d1a
ZJS
846endforeach
847if conf.get('SYSTEM_ALLOC_UID_MIN') >= conf.get('SYSTEM_UID_MAX')
848 error('Invalid uid allocation range')
5c23128d 849endif
fc1a5d1a
ZJS
850if conf.get('SYSTEM_ALLOC_GID_MIN') >= conf.get('SYSTEM_GID_MAX')
851 error('Invalid gid allocation range')
5c23128d 852endif
5c23128d 853
ac09340e
YW
854dynamic_uid_min = get_option('dynamic-uid-min')
855dynamic_uid_max = get_option('dynamic-uid-max')
87d5e4f2
LP
856conf.set('DYNAMIC_UID_MIN', dynamic_uid_min)
857conf.set('DYNAMIC_UID_MAX', dynamic_uid_max)
87d5e4f2 858
ac09340e
YW
859container_uid_base_min = get_option('container-uid-base-min')
860container_uid_base_max = get_option('container-uid-base-max')
87d5e4f2
LP
861conf.set('CONTAINER_UID_BASE_MIN', container_uid_base_min)
862conf.set('CONTAINER_UID_BASE_MAX', container_uid_base_max)
87d5e4f2 863
afde4574
LP
864nobody_user = get_option('nobody-user')
865nobody_group = get_option('nobody-group')
866
2484bff3 867if not meson.is_cross_build()
e92777d2 868 getent_result = run_command('getent', 'passwd', '65534', check : false)
2484bff3
CQ
869 if getent_result.returncode() == 0
870 name = getent_result.stdout().split(':')[0]
871 if name != nobody_user
872 warning('\n' +
873 '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) +
874 'Your build will result in an user table setup that is incompatible with the local system.')
875 endif
afde4574 876 endif
e92777d2 877 id_result = run_command('id', '-u', nobody_user, check : false)
2484bff3 878 if id_result.returncode() == 0
89cdbe1f 879 id = id_result.stdout().strip().to_int()
2484bff3
CQ
880 if id != 65534
881 warning('\n' +
882 '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) +
883 'Your build will result in an user table setup that is incompatible with the local system.')
884 endif
afde4574 885 endif
afde4574 886
e92777d2 887 getent_result = run_command('getent', 'group', '65534', check : false)
2484bff3
CQ
888 if getent_result.returncode() == 0
889 name = getent_result.stdout().split(':')[0]
890 if name != nobody_group
891 warning('\n' +
892 '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) +
893 'Your build will result in an group table setup that is incompatible with the local system.')
894 endif
afde4574 895 endif
e92777d2 896 id_result = run_command('id', '-g', nobody_group, check : false)
2484bff3 897 if id_result.returncode() == 0
89cdbe1f 898 id = id_result.stdout().strip().to_int()
2484bff3
CQ
899 if id != 65534
900 warning('\n' +
d5b3e510 901 '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) +
2484bff3
CQ
902 'Your build will result in an group table setup that is incompatible with the local system.')
903 endif
afde4574
LP
904 endif
905endif
8374cc62 906if nobody_user != nobody_group and not (nobody_user == 'nobody' and nobody_group == 'nogroup')
8ea9fad7 907 warning('\n' +
79f48703 908 'The configured user name "@0@" and group name "@1@" of the nobody user/group are not equivalent.\n'.format(nobody_user, nobody_group) +
8ea9fad7 909 'Please re-check that both "nobody-user" and "nobody-group" options are correctly set.')
8374cc62 910endif
afde4574
LP
911
912conf.set_quoted('NOBODY_USER_NAME', nobody_user)
913conf.set_quoted('NOBODY_GROUP_NAME', nobody_group)
87d5e4f2 914
9a797ddc
ZJS
915static_ugids = []
916foreach option : ['adm-gid',
917 'audio-gid',
918 'cdrom-gid',
919 'dialout-gid',
920 'disk-gid',
921 'input-gid',
922 'kmem-gid',
923 'kvm-gid',
924 'lp-gid',
925 'render-gid',
926 'sgx-gid',
927 'tape-gid',
928 'tty-gid',
929 'users-gid',
930 'utmp-gid',
931 'video-gid',
932 'wheel-gid',
933 'systemd-journal-gid',
934 'systemd-network-uid',
935 'systemd-resolve-uid',
936 'systemd-timesync-uid']
937 name = option.underscorify().to_upper()
938 val = get_option(option)
939
940 # Ensure provided GID argument is numeric, otherwise fall back to default assignment
a36be3e5
YW
941 conf.set(name, val > 0 ? val : '-')
942 if val > 0
9a797ddc
ZJS
943 static_ugids += '@0@:@1@'.format(option, val)
944 endif
945endforeach
84786b8e 946
348b4437
YW
947conf.set10('ENABLE_ADM_GROUP', get_option('adm-group'))
948conf.set10('ENABLE_WHEEL_GROUP', get_option('wheel-group'))
5c23128d 949
ace5e311 950dev_kvm_mode = get_option('dev-kvm-mode')
d924a938 951conf.set_quoted('DEV_KVM_MODE', dev_kvm_mode) # FIXME: convert to 0o… notation
ace5e311 952conf.set10('DEV_KVM_UACCESS', dev_kvm_mode != '0666')
055a083a 953group_render_mode = get_option('group-render-mode')
8feaea5e 954conf.set_quoted('GROUP_RENDER_MODE', group_render_mode)
055a083a 955conf.set10('GROUP_RENDER_UACCESS', group_render_mode != '0666')
5c23128d 956
2a4c156d
ZJS
957kill_user_processes = get_option('default-kill-user-processes')
958conf.set10('KILL_USER_PROCESSES', kill_user_processes)
5c23128d 959
829257d1
ZJS
960dns_servers = get_option('dns-servers')
961conf.set_quoted('DNS_SERVERS', dns_servers)
5c23128d 962
829257d1
ZJS
963ntp_servers = get_option('ntp-servers')
964conf.set_quoted('NTP_SERVERS', ntp_servers)
5c23128d 965
8ca9e92c
DR
966default_locale = get_option('default-locale')
967conf.set_quoted('SYSTEMD_DEFAULT_LOCALE', default_locale)
968
a22f5186
DDM
969nspawn_locale = get_option('nspawn-locale')
970conf.set_quoted('SYSTEMD_NSPAWN_LOCALE', nspawn_locale)
971
f129d0e7 972default_keymap = get_option('default-keymap')
ef7f5baa 973if default_keymap == ''
bf77d597 974 # We canonicalize empty keymap to '@kernel', as it makes the default value
ef7f5baa 975 # in the factory provided /etc/vconsole.conf more obvious.
bf77d597 976 default_keymap = '@kernel'
ef7f5baa 977endif
f129d0e7
MY
978conf.set_quoted('SYSTEMD_DEFAULT_KEYMAP', default_keymap)
979
8f20232f 980localegen_path = get_option('localegen-path')
8f20232f
MK
981if localegen_path != ''
982 conf.set_quoted('LOCALEGEN_PATH', localegen_path)
8f20232f 983endif
71ae5ce5 984conf.set10('HAVE_LOCALEGEN', localegen_path != '')
8f20232f 985
5c23128d
ZJS
986conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
987
21d0dd5a 988service_watchdog = get_option('service-watchdog')
7bc9ea51 989watchdog_value = service_watchdog == '' ? '' : 'WatchdogSec=' + service_watchdog
059cc610 990conf.set_quoted('SERVICE_WATCHDOG', watchdog_value)
21d0dd5a 991
059cc610 992conf.set_quoted('SUSHELL', get_option('debug-shell'))
93912e87 993conf.set_quoted('DEBUGTTY', get_option('debug-tty'))
3131bfe3 994
349cc4a5
ZJS
995enable_debug_hashmap = false
996enable_debug_mmap_cache = false
d6601495 997enable_debug_siphash = false
8f6b442a 998foreach name : get_option('debug-extra')
ad7aa760
YW
999 if name == 'hashmap'
1000 enable_debug_hashmap = true
1001 elif name == 'mmap-cache'
1002 enable_debug_mmap_cache = true
d6601495
YW
1003 elif name == 'siphash'
1004 enable_debug_siphash = true
ad7aa760
YW
1005 else
1006 message('unknown debug option "@0@", ignoring'.format(name))
1007 endif
1008endforeach
349cc4a5
ZJS
1009conf.set10('ENABLE_DEBUG_HASHMAP', enable_debug_hashmap)
1010conf.set10('ENABLE_DEBUG_MMAP_CACHE', enable_debug_mmap_cache)
d6601495 1011conf.set10('ENABLE_DEBUG_SIPHASH', enable_debug_siphash)
fd5dec9a 1012conf.set10('LOG_TRACE', get_option('log-trace'))
d18cb393 1013
3602ca6f
ZJS
1014default_user_path = get_option('user-path')
1015if default_user_path != ''
1016 conf.set_quoted('DEFAULT_USER_PATH', default_user_path)
1017endif
1018
5c23128d
ZJS
1019#####################################################################
1020
1021threads = dependency('threads')
1022librt = cc.find_library('rt')
1023libm = cc.find_library('m')
1024libdl = cc.find_library('dl')
55573787
YW
1025libcrypt = dependency('libcrypt', 'libxcrypt', required : false)
1026if not libcrypt.found()
1027 # fallback to use find_library() if libcrypt is provided by glibc, e.g. for LibreELEC.
1028 libcrypt = cc.find_library('crypt')
1029endif
d625f717 1030libcap = dependency('libcap')
5c23128d 1031
96f8c636
ZJS
1032# On some architectures, libatomic is required. But on some installations,
1033# it is found, but actual linking fails. So let's try to use it opportunistically.
1034# If it is installed, but not needed, it will be dropped because of --as-needed.
1035if cc.links('''int main(int argc, char **argv) { return 0; }''',
1036 args : '-latomic',
1037 name : 'libatomic')
1038 libatomic = declare_dependency(link_args : '-latomic')
1039else
1040 libatomic = []
1041endif
1042
06ca077b 1043crypt_header = conf.get('HAVE_CRYPT_H') == 1 ? '''#include <crypt.h>''' : '''#include <unistd.h>'''
e8644a41 1044foreach ident : [
feee7f62
LB
1045 ['crypt_ra', crypt_header],
1046 ['crypt_preferred_method', crypt_header],
1047 ['crypt_gensalt_ra', crypt_header]]
e8644a41
ZJS
1048
1049 have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE',
1050 dependencies : libcrypt)
1051 conf.set10('HAVE_' + ident[0].to_upper(), have)
1052endforeach
1053
847e5585 1054bpf_framework = get_option('bpf-framework')
b88323e4 1055bpf_compiler = get_option('bpf-compiler')
847e5585
JJ
1056libbpf = dependency('libbpf',
1057 required : bpf_framework,
1058 version : bpf_compiler == 'gcc' ? '>= 1.0.0' : '>= 0.1.0')
7d861e12
JK
1059conf.set10('HAVE_LIBBPF', libbpf.found())
1060
847e5585 1061if not libbpf.found()
cf2dc690 1062 conf.set10('BPF_FRAMEWORK', false)
7d861e12 1063else
76abad4d
JH
1064 clang_found = false
1065 clang_supports_bpf = false
1066 bpf_gcc_found = false
b88323e4 1067 bpftool_strip = false
76abad4d
JH
1068 deps_found = false
1069
1070 if bpf_compiler == 'clang'
1071 # Support 'versioned' clang/llvm-strip binaries, as seen on Debian/Ubuntu
1072 # (like clang-10/llvm-strip-10)
1073 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')
847e5585
JJ
1074 r = find_program('clang',
1075 required : bpf_framework,
1076 version : '>= 10.0.0')
76abad4d
JH
1077 clang_found = r.found()
1078 if clang_found
573c0dc1 1079 clang = r.full_path()
76abad4d 1080 endif
76abad4d
JH
1081 else
1082 clang_found = true
1083 clang = cc.cmd_array()
dc7e9c1b 1084 endif
a6ac8b5a 1085
76abad4d
JH
1086 if clang_found
1087 # Check if 'clang -target bpf' is supported.
1088 clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus', check : false).returncode() == 0
1089 endif
1090 elif bpf_compiler == 'gcc'
76abad4d 1091 bpf_gcc = find_program('bpf-gcc',
e4086f7d 1092 'bpf-none-gcc',
76abad4d 1093 required : true,
4a7a13b5 1094 version : '>= 13.1.0')
76abad4d 1095 bpf_gcc_found = bpf_gcc.found()
a6ac8b5a
YW
1096 endif
1097
76abad4d
JH
1098 if clang_supports_bpf or bpf_gcc_found
1099 # Debian installs this in /usr/sbin/ which is not in $PATH.
1100 # We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian.
1101 # We use 'bpftool gen object' subcommand for bpftool strip, it was added by d80b2fcbe0a023619e0fc73112f2a02c2662f6ab (v5.13).
e3759ac4
JH
1102 bpftool = find_program('bpftool',
1103 '/usr/sbin/bpftool',
847e5585
JJ
1104 required : bpf_framework.enabled() and bpf_compiler == 'gcc',
1105 version : bpf_compiler == 'gcc' ? '>= 7.0.0' : '>= 5.13.0')
e3759ac4 1106
76abad4d
JH
1107 if bpftool.found()
1108 bpftool_strip = true
1109 deps_found = true
b88323e4 1110 elif bpf_compiler == 'clang'
76abad4d
JH
1111 # We require the 'bpftool gen skeleton' subcommand, it was added by 985ead416df39d6fe8e89580cc1db6aa273e0175 (v5.6).
1112 bpftool = find_program('bpftool',
1113 '/usr/sbin/bpftool',
847e5585 1114 required : bpf_framework,
76abad4d 1115 version : '>= 5.6.0')
e3759ac4 1116 endif
68e101da 1117
76abad4d
JH
1118 # We use `llvm-strip` as a fallback if `bpftool gen object` strip support is not available.
1119 if not bpftool_strip and bpftool.found() and clang_supports_bpf
1120 if not meson.is_cross_build()
1121 llvm_strip_bin = run_command(clang, '--print-prog-name', 'llvm-strip',
1122 check : true).stdout().strip()
1123 else
1124 llvm_strip_bin = 'llvm-strip'
1125 endif
847e5585
JJ
1126 llvm_strip = find_program(llvm_strip_bin,
1127 required : bpf_framework,
1128 version : '>= 10.0.0')
76abad4d
JH
1129 deps_found = llvm_strip.found()
1130 endif
1131 endif
68e101da 1132
7d861e12 1133 # Can build BPF program from source code in restricted C
d40ce018 1134 conf.set10('BPF_FRAMEWORK', deps_found)
7d861e12
JK
1135endif
1136
5c23128d 1137libmount = dependency('mount',
c0b4b0f8 1138 version : fuzzer_build ? '>= 0' : '>= 2.30')
5c23128d 1139
9ee80846
JJ
1140libfdisk = dependency('fdisk',
1141 version : '>= 2.32',
1142 disabler : true,
1143 required : get_option('fdisk'))
1144conf.set10('HAVE_LIBFDISK', libfdisk.found())
e594a3b1 1145
1e73a64a
JJ
1146# This prefers pwquality if both are enabled or auto.
1147feature = get_option('pwquality').disable_auto_if(get_option('passwdqc').enabled())
1148libpwquality = dependency('pwquality',
1149 version : '>= 1.4.1',
1150 required : feature)
1151have = libpwquality.found()
1152if not have
1153 # libpwquality is used for both features for simplicity
1154 libpwquality = dependency('passwdqc',
1155 required : get_option('passwdqc'))
70a5db58
LP
1156endif
1157conf.set10('HAVE_PWQUALITY', have)
1e73a64a 1158conf.set10('HAVE_PASSWDQC', not have and libpwquality.found())
70a5db58 1159
43abc59a
JJ
1160libseccomp = dependency('libseccomp',
1161 version : '>= 2.3.1',
1162 required : get_option('seccomp'))
1163conf.set10('HAVE_SECCOMP', libseccomp.found())
1d8aae43 1164
43abc59a
JJ
1165libselinux = dependency('libselinux',
1166 version : '>= 2.1.9',
1167 required : get_option('selinux'))
1168conf.set10('HAVE_SELINUX', libselinux.found())
5c23128d 1169
43abc59a
JJ
1170libapparmor = dependency('libapparmor',
1171 version : '>= 2.13',
1172 required : get_option('apparmor'))
1173conf.set10('HAVE_APPARMOR', libapparmor.found())
5c23128d 1174
07b382cc
ZJS
1175have = get_option('smack') and get_option('smack-run-label') != ''
1176conf.set10('HAVE_SMACK_RUN_LABEL', have)
1177if have
1178 conf.set_quoted('SMACK_RUN_LABEL', get_option('smack-run-label'))
1179endif
5c23128d 1180
aa5ae971
ŁS
1181have = get_option('smack') and get_option('smack-default-process-label') != ''
1182if have
1183 conf.set_quoted('SMACK_DEFAULT_PROCESS_LABEL', get_option('smack-default-process-label'))
1184endif
1185
a0c9ac9a
JJ
1186feature = get_option('polkit')
1187libpolkit = dependency('polkit-gobject-1',
1188 required : feature.disabled() ? feature : false)
1189install_polkit = feature.allowed()
1190install_polkit_pkla = libpolkit.found() and libpolkit.version().version_compare('< 0.106')
1191if install_polkit_pkla
1192 message('Old polkit detected, will install pkla files')
3ca0cb73 1193endif
349cc4a5 1194conf.set10('ENABLE_POLKIT', install_polkit)
3ca0cb73 1195
43abc59a
JJ
1196libacl = dependency('libacl',
1197 required : get_option('acl'))
1198conf.set10('HAVE_ACL', libacl.found())
36f0387e 1199
43abc59a
JJ
1200libaudit = dependency('audit',
1201 required : get_option('audit'))
1202conf.set10('HAVE_AUDIT', libaudit.found())
4fcc033b 1203
43abc59a
JJ
1204libblkid = dependency('blkid',
1205 required : get_option('blkid'))
1206conf.set10('HAVE_BLKID', libblkid.found())
1207conf.set10('HAVE_BLKID_PROBE_SET_HINT',
1208 libblkid.found() and cc.has_function('blkid_probe_set_hint', dependencies : libblkid))
5c23128d 1209
43abc59a
JJ
1210libkmod = dependency('libkmod',
1211 version : '>= 15',
1212 required : get_option('kmod'))
1213conf.set10('HAVE_KMOD', libkmod.found())
1d98716e 1214libkmod_cflags = libkmod.partial_dependency(includes: true, compile_args: true)
5c23128d 1215
43abc59a
JJ
1216libxenctrl = dependency('xencontrol',
1217 version : '>= 4.9',
1218 required : get_option('xenctrl'))
1219conf.set10('HAVE_XENCTRL', libxenctrl.found())
2bdd7a8a 1220libxenctrl_cflags = libxenctrl.partial_dependency(includes: true, compile_args: true)
ede5a78f 1221
a0c9ac9a
JJ
1222feature = get_option('pam')
1223libpam = dependency('pam',
1224 required : feature.disabled() ? feature : false)
1225if not libpam.found()
1226 # Debian older than bookworm and Ubuntu older than 22.10 do not provide the .pc file.
1227 libpam = cc.find_library('pam', required : feature)
1228endif
1229libpam_misc = dependency('pam_misc',
1230 required : feature.disabled() ? feature : false)
1231if not libpam_misc.found()
1232 libpam_misc = cc.find_library('pam_misc', required : feature)
5c23128d 1233endif
a0c9ac9a 1234conf.set10('HAVE_PAM', libpam.found() and libpam_misc.found())
5c23128d 1235
43abc59a
JJ
1236libmicrohttpd = dependency('libmicrohttpd',
1237 version : '>= 0.9.33',
1238 required : get_option('microhttpd'))
1239conf.set10('HAVE_MICROHTTPD', libmicrohttpd.found())
5c23128d 1240
1e73a64a
JJ
1241libcryptsetup = get_option('libcryptsetup')
1242libcryptsetup_plugins = get_option('libcryptsetup-plugins')
1243if libcryptsetup_plugins.enabled()
1244 if libcryptsetup.disabled()
cee60fc3 1245 error('libcryptsetup-plugins cannot be requested without libcryptsetup')
d625f717 1246 endif
1e73a64a
JJ
1247 libcryptsetup = libcryptsetup_plugins
1248endif
1249
1250libcryptsetup = dependency('libcryptsetup',
1251 version : libcryptsetup_plugins.enabled() ? '>= 2.4.0' : '>= 2.0.1',
1252 required : libcryptsetup)
1253
1254have = libcryptsetup.found()
1255foreach ident : ['crypt_set_metadata_size',
1256 'crypt_activate_by_signed_key',
1257 'crypt_token_max',
1258 'crypt_reencrypt_init_by_passphrase',
1259 'crypt_reencrypt',
c5daf14c 1260 'crypt_set_data_offset',
d0eff7a1
AV
1261 'crypt_set_keyring_to_link',
1262 'crypt_resume_by_volume_key']
1e73a64a
JJ
1263 have_ident = have and cc.has_function(
1264 ident,
1265 prefix : '#include <libcryptsetup.h>',
1266 dependencies : libcryptsetup)
1267 conf.set10('HAVE_' + ident.to_upper(), have_ident)
1268endforeach
349cc4a5 1269conf.set10('HAVE_LIBCRYPTSETUP', have)
5c23128d 1270
1e73a64a
JJ
1271# TODO: Use has_function(required : libcryptsetup_plugins) with meson >= 1.3.0
1272if libcryptsetup_plugins.allowed()
aac80717
ZJS
1273 have = (cc.has_function(
1274 'crypt_activate_by_token_pin',
1275 prefix : '#include <libcryptsetup.h>',
1276 dependencies : libcryptsetup) and
1277 cc.has_function(
1278 'crypt_token_external_path',
1279 prefix : '#include <libcryptsetup.h>',
1280 dependencies : libcryptsetup))
d1ae38d8
OK
1281else
1282 have = false
1283endif
1284conf.set10('HAVE_LIBCRYPTSETUP_PLUGINS', have)
1285
43abc59a
JJ
1286libcurl = dependency('libcurl',
1287 version : '>= 7.32.0',
1288 required : get_option('libcurl'))
1289conf.set10('HAVE_LIBCURL', libcurl.found())
47350c5f 1290conf.set10('CURL_NO_OLDIES', conf.get('BUILD_MODE_DEVELOPER') == 1)
5c23128d 1291
1e73a64a
JJ
1292feature = get_option('libidn2').disable_auto_if(get_option('libidn').enabled())
1293libidn = dependency('libidn2',
1294 required : feature)
1295have = libidn.found()
1296if not have
7f7ab228 1297 # libidn is used for both libidn and libidn2 objects
1b931399 1298 libidn = dependency('libidn',
1e73a64a 1299 required : get_option('libidn'))
5c23128d 1300endif
1e73a64a
JJ
1301conf.set10('HAVE_LIBIDN', not have and libidn.found())
1302conf.set10('HAVE_LIBIDN2', have)
5c23128d 1303
43abc59a
JJ
1304libiptc = dependency('libiptc',
1305 required : get_option('libiptc'))
1306conf.set10('HAVE_LIBIPTC', libiptc.found())
5b5f8f8b 1307libiptc_cflags = libiptc.partial_dependency(includes: true, compile_args: true)
5c23128d 1308
43abc59a
JJ
1309libqrencode = dependency('libqrencode',
1310 version : '>= 3',
1311 required : get_option('qrencode'))
1312conf.set10('HAVE_QRENCODE', libqrencode.found())
5c23128d 1313
a0c9ac9a
JJ
1314feature = get_option('gcrypt')
1315libgcrypt = dependency('libgcrypt',
1316 required : feature)
1317libgpg_error = dependency('gpg-error',
1318 required : feature.disabled() ? feature : false)
1319if not libgpg_error.found()
1320 # CentOS 8 does not provide the .pc file.
1321 libgpg_error = cc.find_library('gpg-error', required : feature)
349cc4a5 1322endif
a0c9ac9a
JJ
1323
1324have = libgcrypt.found() and libgpg_error.found()
349cc4a5
ZJS
1325if not have
1326 # link to neither of the libs if one is not found
a44fb601
ZJS
1327 libgcrypt = []
1328 libgpg_error = []
8707c9b2
LB
1329 libgcrypt_cflags = []
1330else
1331 libgcrypt_cflags = libgcrypt.partial_dependency(includes: true, compile_args: true)
a44fb601 1332endif
349cc4a5 1333conf.set10('HAVE_GCRYPT', have)
a44fb601 1334
43abc59a
JJ
1335libgnutls = dependency('gnutls',
1336 version : '>= 3.1.4',
1337 required : get_option('gnutls'))
1338conf.set10('HAVE_GNUTLS', libgnutls.found())
5c23128d 1339
43abc59a
JJ
1340libopenssl = dependency('openssl',
1341 version : '>= 1.1.0',
1342 required : get_option('openssl'))
1343conf.set10('HAVE_OPENSSL', libopenssl.found())
096cbdce 1344
43abc59a
JJ
1345libp11kit = dependency('p11-kit-1',
1346 version : '>= 0.23.3',
1347 required : get_option('p11kit'))
1348conf.set10('HAVE_P11KIT', libp11kit.found())
1349libp11kit_cflags = libp11kit.partial_dependency(includes: true, compile_args: true)
839fddbe 1350
40e9c4e4
JJ
1351feature = get_option('libfido2').require(
1352 conf.get('HAVE_OPENSSL') == 1,
1353 error_message : 'openssl required')
1354libfido2 = dependency('libfido2',
1355 required : feature)
1356conf.set10('HAVE_LIBFIDO2', libfido2.found())
af4fbd46 1357
43abc59a
JJ
1358tpm2 = dependency('tss2-esys tss2-rc tss2-mu tss2-tcti-device',
1359 required : get_option('tpm2'))
1360conf.set10('HAVE_TPM2', tpm2.found())
1361conf.set10('HAVE_TSS2_ESYS3', tpm2.found() and tpm2.version().version_compare('>= 3.0.0'))
5e521624 1362
43abc59a
JJ
1363libdw = dependency('libdw',
1364 required : get_option('elfutils'))
1365conf.set10('HAVE_ELFUTILS', libdw.found())
1366# New in elfutils 0.177
1367conf.set10('HAVE_DWELF_ELF_E_MACHINE_STRING',
1368 libdw.found() and cc.has_function('dwelf_elf_e_machine_string', dependencies : libdw))
d48c2721 1369
43abc59a
JJ
1370libz = dependency('zlib',
1371 required : get_option('zlib'))
1372conf.set10('HAVE_ZLIB', libz.found())
5c23128d 1373
a0c9ac9a
JJ
1374feature = get_option('bzip2')
1375libbzip2 = dependency('bzip2',
1376 required : feature.disabled() ? feature : false)
1377if not libbzip2.found()
1378 # Debian and Ubuntu do not provide the .pc file.
1379 libbzip2 = cc.find_library('bz2', required : feature)
5c23128d 1380endif
a0c9ac9a 1381conf.set10('HAVE_BZIP2', libbzip2.found())
5c23128d 1382
43abc59a
JJ
1383libxz = dependency('liblzma',
1384 required : get_option('xz'))
1385conf.set10('HAVE_XZ', libxz.found())
3fc72d54 1386libxz_cflags = libxz.partial_dependency(includes: true, compile_args: true)
5c23128d 1387
43abc59a
JJ
1388liblz4 = dependency('liblz4',
1389 version : '>= 1.3.0',
1390 required : get_option('lz4'))
1391conf.set10('HAVE_LZ4', liblz4.found())
3fc72d54 1392liblz4_cflags = liblz4.partial_dependency(includes: true, compile_args: true)
5c23128d 1393
43abc59a
JJ
1394libzstd = dependency('libzstd',
1395 version : '>= 1.4.0',
1396 required : get_option('zstd'))
1397conf.set10('HAVE_ZSTD', libzstd.found())
3fc72d54 1398libzstd_cflags = libzstd.partial_dependency(includes: true, compile_args: true)
d80b051c 1399
43abc59a 1400conf.set10('HAVE_COMPRESSION', libxz.found() or liblz4.found() or libzstd.found())
ef5924aa 1401
cd3c6322
LB
1402compression = get_option('default-compression')
1403if compression == 'auto'
43abc59a 1404 if libzstd.found()
cd3c6322 1405 compression = 'zstd'
43abc59a 1406 elif liblz4.found()
cd3c6322 1407 compression = 'lz4'
43abc59a 1408 elif libxz.found()
cd3c6322
LB
1409 compression = 'xz'
1410 else
1411 compression = 'none'
1412 endif
43abc59a 1413elif compression == 'zstd' and not libzstd.found()
cd3c6322 1414 error('default-compression=zstd requires zstd')
43abc59a 1415elif compression == 'lz4' and not liblz4.found()
cd3c6322 1416 error('default-compression=lz4 requires lz4')
43abc59a 1417elif compression == 'xz' and not libxz.found()
cd3c6322
LB
1418 error('default-compression=xz requires xz')
1419endif
1788c6f3 1420conf.set('DEFAULT_COMPRESSION', 'COMPRESSION_@0@'.format(compression.to_upper()))
cd3c6322 1421
b68f4cad
LP
1422libarchive = dependency('libarchive',
1423 version : '>= 3.0',
1424 required : get_option('libarchive'))
1425conf.set10('HAVE_LIBARCHIVE', libarchive.found())
1426
43abc59a
JJ
1427libxkbcommon = dependency('xkbcommon',
1428 version : '>= 0.3.0',
1429 required : get_option('xkbcommon'))
1430conf.set10('HAVE_XKBCOMMON', libxkbcommon.found())
a44fb601 1431
43abc59a
JJ
1432libpcre2 = dependency('libpcre2-8',
1433 required : get_option('pcre2'))
1434conf.set10('HAVE_PCRE2', libpcre2.found())
69e96427 1435
43abc59a
JJ
1436libglib = dependency('glib-2.0',
1437 version : '>= 2.22.0',
1438 required : get_option('glib'))
1439libgobject = dependency('gobject-2.0',
1440 version : '>= 2.22.0',
1441 required : get_option('glib'))
1442libgio = dependency('gio-2.0',
1443 required : get_option('glib'))
1444conf.set10('HAVE_GLIB', libglib.found() and libgobject.found() and libgio.found())
69e96427 1445
101b5943
JJ
1446libdbus = dependency('dbus-1',
1447 version : '>= 1.3.2',
1448 required : get_option('dbus'))
1449conf.set10('HAVE_DBUS', libdbus.found())
69e96427 1450
101b5943 1451dbusdatadir = libdbus.get_variable(pkgconfig: 'datadir', default_value: datadir) / 'dbus-1'
1bd0cc45
YW
1452
1453dbuspolicydir = get_option('dbuspolicydir')
1454if dbuspolicydir == ''
1455 dbuspolicydir = dbusdatadir / 'system.d'
1456endif
1457
1458dbussessionservicedir = get_option('dbussessionservicedir')
1459if dbussessionservicedir == ''
101b5943 1460 dbussessionservicedir = libdbus.get_variable(pkgconfig: 'session_bus_services_dir', default_value: dbusdatadir / 'services')
1bd0cc45
YW
1461endif
1462
1463dbussystemservicedir = get_option('dbussystemservicedir')
1464if dbussystemservicedir == ''
101b5943 1465 dbussystemservicedir = libdbus.get_variable(pkgconfig: 'system_bus_services_dir', default_value: dbusdatadir / 'system-services')
1bd0cc45
YW
1466endif
1467
1468dbus_interfaces_dir = get_option('dbus-interfaces-dir')
1469if dbus_interfaces_dir == '' or dbus_interfaces_dir == 'yes'
1470 if meson.is_cross_build() and dbus_interfaces_dir != 'yes'
1471 dbus_interfaces_dir = 'no'
1472 warning('Exporting D-Bus interface XML files is disabled during cross build. Pass path or "yes" to force enable.')
1473 else
101b5943 1474 dbus_interfaces_dir = libdbus.get_variable(pkgconfig: 'interfaces_dir', default_value: dbusdatadir / 'interfaces')
1bd0cc45
YW
1475 endif
1476endif
1bd0cc45 1477
12b4cffd
YW
1478dmi_arches = ['x86', 'x86_64', 'aarch64', 'arm', 'ia64', 'loongarch64', 'mips']
1479conf.set10('HAVE_DMI', host_machine.cpu_family() in dmi_arches)
1480
e37ad765
ZJS
1481# We support one or the other. If gcrypt is available, we assume it's there to
1482# be used, and use it in preference.
1483opt = get_option('cryptolib')
1484if opt == 'openssl' and conf.get('HAVE_OPENSSL') == 0
1485 error('openssl requested as the default cryptolib, but not available')
1486endif
1487conf.set10('PREFER_OPENSSL',
1488 opt == 'openssl' or (opt == 'auto' and conf.get('HAVE_OPENSSL') == 1 and conf.get('HAVE_GCRYPT') == 0))
1489conf.set10('HAVE_OPENSSL_OR_GCRYPT',
1490 conf.get('HAVE_OPENSSL') == 1 or conf.get('HAVE_GCRYPT') == 1)
9bcf483b 1491lib_openssl_or_gcrypt = conf.get('PREFER_OPENSSL') == 1 ? [libopenssl] : [libgcrypt, libgpg_error]
42303dcb 1492
56ddbf10
YW
1493dns_over_tls = get_option('dns-over-tls')
1494if dns_over_tls != 'false'
e37ad765
ZJS
1495 if dns_over_tls == 'gnutls' and conf.get('PREFER_OPENSSL') == 1
1496 error('Sorry, -Ddns-over-tls=gnutls is not supported when openssl is used as the cryptolib')
1497 endif
1498
1f9aa3d2
LB
1499 if dns_over_tls == 'gnutls'
1500 have_openssl = false
096cbdce 1501 else
1f9aa3d2
LB
1502 have_openssl = conf.get('HAVE_OPENSSL') == 1
1503 if dns_over_tls == 'openssl' and not have_openssl
1504 error('DNS-over-TLS support was requested with openssl, but dependencies are not available')
096cbdce 1505 endif
56ddbf10 1506 endif
1f9aa3d2
LB
1507 if dns_over_tls == 'openssl' or have_openssl
1508 have_gnutls = false
096cbdce 1509 else
1f9aa3d2
LB
1510 have_gnutls = conf.get('HAVE_GNUTLS') == 1 and libgnutls.version().version_compare('>= 3.6.0')
1511 if dns_over_tls != 'auto' and not have_gnutls
1512 str = dns_over_tls == 'gnutls' ? ' with gnutls' : ''
b349bc59 1513 error('DNS-over-TLS support was requested@0@, but dependencies are not available'.format(str))
096cbdce
IT
1514 endif
1515 endif
1516 have = have_gnutls or have_openssl
56ddbf10 1517else
be5536a6
MO
1518 have = false
1519 have_gnutls = false
1520 have_openssl = false
56ddbf10
YW
1521endif
1522conf.set10('ENABLE_DNS_OVER_TLS', have)
096cbdce
IT
1523conf.set10('DNS_OVER_TLS_USE_GNUTLS', have_gnutls)
1524conf.set10('DNS_OVER_TLS_USE_OPENSSL', have_openssl)
56ddbf10 1525
c9299be2 1526default_dns_over_tls = get_option('default-dns-over-tls')
56ddbf10 1527if default_dns_over_tls != 'no' and conf.get('ENABLE_DNS_OVER_TLS') == 0
4310bfc2 1528 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.')
c9299be2 1529 default_dns_over_tls = 'no'
5d67a7ae 1530endif
c9299be2
IT
1531conf.set('DEFAULT_DNS_OVER_TLS_MODE',
1532 'DNS_OVER_TLS_' + default_dns_over_tls.underscorify().to_upper())
411d1f4c 1533conf.set_quoted('DEFAULT_DNS_OVER_TLS_MODE_STR', default_dns_over_tls)
5d67a7ae 1534
3614df05
ZJS
1535default_mdns = get_option('default-mdns')
1536conf.set('DEFAULT_MDNS_MODE',
1537 'RESOLVE_SUPPORT_' + default_mdns.to_upper())
411d1f4c 1538conf.set_quoted('DEFAULT_MDNS_MODE_STR', default_mdns)
3614df05
ZJS
1539
1540default_llmnr = get_option('default-llmnr')
1541conf.set('DEFAULT_LLMNR_MODE',
1542 'RESOLVE_SUPPORT_' + default_llmnr.to_upper())
411d1f4c 1543conf.set_quoted('DEFAULT_LLMNR_MODE_STR', default_llmnr)
3614df05 1544
40e9c4e4
JJ
1545have = get_option('repart').require(
1546 conf.get('HAVE_LIBFDISK') == 1,
1547 error_message : 'fdisk required').allowed()
e594a3b1
LP
1548conf.set10('ENABLE_REPART', have)
1549
7e8facb3 1550default_dnssec = get_option('default-dnssec')
7e8facb3
ZJS
1551if default_dnssec != 'no' and conf.get('HAVE_OPENSSL_OR_GCRYPT') == 0
1552 message('default-dnssec cannot be set to yes or allow-downgrade openssl and gcrypt are disabled. Setting default-dnssec to no.')
1553 default_dnssec = 'no'
1554endif
1555conf.set('DEFAULT_DNSSEC_MODE',
1556 'DNSSEC_' + default_dnssec.underscorify().to_upper())
1557conf.set_quoted('DEFAULT_DNSSEC_MODE_STR', default_dnssec)
1558
40e9c4e4
JJ
1559have = get_option('sysupdate').require(
1560 conf.get('HAVE_OPENSSL') == 1 and
1561 conf.get('HAVE_LIBFDISK') == 1,
1562 error_message : 'fdisk and openssl required').allowed()
43cc7a3e
LP
1563conf.set10('ENABLE_SYSUPDATE', have)
1564
1761066b
LP
1565conf.set10('ENABLE_STORAGETM', get_option('storagetm'))
1566
40e9c4e4
JJ
1567have = get_option('importd').require(
1568 conf.get('HAVE_LIBCURL') == 1 and
1569 conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1 and
1570 conf.get('HAVE_ZLIB') == 1 and
1571 conf.get('HAVE_XZ') == 1,
1572 error_message : 'curl, openssl/grypt, zlib and xz required').allowed()
349cc4a5 1573conf.set10('ENABLE_IMPORTD', have)
5c23128d 1574
40e9c4e4
JJ
1575have = get_option('homed').require(
1576 conf.get('HAVE_OPENSSL') == 1 and
1577 conf.get('HAVE_LIBFDISK') == 1 and
d0eff7a1
AV
1578 conf.get('HAVE_LIBCRYPTSETUP') == 1 and
1579 conf.get('HAVE_CRYPT_RESUME_BY_VOLUME_KEY') == 1,
40e9c4e4 1580 error_message : 'openssl, fdisk and libcryptsetup required').allowed()
70a5db58
LP
1581conf.set10('ENABLE_HOMED', have)
1582
af06ddf5
YW
1583have = have and conf.get('HAVE_PAM') == 1
1584conf.set10('ENABLE_PAM_HOME', have)
1585
1e73a64a
JJ
1586feature = get_option('remote')
1587have_deps = [conf.get('HAVE_MICROHTTPD') == 1,
1588 conf.get('HAVE_LIBCURL') == 1]
1589# sd-j-remote requires µhttpd, and sd-j-upload requires libcurl, so
1590# it's possible to build one without the other. Complain only if
1591# support was explicitly requested. The auxiliary files like sysusers
1592# config should be installed when any of the programs are built.
1593if feature.enabled() and not (have_deps[0] and have_deps[1])
1594 error('remote support was requested, but dependencies are not available')
1595endif
1596have = feature.allowed() and (have_deps[0] or have_deps[1])
349cc4a5 1597conf.set10('ENABLE_REMOTE', have)
5c23128d 1598
2b84d628
ZJS
1599feature = get_option('vmspawn').disable_auto_if(conf.get('BUILD_MODE_DEVELOPER') == 0)
1600conf.set10('ENABLE_VMSPAWN', feature.allowed())
1601
702a52f4
LP
1602conf.set10('DEFAULT_MOUNTFSD_TRUSTED_DIRECTORIES', get_option('default-mountfsd-trusted-directories'))
1603
b3259a6e
ZJS
1604foreach term : ['analyze',
1605 'backlight',
a9149d87 1606 'binfmt',
dfca5587 1607 'compat-mutable-uid-boundaries',
a9149d87 1608 'coredump',
b3259a6e
ZJS
1609 'efi',
1610 'environment-d',
1611 'firstboot',
1612 'gshadow',
1613 'hibernate',
a9149d87 1614 'hostnamed',
b3259a6e
ZJS
1615 'hwdb',
1616 'idn',
1617 'ima',
1618 'initrd',
1782534b 1619 'kernel-install',
b3259a6e 1620 'ldconfig',
a9149d87 1621 'localed',
b3259a6e 1622 'logind',
a9149d87 1623 'machined',
702a52f4 1624 'mountfsd',
a9149d87 1625 'networkd',
dfca5587 1626 'nscd',
8aee931e 1627 'nsresourced',
b3259a6e
ZJS
1628 'nss-myhostname',
1629 'nss-systemd',
1782534b 1630 'oomd',
b3259a6e
ZJS
1631 'portabled',
1632 'pstore',
a9149d87 1633 'quotacheck',
b3259a6e
ZJS
1634 'randomseed',
1635 'resolve',
1636 'rfkill',
1637 'smack',
dfca5587 1638 'sysext',
a9149d87 1639 'sysusers',
b3259a6e
ZJS
1640 'timedated',
1641 'timesyncd',
a9149d87 1642 'tmpfiles',
a9149d87 1643 'tpm',
b3259a6e
ZJS
1644 'userdb',
1645 'utmp',
1646 'vconsole',
1647 'xdg-autostart']
a9149d87
ZJS
1648 have = get_option(term)
1649 name = 'ENABLE_' + term.underscorify().to_upper()
1650 conf.set10(name, have)
5c23128d
ZJS
1651endforeach
1652
bd7e6aa7
ZJS
1653enable_sysusers = conf.get('ENABLE_SYSUSERS') == 1
1654
08540a95
YW
1655foreach tuple : [['nss-mymachines', 'machined'],
1656 ['nss-resolve', 'resolve']]
1657 want = get_option(tuple[0])
1e73a64a 1658 if want.allowed()
08540a95 1659 have = get_option(tuple[1])
1e73a64a 1660 if want.enabled() and not have
08540a95
YW
1661 error('@0@ is requested but @1@ is disabled'.format(tuple[0], tuple[1]))
1662 endif
1663 else
1664 have = false
1665 endif
1666 name = 'ENABLE_' + tuple[0].underscorify().to_upper()
1667 conf.set10(name, have)
1668endforeach
1669
1670enable_nss = false
1671foreach term : ['ENABLE_NSS_MYHOSTNAME',
1672 'ENABLE_NSS_MYMACHINES',
1673 'ENABLE_NSS_RESOLVE',
1674 'ENABLE_NSS_SYSTEMD']
1675 if conf.get(term) == 1
1676 enable_nss = true
1677 endif
1678endforeach
1679conf.set10('ENABLE_NSS', enable_nss)
1680
348b4437 1681conf.set10('ENABLE_TIMEDATECTL', get_option('timedated') or get_option('timesyncd'))
6129ec85 1682
62670a77
FS
1683conf.set10('ENABLE_SSH_PROXY_CONFIG', sshconfdir != 'no')
1684conf.set10('ENABLE_SSH_USERDB_CONFIG', conf.get('ENABLE_USERDB') == 1 and sshdconfdir != 'no')
1685
b68dfb9e 1686conf.set10('SYSTEMD_SLOW_TESTS_DEFAULT', slow_tests)
00d82c81 1687
e6267e83 1688#####################################################################
db7f5ab6 1689
9c45bfb2
FS
1690pymod = import('python')
1691python = pymod.find_installation('python3', required : true, modules : ['jinja2'])
1692python_39 = python.language_version().version_compare('>=3.9')
1693
e6267e83 1694#####################################################################
4d3ef2d1
LP
1695
1696if conf.get('BPF_FRAMEWORK') == 1
1697 bpf_clang_flags = [
1698 '-std=gnu11',
1699 '-Wno-compare-distinct-pointer-types',
1700 '-fno-stack-protector',
1701 '-O2',
1702 '-target',
1703 'bpf',
1704 '-g',
1705 '-c',
1706 ]
1707
1708 bpf_gcc_flags = [
1709 '-std=gnu11',
1710 '-fno-stack-protector',
1ce28e5a 1711 '-fno-ssa-phiopt',
4d3ef2d1 1712 '-O2',
4d3ef2d1
LP
1713 '-mcpu=v3',
1714 '-mco-re',
1715 '-gbtf',
1716 '-c',
1717 ]
1718
1719 # Generate defines that are appropriate to tell the compiler what architecture
1720 # we're compiling for. By default we just map meson's cpu_family to __<cpu_family>__.
1721 # This dictionary contains the exceptions where this doesn't work.
1722 #
1723 # C.f. https://mesonbuild.com/Reference-tables.html#cpu-families
1724 # and src/basic/missing_syscall_def.h.
1725 cpu_arch_defines = {
1726 'ppc' : ['-D__powerpc__'],
1727 'ppc64' : ['-D__powerpc64__', '-D_CALL_ELF=2'],
1728 'riscv32' : ['-D__riscv', '-D__riscv_xlen=32'],
1729 'riscv64' : ['-D__riscv', '-D__riscv_xlen=64'],
1730 'x86' : ['-D__i386__'],
1731
1732 # For arm, assume hardware fp is available.
1733 'arm' : ['-D__arm__', '-D__ARM_PCS_VFP'],
1734 }
1735
1736 bpf_arch_flags = cpu_arch_defines.get(host_machine.cpu_family(),
1737 ['-D__@0@__'.format(host_machine.cpu_family())])
1738 if bpf_compiler == 'gcc'
1739 bpf_arch_flags += ['-m' + host_machine.endian() + '-endian']
1740 endif
1741
1742 libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir')
1743
1744 bpf_o_unstripped_cmd = []
1745 if bpf_compiler == 'clang'
1746 bpf_o_unstripped_cmd += [
1747 clang,
1748 bpf_clang_flags,
1749 bpf_arch_flags,
1750 ]
1751 elif bpf_compiler == 'gcc'
1752 bpf_o_unstripped_cmd += [
1753 bpf_gcc,
1754 bpf_gcc_flags,
1755 bpf_arch_flags,
1756 ]
1757 endif
1758
1759 bpf_o_unstripped_cmd += ['-I.']
1760
1df02192 1761 if not meson.is_cross_build()
4d3ef2d1
LP
1762 target_triplet_cmd = run_command('gcc', '-dumpmachine', check: false)
1763 if target_triplet_cmd.returncode() == 0
1764 target_triplet = target_triplet_cmd.stdout().strip()
1765 bpf_o_unstripped_cmd += [
1766 '-isystem',
1767 '/usr/include/@0@'.format(target_triplet)
1768 ]
1769 endif
1770 endif
1771
1772 bpf_o_unstripped_cmd += [
1773 '-idirafter',
1774 libbpf_include_dir,
1775 '@INPUT@',
1776 '-o',
1777 '@OUTPUT@'
1778 ]
1779
1780 if bpftool_strip
1781 bpf_o_cmd = [
1782 bpftool,
1783 'gen',
1784 'object',
1785 '@OUTPUT@',
1786 '@INPUT@'
1787 ]
1788 elif bpf_compiler == 'clang'
1789 bpf_o_cmd = [
1790 llvm_strip,
1791 '-g',
1792 '@INPUT@',
1793 '-o',
1794 '@OUTPUT@'
1795 ]
1796 endif
1797
1798 skel_h_cmd = [
1799 bpftool,
1800 'gen',
1801 'skeleton',
1802 '@INPUT@'
1803 ]
1804endif
1805
dfca5587
JJ
1806#####################################################################
1807
1808efi_arch = {
31ffb6b1
JJ
1809 'aarch64' : 'aa64',
1810 'arm' : 'arm',
1811 'loongarch32' : 'loongarch32',
1812 'loongarch64' : 'loongarch64',
1813 'riscv32' : 'riscv32',
1814 'riscv64' : 'riscv64',
1815 'x86_64' : 'x64',
1816 'x86' : 'ia32',
dfca5587
JJ
1817}.get(host_machine.cpu_family(), '')
1818
40e9c4e4
JJ
1819pyelftools = pymod.find_installation('python3',
1820 required : get_option('bootloader'),
1821 modules : ['elftools'])
1822
1823have = get_option('bootloader').require(
1824 pyelftools.found() and get_option('efi') and efi_arch != '',
1825 error_message : 'unsupported EFI arch or EFI support is disabled').allowed()
1826conf.set10('ENABLE_BOOTLOADER', have)
1827conf.set_quoted('EFI_MACHINE_TYPE_NAME', have ? efi_arch : '')
2afeaf16
JJ
1828
1829efi_arch_alt = ''
7ea44f17 1830efi_cpu_family_alt = ''
40e9c4e4 1831if have and efi_arch == 'x64' and cc.links('''
2afeaf16
JJ
1832 #include <limits.h>
1833 int main(int argc, char *argv[]) {
1834 return __builtin_popcount(argc - CHAR_MAX);
1835 }''', args : ['-m32', '-march=i686'], name : '32bit build possible')
1836 efi_arch_alt = 'ia32'
7ea44f17 1837 efi_cpu_family_alt = 'x86'
2afeaf16
JJ
1838endif
1839
85915f31
LB
1840pefile = pymod.find_installation('python3', required: false, modules : ['pefile'])
1841
1842want_ukify = get_option('ukify').require(python_39 and (want_tests != 'true' or pefile.found()), error_message : 'Python >= 3.9 and pefile required').allowed()
9c45bfb2
FS
1843conf.set10('ENABLE_UKIFY', want_ukify)
1844
e6267e83 1845#####################################################################
b0bd2ae8 1846
7ff3b883 1847check_efi_alignment_py = find_program('tools/check-efi-alignment.py')
59342868
LP
1848
1849#####################################################################
1850
1851use_provided_vmlinux_h = false
1852use_generated_vmlinux_h = false
1853provided_vmlinux_h_path = get_option('vmlinux-h-path')
1854
1855# For the more complex BPF programs we really want a vmlinux.h (which is arch
1856# specific, but only somewhat bound to kernel version). Ideally the kernel
1857# development headers would ship that, but right now they don't. Hence address
1858# this in two ways:
1859#
1860# 1. Provide a vmlinux.h at build time
1861# 2. Generate the file on the fly where possible (which requires /sys/ to be mounted)
1862#
1863# We generally prefer the former (to support reproducible builds), but will
1864# fallback to the latter.
1865
1866if conf.get('BPF_FRAMEWORK') == 1
1867 enable_vmlinux_h = get_option('vmlinux-h')
1868
1869 if enable_vmlinux_h == 'auto'
1870 if provided_vmlinux_h_path != ''
1871 use_provided_vmlinux_h = true
1872 elif fs.exists('/sys/kernel/btf/vmlinux') and \
1873 bpftool.found() and \
1874 (host_machine.cpu_family() == build_machine.cpu_family()) and \
1875 host_machine.cpu_family() in ['x86_64', 'aarch64']
1876
1877 # We will only generate a vmlinux.h from the running
1878 # kernel if the host and build machine are of the same
1879 # family. Also for now we focus on x86_64 and aarch64,
1880 # since other archs don't seem to be ready yet.
1881
1882 use_generated_vmlinux_h = true
1883 endif
1884 elif enable_vmlinux_h == 'provided'
1885 use_provided_vmlinux_h = true
1886 elif enable_vmlinux_h == 'generated'
1887 if not fs.exists('/sys/kernel/btf/vmlinux')
1888 error('BTF data from kernel not available (/sys/kernel/btf/vmlinux missing), cannot generate vmlinux.h, but was asked to.')
1889 endif
1890 if not bpftool.found()
1891 error('bpftool not available, cannot generate vmlinux.h, but was asked to.')
1892 endif
1893 use_generated_vmlinux_h = true
1894 endif
1895endif
1896
1897if use_provided_vmlinux_h
1898 if not fs.exists(provided_vmlinux_h_path)
1899 error('Path to provided vmlinux.h does not exist.')
1900 endif
1901 vmlinux_h_dependency = []
1902 bpf_o_unstripped_cmd += ['-I' + fs.parent(provided_vmlinux_h_path)]
1903 message('Using provided @0@'.format(provided_vmlinux_h_path))
1904elif use_generated_vmlinux_h
1905 vmlinux_h_dependency = custom_target(
1906 'vmlinux.h',
1907 output: 'vmlinux.h',
1908 command : [ bpftool, 'btf', 'dump', 'file', '/sys/kernel/btf/vmlinux', 'format', 'c' ],
1909 capture : true)
1910
1911 bpf_o_unstripped_cmd += ['-I' + fs.parent(vmlinux_h_dependency.full_path())]
1912 message('Using generated @0@'.format(vmlinux_h_dependency.full_path()))
1913else
1914 message('Using neither provided nor generated vmlinux.h, some features will not be available.')
1915endif
1916
1917conf.set10('HAVE_VMLINUX_H', use_provided_vmlinux_h or use_generated_vmlinux_h)
1918
1919#####################################################################
1920
3691e7fc 1921check_version_history_py = find_program('tools/check-version-history.py')
2afeaf16
JJ
1922elf2efi_py = find_program('tools/elf2efi.py')
1923export_dbus_interfaces_py = find_program('tools/dbus_exporter.py')
d3821a33 1924generate_gperfs = find_program('tools/generate-gperfs.py')
f6fe732f
YW
1925make_autosuspend_rules_py = find_program('tools/make-autosuspend-rules.py')
1926make_directive_index_py = find_program('tools/make-directive-index.py')
3c1f396f 1927sync_docs_py = find_program('tools/sync-docs.py')
f6fe732f 1928make_man_index_py = find_program('tools/make-man-index.py')
6b1aac3c 1929meson_render_jinja2 = find_program('tools/meson-render-jinja2.py')
d3821a33 1930update_dbus_docs_py = find_program('tools/update-dbus-docs.py')
d3821a33 1931update_hwdb_autosuspend_sh = find_program('tools/update-hwdb-autosuspend.sh')
2afeaf16
JJ
1932update_hwdb_sh = find_program('tools/update-hwdb.sh')
1933update_man_rules_py = find_program('tools/update-man-rules.py')
d3821a33
ZJS
1934update_syscall_tables_sh = find_program('tools/update-syscall-tables.sh')
1935xml_helper_py = find_program('tools/xml_helper.py')
f6fe732f 1936
e6267e83 1937#####################################################################
5c23128d 1938
e95acdfe 1939version_tag = get_option('version-tag')
3f6ce3d4
DDM
1940if version_tag == ''
1941 version_tag = meson.project_version()
1942endif
1943
1944conf.set_quoted('VERSION_TAG', version_tag)
1945
1946vcs_tag = get_option('vcs-tag')
d5dd917a
ZJS
1947command = ['sh', '-c',
1948 vcs_tag and fs.exists(project_source_root / '.git') ?
1949 'echo "-g$(git -C . describe --abbrev=7 --match="" --always --dirty=^)"' : ':']
1950version_h = vcs_tag(
1951 input : 'src/version/version.h.in',
1952 output : 'version.h',
1953 fallback : '',
1954 command : command,
1955)
e95acdfe 1956
e95acdfe
YW
1957shared_lib_tag = get_option('shared-lib-tag')
1958if shared_lib_tag == ''
ea2a57be 1959 shared_lib_tag = meson.project_version().split('~')[0]
e95acdfe
YW
1960endif
1961
e6267e83 1962#####################################################################
e95acdfe 1963
7e43be7d 1964if get_option('b_coverage')
92148283 1965 userspace_c_args += ['-include', 'src/basic/coverage.h']
7e43be7d
FS
1966endif
1967
e6267e83 1968#####################################################################
7e43be7d 1969
5c23128d 1970config_h = configure_file(
37efbbd8
ZJS
1971 output : 'config.h',
1972 configuration : conf)
5c23128d 1973
92148283 1974userspace_c_args += ['-include', 'config.h']
f6fe732f 1975
5c25f9db 1976jinja2_cmdline = [meson_render_jinja2, config_h]
8f04a1ca 1977
92148283
JJ
1978userspace = declare_dependency(
1979 compile_args : userspace_c_args,
1980 link_args : userspace_c_ld_args,
56a0b906 1981 sources : version_h,
92148283
JJ
1982)
1983
c18dde32
ZJS
1984man_page_depends = []
1985
e6267e83 1986#####################################################################
348b4437 1987
1d21a7bd 1988simple_tests = []
130c87b1 1989libsystemd_tests = []
1d21a7bd
YW
1990simple_fuzzers = []
1991catalogs = []
c335921e
YW
1992modules = [] # nss, pam, and other plugins
1993executables = []
1994executables_by_name = {}
cbc55c4c 1995fuzzer_exes = []
1d21a7bd 1996
b61016f2
YW
1997# binaries that have --help and are intended for use by humans,
1998# usually, but not always, installed in /bin.
1999public_programs = []
2000
e3c68924 2001# D-Bus introspection XML export
2002dbus_programs = []
e3c68924 2003
3f80c139
ZJS
2004# A list of boot stubs. Required for testing of ukify.
2005boot_stubs = []
2006
3c1eee5b
ZJS
2007build_dir_include = include_directories('.')
2008
8d40961c
YW
2009basic_includes = include_directories(
2010 'src/basic',
e5bc5f1f 2011 'src/fundamental',
8d40961c
YW
2012 'src/systemd',
2013 '.')
2014
2015libsystemd_includes = [basic_includes, include_directories(
2016 'src/libsystemd/sd-bus',
2017 'src/libsystemd/sd-device',
2018 'src/libsystemd/sd-event',
2019 'src/libsystemd/sd-hwdb',
2020 'src/libsystemd/sd-id128',
2021 'src/libsystemd/sd-journal',
2022 'src/libsystemd/sd-netlink',
2023 'src/libsystemd/sd-network',
2024 'src/libsystemd/sd-resolve')]
2025
2026includes = [libsystemd_includes, include_directories('src/shared')]
5c23128d 2027
5c23128d
ZJS
2028subdir('po')
2029subdir('catalog')
dfca5587 2030subdir('src/fundamental')
5c23128d
ZJS
2031subdir('src/basic')
2032subdir('src/libsystemd')
3976f372 2033subdir('src/shared')
3976f372 2034subdir('src/libudev')
5c23128d 2035
5c23128d 2036libsystemd = shared_library(
37efbbd8 2037 'systemd',
56d50ab1 2038 version : libsystemd_version,
8d40961c 2039 include_directories : libsystemd_includes,
37efbbd8
ZJS
2040 link_args : ['-shared',
2041 '-Wl,--version-script=' + libsystemd_sym_path],
8707c9b2 2042 link_with : [libbasic],
99b9f8fd 2043 link_whole : [libsystemd_static],
92148283
JJ
2044 dependencies : [librt,
2045 threads,
2046 userspace],
37efbbd8
ZJS
2047 link_depends : libsystemd_sym,
2048 install : true,
0a5e638c 2049 install_tag: 'libsystemd',
b0d3095f 2050 install_dir : libdir)
5c23128d 2051
039f1673
LB
2052alias_target('libsystemd', libsystemd)
2053
70848ecf
DC
2054install_libsystemd_static = static_library(
2055 'systemd',
2056 libsystemd_sources,
975464e0 2057 basic_sources,
e5bc5f1f 2058 fundamental_sources,
8d40961c 2059 include_directories : libsystemd_includes,
70848ecf
DC
2060 build_by_default : static_libsystemd != 'false',
2061 install : static_libsystemd != 'false',
0a5e638c 2062 install_tag: 'libsystemd',
b0d3095f 2063 install_dir : libdir,
40dbce36 2064 pic : static_libsystemd_pic,
92148283 2065 dependencies : [libblkid,
975464e0 2066 libcap,
92148283 2067 libdl,
8707c9b2 2068 libgcrypt_cflags,
3fc72d54 2069 liblz4_cflags,
92148283 2070 libmount,
c47511da 2071 libopenssl,
92148283 2072 librt,
3fc72d54
MC
2073 libxz_cflags,
2074 libzstd_cflags,
92148283 2075 threads,
40c7d3c7 2076 userspace],
70848ecf
DC
2077 c_args : libsystemd_c_args + (static_libsystemd_pic ? [] : ['-fno-PIC']))
2078
3976f372
YW
2079libudev = shared_library(
2080 'udev',
3976f372
YW
2081 version : libudev_version,
2082 include_directories : includes,
2083 link_args : ['-shared',
2084 '-Wl,--version-script=' + libudev_sym_path],
2085 link_with : [libsystemd_static, libshared_static],
2086 link_whole : libudev_basic,
92148283
JJ
2087 dependencies : [threads,
2088 userspace],
3976f372
YW
2089 link_depends : libudev_sym,
2090 install : true,
0a5e638c 2091 install_tag: 'libudev',
b0d3095f 2092 install_dir : libdir)
3976f372 2093
039f1673
LB
2094alias_target('libudev', libudev)
2095
3976f372
YW
2096install_libudev_static = static_library(
2097 'udev',
2098 basic_sources,
e5bc5f1f 2099 fundamental_sources,
3976f372
YW
2100 shared_sources,
2101 libsystemd_sources,
2102 libudev_sources,
3976f372
YW
2103 include_directories : includes,
2104 build_by_default : static_libudev != 'false',
2105 install : static_libudev != 'false',
0a5e638c 2106 install_tag: 'libudev',
b0d3095f 2107 install_dir : libdir,
3976f372 2108 link_depends : libudev_sym,
92148283
JJ
2109 dependencies : [libmount,
2110 libshared_deps,
40c7d3c7 2111 userspace],
3976f372
YW
2112 c_args : static_libudev_pic ? [] : ['-fno-PIC'],
2113 pic : static_libudev_pic)
2114
e6267e83 2115#####################################################################
47354b44 2116
130c87b1
YW
2117runtest_env = custom_target(
2118 'systemd-runtest.env',
2119 output : 'systemd-runtest.env',
2120 command : [sh, '-c',
2121 '{ echo SYSTEMD_TEST_DATA=@0@; echo SYSTEMD_CATALOG_DIR=@1@; } >@OUTPUT@'.format(
2122 project_source_root / 'test',
2123 project_build_root / 'catalog')],
2124 depends : catalogs,
2125 build_by_default : true)
2126
2127test_cflags = ['-DTEST_CODE=1']
2128# We intentionally do not do inline initializations with definitions for a
2129# bunch of _cleanup_ variables in tests, to ensure valgrind is triggered if we
2130# use the variable unexpectedly. This triggers a lot of maybe-uninitialized
2131# false positives when the combination of -O2 and -flto is used. Suppress them.
2132if '-O2' in c_args and '-flto=auto' in c_args
2133 test_cflags += cc.first_supported_argument('-Wno-maybe-uninitialized')
2134endif
2135
e6267e83 2136#####################################################################
130c87b1 2137
c335921e
YW
2138executable_template = {
2139 'include_directories' : includes,
2140 'link_with' : libshared,
2141 'install_rpath' : pkglibdir,
2142 'install' : true,
2143}
2144
2145generator_template = executable_template + {
2146 'install_dir' : systemgeneratordir,
2147}
2148
2149libexec_template = executable_template + {
2150 'install_dir' : libexecdir,
2151}
2152
2153executable_additional_kwargs = {
2154 'dependencies' : userspace,
2155}
2156
130c87b1
YW
2157test_template = executable_template + {
2158 'build_by_default' : want_tests != 'false',
2159 'install' : install_tests,
2160 'install_dir' : unittestsdir,
2161}
2162
2163test_additional_kwargs = {
2164 'c_args' : test_cflags,
2165 'link_depends' : runtest_env,
2166}
2167
cbc55c4c
YW
2168fuzz_template = executable_template + {
2169 'build_by_default' : fuzzer_build,
2170 'install' : false,
2171}
2172
2173if want_ossfuzz or (want_libfuzzer and fuzzing_engine.found())
2174 fuzz_additional_kwargs = {
2175 'dependencies' : fuzzing_engine,
2176 }
2177elif want_libfuzzer and not fuzzing_engine.found()
2178 fuzz_additional_kwargs = {
2179 'link_args' : ['-fsanitize=fuzzer'],
2180 }
2181else
2182 fuzz_additional_kwargs = {
2183 'sources' : files('src/fuzz/fuzz-main.c'),
2184 }
2185endif
2186fuzz_additional_kwargs += {
2187 'include_directories' : include_directories('src/fuzz'),
2188 'c_args' : test_cflags,
2189}
2190
c335921e
YW
2191nss_template = {
2192 'version' : '2',
2193 'include_directories' : includes,
2194 # Note that we link NSS modules with '-z nodelete' so that mempools never get orphaned
2195 'link_args' : ['-z', 'nodelete'],
2196 'link_with' : [
2197 libsystemd_static,
2198 libshared_static,
2199 libbasic,
2200 ],
2201 'dependencies' : [
2202 librt,
2203 threads,
2204 ],
2205 'install' : true,
2206 'install_tag' : 'nss',
2207 'install_dir' : libdir,
2208}
2209
2210pam_template = {
2211 'name_prefix' : '',
2212 'include_directories' : includes,
2213 'link_with' : [
2214 libsystemd_static,
2215 libshared_static,
2216 ],
2217 'dependencies' : [
2218 libpam_misc,
2219 libpam,
2220 threads,
2221 ],
2222 'install' : true,
2223 'install_tag' : 'pam',
2224 'install_dir' : pamlibdir,
2225}
2226
2227module_additional_kwargs = {
2228 'link_args' : ['-shared'],
2229 'dependencies' : userspace,
2230}
2231
e6267e83 2232#####################################################################
c335921e 2233
b61016f2 2234# systemd-analyze requires 'libcore'
83b6af36 2235subdir('src/core')
b61016f2
YW
2236# systemd-networkd requires 'libsystemd_network'
2237subdir('src/libsystemd-network')
5371c269
YW
2238# hwdb requires 'udev_link_with' and 'udev_rpath'
2239subdir('src/udev')
83b6af36 2240
16b081d6 2241subdir('src/ac-power')
83b6af36 2242subdir('src/analyze')
cb935625 2243subdir('src/ask-password')
7e6ca26f 2244subdir('src/backlight')
98e39a55 2245subdir('src/battery-check')
2c2c3daa 2246subdir('src/binfmt')
cd4300f3 2247subdir('src/boot')
dfca5587 2248subdir('src/boot/efi')
f98df767 2249subdir('src/busctl')
9f907d30 2250subdir('src/cgls')
e2bdf00a 2251subdir('src/cgroups-agent')
9f907d30 2252subdir('src/cgtop')
b61016f2 2253subdir('src/coredump')
98e39a55 2254subdir('src/creds')
2ad279cf 2255subdir('src/cryptenroll')
b4d1892a 2256subdir('src/cryptsetup')
2a456620 2257subdir('src/debug-generator')
98e39a55 2258subdir('src/delta')
16b081d6 2259subdir('src/detect-virt')
ec57a4ea 2260subdir('src/dissect')
2a456620 2261subdir('src/environment-d-generator')
98e39a55 2262subdir('src/escape')
df490fc7
YW
2263subdir('src/firstboot')
2264subdir('src/fsck')
2a456620
YW
2265subdir('src/fstab-generator')
2266subdir('src/getty-generator')
ec57a4ea 2267subdir('src/gpt-auto-generator')
74093422 2268subdir('src/hibernate-resume')
b61016f2 2269subdir('src/home')
83b6af36 2270subdir('src/hostname')
6fab49e4 2271subdir('src/hwdb')
e2bdf00a 2272subdir('src/id128')
83b6af36 2273subdir('src/import')
9f907d30 2274subdir('src/initctl')
81fe141b 2275subdir('src/integritysetup')
f7b349e8 2276subdir('src/journal')
b61016f2 2277subdir('src/journal-remote')
83b6af36
ZJS
2278subdir('src/kernel-install')
2279subdir('src/locale')
b61016f2 2280subdir('src/login')
83b6af36 2281subdir('src/machine')
df490fc7 2282subdir('src/machine-id-setup')
702a52f4 2283subdir('src/mountfsd')
eb51c09d 2284subdir('src/modules-load')
9f907d30 2285subdir('src/mount')
b61016f2 2286subdir('src/network')
98e39a55 2287subdir('src/notify')
83b6af36 2288subdir('src/nspawn')
8aee931e 2289subdir('src/nsresourced')
2080c097
YW
2290subdir('src/nss-myhostname')
2291subdir('src/nss-mymachines')
2292subdir('src/nss-resolve')
2293subdir('src/nss-systemd')
b61016f2
YW
2294subdir('src/oom')
2295subdir('src/partition')
e2bdf00a 2296subdir('src/path')
32295fa0 2297subdir('src/pcrextend')
a4342701 2298subdir('src/pcrlock')
b61016f2
YW
2299subdir('src/portable')
2300subdir('src/pstore')
5371c269 2301subdir('src/quotacheck')
c8c78771 2302subdir('src/random-seed')
6c713961 2303subdir('src/rc-local-generator')
df490fc7 2304subdir('src/remount-fs')
cb935625 2305subdir('src/reply-password')
83b6af36 2306subdir('src/resolve')
7e6ca26f 2307subdir('src/rfkill')
2a9b4bbe 2308subdir('src/rpm')
5c707c8c 2309subdir('src/run')
2a456620 2310subdir('src/run-generator')
b61016f2 2311subdir('src/shutdown')
16b081d6 2312subdir('src/sleep')
22f37744 2313subdir('src/socket-activate')
5371c269 2314subdir('src/socket-proxy')
0e322068 2315subdir('src/ssh-generator')
5c707c8c 2316subdir('src/stdio-bridge')
87e7979d 2317subdir('src/sulogin-shell')
16b081d6 2318subdir('src/sysctl')
9bca4ae4 2319subdir('src/sysext')
7e6ca26f 2320subdir('src/system-update-generator')
c3512573 2321subdir('src/systemctl')
43cc7a3e 2322subdir('src/sysupdate')
6fab49e4 2323subdir('src/sysusers')
6c713961 2324subdir('src/sysv-generator')
1761066b 2325subdir('src/storagetm')
83b6af36
ZJS
2326subdir('src/timedate')
2327subdir('src/timesync')
db64ba81 2328subdir('src/tmpfiles')
1761066b 2329subdir('src/tpm2-setup')
cb935625 2330subdir('src/tty-ask-password-agent')
eb51c09d
YW
2331subdir('src/update-done')
2332subdir('src/update-utmp')
dbab4fb9 2333subdir('src/user-sessions')
b61016f2 2334subdir('src/userdb')
d408a53f 2335subdir('src/varlinkctl')
c8c78771 2336subdir('src/vconsole')
81fe141b 2337subdir('src/veritysetup')
9de3cc14 2338subdir('src/vmspawn')
e2bdf00a 2339subdir('src/volatile-root')
9e61ed11 2340subdir('src/vpick')
0275e918 2341subdir('src/xdg-autostart-generator')
83b6af36 2342
3976f372
YW
2343subdir('src/systemd')
2344
83b6af36 2345subdir('src/test')
7db7d5b7 2346subdir('src/fuzz')
a1d6dbb1 2347subdir('src/ukify/test') # needs to be last for test_env variable
cbc55c4c 2348subdir('test/fuzz')
83b6af36 2349
eb981a5b
LP
2350subdir('mime')
2351
d30d9bf0
LB
2352alias_target('devel', libsystemd_pc, libudev_pc, systemd_pc, udev_pc)
2353
e6267e83 2354#####################################################################
83b6af36 2355
130c87b1
YW
2356foreach test : simple_tests
2357 executables += test_template + { 'sources' : [test] }
2358endforeach
2359
2360foreach test : libsystemd_tests
2361 executables += test_template + test
2362endforeach
2363
cbc55c4c
YW
2364foreach fuzzer : simple_fuzzers
2365 executables += fuzz_template + { 'sources' : [fuzzer] }
2366endforeach
2367
c335921e 2368foreach dict : executables
130c87b1
YW
2369 name = dict.get('name', '')
2370 if name == ''
2371 name = fs.stem(dict.get('sources')[0])
cbc55c4c 2372 assert(name.split('-')[0] in ['test', 'fuzz'])
130c87b1
YW
2373 endif
2374
2375 is_test = name.startswith('test-')
cbc55c4c 2376 is_fuzz = name.startswith('fuzz-')
c335921e
YW
2377
2378 build = true
2379 foreach cond : dict.get('conditions', [])
2380 if conf.get(cond) != 1
2381 build = false
2382 break
2383 endif
2384 endforeach
2385 if not build
2386 continue
2387 endif
2388
2389 kwargs = {}
2390 foreach key, val : dict
130c87b1
YW
2391 if key in ['name', 'dbus', 'public', 'conditions',
2392 'type', 'suite', 'timeout', 'parallel']
c335921e
YW
2393 continue
2394 endif
130c87b1 2395
c335921e
YW
2396 kwargs += { key : val }
2397 endforeach
2398
2399 foreach key, val : executable_additional_kwargs
2400 kwargs += { key : [ kwargs.get(key, []), val ]}
2401 endforeach
2402
130c87b1
YW
2403 if is_test
2404 kwargs += { 'install_dir' : kwargs.get('install_dir') / dict.get('type', '') }
2405 foreach key, val : test_additional_kwargs
2406 kwargs += { key : [ kwargs.get(key, []), val ] }
2407 endforeach
2408 endif
2409
cbc55c4c
YW
2410 if is_fuzz
2411 foreach key, val : fuzz_additional_kwargs
2412 kwargs += { key : [ kwargs.get(key, []), val ] }
2413 endforeach
2414 endif
2415
c335921e
YW
2416 exe = executable(
2417 name,
2418 kwargs : kwargs,
2419 )
2420
2421 executables_by_name += { name : exe }
2422
2423 if dict.get('build_by_default', true)
2424 if dict.get('dbus', false)
2425 dbus_programs += exe
2426 endif
2427 if dict.get('public', false)
2428 public_programs += exe
2429 endif
2430 endif
130c87b1
YW
2431
2432 if is_test
2433 type = dict.get('type', '')
2434 suite = dict.get('suite', '')
2435 if suite == ''
2436 suite = fs.name(fs.parent(dict.get('sources')[0]))
2437 if suite.startswith('sd-')
2438 suite = 'libsystemd'
2439 endif
2440 endif
2441
2442 if type == 'manual'
2443 message('@0@/@1@ is a manual test'.format(suite, name))
2444 elif type == 'unsafe' and want_tests != 'unsafe'
2445 message('@0@/@1@ is an unsafe test'.format(suite, name))
2446 elif dict.get('build_by_default')
2447 test(name, exe,
2448 env : test_env,
2449 timeout : dict.get('timeout', 30),
2450 suite : suite,
2451 is_parallel : dict.get('parallel', true))
2452 endif
2453 endif
cbc55c4c
YW
2454
2455 if is_fuzz
2456 fuzzer_exes += exe
2457
2458 if want_tests != 'false'
2459 # Run the fuzz regression tests without any sanitizers enabled.
f933f752 2460 # Additional invocations with sanitizers may get added below.
cbc55c4c
YW
2461 fuzz_ins = fuzz_regression_tests.get(name, {})
2462 foreach directive : fuzz_ins.get('directives', [])
f933f752
ZJS
2463 tt = '@0@_@1@'.format(name, fs.name(directive.full_path()))
2464 if tt.substring(45) != ''
2465 error('Directive sample name is too long:', directive.full_path())
2466 endif
2467
2468 test(tt,
cbc55c4c
YW
2469 exe,
2470 suite : 'fuzz',
2471 args : directive.full_path(),
2472 depends : directive)
2473 endforeach
2474 foreach file : fuzz_ins.get('files', [])
f933f752
ZJS
2475 tt = '@0@_@1@'.format(name, fs.name(file))
2476 if tt.substring(45) != ''
2477 error('Fuzz sample name is too long:', fs.name(file))
2478 endif
2479
2480 test(tt,
cbc55c4c
YW
2481 exe,
2482 suite : 'fuzz',
2483 args : file)
2484 endforeach
2485 endif
2486 endif
c335921e
YW
2487endforeach
2488
cbc55c4c
YW
2489alias_target('fuzzers', fuzzer_exes)
2490
e6267e83 2491#####################################################################
c335921e 2492
130c87b1 2493test_dlopen = executables_by_name.get('test-dlopen')
83b6af36 2494
c335921e
YW
2495foreach dict : modules
2496 name = dict.get('name')
2497 is_nss = name.startswith('nss_')
2498 is_pam = name.startswith('pam_')
2499
2500 build = true
2501 foreach cond : dict.get('conditions', [])
2502 if conf.get(cond) != 1
2503 build = false
2504 break
2505 endif
2506 endforeach
2507 if not build
2508 continue
2509 endif
2510
2511 kwargs = {}
2512 foreach key, val : dict
90461ef5 2513 if key in ['name', 'conditions', 'version-script']
c335921e
YW
2514 continue
2515 endif
2516 kwargs += { key : val }
2517 endforeach
2518
c335921e
YW
2519 kwargs += {
2520 'link_args' : [
2521 kwargs.get('link_args', []),
90461ef5
JJ
2522 '-Wl,--version-script=' + dict.get('version-script'),
2523 ],
2524 'link_depends' : [
2525 kwargs.get('link_depends', []),
2526 dict.get('version-script'),
c335921e
YW
2527 ],
2528 }
2529 foreach key, val : module_additional_kwargs
2530 kwargs += { key : [ kwargs.get(key, []), val ]}
2531 endforeach
2532
2533 lib = shared_library(
2534 name,
2535 kwargs : kwargs,
2536 )
2537
2538 if is_nss
2539 # We cannot use shared_module because it does not support version suffix.
2540 # Unfortunately shared_library insists on creating the symlink…
c31ba5cf 2541 meson.add_install_script(sh, '-c', 'rm $DESTDIR@0@/lib@1@.so'.format(libdir, name),
c335921e
YW
2542 install_tag : 'nss')
2543 endif
2544
2545 if want_tests != 'false' and (is_nss or is_pam)
2546 test('dlopen-' + name,
2547 test_dlopen,
2548 # path to dlopen must include a slash
2549 args : lib.full_path(),
dc4a0055
YW
2550 depends : lib,
2551 suite : is_nss ? 'nss' : 'pam')
c335921e
YW
2552 endif
2553endforeach
2554
e6267e83 2555#####################################################################
5c23128d 2556
f9a6cb0e 2557ukify = custom_target(
30ec2eae
ZJS
2558 'ukify',
2559 input : 'src/ukify/ukify.py',
2560 output : 'ukify',
2561 command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
9a01fe39 2562 install : want_ukify,
30ec2eae 2563 install_mode : 'rwxr-xr-x',
f65aa477 2564 install_dir : bindir)
9a01fe39 2565if want_ukify
42551ea7 2566 public_programs += ukify
f65aa477 2567
a1ca52c2 2568 # symlink for backwards compatibility after rename
f65aa477
ZJS
2569 meson.add_install_script(sh, '-c',
2570 ln_s.format(bindir / 'ukify',
2571 libexecdir / 'ukify'))
f9a6cb0e
ZJS
2572endif
2573
e6267e83 2574#####################################################################
69e96427 2575
e5cc6d10
YW
2576subdir('rules.d')
2577subdir('test')
2578
e6267e83 2579#####################################################################
5c23128d 2580
10783aef
ZJS
2581subdir('docs/sysvinit')
2582subdir('docs/var-log')
2583subdir('hwdb.d')
2584subdir('man')
378e9d2b 2585subdir('modprobe.d')
10783aef
ZJS
2586subdir('network')
2587subdir('presets')
2588subdir('shell-completion/bash')
2589subdir('shell-completion/zsh')
5c23128d
ZJS
2590subdir('sysctl.d')
2591subdir('sysusers.d')
2592subdir('tmpfiles.d')
4f10b807 2593subdir('units')
5c23128d 2594
5c23128d
ZJS
2595install_subdir('factory/etc',
2596 install_dir : factorydir)
623370e6 2597subdir('factory/templates')
5c23128d 2598
d7aa78c3
JT
2599if install_sysconfdir
2600 install_data('xorg/50-systemd-user.sh',
2601 install_dir : xinitrcdir)
2602endif
f09eb768 2603install_data('LICENSE.GPL2',
5c23128d 2604 'LICENSE.LGPL2.1',
f09eb768
LP
2605 'NEWS',
2606 'README',
8e3fee33
ZJS
2607 'docs/CODING_STYLE.md',
2608 'docs/DISTRO_PORTING.md',
2609 'docs/ENVIRONMENT.md',
2610 'docs/HACKING.md',
2611 'docs/TRANSIENT-SETTINGS.md',
2612 'docs/TRANSLATORS.md',
2613 'docs/UIDS-GIDS.md',
5c23128d 2614 install_dir : docdir)
d68b342b 2615
9c6e32a2
LB
2616install_subdir('LICENSES',
2617 install_dir : docdir)
2618
9289e093 2619install_emptydir(systemdstatedir)
94e75a54 2620
e6267e83 2621#####################################################################
d68b342b 2622
2d4efd1d
LB
2623# Ensure that changes to the docs/ directory do not break the
2624# basic Github pages build. But only run it in developer mode,
2625# as it might be fragile due to changes in the tooling, and it is
2626# not generally useful for users.
2627jekyll = find_program('jekyll', required : false)
2628if get_option('mode') == 'developer' and want_tests != 'false' and jekyll.found()
2629 test('github-pages',
2630 jekyll,
02e0f430 2631 suite : 'dist',
2d4efd1d 2632 args : ['build',
fce9abb2
ZJS
2633 '--source', project_source_root / 'docs',
2634 '--destination', project_build_root / '_site'])
2d4efd1d
LB
2635endif
2636
e6267e83 2637#####################################################################
2d4efd1d 2638
dd1e33c8 2639check_help = find_program('tools/check-help.sh')
ffb7406b 2640check_version = find_program('tools/check-version.sh')
005a29f2
ZJS
2641
2642foreach exec : public_programs
739a62bb 2643 name = fs.name(exec.full_path())
938be089
ZJS
2644 if want_tests != 'false'
2645 test('check-help-' + name,
dd1e33c8 2646 check_help,
02e0f430 2647 suite : 'dist',
e93ada98
DDM
2648 args : exec.full_path(),
2649 depends: exec)
ffb7406b 2650
ea2a57be
DDM
2651 version = meson.project_version()
2652 if name == 'udevadm'
2653 # For compatibility reasons we can't use the full version in udevadm.
2654 version = version.split('~')[0]
2655 endif
2656
ffb7406b
ZJS
2657 test('check-version-' + name,
2658 check_version,
02e0f430 2659 suite : 'dist',
ffb7406b 2660 args : [exec.full_path(),
ea2a57be 2661 version],
ffb7406b 2662 depends: exec)
938be089 2663 endif
005a29f2
ZJS
2664endforeach
2665
52d4d1d3 2666# Enable tests for all supported sanitizers
7db5761d 2667foreach tuple : fuzz_sanitizers
52d4d1d3
ZJS
2668 sanitizer = tuple[0]
2669 build = tuple[1]
b68dfb9e 2670
7a6397d2 2671 if cc.has_link_argument('-fsanitize=@0@'.format(sanitizer))
7db5761d
MK
2672 foreach fuzzer, fuzz_ins : fuzz_regression_tests
2673 name = '@0@:@1@'.format(fuzzer, sanitizer)
2674 if want_tests == 'false'
2675 message('Not compiling @0@ because tests is set to false'.format(name))
2676 continue
52d4d1d3 2677 endif
7db5761d
MK
2678 if not fuzz_tests
2679 message('Not compiling @0@ because fuzz-tests is set to false'.format(name))
2680 continue
2681 endif
2682 exe = custom_target(
2683 name,
2684 output : name,
cbc55c4c 2685 depends : build,
7db5761d
MK
2686 command : [ln, '-fs',
2687 build.full_path() / fuzzer,
2688 '@OUTPUT@'],
2689 build_by_default : true)
2690
cbc55c4c
YW
2691 foreach directive : fuzz_ins.get('directives', [])
2692 test('@0@_@1@_@2@'.format(fuzzer, fs.name(directive.full_path()), sanitizer),
2693 env,
2694 suite : 'fuzz+san',
2695 env : ['UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1'],
2696 timeout : 60,
2697 args : [exe.full_path(), directive.full_path()],
2698 depends : directive)
2699 endforeach
2700 foreach file : fuzz_ins.get('files', [])
2701 test('@0@_@1@_@2@'.format(fuzzer, fs.name(file), sanitizer),
52d4d1d3 2702 env,
14056a52 2703 suite : 'fuzz+san',
89767158
EV
2704 env : ['UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1'],
2705 timeout : 60,
cbc55c4c 2706 args : [exe.full_path(), file])
7db5761d 2707 endforeach
52d4d1d3 2708 endforeach
b68dfb9e
ZJS
2709 endif
2710endforeach
2711
e6267e83 2712#####################################################################
b68dfb9e 2713
0700e8ba 2714if git.found()
37efbbd8 2715 all_files = run_command(
0f4c4f38
ZJS
2716 env, '-u', 'GIT_WORK_TREE',
2717 git, '--git-dir=@0@/.git'.format(project_source_root),
ba9ca60a 2718 'ls-files', ':/*.[ch]', ':/*.cc',
e92777d2
ZJS
2719 check : false)
2720 if all_files.returncode() == 0
2721 all_files = files(all_files.stdout().split())
2722
2723 custom_target(
2724 'tags',
2725 output : 'tags',
2726 command : [env, 'etags', '-o', '@0@/TAGS'.format(project_source_root)] + all_files)
2727 run_target(
2728 'ctags',
691db9a7 2729 command : [env, 'ctags', '--tag-relative=never', '-o', '@0@/tags'.format(project_source_root)] + all_files)
60892358
ZJS
2730
2731 ############################################
2732
2733 if want_tests != 'false' and conf.get('BUILD_MODE_DEVELOPER') == 1
2734 test('check-includes',
2735 files('tools/check-includes.py'),
2736 args: all_files,
dc4a0055
YW
2737 env : ['PROJECT_SOURCE_ROOT=@0@'.format(project_source_root)],
2738 suite : 'headers')
60892358 2739 endif
e92777d2 2740 endif
177929c2 2741
60892358
ZJS
2742 ####################################################
2743
dd1e33c8 2744 git_contrib_sh = find_program('tools/git-contrib.sh')
a923e085 2745 run_target(
37efbbd8 2746 'git-contrib',
dd1e33c8 2747 command : [git_contrib_sh])
dd6ab3df 2748
60892358
ZJS
2749 ####################################################
2750
dd6ab3df 2751 git_head = run_command(
e92777d2
ZJS
2752 git, '--git-dir=@0@/.git'.format(project_source_root),
2753 'rev-parse', 'HEAD',
2754 check : false).stdout().strip()
dd6ab3df 2755 git_head_short = run_command(
e92777d2
ZJS
2756 git, '--git-dir=@0@/.git'.format(project_source_root),
2757 'rev-parse', '--short=7', 'HEAD',
2758 check : false).stdout().strip()
dd6ab3df
ZJS
2759
2760 run_target(
2761 'git-snapshot',
0f4c4f38 2762 command : [git, 'archive',
1485aacb 2763 '-o', '@0@/systemd-@1@.tar.gz'.format(project_source_root,
dd6ab3df
ZJS
2764 git_head_short),
2765 '--prefix', 'systemd-@0@/'.format(git_head),
2766 'HEAD'])
2767endif
829257d1 2768
e6267e83 2769#####################################################################
829257d1 2770
dd1e33c8 2771check_api_docs_sh = find_program('tools/check-api-docs.sh')
51b13863
LP
2772run_target(
2773 'check-api-docs',
2774 depends : [man, libsystemd, libudev],
dd1e33c8 2775 command : [check_api_docs_sh, libsystemd.full_path(), libudev.full_path()])
51b13863 2776
f12c5d36
ZJS
2777alias_target('update-dbus-docs', update_dbus_docs)
2778alias_target('update-man-rules', update_man_rules)
e3c368f6 2779
0628d48e
LB
2780if not meson.is_cross_build()
2781 custom_target(
2782 'export-dbus-interfaces',
4645074e 2783 output : fs.name(dbus_interfaces_dir),
0628d48e 2784 install : dbus_interfaces_dir != 'no',
4645074e 2785 install_dir : fs.parent(dbus_interfaces_dir),
0628d48e
LB
2786 command : [export_dbus_interfaces_py, '@OUTPUT@', dbus_programs])
2787endif
e3c68924 2788
5083e427
FS
2789meson_extract_unit_files = find_program('tools/meson-extract-unit-files.py')
2790custom_target('installed-unit-files.txt',
2791 output : 'installed-unit-files.txt',
2792 capture : true,
2793 install : want_tests != 'no' and install_tests,
2794 install_dir : testdata_dir,
2795 command : [meson_extract_unit_files, project_build_root])
2796
e6267e83 2797#####################################################################
829257d1 2798
e92777d2
ZJS
2799alt_time_epoch = run_command('date', '-Is', '-u', '-d', '@@0@'.format(time_epoch),
2800 check : true).stdout().strip()
12085ebb
ZJS
2801
2802summary({
12085ebb
ZJS
2803 'split bin-sbin' : split_bin,
2804 'prefix directory' : prefixdir,
12085ebb
ZJS
2805 'sysconf directory' : sysconfdir,
2806 'include directory' : includedir,
2807 'lib directory' : libdir,
12085ebb
ZJS
2808 'SysV init scripts' : sysvinit_path,
2809 'SysV rc?.d directories' : sysvrcnd_path,
2810 'PAM modules directory' : pamlibdir,
2811 'PAM configuration directory' : pamconfdir,
0abd510f 2812 'ssh server configuration directory' : sshdconfdir,
5360b10f 2813 'ssh server privilege separation directory' : sshdprivsepdir,
0abd510f 2814 'ssh client configuration directory' : sshconfdir,
12085ebb
ZJS
2815 'libcryptsetup plugins directory' : libcryptsetup_plugins_dir,
2816 'RPM macros directory' : rpmmacrosdir,
2817 'modprobe.d directory' : modprobedir,
2818 'D-Bus policy directory' : dbuspolicydir,
2819 'D-Bus session directory' : dbussessionservicedir,
2820 'D-Bus system directory' : dbussystemservicedir,
7e560e79 2821 'D-Bus interfaces directory' : dbus_interfaces_dir,
12085ebb
ZJS
2822 'bash completions directory' : bashcompletiondir,
2823 'zsh completions directory' : zshcompletiondir,
a2b0cd3f 2824 'private shared lib version tag' : shared_lib_tag,
12085ebb
ZJS
2825 'extra start script' : get_option('rc-local'),
2826 'debug shell' : '@0@ @ @1@'.format(get_option('debug-shell'),
2827 get_option('debug-tty')),
2828 'system UIDs' : '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_UID_MAX'),
2829 conf.get('SYSTEM_ALLOC_UID_MIN')),
2830 'system GIDs' : '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
2831 conf.get('SYSTEM_ALLOC_GID_MIN')),
2832 'dynamic UIDs' : '@0@…@1@'.format(dynamic_uid_min, dynamic_uid_max),
2833 'container UID bases' : '@0@…@1@'.format(container_uid_base_min, container_uid_base_max),
2834 'static UID/GID allocations' : ' '.join(static_ugids),
2835 '/dev/kvm access mode' : get_option('dev-kvm-mode'),
2836 'render group access mode' : get_option('group-render-mode'),
2837 'certificate root directory' : get_option('certificate-root'),
2838 'support URL' : support_url,
2839 'nobody user name' : nobody_user,
2840 'nobody group name' : nobody_group,
2841 'fallback hostname' : get_option('fallback-hostname'),
9798deaf 2842 'default compression method' : compression,
12085ebb
ZJS
2843 'default DNSSEC mode' : default_dnssec,
2844 'default DNS-over-TLS mode' : default_dns_over_tls,
2845 'default mDNS mode' : default_mdns,
2846 'default LLMNR mode' : default_llmnr,
2847 'default DNS servers' : dns_servers.split(' '),
2848 'default NTP servers' : ntp_servers.split(' '),
78266a54
LP
2849 'default net.naming_scheme= value': default_net_naming_scheme,
2850 'default KillUserProcesses= value': kill_user_processes,
12085ebb 2851 'default locale' : default_locale,
88b6f0de 2852 'default nspawn locale' : nspawn_locale,
79dec86a 2853 'default status unit format' : status_unit_format_default,
12085ebb
ZJS
2854 'default user $PATH' :
2855 default_user_path != '' ? default_user_path : '(same as system services)',
2856 'systemd service watchdog' : service_watchdog == '' ? 'disabled' : service_watchdog,
2857 'time epoch' : '@0@ (@1@)'.format(time_epoch, alt_time_epoch)})
829257d1
ZJS
2858
2859# TODO:
2860# CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
2861# CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
2862# LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
2863
829257d1
ZJS
2864found = []
2865missing = []
2866
2867foreach tuple : [
56d68e71
ZJS
2868 # dependencies
2869 ['ACL'],
829257d1 2870 ['AUDIT'],
829257d1 2871 ['AppArmor'],
56d68e71
ZJS
2872 ['IMA'],
2873 ['PAM'],
829257d1 2874 ['SECCOMP'],
56d68e71 2875 ['SELinux'],
829257d1 2876 ['SMACK'],
56d68e71
ZJS
2877 ['blkid'],
2878 ['elfutils'],
829257d1 2879 ['gcrypt'],
829257d1 2880 ['gnutls'],
7d861e12 2881 ['libbpf'],
56d68e71 2882 ['libcryptsetup'],
d1ae38d8 2883 ['libcryptsetup-plugins'],
829257d1 2884 ['libcurl'],
56d68e71
ZJS
2885 ['libfdisk'],
2886 ['libfido2'],
829257d1 2887 ['libidn'],
56d68e71 2888 ['libidn2'],
829257d1 2889 ['libiptc'],
56d68e71
ZJS
2890 ['microhttpd'],
2891 ['openssl'],
2892 ['p11kit'],
1d8aae43 2893 ['passwdqc'],
56d68e71
ZJS
2894 ['pcre2'],
2895 ['pwquality'],
2896 ['qrencode'],
2897 ['tpm2'],
2898 ['xkbcommon'],
2899
2900 # compression libs
2901 ['zstd'],
2902 ['lz4'],
2903 ['xz'],
2904 ['zlib'],
2905 ['bzip2'],
2906
2907 # components
2908 ['backlight'],
829257d1 2909 ['binfmt'],
dfca5587 2910 ['bootloader'],
0a0d4899 2911 ['bpf-framework', conf.get('BPF_FRAMEWORK') == 1],
56d68e71 2912 ['coredump'],
56d68e71 2913 ['efi'],
dfca5587 2914 ['environment.d'],
829257d1 2915 ['firstboot'],
56d68e71
ZJS
2916 ['hibernate'],
2917 ['homed'],
2918 ['hostnamed'],
2919 ['hwdb'],
2920 ['importd'],
2921 ['initrd'],
f887eab1 2922 ['kernel-install'],
56d68e71 2923 ['localed'],
829257d1
ZJS
2924 ['logind'],
2925 ['machined'],
56d68e71
ZJS
2926 ['networkd'],
2927 ['nss-myhostname'],
2928 ['nss-mymachines'],
2929 ['nss-resolve'],
2930 ['nss-systemd'],
2931 ['oomd'],
61d0578b 2932 ['portabled'],
56d68e71
ZJS
2933 ['pstore'],
2934 ['quotacheck'],
2935 ['randomseed'],
2936 ['repart'],
2937 ['resolve'],
2938 ['rfkill'],
9bca4ae4 2939 ['sysext'],
0a0d4899 2940 ['systemd-analyze', conf.get('ENABLE_ANALYZE') == 1],
43cc7a3e 2941 ['sysupdate'],
56d68e71 2942 ['sysusers'],
1761066b 2943 ['storagetm'],
829257d1
ZJS
2944 ['timedated'],
2945 ['timesyncd'],
56d68e71
ZJS
2946 ['tmpfiles'],
2947 ['userdb'],
2948 ['vconsole'],
9de3cc14 2949 ['vmspawn'],
56d68e71
ZJS
2950 ['xdg-autostart'],
2951
2952 # optional features
12b4cffd 2953 ['dmi'],
56d68e71 2954 ['idn'],
829257d1 2955 ['polkit'],
56d68e71 2956 ['nscd'],
0a0d4899 2957 ['legacy-pkla', install_polkit_pkla],
829257d1 2958 ['kmod'],
ede5a78f 2959 ['xenctrl'],
829257d1
ZJS
2960 ['dbus'],
2961 ['glib'],
829257d1 2962 ['tpm'],
0a0d4899
JH
2963 ['man pages', want_man],
2964 ['html pages', want_html],
2965 ['man page indices', want_man and have_lxml],
829257d1 2966 ['SysV compat'],
56d68e71 2967 ['compat-mutable-uid-boundaries'],
829257d1
ZJS
2968 ['utmp'],
2969 ['ldconfig'],
0a0d4899
JH
2970 ['adm group', get_option('adm-group')],
2971 ['wheel group', get_option('wheel-group')],
b14e1b43 2972 ['gshadow'],
829257d1
ZJS
2973 ['debug hashmap'],
2974 ['debug mmap cache'],
d6601495 2975 ['debug siphash'],
0a0d4899 2976 ['trace logging', conf.get('LOG_TRACE') == 1],
69525346
YW
2977 ['slow tests', slow_tests],
2978 ['fuzz tests', fuzz_tests],
0a0d4899
JH
2979 ['install tests', install_tests],
2980 ['link-udev-shared', get_option('link-udev-shared')],
2981 ['link-systemctl-shared', get_option('link-systemctl-shared')],
2982 ['link-networkd-shared', get_option('link-networkd-shared')],
2983 ['link-timesyncd-shared', get_option('link-timesyncd-shared')],
2984 ['link-journalctl-shared', get_option('link-journalctl-shared')],
2985 ['link-boot-shared', get_option('link-boot-shared')],
c06d2e44 2986 ['link-portabled-shared', get_option('link-portabled-shared')],
93651582 2987 ['first-boot-full-preset'],
ceedbf81 2988 ['fexecve'],
0a0d4899
JH
2989 ['standalone-binaries', get_option('standalone-binaries')],
2990 ['coverage', get_option('b_coverage')],
829257d1
ZJS
2991]
2992
af4d7860
ZJS
2993 if tuple.length() >= 2
2994 cond = tuple[1]
2995 else
829257d1
ZJS
2996 ident1 = 'HAVE_' + tuple[0].underscorify().to_upper()
2997 ident2 = 'ENABLE_' + tuple[0].underscorify().to_upper()
349cc4a5 2998 cond = conf.get(ident1, 0) == 1 or conf.get(ident2, 0) == 1
829257d1
ZJS
2999 endif
3000 if cond
5a8b1640 3001 found += tuple[0]
829257d1 3002 else
5a8b1640 3003 missing += tuple[0]
829257d1
ZJS
3004 endif
3005endforeach
3006
c716c253
ZJS
3007if static_libsystemd == 'false'
3008 missing += 'static-libsystemd'
3009else
3010 found += 'static-libsystemd(@0@)'.format(static_libsystemd)
3011endif
3012
3013if static_libudev == 'false'
3014 missing += 'static-libudev'
3015else
3016 found += 'static-libudev(@0@)'.format(static_libudev)
3017endif
3018
57633d23
ZJS
3019if conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1 and conf.get('PREFER_OPENSSL') == 1
3020 found += 'cryptolib(openssl)'
3021elif conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1
3022 found += 'cryptolib(gcrypt)'
3023else
3024 missing += 'cryptolib'
3025endif
3026
237f2da9
ZJS
3027if conf.get('DNS_OVER_TLS_USE_GNUTLS') == 1
3028 found += 'DNS-over-TLS(gnutls)'
3029elif conf.get('DNS_OVER_TLS_USE_OPENSSL') == 1
3030 found += 'DNS-over-TLS(openssl)'
3031else
3032 missing += 'DNS-over-TLS'
3033endif
3034
12085ebb
ZJS
3035summary({
3036 'enabled' : ', '.join(found),
3037 'disabled' : ', '.join(missing)},
3038 section : 'Features')