From 7be812ae70aa7e713918d41b2b9dc09e6199f6fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Jul 2026 22:00:28 +0200 Subject: [PATCH 1/2] meson: rework -Dstandalone-binaries= option The option is generalized from a simple boolean switch that enables a fixed list to a list-of-patterns. The old value works, but is deprecated: -Dstandalone-binaries=true is translated to -Dstandalone-binaries=repart,report,tmpfiles,sysusers,shutdown. We could already build all normal executables as .standalone, but the installation only supported a small fixes subset. This wasn't flexible enough: - packagers might want to provide additional standalone binaries then the small subset that was already enabled - but at the same time, whenever new binaries were added to this subset, downstream packaging had to be adjusted in sync, at least in the case of Fedora, because otherwise we'd get a complaint about unexpected .standalone binaries in the temporary install root. With the new option, downstreams can just specify the binaries that they want to be installed in the .standalone variant. As usual with this type of change, the build dir must be reprovisioned. --- meson.build | 44 ++++++++++++++++++++-------------------- meson_options.txt | 5 +++-- src/repart/meson.build | 1 - src/report/meson.build | 6 ------ src/shutdown/meson.build | 1 - src/sysusers/meson.build | 1 - src/tmpfiles/meson.build | 1 - test/meson.build | 4 ++-- 8 files changed, 27 insertions(+), 36 deletions(-) diff --git a/meson.build b/meson.build index 3567392541..e3d0b3c5a2 100644 --- a/meson.build +++ b/meson.build @@ -99,7 +99,10 @@ endif conf.set10('HAVE_SPLIT_BIN', split_bin, description : 'bin and sbin directories are separate') -have_standalone_binaries = get_option('standalone-binaries') +standalone_binaries = get_option('standalone-binaries').split(',') +if standalone_binaries == [''] + standalone_binaries = [] +endif conf.set10('CREATE_LOG_DIRS', get_option('create-log-dirs')) @@ -2027,13 +2030,15 @@ endif # The 'install' field is extended to also control whether the automatically # added variant, which is statically linked with libsystemd-shared, is installed: -# 'yes' : Mapped to true. The static variant will not be installed. -# 'no' : Mapped to false. The static variant will not be installed either. -# 'both' : Mapped to true. The static variant will also be installed. +# 'yes' : Mapped to true. +# 'no' : Mapped to false. # 'static' : Mapped to false, and its target name is suffixed with '.shared'. # The static variant will be installed instead using the original name # (without the '.standalone' suffix). # Currently, test and fuzzer executables only support 'yes' or 'no'. +# +# For executables matched by the install-standalone list, a .standalone variant +# will be installed if install is true. executable_template = { 'include_directories' : includes, 'link_with' : [libshared], @@ -2349,24 +2354,20 @@ foreach dict : executables name_static = name + '.standalone' install = dict.get('install') build_by_default = dict.get('build_by_default') - if install == 'yes' - install_shared = true - install_static = false + install_standalone = false + if not (is_test or is_fuzz) + foreach pattern : standalone_binaries + if name.contains(pattern) + install_standalone = true + endif + endforeach + endif + + if install in ['yes', 'no'] + install_shared = install == 'yes' + install_static = install_shared and install_standalone build_by_default_shared = build_by_default - build_by_default_static = false - elif install == 'no' - install_shared = false - install_static = false - build_by_default_shared = build_by_default - build_by_default_static = false - elif install == 'both' - if is_test or is_fuzz - error('Install mode "@0@" is not supported for test or fuzzer target "@1@"'.format(install, name)) - endif - install_shared = true - install_static = true - build_by_default_shared = build_by_default - build_by_default_static = build_by_default + build_by_default_static = build_by_default and install_standalone elif install == 'static' if is_test or is_fuzz error('Install mode "@0@" is not supported for test or fuzzer target "@1@"'.format(install, name)) @@ -3165,7 +3166,6 @@ foreach tuple : [ ['link-portabled-shared', get_option('link-portabled-shared')], ['first-boot-full-preset'], ['fexecve'], - ['standalone-binaries', get_option('standalone-binaries')], ['coverage', get_option('b_coverage')], ] diff --git a/meson_options.txt b/meson_options.txt index 6a1c870b04..97eec7d08e 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -40,8 +40,9 @@ option('static-libsystemd', type : 'combo', option('static-libudev', type : 'combo', choices : ['false', 'true', 'pic', 'no-pic'], description : 'install a static library for libudev') -option('standalone-binaries', type : 'boolean', value : false, - description : 'also build standalone versions of supported binaries') +option('standalone-binaries', type : 'string', + deprecated : { 'true' : 'repart,report,shutdown,sysusers,tmpfiles', 'false' : '' }, + description : 'comma-separated list of patterns specifying binaries to install as .standalone') option('build-static', type : 'boolean', value : false, description : 'build static versions of supported binaries') diff --git a/src/repart/meson.build b/src/repart/meson.build index 1cff471087..364b34c6e9 100644 --- a/src/repart/meson.build +++ b/src/repart/meson.build @@ -21,7 +21,6 @@ executables += [ libopenssl_cflags, tpm2_cflags, ], - 'install' : have_standalone_binaries ? 'both' : 'yes', }, ] diff --git a/src/report/meson.build b/src/report/meson.build index 3eaf20a397..76182a4131 100644 --- a/src/report/meson.build +++ b/src/report/meson.build @@ -13,7 +13,6 @@ executables += [ 'dependencies' : [ libcurl_cflags, ], - 'install' : have_standalone_binaries ? 'both' : 'yes', }, libexec_template + { 'name' : 'systemd-report-basic', @@ -22,7 +21,6 @@ executables += [ 'report-basic.c', 'report-basic-server.c', ), - 'install' : have_standalone_binaries ? 'both' : 'yes', }, libexec_template + { 'name' : 'systemd-report-cgroup', @@ -30,7 +28,6 @@ executables += [ 'report-cgroup.c', 'report-cgroup-server.c', ), - 'install' : have_standalone_binaries ? 'both' : 'yes', }, libexec_template + { 'name' : 'systemd-report-files', @@ -38,7 +35,6 @@ executables += [ 'report-files.c', 'report-files-server.c', ), - 'install' : have_standalone_binaries ? 'both' : 'yes', }, libexec_template + { 'name' : 'systemd-report-sign-plain', @@ -47,13 +43,11 @@ executables += [ ), 'dependencies' : libopenssl_cflags, 'conditions' : ['HAVE_OPENSSL'], - 'install' : have_standalone_binaries ? 'both' : 'yes', }, libexec_template + { 'name' : 'systemd-report-sign-tsm', 'export' : files( 'report-sign-tsm.c', ), - 'install' : have_standalone_binaries ? 'both' : 'yes', }, ] diff --git a/src/shutdown/meson.build b/src/shutdown/meson.build index e9f4abeaa9..1545db92e5 100644 --- a/src/shutdown/meson.build +++ b/src/shutdown/meson.build @@ -19,7 +19,6 @@ executables += [ 'shutdown.c', ) + shutdown_detach_sources, 'dependencies' : libmount_cflags, - 'install' : have_standalone_binaries ? 'both' : 'yes', }, test_template + { 'sources' : files('test-umount.c') + diff --git a/src/sysusers/meson.build b/src/sysusers/meson.build index 4fc99bfb24..a8eff21bdc 100644 --- a/src/sysusers/meson.build +++ b/src/sysusers/meson.build @@ -10,6 +10,5 @@ executables += [ 'public' : true, 'export' : files('sysusers.c'), 'dependencies' : libaudit_cflags, - 'install' : have_standalone_binaries ? 'both' : 'yes', }, ] diff --git a/src/tmpfiles/meson.build b/src/tmpfiles/meson.build index 8c18190e12..c6f22f56ff 100644 --- a/src/tmpfiles/meson.build +++ b/src/tmpfiles/meson.build @@ -16,7 +16,6 @@ executables += [ libacl_cflags, libselinux_cflags, ], - 'install' : have_standalone_binaries ? 'both' : 'yes', }, test_template + { 'sources' : files('test-offline-passwd.c') + diff --git a/test/meson.build b/test/meson.build index 9fd1b55d61..df1a1671c0 100644 --- a/test/meson.build +++ b/test/meson.build @@ -16,7 +16,7 @@ if conf.get('ENABLE_SYSUSERS') == 1 env : test_env, suite : 'sysusers') - if have_standalone_binaries + if 'systemd-sysusers.standalone' in executables_by_name exe = executables_by_name.get('systemd-sysusers.standalone') test('test-sysusers.standalone', test_sysusers_sh, @@ -85,7 +85,7 @@ if want_tests != 'false' and conf.get('ENABLE_TMPFILES') == 1 depends : exe, suite : 'tmpfiles') - if have_standalone_binaries + if 'systemd-tmpfiles.standalone' in executables_by_name exe = executables_by_name.get('systemd-tmpfiles.standalone') test('test-systemd-tmpfiles.standalone', test_systemd_tmpfiles_py, From 55f52b1180bde549220fe9776a4cba09bc997110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Jul 2026 23:19:16 +0200 Subject: [PATCH 2/2] meson: stop registering .standalone in executables_by_name af4c5730e524c972994232259e5051b951142485 tried to have meson stop building all possible .standalone binaries in for tests. But it turns out that those binaries are still built for meson-test-prereq, because they are listed in executables_by_name, and we interate over executables_by_name and add all exes found there as dependencies for two tests: test-link-abi and libshared-unused-symbols. So we'd end up still building all the .standalone binaries. To really fix this, define the executables() for .standalone targets, but don't add them to this array. A secondary change is to set build_by_default to true for .standalone binaries if have_dlopen_tests is set. This means that we'll build more binaries in the "build" phase, instead of only building them "on demand" for tests. I think it is nicer to build everything that'll be used in one step, and then only run the tests in the test target. For example, tests may be run under root or in some special environment, and building thins there is iffy. The overall effect of this change should be that we stop building or testing .standalone variants for binaries that we'll not later install, unless -Ddlopen-tests=true is specified. Also exclude .standalone binaries from check-help test. The test fails for some binaries when the width is exceeded because of the ".standalone" suffix in the name. The actual binary would be called without the suffix, so the test is not testing a realistic scenario. --- meson.build | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/meson.build b/meson.build index e3d0b3c5a2..c5b3b7dfe8 100644 --- a/meson.build +++ b/meson.build @@ -1829,7 +1829,7 @@ fuzzer_exes = [] sources = [] # binaries that have --help and are intended for use by humans, -# usually, but not always, installed in /bin. +# usually, but not always, installed in /usr/bin. public_programs = [] # D-Bus introspection XML export @@ -2367,7 +2367,7 @@ foreach dict : executables install_shared = install == 'yes' install_static = install_shared and install_standalone build_by_default_shared = build_by_default - build_by_default_static = build_by_default and install_standalone + build_by_default_static = build_by_default and (install_standalone or want_dlopen_tests) elif install == 'static' if is_test or is_fuzz error('Install mode "@0@" is not supported for test or fuzzer target "@1@"'.format(install, name)) @@ -2444,9 +2444,9 @@ foreach dict : executables install: install_static, ) - executables_by_name += { name_static : exe_static } - if build_by_default_static + executables_by_name += { name_static : exe_static } + if dict.get('dbus', false) and not build_by_default_shared dbus_programs += exe_static endif @@ -2763,18 +2763,20 @@ endif foreach exec : public_programs name = fs.name(exec.full_path()) if want_tests != 'false' - test('check-help-' + name, - check_help_sh, - suite : 'dist', - args : exec.full_path(), - depends: exec) - test('check-version-' + name, check_version_sh, suite : 'dist', args : [exec.full_path(), project_major_version], depends: exec) + + if not name.endswith('.standalone') + test('check-help-' + name, + check_help_sh, + suite : 'dist', + args : exec.full_path(), + depends: exec) + endif endif endforeach