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