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