package/util-linux: build programs and libraries in separate packages

The different tools and libraries in util-linux have a lot of optional
dependencies. When we want to support those optional dependencies, we
can easily generate dependency cycles. For instance, findmount and lsblk
need udev to work correctly, but eudev and systemd both depend libblkid,
which comes from util-linux.

Normal distros (e.g. Debian) solve this by first building a minimal
package that has no dependencies at all, then build the packages that
depend on util-linux, and finally rebuild util-linux with all bells and
whistles. Solve it in Buildroot by means of the following changes:

- Split util-linux into two packages:
  - util-linux-libs, providing lib{blkid,fdisk,mount,smartcols,uuid}.
  - util-linux, providing both the aforementioned libs and the programs.
- Add a blind selection for util-linux-libs, i.e. it is indirectly
  selected according to the util-linux options.
- Make host and target util-linux have a build dependencies on the -libs
  packages.
- Make eudev and systemd have build dependencies on util-linux-libs.
  This can be extended to other packages in the future but is not needed
  right now because the configuration options are backward-compatible.
- Make util-linux have an optional build dependency on the package that
  provides libudev (either eudev or systemd), if it is selected.

Installing util-linux overrides files installed by util-linux-libs but
this is not a problem: it's allowed for a package to overwrite files
from another package, as long as there is a dependency between the two.

util-linux-libs has a Config.in symbol for the package as a whole, but
not for the individual libraries: it simply reuses the symbols of the
full package.

The build dependency of util-linux on util-linux-libs ensures that
util-linux overwrites the files installed by util-linux-libs and not
vice versa. In practice this dependency shouldn't be needed: the only
reason for util-linux-libs to be built is to break a circular
dependency. In that case, there is already a transitive dependency of
util-linux on util-linux-libs, so adding it explicitly is redundant.
Still, better safe than sorry.

host-util-linux-libs is not needed at the moment. It can be added if we
have a dependency cycle problem later.

With this approach we don't need to patch configuration files neither
change packages other than eudev and systemd.

Other packages that require util-linux libraries and whose libraries may
be used by util-linux programs can be updated later. We also don't need
to change any existing defconfig, since all configuration options are
kept in the util-linux package.

Fixes: https://bugs.busybox.net/show_bug.cgi?id=11811

Signed-off-by: Carlos Santos <unixmania@gmail.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
This commit is contained in:
Carlos Santos 2019-09-29 11:01:35 -03:00 committed by Arnout Vandecappelle (Essensium/Mind)
parent d3370a48d5
commit 8bafc6dc8a
8 changed files with 120 additions and 9 deletions

View File

@ -7,6 +7,7 @@ config BR2_PACKAGE_EUDEV
select BR2_PACKAGE_HAS_UDEV
select BR2_PACKAGE_UDEV_GENTOO_SCRIPTS if BR2_INIT_OPENRC
select BR2_PACKAGE_UTIL_LINUX
select BR2_PACKAGE_UTIL_LINUX_LIBS
select BR2_PACKAGE_UTIL_LINUX_LIBBLKID
select BR2_PACKAGE_KMOD
help

View File

@ -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),)

View File

@ -28,6 +28,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_LIBMOUNT
select BR2_PACKAGE_UTIL_LINUX_AGETTY
select BR2_PACKAGE_UTIL_LINUX_MOUNT

View File

@ -15,7 +15,7 @@ SYSTEMD_DEPENDENCIES = \
host-gperf \
kmod \
libcap \
util-linux \
util-linux-libs \
$(TARGET_NLS_DEPENDENCIES)
SYSTEMD_PROVIDES = udev

View File

@ -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()

View File

@ -0,0 +1 @@
../util-linux.hash

View File

@ -0,0 +1,86 @@
################################################################################
#
# util-linux-libs
#
################################################################################
# Please keep this file as similar as possible to util-linux.mk
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 and optionally in hwclock
# (but we disable that option). rfkill uses an ISC-style license.
UTIL_LINUX_LIBS_LICENSE = LGPL-2.1+ (libblkid, libfdisk, libmount), 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)
# 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
# systemd depends on util-linux-libs so we disable systemd support
UTIL_LINUX_LIBS_CONF_OPTS += \
--without-systemd \
--with-systemdsystemunitdir=no
# systemd/eudev depend on util-linux-libs so we disable udev support
UTIL_LINUX_LIBS_CONF_OPTS += --without-udev
# No libs use wchar
UTIL_LINUX_LIBS_CONF_OPTS += --disable-widechar
# No libs use ncurses
UTIL_LINUX_LIBS_CONF_OPTS += --without-ncursesw --without-ncurses
# 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)
# libmount python bindings are separate, will be installed by full util-linux
UTIL_LINUX_LIBS_CONF_OPTS += --without-python --disable-pylibmount
# No libs use readline
UTIL_LINUX_LIBS_CONF_OPTS += --without-readline
# No libs use audit
UTIL_LINUX_LIBS_CONF_OPTS += --without-audit
$(eval $(autotools-package))

View File

@ -4,6 +4,9 @@
#
################################################################################
# When making changes to this file, please check if
# util-linux-libs/util-linux-libs.mk needs to be updated accordingly as well.
UTIL_LINUX_VERSION_MAJOR = 2.35
UTIL_LINUX_VERSION_MINOR = 2
UTIL_LINUX_VERSION = $(UTIL_LINUX_VERSION_MAJOR).$(UTIL_LINUX_VERSION_MINOR)
@ -22,19 +25,16 @@ UTIL_LINUX_LICENSE_FILES = README.licensing \
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
@ -50,6 +50,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)
@ -266,3 +280,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