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