diff --git a/package/eudev/Config.in b/package/eudev/Config.in
index 0ee5390dfb..90b76917b4 100644
--- a/package/eudev/Config.in
+++ b/package/eudev/Config.in
@@ -6,6 +6,7 @@ config BR2_PACKAGE_EUDEV
 	depends on !BR2_STATIC_LIBS # kmod
 	select BR2_PACKAGE_HAS_UDEV
 	select BR2_PACKAGE_UTIL_LINUX
+	select BR2_PACKAGE_UTIL_LINUX_LIBS
 	select BR2_PACKAGE_UTIL_LINUX_LIBBLKID
 	select BR2_PACKAGE_KMOD
 	help
diff --git a/package/eudev/eudev.mk b/package/eudev/eudev.mk
index 6e4a047f07..aa658e37bb 100644
--- a/package/eudev/eudev.mk
+++ b/package/eudev/eudev.mk
@@ -18,7 +18,8 @@ EUDEV_CONF_OPTS = \
 	--enable-kmod \
 	--enable-blkid
 
-EUDEV_DEPENDENCIES = host-gperf host-pkgconf util-linux kmod
+# eudev requires only the util-linux libraries at build time
+EUDEV_DEPENDENCIES = host-gperf host-pkgconf util-linux-libs kmod
 EUDEV_PROVIDES = udev
 
 ifeq ($(BR2_ROOTFS_MERGED_USR),)
diff --git a/package/systemd/Config.in b/package/systemd/Config.in
index ad72a269ef..e8444e4e0b 100644
--- a/package/systemd/Config.in
+++ b/package/systemd/Config.in
@@ -23,6 +23,7 @@ menuconfig BR2_PACKAGE_SYSTEMD
 	select BR2_PACKAGE_DBUS # runtime dependency only
 	select BR2_PACKAGE_LIBCAP
 	select BR2_PACKAGE_UTIL_LINUX
+	select BR2_PACKAGE_UTIL_LINUX_LIBS
 	select BR2_PACKAGE_UTIL_LINUX_LIBBLKID
 	select BR2_PACKAGE_UTIL_LINUX_LIBMOUNT
 	select BR2_PACKAGE_UTIL_LINUX_BINARIES
diff --git a/package/systemd/systemd.mk b/package/systemd/systemd.mk
index 686886e345..d42773a018 100644
--- a/package/systemd/systemd.mk
+++ b/package/systemd/systemd.mk
@@ -14,7 +14,7 @@ SYSTEMD_DEPENDENCIES = \
 	host-gperf \
 	kmod \
 	libcap \
-	util-linux \
+	util-linux-libs \
 	$(TARGET_NLS_DEPENDENCIES)
 
 SYSTEMD_PROVIDES = udev
diff --git a/package/util-linux/Config.in b/package/util-linux/Config.in
index 39eb2c03a0..8049603fae 100644
--- a/package/util-linux/Config.in
+++ b/package/util-linux/Config.in
@@ -9,6 +9,9 @@ menuconfig BR2_PACKAGE_UTIL_LINUX
 
 if BR2_PACKAGE_UTIL_LINUX
 
+config BR2_PACKAGE_UTIL_LINUX_LIBS
+	bool
+
 config BR2_PACKAGE_UTIL_LINUX_LIBBLKID
 	bool "libblkid"
 	depends on BR2_USE_MMU # fork()
diff --git a/package/util-linux/util-linux-libs/util-linux-libs.hash b/package/util-linux/util-linux-libs/util-linux-libs.hash
new file mode 120000
index 0000000000..dc1b2f866a
--- /dev/null
+++ b/package/util-linux/util-linux-libs/util-linux-libs.hash
@@ -0,0 +1 @@
+../util-linux.hash
\ No newline at end of file
diff --git a/package/util-linux/util-linux-libs/util-linux-libs.mk b/package/util-linux/util-linux-libs/util-linux-libs.mk
new file mode 100644
index 0000000000..04fccf90c1
--- /dev/null
+++ b/package/util-linux/util-linux-libs/util-linux-libs.mk
@@ -0,0 +1,91 @@
+################################################################################
+#
+# util-linux-libs
+#
+################################################################################
+
+UTIL_LINUX_LIBS_VERSION = $(UTIL_LINUX_VERSION)
+UTIL_LINUX_LIBS_SOURCE = $(UTIL_LINUX_SOURCE)
+UTIL_LINUX_LIBS_SITE = $(UTIL_LINUX_SITE)
+UTIL_LINUX_LIBS_DL_SUBDIR = $(UTIL_LINUX_DL_SUBDIR)
+
+# README.licensing claims that some files are GPL-2.0 only, but this is not true.
+# Some files are GPL-3.0+ but only in tests. rfkill uses an ISC-style license.
+UTIL_LINUX_LIBS_LICENSE = LGPL-2.1+ (libblkid, libfdisk, libmount, libsmartcols), BSD-3-Clause (libuuid)
+UTIL_LINUX_LIBS_LICENSE_FILES = README.licensing \
+	Documentation/licenses/COPYING.BSD-3-Clause \
+	Documentation/licenses/COPYING.LGPL-2.1-or-later
+UTIL_LINUX_LIBS_INSTALL_STAGING = YES
+
+UTIL_LINUX_LIBS_DEPENDENCIES = host-pkgconf $(TARGET_NLS_DEPENDENCIES)
+UTIL_LINUX_LIBS_CONF_OPTS += \
+	--disable-rpath \
+	--disable-makeinstall-chown
+UTIL_LINUX_LIBS_LINK_LIBS = $(TARGET_NLS_LIBS)
+
+# systemd depends on util-linux so we enable systemd support
+# (which needs systemd to be installed)
+UTIL_LINUX_LIBS_CONF_OPTS += \
+	--without-systemd \
+	--with-systemdsystemunitdir=no
+
+HOST_UTIL_LINUX_LIBS_DEPENDENCIES = host-pkgconf
+HOST_UTIL_LINUX_LIBS_CONF_OPTS = --disable-makeinstall-chown
+
+# We also don't want the host-python dependency
+HOST_UTIL_LINUX_LIBS_CONF_OPTS += --without-python
+
+# Prevent the installation from attempting to move shared libraries from
+# ${usrlib_execdir} (/usr/lib) to ${libdir} (/lib), since both paths are
+# the same when merged usr is in use.
+ifeq ($(BR2_ROOTFS_MERGED_USR),y)
+UTIL_LINUX_LIBS_CONF_OPTS += --bindir=/usr/bin --sbindir=/usr/sbin --libdir=/usr/lib
+endif
+
+# Unfortunately, the util-linux does LIBS="" at the end of its
+# configure script. So we have to pass the proper LIBS value when
+# calling the configure script to make configure tests pass properly,
+# and then pass it again at build time.
+UTIL_LINUX_LIBS_CONF_ENV += LIBS="$(UTIL_LINUX_LIBS_LINK_LIBS)"
+UTIL_LINUX_LIBS_MAKE_OPTS += LIBS="$(UTIL_LINUX_LIBS_LINK_LIBS)"
+
+# libmount optionally uses selinux
+ifeq ($(BR2_PACKAGE_UTIL_LINUX_LIBMOUNT)$(BR2_PACKAGE_LIBSELINUX),yy)
+UTIL_LINUX_LIBS_DEPENDENCIES += libselinux
+UTIL_LINUX_LIBS_CONF_OPTS += --with-selinux
+else
+UTIL_LINUX_LIBS_CONF_OPTS += --without-selinux
+endif
+
+# Disable utilities
+UTIL_LINUX_LIBS_CONF_OPTS += \
+	--disable-all-programs \
+	$(if $(BR2_PACKAGE_UTIL_LINUX_LIBBLKID),--enable-libblkid,--disable-libblkid) \
+	$(if $(BR2_PACKAGE_UTIL_LINUX_LIBFDISK),--enable-libfdisk,--disable-libfdisk) \
+	$(if $(BR2_PACKAGE_UTIL_LINUX_LIBMOUNT),--enable-libmount,--disable-libmount) \
+	$(if $(BR2_PACKAGE_UTIL_LINUX_LIBSMARTCOLS),--enable-libsmartcols,--disable-libsmartcols) \
+	$(if $(BR2_PACKAGE_UTIL_LINUX_LIBUUID),--enable-libuuid,--disable-libuuid)
+
+# In the host version of util-linux-libs, we only require libuuid and libmount
+# (plus libblkid as an indirect dependency of libmount). So disable libfdisk
+# and libsmartcols, unless BR2_PACKAGE_HOST_UTIL_LINUX is set.
+HOST_UTIL_LINUX_LIBS_CONF_OPTS += \
+	--enable-libblkid \
+	$(if $(BR2_PACKAGE_HOST_UTIL_LINUX),--enable-libfdisk,--disable-libfdisk) \
+	--enable-libmount \
+	$(if $(BR2_PACKAGE_HOST_UTIL_LINUX),--enable-libsmartcols,--disable-libsmartcols) \
+	--enable-libuuid \
+	--without-ncurses \
+	--without-ncursesw \
+	--without-tinfo
+
+# Install libmount Python bindings
+ifeq ($(BR2_PACKAGE_UTIL_LINUX_LIBMOUNT)$(BR2_PACKAGE_PYTHON)$(BR2_PACKAGE_PYTHON3),yy)
+UTIL_LINUX_LIBS_CONF_OPTS += --with-python --enable-pylibmount
+UTIL_LINUX_LIBS_DEPENDENCIES += $(if $(BR2_PACKAGE_PYTHON),python,python3)
+else
+UTIL_LINUX_LIBS_CONF_OPTS += --without-python --disable-pylibmount
+endif
+
+$(eval $(autotools-package))
+$(eval $(host-autotools-package))
diff --git a/package/util-linux/util-linux.mk b/package/util-linux/util-linux.mk
index ecc3ab62de..330be6f8ee 100644
--- a/package/util-linux/util-linux.mk
+++ b/package/util-linux/util-linux.mk
@@ -19,18 +19,15 @@ UTIL_LINUX_LICENSE_FILES = README.licensing \
 	Documentation/licenses/COPYING.ISC \
 	Documentation/licenses/COPYING.LGPL-2.1-or-later
 UTIL_LINUX_INSTALL_STAGING = YES
-UTIL_LINUX_DEPENDENCIES = host-pkgconf $(TARGET_NLS_DEPENDENCIES)
+UTIL_LINUX_DEPENDENCIES = \
+	host-pkgconf \
+	$(if $(BR2_PACKAGE_UTIL_LINUX_LIBS),util-linux-libs) \
+	$(TARGET_NLS_DEPENDENCIES)
 UTIL_LINUX_CONF_OPTS += \
 	--disable-rpath \
 	--disable-makeinstall-chown
 UTIL_LINUX_LIBS = $(TARGET_NLS_LIBS)
 
-# system depends on util-linux so we enable systemd support
-# (which needs systemd to be installed)
-UTIL_LINUX_CONF_OPTS += \
-	--without-systemd \
-	--with-systemdsystemunitdir=no
-
 HOST_UTIL_LINUX_DEPENDENCIES = host-pkgconf
 
 # We also don't want the host-python dependency
@@ -43,6 +40,20 @@ ifeq ($(BR2_ROOTFS_MERGED_USR),y)
 UTIL_LINUX_CONF_OPTS += --bindir=/usr/bin --sbindir=/usr/sbin --libdir=/usr/lib
 endif
 
+ifeq ($(BR2_PACKAGE_SYSTEMD),y)
+UTIL_LINUX_CONF_OPTS += --with-systemd --with-systemdsystemunitdir=/usr/lib/systemd/system
+UTIL_LINUX_DEPENDENCIES += systemd
+else
+UTIL_LINUX_CONF_OPTS += --without-systemd --with-systemdsystemunitdir=no
+endif
+
+ifeq ($(BR2_PACKAGE_HAS_UDEV),y)
+UTIL_LINUX_CONF_OPTS += --with-udev
+UTIL_LINUX_DEPENDENCIES += udev
+else
+UTIL_LINUX_CONF_OPTS += --without-udev
+endif
+
 ifeq ($(BR2_PACKAGE_NCURSES),y)
 UTIL_LINUX_DEPENDENCIES += ncurses
 ifeq ($(BR2_PACKAGE_NCURSES_WCHAR),y)
@@ -258,3 +269,7 @@ UTIL_LINUX_POST_INSTALL_TARGET_HOOKS += UTIL_LINUX_GETTY_SYMLINK
 
 $(eval $(autotools-package))
 $(eval $(host-autotools-package))
+
+# Must be included after the autotools-package call, to make sure all variables
+# are available
+include package/util-linux/util-linux-libs/util-linux-libs.mk
