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