]> git.ipfire.org Git - thirdparty/systemd.git/blame - meson.build
dlfcn-util: add two new macros for making it easier to create "sym_xyz" indirect...
[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')
b61016f2
YW
2177subdir('src/portable')
2178subdir('src/pstore')
5371c269 2179subdir('src/quotacheck')
c8c78771 2180subdir('src/random-seed')
6c713961 2181subdir('src/rc-local-generator')
df490fc7 2182subdir('src/remount-fs')
cb935625 2183subdir('src/reply-password')
83b6af36 2184subdir('src/resolve')
7e6ca26f 2185subdir('src/rfkill')
2a9b4bbe 2186subdir('src/rpm')
5c707c8c 2187subdir('src/run')
2a456620 2188subdir('src/run-generator')
b61016f2 2189subdir('src/shutdown')
16b081d6 2190subdir('src/sleep')
22f37744 2191subdir('src/socket-activate')
5371c269 2192subdir('src/socket-proxy')
5c707c8c 2193subdir('src/stdio-bridge')
87e7979d 2194subdir('src/sulogin-shell')
16b081d6 2195subdir('src/sysctl')
9bca4ae4 2196subdir('src/sysext')
7e6ca26f 2197subdir('src/system-update-generator')
c3512573 2198subdir('src/systemctl')
43cc7a3e 2199subdir('src/sysupdate')
6fab49e4 2200subdir('src/sysusers')
6c713961 2201subdir('src/sysv-generator')
1761066b 2202subdir('src/storagetm')
83b6af36
ZJS
2203subdir('src/timedate')
2204subdir('src/timesync')
db64ba81 2205subdir('src/tmpfiles')
1761066b 2206subdir('src/tpm2-setup')
cb935625 2207subdir('src/tty-ask-password-agent')
eb51c09d
YW
2208subdir('src/update-done')
2209subdir('src/update-utmp')
dbab4fb9 2210subdir('src/user-sessions')
b61016f2 2211subdir('src/userdb')
d408a53f 2212subdir('src/varlinkctl')
c8c78771 2213subdir('src/vconsole')
81fe141b 2214subdir('src/veritysetup')
e2bdf00a 2215subdir('src/volatile-root')
0275e918 2216subdir('src/xdg-autostart-generator')
83b6af36 2217
3976f372
YW
2218subdir('src/systemd')
2219
83b6af36 2220subdir('src/test')
7db7d5b7 2221subdir('src/fuzz')
a1d6dbb1 2222subdir('src/ukify/test') # needs to be last for test_env variable
cbc55c4c 2223subdir('test/fuzz')
83b6af36 2224
d30d9bf0
LB
2225alias_target('devel', libsystemd_pc, libudev_pc, systemd_pc, udev_pc)
2226
83b6af36
ZJS
2227############################################################
2228
130c87b1
YW
2229foreach test : simple_tests
2230 executables += test_template + { 'sources' : [test] }
2231endforeach
2232
2233foreach test : libsystemd_tests
2234 executables += test_template + test
2235endforeach
2236
cbc55c4c
YW
2237foreach fuzzer : simple_fuzzers
2238 executables += fuzz_template + { 'sources' : [fuzzer] }
2239endforeach
2240
c335921e 2241foreach dict : executables
130c87b1
YW
2242 name = dict.get('name', '')
2243 if name == ''
2244 name = fs.stem(dict.get('sources')[0])
cbc55c4c 2245 assert(name.split('-')[0] in ['test', 'fuzz'])
130c87b1
YW
2246 endif
2247
2248 is_test = name.startswith('test-')
cbc55c4c 2249 is_fuzz = name.startswith('fuzz-')
c335921e
YW
2250
2251 build = true
2252 foreach cond : dict.get('conditions', [])
2253 if conf.get(cond) != 1
2254 build = false
2255 break
2256 endif
2257 endforeach
2258 if not build
2259 continue
2260 endif
2261
2262 kwargs = {}
2263 foreach key, val : dict
130c87b1
YW
2264 if key in ['name', 'dbus', 'public', 'conditions',
2265 'type', 'suite', 'timeout', 'parallel']
c335921e
YW
2266 continue
2267 endif
130c87b1 2268
c335921e
YW
2269 kwargs += { key : val }
2270 endforeach
2271
2272 foreach key, val : executable_additional_kwargs
2273 kwargs += { key : [ kwargs.get(key, []), val ]}
2274 endforeach
2275
130c87b1
YW
2276 if is_test
2277 kwargs += { 'install_dir' : kwargs.get('install_dir') / dict.get('type', '') }
2278 foreach key, val : test_additional_kwargs
2279 kwargs += { key : [ kwargs.get(key, []), val ] }
2280 endforeach
2281 endif
2282
cbc55c4c
YW
2283 if is_fuzz
2284 foreach key, val : fuzz_additional_kwargs
2285 kwargs += { key : [ kwargs.get(key, []), val ] }
2286 endforeach
2287 endif
2288
c335921e
YW
2289 exe = executable(
2290 name,
2291 kwargs : kwargs,
2292 )
2293
2294 executables_by_name += { name : exe }
2295
2296 if dict.get('build_by_default', true)
2297 if dict.get('dbus', false)
2298 dbus_programs += exe
2299 endif
2300 if dict.get('public', false)
2301 public_programs += exe
2302 endif
2303 endif
130c87b1
YW
2304
2305 if is_test
2306 type = dict.get('type', '')
2307 suite = dict.get('suite', '')
2308 if suite == ''
2309 suite = fs.name(fs.parent(dict.get('sources')[0]))
2310 if suite.startswith('sd-')
2311 suite = 'libsystemd'
2312 endif
2313 endif
2314
2315 if type == 'manual'
2316 message('@0@/@1@ is a manual test'.format(suite, name))
2317 elif type == 'unsafe' and want_tests != 'unsafe'
2318 message('@0@/@1@ is an unsafe test'.format(suite, name))
2319 elif dict.get('build_by_default')
2320 test(name, exe,
2321 env : test_env,
2322 timeout : dict.get('timeout', 30),
2323 suite : suite,
2324 is_parallel : dict.get('parallel', true))
2325 endif
2326 endif
cbc55c4c
YW
2327
2328 if is_fuzz
2329 fuzzer_exes += exe
2330
2331 if want_tests != 'false'
2332 # Run the fuzz regression tests without any sanitizers enabled.
f933f752 2333 # Additional invocations with sanitizers may get added below.
cbc55c4c
YW
2334 fuzz_ins = fuzz_regression_tests.get(name, {})
2335 foreach directive : fuzz_ins.get('directives', [])
f933f752
ZJS
2336 tt = '@0@_@1@'.format(name, fs.name(directive.full_path()))
2337 if tt.substring(45) != ''
2338 error('Directive sample name is too long:', directive.full_path())
2339 endif
2340
2341 test(tt,
cbc55c4c
YW
2342 exe,
2343 suite : 'fuzz',
2344 args : directive.full_path(),
2345 depends : directive)
2346 endforeach
2347 foreach file : fuzz_ins.get('files', [])
f933f752
ZJS
2348 tt = '@0@_@1@'.format(name, fs.name(file))
2349 if tt.substring(45) != ''
2350 error('Fuzz sample name is too long:', fs.name(file))
2351 endif
2352
2353 test(tt,
cbc55c4c
YW
2354 exe,
2355 suite : 'fuzz',
2356 args : file)
2357 endforeach
2358 endif
2359 endif
c335921e
YW
2360endforeach
2361
cbc55c4c
YW
2362alias_target('fuzzers', fuzzer_exes)
2363
c335921e
YW
2364############################################################
2365
130c87b1 2366test_dlopen = executables_by_name.get('test-dlopen')
83b6af36 2367
c335921e
YW
2368foreach dict : modules
2369 name = dict.get('name')
2370 is_nss = name.startswith('nss_')
2371 is_pam = name.startswith('pam_')
2372
2373 build = true
2374 foreach cond : dict.get('conditions', [])
2375 if conf.get(cond) != 1
2376 build = false
2377 break
2378 endif
2379 endforeach
2380 if not build
2381 continue
2382 endif
2383
2384 kwargs = {}
2385 foreach key, val : dict
90461ef5 2386 if key in ['name', 'conditions', 'version-script']
c335921e
YW
2387 continue
2388 endif
2389 kwargs += { key : val }
2390 endforeach
2391
c335921e
YW
2392 kwargs += {
2393 'link_args' : [
2394 kwargs.get('link_args', []),
90461ef5
JJ
2395 '-Wl,--version-script=' + dict.get('version-script'),
2396 ],
2397 'link_depends' : [
2398 kwargs.get('link_depends', []),
2399 dict.get('version-script'),
c335921e
YW
2400 ],
2401 }
2402 foreach key, val : module_additional_kwargs
2403 kwargs += { key : [ kwargs.get(key, []), val ]}
2404 endforeach
2405
2406 lib = shared_library(
2407 name,
2408 kwargs : kwargs,
2409 )
2410
2411 if is_nss
2412 # We cannot use shared_module because it does not support version suffix.
2413 # Unfortunately shared_library insists on creating the symlink…
c31ba5cf 2414 meson.add_install_script(sh, '-c', 'rm $DESTDIR@0@/lib@1@.so'.format(libdir, name),
c335921e
YW
2415 install_tag : 'nss')
2416 endif
2417
2418 if want_tests != 'false' and (is_nss or is_pam)
2419 test('dlopen-' + name,
2420 test_dlopen,
2421 # path to dlopen must include a slash
2422 args : lib.full_path(),
dc4a0055
YW
2423 depends : lib,
2424 suite : is_nss ? 'nss' : 'pam')
c335921e
YW
2425 endif
2426endforeach
2427
5c23128d
ZJS
2428############################################################
2429
f9a6cb0e 2430ukify = custom_target(
30ec2eae
ZJS
2431 'ukify',
2432 input : 'src/ukify/ukify.py',
2433 output : 'ukify',
2434 command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
9a01fe39 2435 install : want_ukify,
30ec2eae 2436 install_mode : 'rwxr-xr-x',
f65aa477 2437 install_dir : bindir)
9a01fe39 2438if want_ukify
42551ea7 2439 public_programs += ukify
f65aa477 2440
a1ca52c2 2441 # symlink for backwards compatibility after rename
f65aa477
ZJS
2442 meson.add_install_script(sh, '-c',
2443 ln_s.format(bindir / 'ukify',
2444 libexecdir / 'ukify'))
f9a6cb0e
ZJS
2445endif
2446
69e96427
ZJS
2447############################################################
2448
e5cc6d10
YW
2449subdir('rules.d')
2450subdir('test')
2451
69e96427 2452############################################################
5c23128d 2453
10783aef
ZJS
2454subdir('docs/sysvinit')
2455subdir('docs/var-log')
2456subdir('hwdb.d')
2457subdir('man')
378e9d2b 2458subdir('modprobe.d')
10783aef
ZJS
2459subdir('network')
2460subdir('presets')
2461subdir('shell-completion/bash')
2462subdir('shell-completion/zsh')
5c23128d
ZJS
2463subdir('sysctl.d')
2464subdir('sysusers.d')
2465subdir('tmpfiles.d')
4f10b807 2466subdir('units')
5c23128d 2467
5c23128d
ZJS
2468install_subdir('factory/etc',
2469 install_dir : factorydir)
623370e6 2470subdir('factory/templates')
5c23128d 2471
d7aa78c3
JT
2472if install_sysconfdir
2473 install_data('xorg/50-systemd-user.sh',
2474 install_dir : xinitrcdir)
2475endif
f09eb768 2476install_data('LICENSE.GPL2',
5c23128d 2477 'LICENSE.LGPL2.1',
f09eb768
LP
2478 'NEWS',
2479 'README',
eea98402 2480 'docs/CODING_STYLE.md',
1d1cb168 2481 'docs/DISTRO_PORTING.md',
9e825ebf 2482 'docs/ENVIRONMENT.md',
5425f8a5 2483 'docs/HACKING.md',
9e825ebf 2484 'docs/TRANSIENT-SETTINGS.md',
b6dc0d7d 2485 'docs/TRANSLATORS.md',
9e825ebf 2486 'docs/UIDS-GIDS.md',
5c23128d 2487 install_dir : docdir)
d68b342b 2488
9c6e32a2
LB
2489install_subdir('LICENSES',
2490 install_dir : docdir)
2491
9289e093 2492install_emptydir(systemdstatedir)
94e75a54 2493
d68b342b
ZJS
2494############################################################
2495
2d4efd1d
LB
2496# Ensure that changes to the docs/ directory do not break the
2497# basic Github pages build. But only run it in developer mode,
2498# as it might be fragile due to changes in the tooling, and it is
2499# not generally useful for users.
2500jekyll = find_program('jekyll', required : false)
2501if get_option('mode') == 'developer' and want_tests != 'false' and jekyll.found()
2502 test('github-pages',
2503 jekyll,
02e0f430 2504 suite : 'dist',
2d4efd1d 2505 args : ['build',
fce9abb2
ZJS
2506 '--source', project_source_root / 'docs',
2507 '--destination', project_build_root / '_site'])
2d4efd1d
LB
2508endif
2509
2510############################################################
2511
dd1e33c8 2512check_help = find_program('tools/check-help.sh')
ffb7406b 2513check_version = find_program('tools/check-version.sh')
005a29f2
ZJS
2514
2515foreach exec : public_programs
739a62bb 2516 name = fs.name(exec.full_path())
938be089
ZJS
2517 if want_tests != 'false'
2518 test('check-help-' + name,
dd1e33c8 2519 check_help,
02e0f430 2520 suite : 'dist',
e93ada98
DDM
2521 args : exec.full_path(),
2522 depends: exec)
ffb7406b
ZJS
2523
2524 test('check-version-' + name,
2525 check_version,
02e0f430 2526 suite : 'dist',
ffb7406b
ZJS
2527 args : [exec.full_path(),
2528 meson.project_version()],
2529 depends: exec)
938be089 2530 endif
005a29f2
ZJS
2531endforeach
2532
52d4d1d3 2533# Enable tests for all supported sanitizers
7db5761d 2534foreach tuple : fuzz_sanitizers
52d4d1d3
ZJS
2535 sanitizer = tuple[0]
2536 build = tuple[1]
b68dfb9e 2537
7a6397d2 2538 if cc.has_link_argument('-fsanitize=@0@'.format(sanitizer))
7db5761d
MK
2539 foreach fuzzer, fuzz_ins : fuzz_regression_tests
2540 name = '@0@:@1@'.format(fuzzer, sanitizer)
2541 if want_tests == 'false'
2542 message('Not compiling @0@ because tests is set to false'.format(name))
2543 continue
52d4d1d3 2544 endif
7db5761d
MK
2545 if not fuzz_tests
2546 message('Not compiling @0@ because fuzz-tests is set to false'.format(name))
2547 continue
2548 endif
2549 exe = custom_target(
2550 name,
2551 output : name,
cbc55c4c 2552 depends : build,
7db5761d
MK
2553 command : [ln, '-fs',
2554 build.full_path() / fuzzer,
2555 '@OUTPUT@'],
2556 build_by_default : true)
2557
cbc55c4c
YW
2558 foreach directive : fuzz_ins.get('directives', [])
2559 test('@0@_@1@_@2@'.format(fuzzer, fs.name(directive.full_path()), sanitizer),
2560 env,
2561 suite : 'fuzz+san',
2562 env : ['UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1'],
2563 timeout : 60,
2564 args : [exe.full_path(), directive.full_path()],
2565 depends : directive)
2566 endforeach
2567 foreach file : fuzz_ins.get('files', [])
2568 test('@0@_@1@_@2@'.format(fuzzer, fs.name(file), sanitizer),
52d4d1d3 2569 env,
14056a52 2570 suite : 'fuzz+san',
89767158
EV
2571 env : ['UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1'],
2572 timeout : 60,
cbc55c4c 2573 args : [exe.full_path(), file])
7db5761d 2574 endforeach
52d4d1d3 2575 endforeach
b68dfb9e
ZJS
2576 endif
2577endforeach
2578
2579############################################################
2580
0700e8ba 2581if git.found()
37efbbd8 2582 all_files = run_command(
0f4c4f38
ZJS
2583 env, '-u', 'GIT_WORK_TREE',
2584 git, '--git-dir=@0@/.git'.format(project_source_root),
ba9ca60a 2585 'ls-files', ':/*.[ch]', ':/*.cc',
e92777d2
ZJS
2586 check : false)
2587 if all_files.returncode() == 0
2588 all_files = files(all_files.stdout().split())
2589
2590 custom_target(
2591 'tags',
2592 output : 'tags',
2593 command : [env, 'etags', '-o', '@0@/TAGS'.format(project_source_root)] + all_files)
2594 run_target(
2595 'ctags',
691db9a7 2596 command : [env, 'ctags', '--tag-relative=never', '-o', '@0@/tags'.format(project_source_root)] + all_files)
60892358
ZJS
2597
2598 ############################################
2599
2600 if want_tests != 'false' and conf.get('BUILD_MODE_DEVELOPER') == 1
2601 test('check-includes',
2602 files('tools/check-includes.py'),
2603 args: all_files,
dc4a0055
YW
2604 env : ['PROJECT_SOURCE_ROOT=@0@'.format(project_source_root)],
2605 suite : 'headers')
60892358 2606 endif
e92777d2 2607 endif
177929c2 2608
60892358
ZJS
2609 ####################################################
2610
dd1e33c8 2611 git_contrib_sh = find_program('tools/git-contrib.sh')
a923e085 2612 run_target(
37efbbd8 2613 'git-contrib',
dd1e33c8 2614 command : [git_contrib_sh])
dd6ab3df 2615
60892358
ZJS
2616 ####################################################
2617
dd6ab3df 2618 git_head = run_command(
e92777d2
ZJS
2619 git, '--git-dir=@0@/.git'.format(project_source_root),
2620 'rev-parse', 'HEAD',
2621 check : false).stdout().strip()
dd6ab3df 2622 git_head_short = run_command(
e92777d2
ZJS
2623 git, '--git-dir=@0@/.git'.format(project_source_root),
2624 'rev-parse', '--short=7', 'HEAD',
2625 check : false).stdout().strip()
dd6ab3df
ZJS
2626
2627 run_target(
2628 'git-snapshot',
0f4c4f38 2629 command : [git, 'archive',
1485aacb 2630 '-o', '@0@/systemd-@1@.tar.gz'.format(project_source_root,
dd6ab3df
ZJS
2631 git_head_short),
2632 '--prefix', 'systemd-@0@/'.format(git_head),
2633 'HEAD'])
2634endif
829257d1
ZJS
2635
2636############################################################
2637
dd1e33c8 2638check_api_docs_sh = find_program('tools/check-api-docs.sh')
51b13863
LP
2639run_target(
2640 'check-api-docs',
2641 depends : [man, libsystemd, libudev],
dd1e33c8 2642 command : [check_api_docs_sh, libsystemd.full_path(), libudev.full_path()])
51b13863 2643
f12c5d36
ZJS
2644alias_target('update-dbus-docs', update_dbus_docs)
2645alias_target('update-man-rules', update_man_rules)
e3c368f6 2646
0628d48e
LB
2647if not meson.is_cross_build()
2648 custom_target(
2649 'export-dbus-interfaces',
4645074e 2650 output : fs.name(dbus_interfaces_dir),
0628d48e 2651 install : dbus_interfaces_dir != 'no',
4645074e 2652 install_dir : fs.parent(dbus_interfaces_dir),
0628d48e
LB
2653 command : [export_dbus_interfaces_py, '@OUTPUT@', dbus_programs])
2654endif
e3c68924 2655
51b13863 2656############################################################
829257d1 2657
e92777d2
ZJS
2658alt_time_epoch = run_command('date', '-Is', '-u', '-d', '@@0@'.format(time_epoch),
2659 check : true).stdout().strip()
12085ebb
ZJS
2660
2661summary({
12085ebb
ZJS
2662 'split bin-sbin' : split_bin,
2663 'prefix directory' : prefixdir,
12085ebb
ZJS
2664 'sysconf directory' : sysconfdir,
2665 'include directory' : includedir,
2666 'lib directory' : libdir,
12085ebb
ZJS
2667 'SysV init scripts' : sysvinit_path,
2668 'SysV rc?.d directories' : sysvrcnd_path,
2669 'PAM modules directory' : pamlibdir,
2670 'PAM configuration directory' : pamconfdir,
2671 'libcryptsetup plugins directory' : libcryptsetup_plugins_dir,
2672 'RPM macros directory' : rpmmacrosdir,
2673 'modprobe.d directory' : modprobedir,
2674 'D-Bus policy directory' : dbuspolicydir,
2675 'D-Bus session directory' : dbussessionservicedir,
2676 'D-Bus system directory' : dbussystemservicedir,
7e560e79 2677 'D-Bus interfaces directory' : dbus_interfaces_dir,
12085ebb
ZJS
2678 'bash completions directory' : bashcompletiondir,
2679 'zsh completions directory' : zshcompletiondir,
a2b0cd3f 2680 'private shared lib version tag' : shared_lib_tag,
12085ebb
ZJS
2681 'extra start script' : get_option('rc-local'),
2682 'debug shell' : '@0@ @ @1@'.format(get_option('debug-shell'),
2683 get_option('debug-tty')),
2684 'system UIDs' : '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_UID_MAX'),
2685 conf.get('SYSTEM_ALLOC_UID_MIN')),
2686 'system GIDs' : '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
2687 conf.get('SYSTEM_ALLOC_GID_MIN')),
2688 'dynamic UIDs' : '@0@…@1@'.format(dynamic_uid_min, dynamic_uid_max),
2689 'container UID bases' : '@0@…@1@'.format(container_uid_base_min, container_uid_base_max),
2690 'static UID/GID allocations' : ' '.join(static_ugids),
2691 '/dev/kvm access mode' : get_option('dev-kvm-mode'),
2692 'render group access mode' : get_option('group-render-mode'),
2693 'certificate root directory' : get_option('certificate-root'),
2694 'support URL' : support_url,
2695 'nobody user name' : nobody_user,
2696 'nobody group name' : nobody_group,
2697 'fallback hostname' : get_option('fallback-hostname'),
9798deaf 2698 'default compression method' : compression,
12085ebb
ZJS
2699 'default DNSSEC mode' : default_dnssec,
2700 'default DNS-over-TLS mode' : default_dns_over_tls,
2701 'default mDNS mode' : default_mdns,
2702 'default LLMNR mode' : default_llmnr,
2703 'default DNS servers' : dns_servers.split(' '),
2704 'default NTP servers' : ntp_servers.split(' '),
2705 'default cgroup hierarchy' : default_hierarchy,
2706 'default net.naming-scheme value' : default_net_naming_scheme,
2707 'default KillUserProcesses value' : kill_user_processes,
2708 'default locale' : default_locale,
88b6f0de 2709 'default nspawn locale' : nspawn_locale,
79dec86a 2710 'default status unit format' : status_unit_format_default,
12085ebb
ZJS
2711 'default user $PATH' :
2712 default_user_path != '' ? default_user_path : '(same as system services)',
2713 'systemd service watchdog' : service_watchdog == '' ? 'disabled' : service_watchdog,
2714 'time epoch' : '@0@ (@1@)'.format(time_epoch, alt_time_epoch)})
829257d1
ZJS
2715
2716# TODO:
2717# CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
2718# CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
2719# LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
2720
829257d1
ZJS
2721found = []
2722missing = []
2723
2724foreach tuple : [
56d68e71
ZJS
2725 # dependencies
2726 ['ACL'],
829257d1 2727 ['AUDIT'],
829257d1 2728 ['AppArmor'],
56d68e71
ZJS
2729 ['IMA'],
2730 ['PAM'],
829257d1 2731 ['SECCOMP'],
56d68e71 2732 ['SELinux'],
829257d1 2733 ['SMACK'],
56d68e71
ZJS
2734 ['blkid'],
2735 ['elfutils'],
829257d1 2736 ['gcrypt'],
829257d1 2737 ['gnutls'],
7d861e12 2738 ['libbpf'],
56d68e71 2739 ['libcryptsetup'],
d1ae38d8 2740 ['libcryptsetup-plugins'],
829257d1 2741 ['libcurl'],
56d68e71
ZJS
2742 ['libfdisk'],
2743 ['libfido2'],
829257d1 2744 ['libidn'],
56d68e71 2745 ['libidn2'],
829257d1 2746 ['libiptc'],
56d68e71
ZJS
2747 ['microhttpd'],
2748 ['openssl'],
2749 ['p11kit'],
1d8aae43 2750 ['passwdqc'],
56d68e71
ZJS
2751 ['pcre2'],
2752 ['pwquality'],
2753 ['qrencode'],
2754 ['tpm2'],
2755 ['xkbcommon'],
2756
2757 # compression libs
2758 ['zstd'],
2759 ['lz4'],
2760 ['xz'],
2761 ['zlib'],
2762 ['bzip2'],
2763
2764 # components
2765 ['backlight'],
829257d1 2766 ['binfmt'],
dfca5587 2767 ['bootloader'],
0a0d4899 2768 ['bpf-framework', conf.get('BPF_FRAMEWORK') == 1],
56d68e71 2769 ['coredump'],
56d68e71 2770 ['efi'],
dfca5587 2771 ['environment.d'],
829257d1 2772 ['firstboot'],
56d68e71
ZJS
2773 ['hibernate'],
2774 ['homed'],
2775 ['hostnamed'],
2776 ['hwdb'],
2777 ['importd'],
2778 ['initrd'],
f887eab1 2779 ['kernel-install'],
56d68e71 2780 ['localed'],
829257d1
ZJS
2781 ['logind'],
2782 ['machined'],
56d68e71
ZJS
2783 ['networkd'],
2784 ['nss-myhostname'],
2785 ['nss-mymachines'],
2786 ['nss-resolve'],
2787 ['nss-systemd'],
2788 ['oomd'],
61d0578b 2789 ['portabled'],
56d68e71
ZJS
2790 ['pstore'],
2791 ['quotacheck'],
2792 ['randomseed'],
2793 ['repart'],
2794 ['resolve'],
2795 ['rfkill'],
9bca4ae4 2796 ['sysext'],
0a0d4899 2797 ['systemd-analyze', conf.get('ENABLE_ANALYZE') == 1],
43cc7a3e 2798 ['sysupdate'],
56d68e71 2799 ['sysusers'],
1761066b 2800 ['storagetm'],
829257d1
ZJS
2801 ['timedated'],
2802 ['timesyncd'],
56d68e71
ZJS
2803 ['tmpfiles'],
2804 ['userdb'],
2805 ['vconsole'],
2806 ['xdg-autostart'],
2807
2808 # optional features
12b4cffd 2809 ['dmi'],
56d68e71 2810 ['idn'],
829257d1 2811 ['polkit'],
56d68e71 2812 ['nscd'],
0a0d4899 2813 ['legacy-pkla', install_polkit_pkla],
829257d1 2814 ['kmod'],
ede5a78f 2815 ['xenctrl'],
829257d1
ZJS
2816 ['dbus'],
2817 ['glib'],
829257d1 2818 ['tpm'],
0a0d4899
JH
2819 ['man pages', want_man],
2820 ['html pages', want_html],
2821 ['man page indices', want_man and have_lxml],
829257d1 2822 ['SysV compat'],
56d68e71 2823 ['compat-mutable-uid-boundaries'],
829257d1
ZJS
2824 ['utmp'],
2825 ['ldconfig'],
0a0d4899
JH
2826 ['adm group', get_option('adm-group')],
2827 ['wheel group', get_option('wheel-group')],
b14e1b43 2828 ['gshadow'],
829257d1
ZJS
2829 ['debug hashmap'],
2830 ['debug mmap cache'],
d6601495 2831 ['debug siphash'],
0a0d4899 2832 ['trace logging', conf.get('LOG_TRACE') == 1],
69525346
YW
2833 ['slow tests', slow_tests],
2834 ['fuzz tests', fuzz_tests],
0a0d4899
JH
2835 ['install tests', install_tests],
2836 ['link-udev-shared', get_option('link-udev-shared')],
2837 ['link-systemctl-shared', get_option('link-systemctl-shared')],
2838 ['link-networkd-shared', get_option('link-networkd-shared')],
2839 ['link-timesyncd-shared', get_option('link-timesyncd-shared')],
2840 ['link-journalctl-shared', get_option('link-journalctl-shared')],
2841 ['link-boot-shared', get_option('link-boot-shared')],
c06d2e44 2842 ['link-portabled-shared', get_option('link-portabled-shared')],
93651582 2843 ['first-boot-full-preset'],
ceedbf81 2844 ['fexecve'],
0a0d4899
JH
2845 ['standalone-binaries', get_option('standalone-binaries')],
2846 ['coverage', get_option('b_coverage')],
829257d1
ZJS
2847]
2848
af4d7860
ZJS
2849 if tuple.length() >= 2
2850 cond = tuple[1]
2851 else
829257d1
ZJS
2852 ident1 = 'HAVE_' + tuple[0].underscorify().to_upper()
2853 ident2 = 'ENABLE_' + tuple[0].underscorify().to_upper()
349cc4a5 2854 cond = conf.get(ident1, 0) == 1 or conf.get(ident2, 0) == 1
829257d1
ZJS
2855 endif
2856 if cond
5a8b1640 2857 found += tuple[0]
829257d1 2858 else
5a8b1640 2859 missing += tuple[0]
829257d1
ZJS
2860 endif
2861endforeach
2862
c716c253
ZJS
2863if static_libsystemd == 'false'
2864 missing += 'static-libsystemd'
2865else
2866 found += 'static-libsystemd(@0@)'.format(static_libsystemd)
2867endif
2868
2869if static_libudev == 'false'
2870 missing += 'static-libudev'
2871else
2872 found += 'static-libudev(@0@)'.format(static_libudev)
2873endif
2874
57633d23
ZJS
2875if conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1 and conf.get('PREFER_OPENSSL') == 1
2876 found += 'cryptolib(openssl)'
2877elif conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1
2878 found += 'cryptolib(gcrypt)'
2879else
2880 missing += 'cryptolib'
2881endif
2882
237f2da9
ZJS
2883if conf.get('DNS_OVER_TLS_USE_GNUTLS') == 1
2884 found += 'DNS-over-TLS(gnutls)'
2885elif conf.get('DNS_OVER_TLS_USE_OPENSSL') == 1
2886 found += 'DNS-over-TLS(openssl)'
2887else
2888 missing += 'DNS-over-TLS'
2889endif
2890
12085ebb
ZJS
2891summary({
2892 'enabled' : ', '.join(found),
2893 'disabled' : ', '.join(missing)},
2894 section : 'Features')