meson: Still build libshared even if libmount is disabled

Currently, if the libmount feature is disabled, we don't build
libshared and as a result skip building every other executable as
well. Among other things, this makes our nodeps CI builds kind of
pointless since hardly any code will be compiled.

Let's improve on the situation by making libmount properly optional
in libshared. Then, we only skip building the executables that
actually need libmount.
This commit is contained in:
Daan De Meyer
2025-11-24 10:57:58 +01:00
parent e910f9bc63
commit 7336f2c748
16 changed files with 138 additions and 44 deletions

View File

@@ -1163,8 +1163,9 @@ endif
libmount = dependency('mount',
version : fuzzer_build ? '>= 0' : '>= 2.30',
disabler : true,
required : get_option('libmount'))
have = libmount.found()
conf.set10('HAVE_LIBMOUNT', have)
libmount_cflags = libmount.partial_dependency(includes: true, compile_args: true)
libfdisk = dependency('fdisk',

View File

@@ -1,5 +1,36 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
load_fragment_gperf_gperf = custom_target(
input : 'load-fragment-gperf.gperf.in',
output: 'load-fragment-gperf.gperf',
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'])
libcore_build_dir = meson.current_build_dir()
core_includes = [includes, include_directories('.')]
systemd_pc = custom_target(
input : 'systemd.pc.in',
output : 'systemd.pc',
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : pkgconfigdatadir != 'no',
install_tag : 'devel',
install_dir : pkgconfigdatadir)
if conf.get('HAVE_LIBMOUNT') != 1
libcore = disabler()
core_test_template = test_template + {
'link_with' : [
libcore,
libshared,
],
'include_directories' : core_includes,
'suite' : 'core',
}
subdir_done()
endif
libcore_sources = files(
'audit-fd.c',
'automount.c',
@@ -84,11 +115,6 @@ endif
sources += libcore_sources
load_fragment_gperf_gperf = custom_target(
input : 'load-fragment-gperf.gperf.in',
output: 'load-fragment-gperf.gperf',
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'])
load_fragment_gperf_c = custom_target(
input : load_fragment_gperf_gperf,
output : 'load-fragment-gperf.c',
@@ -123,7 +149,6 @@ man_page_depends += bpf_delegate_xml
generated_sources += [load_fragment_gperf_c, load_fragment_gperf_nulstr_c, bpf_delegate_configs_inc]
libcore_sources += [load_fragment_gperf_c, load_fragment_gperf_nulstr_c, bpf_delegate_configs_inc]
libcore_build_dir = meson.current_build_dir()
libcore_name = 'systemd-core-@0@'.format(shared_lib_tag)
libcore_static = static_library(
@@ -155,8 +180,6 @@ libcore = shared_library(
install : true,
install_dir : pkglibdir)
core_includes = [includes, include_directories('.')]
systemd_sources = files(
'main.c',
'crash-handler.c',
@@ -257,14 +280,6 @@ foreach item : in_files
install_dir : dir)
endforeach
systemd_pc = custom_target(
input : 'systemd.pc.in',
output : 'systemd.pc',
command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : pkgconfigdatadir != 'no',
install_tag : 'devel',
install_dir : pkgconfigdatadir)
install_data('org.freedesktop.systemd1.conf',
install_dir : dbuspolicydir)
install_data('org.freedesktop.systemd1.service',

View File

@@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
executables += [
executable_template + {
'name' : 'systemd-creds',

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBCRYPTSETUP') != 1
if conf.get('HAVE_LIBCRYPTSETUP') != 1 or conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif

View File

@@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
executables += [
generator_template + {
'name' : 'systemd-fstab-generator',

View File

@@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
executables += [
executable_template + {
'name' : 'systemd-mount',

View File

@@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
executables += [
libexec_template + {
'name' : 'systemd-remount-fs',

View File

@@ -38,6 +38,7 @@ bool fstab_enabled_full(int enabled) {
}
int fstab_has_fstype(const char *fstype) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r;
@@ -65,6 +66,9 @@ int fstab_has_fstype(const char *fstype) {
if (streq_ptr(sym_mnt_fs_get_fstype(fs), fstype))
return true;
}
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
}
bool fstab_is_extrinsic(const char *mount, const char *opts) {
@@ -92,6 +96,7 @@ bool fstab_is_extrinsic(const char *mount, const char *opts) {
return false;
}
#if HAVE_LIBMOUNT
static int fstab_is_same_node(const char *what_fstab, const char *path) {
_cleanup_free_ char *node = NULL;
@@ -110,8 +115,10 @@ static int fstab_is_same_node(const char *what_fstab, const char *path) {
return false;
}
#endif
int fstab_has_mount_point_prefix_strv(char * const *prefixes) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r;
@@ -147,9 +154,13 @@ int fstab_has_mount_point_prefix_strv(char * const *prefixes) {
if (path_startswith_strv(path, prefixes))
return true;
}
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
}
int fstab_is_mount_point_full(const char *where, const char *path) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r;
@@ -184,6 +195,9 @@ int fstab_is_mount_point_full(const char *where, const char *path) {
if (r > 0 || (r < 0 && !ERRNO_IS_DEVICE_ABSENT(r)))
return r;
}
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
}
int fstab_filter_options(

View File

@@ -1,9 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "libmount-util.h"
#if HAVE_LIBMOUNT
#include <stdio.h>
#include "fstab-util.h"
#include "libmount-util.h"
#include "log.h"
static void *libmount_dl = NULL;
@@ -39,8 +41,10 @@ DLSYM_PROTOTYPE(mnt_table_parse_mtab) = NULL;
DLSYM_PROTOTYPE(mnt_table_parse_stream) = NULL;
DLSYM_PROTOTYPE(mnt_table_parse_swaps) = NULL;
DLSYM_PROTOTYPE(mnt_unref_monitor) = NULL;
#endif
int dlopen_libmount(void) {
#if HAVE_LIBMOUNT
ELF_NOTE_DLOPEN("mount",
"Support for mount enumeration",
ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
@@ -81,8 +85,12 @@ int dlopen_libmount(void) {
DLSYM_ARG(mnt_table_parse_stream),
DLSYM_ARG(mnt_table_parse_swaps),
DLSYM_ARG(mnt_unref_monitor));
#else
return -EOPNOTSUPP;
#endif
}
#if HAVE_LIBMOUNT
int libmount_parse_full(
const char *path,
FILE *source,
@@ -151,3 +159,4 @@ int libmount_is_leaf(
return r == 1;
}
#endif

View File

@@ -1,11 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "shared-forward.h"
#if HAVE_LIBMOUNT
/* This needs to be after sys/mount.h */
#include <libmount.h> /* IWYU pragma: export */
#include "dlfcn-util.h"
#include "shared-forward.h"
extern DLSYM_PROTOTYPE(mnt_free_iter);
extern DLSYM_PROTOTYPE(mnt_free_table);
@@ -39,8 +42,6 @@ extern DLSYM_PROTOTYPE(mnt_table_parse_stream);
extern DLSYM_PROTOTYPE(mnt_table_parse_swaps);
extern DLSYM_PROTOTYPE(mnt_unref_monitor);
int dlopen_libmount(void);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_table*, sym_mnt_free_table, mnt_free_tablep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_iter*, sym_mnt_free_iter, mnt_free_iterp, NULL);
@@ -55,14 +56,12 @@ static inline int libmount_parse_mountinfo(
FILE *source,
struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter) {
return libmount_parse_full("/proc/self/mountinfo", source, MNT_ITER_FORWARD, ret_table, ret_iter);
}
static inline int libmount_parse_with_utab(
struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter) {
return libmount_parse_full(NULL, NULL, MNT_ITER_FORWARD, ret_table, ret_iter);
}
@@ -71,3 +70,6 @@ int libmount_parse_fstab(struct libmnt_table **ret_table, struct libmnt_iter **r
int libmount_is_leaf(
struct libmnt_table *table,
struct libmnt_fs *fs);
#endif
int dlopen_libmount(void);

View File

@@ -38,6 +38,7 @@
#include "user-util.h"
int umount_recursive_full(const char *prefix, int flags, char **keep) {
#if HAVE_LIBMOUNT
_cleanup_fclose_ FILE *f = NULL;
int n = 0, r;
@@ -110,6 +111,9 @@ int umount_recursive_full(const char *prefix, int flags, char **keep) {
}
return n;
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
}
#define MS_CONVERTIBLE_FLAGS (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_NOSYMFOLLOW|MS_RELATIME|MS_NOATIME|MS_STRICTATIME|MS_NODIRATIME)
@@ -175,11 +179,6 @@ int bind_remount_recursive_with_mountinfo(
char **deny_list,
FILE *proc_self_mountinfo) {
_cleanup_fclose_ FILE *proc_self_mountinfo_opened = NULL;
_cleanup_set_free_ Set *done = NULL;
unsigned n_tries = 0;
int r;
assert(prefix);
if ((flags_mask & ~MS_CONVERTIBLE_FLAGS) == 0 && strv_isempty(deny_list) && !skip_mount_set_attr) {
@@ -206,6 +205,12 @@ int bind_remount_recursive_with_mountinfo(
return 0; /* Nice, this worked! */
}
#if HAVE_LIBMOUNT
_cleanup_fclose_ FILE *proc_self_mountinfo_opened = NULL;
_cleanup_set_free_ Set *done = NULL;
unsigned n_tries = 0;
int r;
if (!proc_self_mountinfo) {
r = fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo_opened);
if (r < 0)
@@ -404,6 +409,9 @@ int bind_remount_recursive_with_mountinfo(
log_trace("Remounted %s.", x);
}
}
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
}
int bind_remount_one_with_mountinfo(
@@ -412,12 +420,6 @@ int bind_remount_one_with_mountinfo(
unsigned long flags_mask,
FILE *proc_self_mountinfo) {
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
unsigned long flags = 0;
struct libmnt_fs *fs;
const char *opts;
int r;
assert(path);
assert(proc_self_mountinfo);
@@ -438,6 +440,13 @@ int bind_remount_one_with_mountinfo(
return 0; /* Nice, this worked! */
}
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
unsigned long flags = 0;
struct libmnt_fs *fs;
const char *opts;
int r;
rewind(proc_self_mountinfo);
r = dlopen_libmount();
@@ -481,6 +490,9 @@ int bind_remount_one_with_mountinfo(
}
return 0;
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
}
int bind_remount_one(const char *path, unsigned long new_flags, unsigned long flags_mask) {
@@ -859,6 +871,16 @@ int mount_option_mangle(
unsigned long *ret_mount_flags,
char **ret_remaining_options) {
assert(ret_mount_flags);
assert(ret_remaining_options);
if (!options) {
*ret_mount_flags = mount_flags;
*ret_remaining_options = NULL;
return 0;
}
#if HAVE_LIBMOUNT
const struct libmnt_optmap *map;
_cleanup_free_ char *ret = NULL;
int r;
@@ -876,9 +898,6 @@ int mount_option_mangle(
* The validity of options stored in '*ret_remaining_options' is not checked.
* If 'options' is NULL, this just copies 'mount_flags' to *ret_mount_flags. */
assert(ret_mount_flags);
assert(ret_remaining_options);
r = dlopen_libmount();
if (r < 0)
return r;
@@ -922,6 +941,9 @@ int mount_option_mangle(
*ret_remaining_options = TAKE_PTR(ret);
return 0;
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
}
static int mount_in_namespace_legacy(
@@ -1640,6 +1662,7 @@ void sub_mount_array_free(SubMount *s, size_t n) {
free(s);
}
#if HAVE_LIBMOUNT
static int sub_mount_compare(const SubMount *a, const SubMount *b) {
assert(a);
assert(b);
@@ -1659,9 +1682,10 @@ static void sub_mount_drop(SubMount *s, size_t n) {
m = i;
}
}
#endif
int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_mounts) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
SubMount *mounts = NULL;
@@ -1738,6 +1762,9 @@ int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_moun
*ret_mounts = TAKE_PTR(mounts);
*ret_n_mounts = n;
return 0;
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
}
int bind_mount_submounts(
@@ -2015,6 +2042,7 @@ int path_get_mount_info_at(
char **ret_options,
char **ret_source) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r, mnt_id;
@@ -2077,6 +2105,9 @@ int path_get_mount_info_at(
}
return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Cannot find mount ID %i from /proc/self/mountinfo.", mnt_id);
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
}
int path_is_network_fs_harder_at(int dir_fd, const char *path) {

View File

@@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
systemd_shutdown_sources = files(
'detach-dm.c',
'detach-loopback.c',

View File

@@ -349,6 +349,7 @@ executables += [
},
test_template + {
'sources' : files('test-libmount.c'),
'conditions' : ['HAVE_LIBMOUNT'],
'dependencies' : [
libmount_cflags,
threads,
@@ -368,6 +369,7 @@ executables += [
},
test_template + {
'sources' : files('test-mount-util.c'),
'conditions' : ['HAVE_LIBMOUNT'],
'dependencies' : libmount_cflags,
},
test_template + {

View File

@@ -54,7 +54,7 @@ static int run(int argc, char **argv) {
ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID);
ASSERT_DLOPEN(dlopen_libfido2, HAVE_LIBFIDO2);
ASSERT_DLOPEN(dlopen_libkmod, HAVE_KMOD);
ASSERT_DLOPEN(dlopen_libmount, true);
ASSERT_DLOPEN(dlopen_libmount, HAVE_LIBMOUNT);
ASSERT_DLOPEN(dlopen_libpam, HAVE_PAM);
ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP);
ASSERT_DLOPEN(dlopen_libselinux, HAVE_SELINUX);

View File

@@ -108,7 +108,7 @@ endif
############################################################
test_compare_versions_sh = files('test-compare-versions.sh')
if want_tests != 'false'
if want_tests != 'false' and executables_by_name.has_key('systemd-analyze')
exe = executables_by_name.get('systemd-analyze')
test('test-compare-versions',
test_compare_versions_sh,
@@ -151,7 +151,7 @@ endif
############################################################
test_fstab_generator_sh = files('test-fstab-generator.sh')
if want_tests != 'false'
if want_tests != 'false' and executables_by_name.has_key('systemd-fstab-generator')
exe = executables_by_name.get('systemd-fstab-generator')
test('test-fstab-generator',
test_fstab_generator_sh,

View File

@@ -331,8 +331,8 @@ def main():
print(item, file=sys.stderr)
sys.exit(77 if arguments.test else 1)
if not os.path.exists(f'{arguments.build_dir}/systemd'):
sys.exit(f"{arguments.build_dir}/systemd doesn't exist. Use --build-dir=.")
if not os.path.exists(f'{arguments.build_dir}'):
sys.exit(f"{arguments.build_dir} doesn't exist.")
missing_version = []
stats = {page.split('/')[-1] : process(page, missing_version) for page in arguments.pages}