[meta-xilinx] [meta-xilinx-bsp][RFC] libmali: Use update-alternatives to switch between GL backends

Jean-Francois Dagenais jeff.dagenais at gmail.com
Thu Mar 14 06:20:33 PDT 2019


Hi guys,

Thanks for your work on this...

> On Mar 13, 2019, at 14:26, Manjukumar Matha <manjukumar.harthikote-matha at xilinx.com> wrote:
> 
> From: Alejandro Enedino Hernandez Samaniego <alejandr at xilinx.com>
> 
> libmali provides GL backends based on x11, fbdev and wayland,
> we should be able to switch between them at runtime since it is
> the same ABI, it should only be a matter of loading the correct
> shared library by the interpreter (dynamic linker).
> 
> Use the update-alternatives class, to provide a way for the user
> to choose the desired backend at runtime, do this by setting
> priorities, the package with the highest priority will be chosen
> as default at build time, but it can easily be changed at runtime
> afterwards.
> This change implies that the libmali package will install all

Nitpicking: missing line between above paragraph separation.

> backends regardless of which one was chosen, but it will only use
> one as default.
> 
> Use the x11 backend by default at build time; given that it is
> the same ABI, applications which depend on libmali, can build
> regardless of the chosen backend at build time.

Mh. Since it doesn't make a difference at build time, perhaps using the
"headless" backend would be the better, lowest dependency, choice.

> 
> Update-alternatives uses a set of commands on the postinst
> scripts when creating the root filesystem, which basically create
> the soft link between the chosen alternative and the binary/library.
> This usually works seamlessly (for binaries), but it does not in the
> case of libraries, because ldconfig is run at the end of the
> do_rootfs task, and it removes the link that was just created,
> it is important to note that this is simply normal ldconfig behavior
> and its not something we can fix, so we defer execution of
> update-alternatives until the first boot, hence avoiding the link
> removal by ldconfig.
> 
> Switching backends at build time will also help to avoid longer
> build times, since it will only invalidate the do_package task,
> rebuilding an image after switching a backend (at build time)
> should only execute the do_package task along with the do_rootfs
> task.

Hooray!

> 
> Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandr at xilinx.com>
> Signed-off-by: Manjukumar Matha <manjukumar.harthikote-matha at xilinx.com>
> ---
> .../recipes-graphics/libgles/libmali-xlnx.bb       | 101 ++++++++++++++-------
> 1 file changed, 67 insertions(+), 34 deletions(-)
> 
> diff --git a/meta-xilinx-bsp/recipes-graphics/libgles/libmali-xlnx.bb b/meta-xilinx-bsp/recipes-graphics/libgles/libmali-xlnx.bb
> index 504ea6d..7191c25 100644
> --- a/meta-xilinx-bsp/recipes-graphics/libgles/libmali-xlnx.bb
> +++ b/meta-xilinx-bsp/recipes-graphics/libgles/libmali-xlnx.bb
> @@ -4,9 +4,9 @@ LICENSE = "Proprietary"
> LICENSE_FLAGS = "xilinx"
> LIC_FILES_CHKSUM = "file://README.md;md5=d5750ae6496dd931669b454b5aaae2cd"
> 
> -inherit distro_features_check
> +inherit distro_features_check update-alternatives
> 
> -ANY_OF_DISTRO_FEATURES = "fbdev x11"
> +REQUIRED_DISTRO_FEATURES = "x11 fbdev wayland"
> 
> PROVIDES += "virtual/libgles1 virtual/libgles2 virtual/egl virtual/libgbm"
> 
> @@ -40,22 +40,14 @@ PACKAGE_ARCH = "${SOC_FAMILY}"
> 
> S = "${WORKDIR}/git"
> 
> -X11RDEPENDS = "libxdamage libxext libx11 libdrm libxfixes"
> -X11DEPENDS = "libxdamage libxext virtual/libx11 libdrm libxfixes"
> +# If were switching at runtime, we need all RDEPENDS needed for all backends available
> +RDEPENDS_${PN} = " kernel-module-mali libxdamage libxext libx11 libdrm libxfixes"

I believe this will install x11 libs in images even if one doesn't have "x11" in
DISTRO_FEATURES. This is my case and I would not use the recipe like this. I
would argue that typical embedded systems will choose in advance which of the
variant (x11, wayland, fbdev, headless) would be used and to keep things tight,
would expect unused libs and components not to make it to the rootfs. The cues
in DISTRO_FEATURES should be honoured as was the case in the recipe right now.

> 
> -RDEPENDS_${PN} = " \
> -	kernel-module-mali \
> -	${@bb.utils.contains('DISTRO_FEATURES', 'x11', '${X11RDEPENDS}', '', d)} \
> -	"
> +# We dont build anything but we want to avoid QA warning build-deps
> +DEPENDS = "wayland"

Won't this cause wayland libs to be built and installed on systems which don't
even have "wayland" in their DISTRO_FEATURES? I'm pretty sure there's a way to
clear those QA errors. I think the bin_package.bbclass is what you want here.
Certainly it is my opinion that since the recipe doesn't configure or compile it
doesn't need any extra DEPENDS, only RDEPENDS are required. If you use
bin_package.bbclass (and in any case in fact) the current "do_compile" should be
replaced by:

do_untar_bins() {
	# Extract the MALI binaries into workdir tar -xf
	${WORKDIR}/mali/rel-v2018.3/r8p0-01rel0.tar -C ${S}
} addtask untar_bins after do_unpack before do_install


> 
> -DEPENDS = "\
> -	${@bb.utils.contains('DISTRO_FEATURES', 'x11', '${X11DEPENDS}', '', d)} \
> -	${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'wayland libdrm', '', d)} \
> -	"
> -
> -USE_X11 = "${@bb.utils.contains("DISTRO_FEATURES", "x11", "yes", "no", d)}"
> -USE_FB = "${@bb.utils.contains("DISTRO_FEATURES", "fbdev", "yes", "no", d)}"
> -USE_WL = "${@bb.utils.contains("DISTRO_FEATURES", "wayland", "yes", "no", d)}"
> +# x11 is default, set to "fbdev" , "wayland", or "headless" if required
> +MALI_BACKEND_DEFAULT ?= "x11"
> 
> do_install() {
>     #Identify the ARCH type
> @@ -87,25 +79,66 @@ do_install() {
> 
>     cp -a --no-preserve=ownership ${S}/${PV}/${ARCH_PLATFORM_DIR}/common/*.so* ${D}${libdir}
> 
> -    if [ "${USE_WL}" = "yes" ]; then
> -	install -m 0644 ${S}/${PV}/glesHeaders/GBM/gbm.h ${D}${includedir}/
> -	install -m 0644 ${WORKDIR}/gbm.pc ${D}${libdir}/pkgconfig/gbm.pc
> -	install -Dm 0644 ${S}/${PV}/${ARCH_PLATFORM_DIR}/wayland/libMali.so.8.0 ${D}${libdir}/wayland/libMali.so.8.0
> -	ln -snf wayland/libMali.so.8.0 ${D}${libdir}/libMali.so.8.0
> -    elif [ "${USE_X11}" = "yes" ]; then
> -	install -Dm 0644 ${S}/${PV}/${ARCH_PLATFORM_DIR}/x11/libMali.so.8.0 ${D}${libdir}/x11/libMali.so.8.0
> -	ln -snf x11/libMali.so.8.0 ${D}${libdir}/libMali.so.8.0
> -    elif [ "${USE_FB}" = "yes" ]; then
> -	install -Dm 0644 ${S}/${PV}/${ARCH_PLATFORM_DIR}/fbdev/libMali.so.8.0 ${D}${libdir}/fbdev/libMali.so.8.0
> -	ln -snf fbdev/libMali.so.8.0 ${D}${libdir}/libMali.so.8.0
> -    else
> -	install -Dm 0644 ${S}/${PV}/${ARCH_PLATFORM_DIR}/headless/libMali.so.8.0 ${D}${libdir}/headless/libMali.so.8.0
> -	ln -snf headless/libMali.so.8.0 ${D}${libdir}/libMali.so.8.0
> -    fi

I would keep a similar mechanism here which skips unwanted variants of the lib,
for example if "x11" not in the DISTRO_FEATURES, it shouldn't even be installed.
The package will then be empty and be pruned (by default), which would be the
desired behaviour. So use just if's, no elif's.

> 
> -    if ${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'false', 'true', d)}; then
> -        sed -i -e 's/^#if defined(MESA_EGL_NO_X11_HEADERS)$/#if (1)/' ${D}${includedir}/EGL/eglplatform.h
> -    fi
> +    install -m 0644 ${S}/${PV}/glesHeaders/GBM/gbm.h ${D}${includedir}/
> +    install -m 0644 ${WORKDIR}/gbm.pc ${D}${libdir}/pkgconfig/gbm.pc
> +    install -Dm 0644 ${S}/${PV}/${ARCH_PLATFORM_DIR}/wayland/libMali.so.8.0 ${D}${libdir}/wayland/libMali.so.8.0
> +    install -Dm 0644 ${S}/${PV}/${ARCH_PLATFORM_DIR}/x11/libMali.so.8.0 ${D}${libdir}/x11/libMali.so.8.0
> +    install -Dm 0644 ${S}/${PV}/${ARCH_PLATFORM_DIR}/fbdev/libMali.so.8.0 ${D}${libdir}/fbdev/libMali.so.8.0
> +    install -Dm 0644 ${S}/${PV}/${ARCH_PLATFORM_DIR}/headless/libMali.so.8.0 ${D}${libdir}/headless/libMali.so.8.0
> +
> +    # We need to have one of the libraries available at build time for the linker
> +    ln -snf x11/libMali.so.8.0 ${D}${libdir}/libMali.so.8.0

A repeat of my above comment: use headless here instead? (Does it even matter?) 

> +}
> +
> +
> +# We need separate packages to provide multiple alternatives, at this point we install
> +# everything on the default one but that can be split if necessary
> +PACKAGES += "${PN}-x11 ${PN}-fbdev ${PN}-wayland ${PN}-headless"

This is good, I like the package split like that. The different runtime
dependencies for either x11 libs or wayland libs etc should be set on those
packages though. Something like: RDEPENDS_${PN}-wayland += "wayland
kernel-module-mali" RDEPENDS_${PN}-x11 += "X11 kernel-module-mali"

Also, I couldn't find the "FILES_${PN}-wayland = "${D}${libdir}/wayland ..." so
I don't understand how the package split does it's thing. Some other yocto-style
black magic?

> +
> +# This is default/common for all alternatives
> +ALTERNATIVE_LINK_NAME[libmali-xlnx] = "${libdir}/libMali.so.8.0"
> +
> +
> +# Declare alternatives and corresponding library location
> +ALTERNATIVE_${PN}-x11 = "libmali-xlnx"
> +ALTERNATIVE_TARGET_libmali-xlnx-x11[libmali-xlnx] = "${libdir}/x11/libMali.so.8.0"
> +
> +ALTERNATIVE_${PN}-fbdev = "libmali-xlnx"
> +ALTERNATIVE_TARGET_libmali-xlnx-fbdev[libmali-xlnx] = "${libdir}/fbdev/libMali.so.8.0"
> +
> +ALTERNATIVE_${PN}-wayland = "libmali-xlnx"
> +ALTERNATIVE_TARGET_libmali-xlnx-wayland[libmali-xlnx] = "${libdir}/wayland/libMali.so.8.0"
> +
> +ALTERNATIVE_${PN}-headless = "libmali-xlnx"
> +ALTERNATIVE_TARGET_libmali-xlnx-headless[libmali-xlnx] = "${libdir}/headless/libMali.so.8.0"
> +
> +# Set priorities according to what we prveiously defined
> +ALTERNATIVE_PRIORITY_libmali-xlnx-x11[libmali-xlnx] = "${@bb.utils.contains("MALI_BACKEND_DEFAULT", "x11", "20", "10", d)}"
> +ALTERNATIVE_PRIORITY_libmali-xlnx-fbdev[libmali-xlnx] = "${@bb.utils.contains("MALI_BACKEND_DEFAULT", "fbdev", "20", "10", d)}"
> +ALTERNATIVE_PRIORITY_libmali-xlnx-wayland[libmali-xlnx] = "${@bb.utils.contains("MALI_BACKEND_DEFAULT", "wayland", "20", "10", d)}"
> +ALTERNATIVE_PRIORITY_libmali-xlnx-headless[libmali-xlnx] = "${@bb.utils.contains("MALI_BACKEND_DEFAULT", "headless", "20", "10", d)}"
> +
> +
> +# Package gets renamed on the debian class, but we want to keep -xlnx
> +DEBIAN_NOAUTONAME_libmali-xlnx = "1"
> +
> +# Update alternatives will actually have separate postinst scripts (one for each package)
> +# This wont work for us, so we create a common postinst script and we pass that as the general
> +# libmali-xlnx postinst script, but we defer execution to run on first boot (pkg_postinst_ontarget).
> +# This will avoid ldconfig removing the symbolic links when creating the root filesystem.
> +python populate_packages_updatealternatives_append () {
> +    # We need to remove the 'fake' libmali-xlnx before creating any links
> +    libdir = d.getVar('libdir')
> +    common_postinst = "#!/bin/sh\nrm " + libdir + "/libMali.so.8.0\n"
> +    for pkg in (d.getVar('PACKAGES') or "").split():
> +        # Not all packages provide an alternative (e.g. ${PN}-lic)
> +        postinst = d.getVar('pkg_postinst_%s' % pkg)
> +        if postinst:
> +            old_postinst = postinst
> +            new_postinst = postinst.replace('#!/bin/sh','')
> +            common_postinst += new_postinst
> +    d.setVar('pkg_postinst_ontarget_%s' % 'libmali-xlnx', common_postinst)
> }
> 
> 
> -- 
> 2.7.4
> 
> -- 
> _______________________________________________
> meta-xilinx mailing list
> meta-xilinx at yoctoproject.org
> https://lists.yoctoproject.org/listinfo/meta-xilinx



More information about the meta-xilinx mailing list