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