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