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