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