diff --git a/.github/workflows/build_test.sh b/.github/workflows/build_test.sh index 986e30c595..113af704a8 100755 --- a/.github/workflows/build_test.sh +++ b/.github/workflows/build_test.sh @@ -135,9 +135,6 @@ $CC --version meson --version ninja --version -# TODO: drop once minimum meson version is bumped to 0.62 or newer -find . -type f -name meson.build -exec sed -i 's/install_emptydir(\(.*\), install_tag : .*)/install_emptydir(\1)/g' '{}' '+' - for args in "${ARGS[@]}"; do SECONDS=0 diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh index 94ecdc6072..168bcc55c3 100755 --- a/.github/workflows/unit_tests.sh +++ b/.github/workflows/unit_tests.sh @@ -33,8 +33,6 @@ function info() { } function run_meson() { - # TODO: drop once minimum meson version is bumped to 0.62 or newer - find . -type f -name meson.build -exec sed -i 's/install_emptydir(\(.*\), install_tag : .*)/install_emptydir(\1)/g' '{}' '+' if ! meson "$@"; then find . -type f -name meson-log.txt -exec cat '{}' + return 1 diff --git a/README b/README index 9b019396c8..9f5c48b67f 100644 --- a/README +++ b/README @@ -255,7 +255,7 @@ REQUIREMENTS: python-pefile (optional, required for ukify) python-lxml (optional, required to build the indices) pyelftools (optional, required for systemd-boot) - meson >= 0.60.0 + meson >= 0.62.0 ninja gcc >= 8.4 >= 13.1.0 is required to build BPF program by using GCC diff --git a/man/meson.build b/man/meson.build index 20a073442e..6b33c60757 100644 --- a/man/meson.build +++ b/man/meson.build @@ -92,7 +92,9 @@ foreach tuple : manpages output : htmlalias, command : [ln, '-fs', html, '@OUTPUT@']) if want_html - meson.add_install_script(sh, '-c', ln_s.format(docdir / 'html' / html, docdir / 'html' / htmlalias)) + install_symlink(htmlalias, + pointing_to : html, + install_dir : docdir / 'html') p2 += link endif html_pages += link @@ -163,7 +165,9 @@ foreach tuple : xsltproc.found() ? [['systemd.directives', '7', systemd_directiv output : htmlalias, command : [ln, '-fs', html, '@OUTPUT@']) if want_html - meson.add_install_script(sh, '-c', ln_s.format(docdir / 'html' / html, docdir / 'html' / htmlalias)) + install_symlink(htmlalias, + pointing_to : html, + install_dir : docdir / 'html') p2 += link endif html_pages += link diff --git a/meson.build b/meson.build index 1cdce6a868..d87c651fc6 100644 --- a/meson.build +++ b/meson.build @@ -10,8 +10,8 @@ project('systemd', 'c', 'localstatedir=/var', 'warning_level=2', ], - meson_version : '>= 0.60.0', - ) + meson_version : '>= 0.62.0', +) project_major_version = meson.project_version().split('.')[0].split('~')[0] if meson.project_version().contains('.') @@ -127,6 +127,7 @@ datadir = prefixdir / get_option('datadir') localstatedir = '/' / get_option('localstatedir') libexecdir = prefixdir / 'lib/systemd' +libexecdir_to_bin = '../../bin/' pkglibdir = libdir / 'systemd' install_sysconfdir = get_option('install-sysconfdir') != 'false' @@ -1244,18 +1245,30 @@ foreach ident : ['crypt_set_metadata_size', endforeach conf.set10('HAVE_LIBCRYPTSETUP', have) -# TODO: Use has_function(required : libcryptsetup_plugins) with meson >= 1.3.0 -if libcryptsetup_plugins.allowed() +if meson.version().version_compare('>=1.3.0') have = (cc.has_function( 'crypt_activate_by_token_pin', prefix : '#include ', - dependencies : libcryptsetup) and + dependencies : libcryptsetup, + required : libcryptsetup_plugins) and cc.has_function( 'crypt_token_external_path', prefix : '#include ', - dependencies : libcryptsetup)) + dependencies : libcryptsetup, + required : libcryptsetup_plugins)) else - have = false + if libcryptsetup_plugins.allowed() + have = (cc.has_function( + 'crypt_activate_by_token_pin', + prefix : '#include ', + dependencies : libcryptsetup) and + cc.has_function( + 'crypt_token_external_path', + prefix : '#include ', + dependencies : libcryptsetup)) + else + have = false + endif endif conf.set10('HAVE_LIBCRYPTSETUP_PLUGINS', have) @@ -2635,9 +2648,9 @@ if want_ukify public_programs += ukify # symlink for backwards compatibility after rename - meson.add_install_script(sh, '-c', - ln_s.format(bindir / 'ukify', - libexecdir / 'ukify')) + install_symlink('ukify', + pointing_to : libexecdir_to_bin / 'ukify', + install_dir : libexecdir) endif ##################################################################### diff --git a/profile.d/meson.build b/profile.d/meson.build index fa03ed0ab0..b1692920f4 100644 --- a/profile.d/meson.build +++ b/profile.d/meson.build @@ -4,15 +4,33 @@ install_data('70-systemd-shell-extra.sh', install_dir : shellprofiledir.startswi install_data('80-systemd-osc-context.sh', install_dir : shellprofiledir.startswith('/usr/') ? shellprofiledir : libexecdir / 'profile.d') if conf.get('LINK_SHELL_EXTRA_DROPIN') == 1 - install_emptydir(shellprofiledir) + if meson.version().version_compare('>=1.3.0') + install_symlink( + '70-systemd-shell-extra.sh', + pointing_to : fs.relative_to(libexecdir / 'profile.d' / '70-systemd-shell-extra.sh', + shellprofiledir), + install_dir : shellprofiledir) + else + install_emptydir(shellprofiledir) - meson.add_install_script(sh, '-c', - ln_s.format(libexecdir / 'profile.d' / '70-systemd-shell-extra.sh', shellprofiledir / '70-systemd-shell-extra.sh')) + meson.add_install_script(sh, '-c', + ln_s.format(libexecdir / 'profile.d' / '70-systemd-shell-extra.sh', + shellprofiledir / '70-systemd-shell-extra.sh')) + endif endif if conf.get('LINK_OSC_CONTEXT_DROPIN') == 1 - install_emptydir(shellprofiledir) + if meson.version().version_compare('>=1.3.0') + install_symlink( + '80-systemd-osc-context.sh', + pointing_to : fs.relative_to(libexecdir / 'profile.d' / '80-systemd-osc-context.sh', + shellprofiledir), + install_dir : shellprofiledir) + else + install_emptydir(shellprofiledir) - meson.add_install_script(sh, '-c', - ln_s.format(libexecdir / 'profile.d' / '80-systemd-osc-context.sh', shellprofiledir / '80-systemd-osc-context.sh')) + meson.add_install_script(sh, '-c', + ln_s.format(libexecdir / 'profile.d' / '80-systemd-osc-context.sh', + shellprofiledir / '80-systemd-osc-context.sh')) + endif endif diff --git a/src/core/meson.build b/src/core/meson.build index f0206c7a9b..f1c7e334be 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -260,13 +260,17 @@ install_emptydir(usergeneratordir) if install_sysconfdir install_emptydir(pkgsysconfdir / 'system') install_emptydir(pkgsysconfdir / 'user') - install_emptydir(sysconfdir / 'xdg/systemd') - meson.add_install_script(sh, '-c', ln_s.format(pkgsysconfdir / 'user', - sysconfdir / 'xdg/systemd/user')) + + assert(sysconfdir / 'systemd' == pkgsysconfdir) + install_symlink('user', + pointing_to : '../../systemd/user', + install_dir : sysconfdir / 'xdg/systemd') endif -install_emptydir(sbindir) -meson.add_install_script(sh, '-c', ln_s.format(libexecdir / 'systemd', sbindir / 'init')) +assert(fs.parent(sbindir) / 'lib/systemd' == libexecdir) +install_symlink('init', + pointing_to : '../lib/systemd/systemd', + install_dir : sbindir) ############################################################ diff --git a/src/cryptsetup/meson.build b/src/cryptsetup/meson.build index ad60190e74..056a9d4672 100644 --- a/src/cryptsetup/meson.build +++ b/src/cryptsetup/meson.build @@ -33,6 +33,6 @@ executables += [ ] # symlink for backwards compatibility after rename -meson.add_install_script(sh, '-c', - ln_s.format(bindir / 'systemd-cryptsetup', - libexecdir / 'systemd-cryptsetup')) +install_symlink('systemd-cryptsetup', + pointing_to : libexecdir_to_bin / 'systemd-cryptsetup', + install_dir : libexecdir) diff --git a/src/dissect/meson.build b/src/dissect/meson.build index 7e7a089b44..24943cc802 100644 --- a/src/dissect/meson.build +++ b/src/dissect/meson.build @@ -12,7 +12,6 @@ executables += [ }, ] -install_emptydir(sbindir) -meson.add_install_script(sh, '-c', - ln_s.format(bindir / 'systemd-dissect', - sbindir / 'mount.ddi')) +install_symlink('mount.ddi', + pointing_to : sbin_to_bin + 'systemd-dissect', + install_dir : sbindir) diff --git a/src/environment-d-generator/meson.build b/src/environment-d-generator/meson.build index cc41b6b334..51aad9200d 100644 --- a/src/environment-d-generator/meson.build +++ b/src/environment-d-generator/meson.build @@ -13,6 +13,9 @@ executables += [ ] install_emptydir(environmentdir) +# install_symlink() does not support broken symlink, and /etc/environment is not managed by us, thus +# may not exist. Hence, we need to create it by using the custom install script here. +# See https://github.com/mesonbuild/meson/pull/12266 . meson.add_install_script(sh, '-c', ln_s.format(sysconfdir / 'environment', environmentdir / '99-environment.conf')) diff --git a/src/fstab-generator/meson.build b/src/fstab-generator/meson.build index 7b90580e90..fb492158fc 100644 --- a/src/fstab-generator/meson.build +++ b/src/fstab-generator/meson.build @@ -7,6 +7,7 @@ executables += [ }, ] -meson.add_install_script(sh, '-c', - ln_s.format(systemgeneratordir / 'systemd-fstab-generator', - libexecdir / 'systemd-sysroot-fstab-check')) +assert(libexecdir / fs.name(systemgeneratordir) == systemgeneratordir) +install_symlink('systemd-sysroot-fstab-check', + pointing_to : fs.name(systemgeneratordir) / 'systemd-fstab-generator', + install_dir : libexecdir) diff --git a/src/home/meson.build b/src/home/meson.build index da34c418fa..74174dec9e 100644 --- a/src/home/meson.build +++ b/src/home/meson.build @@ -140,6 +140,6 @@ if install_sysconfdir_samples install_dir : pkgconfigfiledir) endif -meson.add_install_script(sh, '-c', - ln_s.format(bindir / 'homectl', - bindir / 'systemd-home-fallback-shell')) +install_symlink('systemd-home-fallback-shell', + pointing_to : 'homectl', + install_dir : bindir) diff --git a/src/mount/meson.build b/src/mount/meson.build index 176fb53dca..dd996cfba4 100644 --- a/src/mount/meson.build +++ b/src/mount/meson.build @@ -9,5 +9,6 @@ executables += [ }, ] -meson.add_install_script(sh, '-c', ln_s.format(bindir / 'systemd-mount', - bindir / 'systemd-umount')) +install_symlink('systemd-umount', + pointing_to : 'systemd-mount', + install_dir : bindir) diff --git a/src/resolve/meson.build b/src/resolve/meson.build index bfbe0bd15e..7e388f835b 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -311,15 +311,14 @@ if conf.get('ENABLE_RESOLVE') == 1 install_data('resolv.conf', install_dir : libexecdir) - install_emptydir(sbindir) - meson.add_install_script(sh, '-c', - ln_s.format(bindir / 'resolvectl', - sbindir / 'resolvconf')) + install_symlink('resolvconf', + pointing_to : sbin_to_bin + 'resolvectl', + install_dir : sbindir) # symlink for backwards compatibility after rename - meson.add_install_script(sh, '-c', - ln_s.format(bindir / 'resolvectl', - bindir / 'systemd-resolve')) + install_symlink('systemd-resolve', + pointing_to : 'resolvectl', + install_dir : bindir) endif custom_target( diff --git a/src/run/meson.build b/src/run/meson.build index 221b441fac..a228d25014 100644 --- a/src/run/meson.build +++ b/src/run/meson.build @@ -8,11 +8,9 @@ executables += [ }, ] -install_emptydir(bindir) - -meson.add_install_script(sh, '-c', - ln_s.format(bindir / 'systemd-run', - bindir / 'run0')) +install_symlink('run0', + pointing_to : 'systemd-run', + install_dir : bindir) custom_target( 'systemd-run0', diff --git a/src/ssh-generator/meson.build b/src/ssh-generator/meson.build index d0473e2cbb..e36f9fae08 100644 --- a/src/ssh-generator/meson.build +++ b/src/ssh-generator/meson.build @@ -21,9 +21,18 @@ if conf.get('ENABLE_SSH_PROXY_CONFIG') == 1 install_dir : sshconfdir.startswith('/usr/') ? sshconfdir : libexecdir / 'ssh_config.d') if conf.get('LINK_SSH_PROXY_DROPIN') == 1 - install_emptydir(sshconfdir) + if meson.version().version_compare('>=1.3.0') + install_symlink( + '20-systemd-ssh-proxy.conf', + pointing_to : fs.relative_to(libexecdir / 'ssh_config.d' / '20-systemd-ssh-proxy.conf', + sshconfdir), + install_dir : sshconfdir) + else + install_emptydir(sshconfdir) - meson.add_install_script(sh, '-c', - ln_s.format(libexecdir / 'ssh_config.d' / '20-systemd-ssh-proxy.conf', sshconfdir / '20-systemd-ssh-proxy.conf')) + meson.add_install_script(sh, '-c', + ln_s.format(libexecdir / 'ssh_config.d' / '20-systemd-ssh-proxy.conf', + sshconfdir / '20-systemd-ssh-proxy.conf')) + endif endif endif diff --git a/src/sysext/meson.build b/src/sysext/meson.build index 2983970d80..25f6b91335 100644 --- a/src/sysext/meson.build +++ b/src/sysext/meson.build @@ -10,6 +10,7 @@ executables += [ ] if conf.get('ENABLE_SYSEXT') == 1 - meson.add_install_script(sh, '-c', ln_s.format(bindir / 'systemd-sysext', - bindir / 'systemd-confext')) + install_symlink('systemd-confext', + pointing_to : 'systemd-sysext', + install_dir : bindir) endif diff --git a/src/systemctl/meson.build b/src/systemctl/meson.build index 46218dc8ef..bdeda919fd 100644 --- a/src/systemctl/meson.build +++ b/src/systemctl/meson.build @@ -75,8 +75,7 @@ executables += [ foreach alias : (['halt', 'poweroff', 'reboot', 'shutdown'] + (conf.get('HAVE_SYSV_COMPAT') == 1 ? ['runlevel', 'telinit'] : [])) - install_emptydir(sbindir) - meson.add_install_script(sh, '-c', - ln_s.format(bindir / 'systemctl', - sbindir / alias)) + install_symlink(alias, + pointing_to : sbin_to_bin + 'systemctl', + install_dir : sbindir) endforeach diff --git a/src/udev/meson.build b/src/udev/meson.build index b24234bba2..c77609543b 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -269,9 +269,10 @@ executables += [ }, ] -meson.add_install_script(sh, '-c', ln_s.format(bindir / 'udevadm', - libexecdir / 'systemd-udevd'), - install_tag : 'udev') +install_symlink('systemd-udevd', + pointing_to : libexecdir_to_bin + 'udevadm', + install_dir : libexecdir, + install_tag : 'udev') if install_sysconfdir_samples install_data('udev.conf', diff --git a/src/userdb/meson.build b/src/userdb/meson.build index f6d068500d..57948d8df9 100644 --- a/src/userdb/meson.build +++ b/src/userdb/meson.build @@ -34,9 +34,18 @@ if conf.get('ENABLE_SSH_USERDB_CONFIG') == 1 install_dir : sshdconfdir.startswith('/usr/') ? sshdconfdir : libexecdir / 'sshd_config.d') if conf.get('LINK_SSHD_USERDB_DROPIN') == 1 - install_emptydir(sshdconfdir) + if meson.version().version_compare('>=1.3.0') + install_symlink( + '20-systemd-userdb.conf', + pointing_to : fs.relative_to(libexecdir / 'sshd_config.d' / '20-systemd-userdb.conf', + sshdconfdir), + install_dir : sshdconfdir) + else + install_emptydir(sshdconfdir) - meson.add_install_script(sh, '-c', - ln_s.format(libexecdir / 'sshd_config.d' / '20-systemd-userdb.conf', sshdconfdir / '20-systemd-userdb.conf')) + meson.add_install_script(sh, '-c', + ln_s.format(libexecdir / 'sshd_config.d' / '20-systemd-userdb.conf', + sshdconfdir / '20-systemd-userdb.conf')) + endif endif endif diff --git a/test/fuzz/meson.build b/test/fuzz/meson.build index 54cbb75532..d88d6218d2 100644 --- a/test/fuzz/meson.build +++ b/test/fuzz/meson.build @@ -36,13 +36,16 @@ fuzz_regression_tests += { 'fuzz-unit-file' : dict } ############################################################ -# TODO: Use native string formatting with meson >= 1.3.0 -if get_option('auto_features').enabled() - sanitize_auto_features = 'enabled' -elif get_option('auto_features').disabled() - sanitize_auto_features = 'disabled' +if meson.version().version_compare('>=1.3.0') + sanitize_auto_features = '@0@'.format(get_option('auto_features')) else - sanitize_auto_features = 'auto' + if get_option('auto_features').enabled() + sanitize_auto_features = 'enabled' + elif get_option('auto_features').disabled() + sanitize_auto_features = 'disabled' + else + sanitize_auto_features = 'auto' + endif endif fuzz_c_args = get_option('c_args') diff --git a/test/meson.build b/test/meson.build index 59e9cd36fd..e2d10a3886 100644 --- a/test/meson.build +++ b/test/meson.build @@ -474,27 +474,22 @@ if install_tests foreach subdir : testdata_subdirs # install_subdir() before meson 1.3.0 does not handle symlinks correctly (it follows them # instead of copying the symlink) so we use rsync instead. - if meson.version().version_compare('<1.3.0') + if meson.version().version_compare('>=1.3.0') + install_subdir(subdir, + exclude_files : ['.gitattributes'], + install_dir : testdata_dir, + follow_symlinks : false) + else if not rsync.found() error('rsync is required to install the integration test data') endif - rsync_r = rsync.full_path() + ' -rlpt --exclude .gitattributes --exclude 25-default.link -- "@0@" "${DESTDIR:-}@1@"' + rsync_r = rsync.full_path() + ' -rlpt --exclude .gitattributes -- "@0@" "${DESTDIR:-}@1@"' meson.add_install_script(sh, '-c', rsync_r.format(meson.current_source_dir() / subdir, testdata_dir)) - else - install_subdir(subdir, - exclude_files : ['.gitattributes', '25-default.link'], - install_dir : testdata_dir, - follow_symlinks : false) endif endforeach - # test-network/conf/25-default.link is a local symlink that becomes dangling when installed, so we - # exclude it and create the correct symlink here. - meson.add_install_script(sh, '-c', ln_s.format(networkdir / '99-default.link', - testdata_dir / 'test-network/conf/25-default.link')) - install_data(kbd_model_map, install_dir : testdata_dir + '/test-keymap-util') @@ -511,6 +506,8 @@ if install_tests # The unit tests implemented as shell scripts expect to find testdata/ # in the directory where they are stored. - meson.add_install_script(sh, '-c', ln_s.format(testdata_dir, - unittestsdir / 'testdata')) + assert(fs.parent(unittestsdir) / 'testdata' == testdata_dir) + install_symlink('testdata', + pointing_to : '../testdata', + install_dir : unittestsdir) endif diff --git a/test/test-network/conf/25-default.link b/test/test-network/conf/25-default.link deleted file mode 120000 index dee89415e5..0000000000 --- a/test/test-network/conf/25-default.link +++ /dev/null @@ -1 +0,0 @@ -../../../network/99-default.link \ No newline at end of file diff --git a/test/test-network/conf/25-default.link b/test/test-network/conf/25-default.link new file mode 100644 index 0000000000..9b95e12fda --- /dev/null +++ b/test/test-network/conf/25-default.link @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: MIT-0 +# +# This is a copy of 99-default.link. + +[Match] +OriginalName=* + +[Link] +NamePolicy=keep kernel database onboard slot path +AlternativeNamesPolicy=database onboard slot path mac +MACAddressPolicy=persistent diff --git a/units/meson.build b/units/meson.build index 84c3757b10..b29bed068f 100644 --- a/units/meson.build +++ b/units/meson.build @@ -922,16 +922,17 @@ foreach unit : units if install foreach target : unit.get('symlinks', []) if target.endswith('/') - install_emptydir(systemunitdir / target, install_tag : unit.get('install_tag', '')) - meson.add_install_script(sh, '-c', - ln_s.format(systemunitdir / name, - systemunitdir / target / name), - install_tag : unit.get('install_tag', '')) + # '/' is only allowed at the end of the target + assert(target.replace('/', '') + '/' == target) + install_symlink(name, + pointing_to : '..' / name, + install_dir : systemunitdir / target, + install_tag : unit.get('install_tag', '')) else - meson.add_install_script(sh, '-c', - ln_s.format(systemunitdir / name, - systemunitdir / target), - install_tag : unit.get('install_tag', '')) + install_symlink(target, + pointing_to : name, + install_dir : systemunitdir, + install_tag : unit.get('install_tag', '')) endif endforeach endif @@ -947,10 +948,18 @@ install_data('user@0.service.d/10-login-barrier.conf', ############################################################ -install_emptydir(dbussessionservicedir) -meson.add_install_script(sh, '-c', - ln_s.format(dbussystemservicedir / 'org.freedesktop.systemd1.service', - dbussessionservicedir / 'org.freedesktop.systemd1.service')) +if meson.version().version_compare('>=1.3.0') + install_symlink( + 'org.freedesktop.systemd1.service', + pointing_to : fs.relative_to(dbussystemservicedir / 'org.freedesktop.systemd1.service', + dbussessionservicedir), + install_dir : dbussessionservicedir) +else + install_emptydir(dbussessionservicedir) + meson.add_install_script(sh, '-c', + ln_s.format(dbussystemservicedir / 'org.freedesktop.systemd1.service', + dbussessionservicedir / 'org.freedesktop.systemd1.service')) +endif if conf.get('HAVE_SYSV_COMPAT') == 1 foreach i : [1, 2, 3, 4, 5] diff --git a/units/user/meson.build b/units/user/meson.build index 290f268ef1..c669e4bb1c 100644 --- a/units/user/meson.build +++ b/units/user/meson.build @@ -50,14 +50,15 @@ foreach unit : units foreach target : unit.get('symlinks', []) if target.endswith('/') - install_emptydir(userunitdir / target) - meson.add_install_script(sh, '-c', - ln_s.format(userunitdir / file, - userunitdir / target / file)) + # '/' is only allowed at the end of the target + assert(target.replace('/', '') + '/' == target) + install_symlink(file, + pointing_to : '..' / file, + install_dir : userunitdir / target) else - meson.add_install_script(sh, '-c', - ln_s.format(userunitdir / file, - userunitdir / target)) + install_symlink(target, + pointing_to : file, + install_dir : userunitdir) endif endforeach endif