Subject: [bug#74517] [PATCH 2/8] gnu: zbar: Split outputs.

From: Maxim Cournoyer <[email-masked]>
Date: Mon, 25 Nov 2024 12:04:39 +0900

Hi,

Nicolas Graves <[email-masked]> writes:

> * gnu/packages/aidc.scm (zbar): Split outputs.
> [build-system]: Switch to glib-or-gtk-build-system.
> [arguments]<#:configure-flags>: Add --disable-static.
> <#:modules>: Use srfi-26 and gremlin's file-runpath.
> <#:phases>: Add phase 'split-outputs.
> [native-inputs]: Improve style.
> [inputs]: Improve style. Replace v4l-utils by v4l-utils-minimal.
> ---
>  gnu/packages/aidc.scm | 94 +++++++++++++++++++++++++++++++++----------
>  1 file changed, 73 insertions(+), 21 deletions(-)

[...]

>  (define-public zxing-cpp
>    ;; Use the master branch as it includes unreleased build system improvements
> @@ -184,32 +187,81 @@ (define-public zbar
>           (commit version)))
>         (file-name (git-file-name name version))
>         (sha256
> -        (base32
> -         "0rf3i7lx0fqzxsngird6l4d4dnl612nr32rm8sib699qqx67px8n"))))
> -    (build-system gnu-build-system)
> +        (base32 "0rf3i7lx0fqzxsngird6l4d4dnl612nr32rm8sib699qqx67px8n"))))
> +    (build-system glib-or-gtk-build-system)
> +    ;; XXX: qt output is broken: zbarcam-qt fails with segmentation fault, but
> +    ;; this error happened before the output split.

As an alternative to packaging broken outputs, perhaps we could simply
tell the build system to not build with Qt, or wholly remove it from the
inputs?

> +    (outputs '("out" "gtk" "qt"))
>      (arguments
> -     '(#:configure-flags (list "--with-gtk=auto"
> +     (list
> +      #:configure-flags '(list "--disable-static"
> +                               "--with-gtk=auto"
>                                 "--with-python=auto"
>                                 (string-append "--with-dbusconfdir="
>                                                (assoc-ref %outputs "out")
> -                                              "/etc"))))
> +                                              "/etc"))
> +      #:modules `(((guix build gremlin) #:select (file-runpath))
> +                  (srfi srfi-26)
> +                  ,@%glib-or-gtk-build-system-modules)
> +      #:phases
> +      #~(modify-phases %standard-phases
> +          (add-after 'install 'split-outputs
> +            (lambda* (#:key outputs #:allow-other-keys)
> +              (let ((out (assoc-ref outputs "out"))
> +                    (gtk (assoc-ref outputs "gtk")))

This can be rewritten using the gexp variabls #$output and #$output:gtk.
> +
> +                ;; XXX: Using set-file-runpath leads to runpath-too-long-error
> +                (define (prepend-to-runpath path file)
> +                  (invoke "patchelf" "--set-rpath"
> +                          (string-join (cons* path (file-runpath file)) ":")
> +                          file))
> +
> +                (define (move-output-file target file)
> +                  (let* ((source (string-append out file))
> +                         (destination (string-append target file)))
> +                    (mkdir-p (dirname destination))
> +                    (rename-file source destination)
> +                    (when (and (eq? (stat:type (lstat destination)) 'regular)
> +                               (elf-file? destination))
> +                      (prepend-to-runpath
> +                       (string-append out "/lib:" target "/lib")
> +                       destination))))
> +
> +                (for-each
> +                 (lambda (kind)
> +                   (for-each
> +                    (cut move-output-file (assoc-ref outputs kind) <>)
> +                    (cons*
> +                     (string-append "/lib/pkgconfig/zbar-" kind ".pc")
> +                     (string-append "/bin/zbarcam-" kind)
> +                     (map (cut string-drop <> 1)
> +                          (with-directory-excursion out
> +                            (find-files
> +                             "./lib"
> +                             (string-append "lib.*" kind "\\.so.*")))))))
> +                 '("gtk" "qt"))
> +
> +                (for-each
> +                 (cut move-output-file gtk <>)
> +                 '("/share/gir-1.0" "/lib/girepository-1.0"))))))))

That is clever, perhaps too clever (in comparison to the simple brute
force approach of using a distinct minimal package variant built without
the extra inputs) :-).

>      (native-inputs
> -     `(("autoconf" ,autoconf)
> -       ("automake" ,automake)
> -       ("gettext" ,gettext-minimal)
> -       ("glib" ,glib "bin")
> -       ("gobject-introspection" ,gobject-introspection)
> -       ("libtool" ,libtool)
> -       ("pkg-config" ,pkg-config)
> -       ("python-wrapper" ,python-wrapper)))
> +     (list autoconf
> +           automake
> +           gettext-minimal
> +           `(,glib "bin")
> +           gobject-introspection
> +           libtool
> +           patchelf
> +           pkg-config
> +           python-wrapper))
>      (inputs
> -     `(("dbus" ,dbus)
> -       ("imagemagick" ,imagemagick)
> -       ("libjpeg" ,libjpeg-turbo)
> -       ("perl" ,perl)
> -       ("python" ,python)
> -       ("qtx11extras" ,qtx11extras)
> -       ("v4l-utils" ,v4l-utils)))
> +     (list dbus
> +           imagemagick
> +           libjpeg-turbo
> +           perl
> +           python
> +           qtx11extras
> +           v4l-utils-minimal))

Could be done in a separate commit; this entangles concern and makes it
easier if in the future a revert needs to be made.

-- 
Thanks,
Maxim