TurboVNC / turbovnc

Main TurboVNC repository
https://TurboVNC.org
GNU General Public License v2.0
773 stars 139 forks source link

Build system issues found while packaging #339

Closed Apteryks closed 2 years ago

Apteryks commented 2 years ago

Hello, and thank you for this useful project.

Below, I share the package of turbovnc that I'll propose for inclusion in GNU Guix, a package manager that can be used on top of any GNU/Linux machine, similar in essence to Nix. I do not expect all the idiosyncracies of the Scheme/Guix language to be understood, but I'll document the parts where the build system failed.

(define-public turbovnc
  (package
    (name "turbovnc")
    (version "3.0.1")
    (source
     (origin
       (method url-fetch)
       (uri (string-append "mirror://sourceforge/turbovnc/" version
                           "/turbovnc-" version ".tar.gz"))
       (modules '((guix build utils)
                  (ice-9 ftw)
                  (srfi srfi-26)))
       (snippet
        #~(begin
            ;; TODO: Unbundle jsch and jzlib, bundled under java/com/jcraft/ as
            ;; well as mindrot and spf4j, bundled under java/org.  These are
            ;; used by the 'vncviewer' program.

It'd be nice if the big Java dependencies such as jsch could be used from the system.

            (define (directory? x)
              (and=> (stat x #f) (compose (cut eq? 'directory <>) stat:type)))

            (define (delete-all-but directory . preserve)
              (with-directory-excursion directory
                (let* ((pred (negate (cut member <> (append '("." "..")
                                                            preserve))))
                       (items (scandir "." pred)))
                  (for-each (lambda (item)
                              (if (directory? item)
                                  (delete-file-recursively item)
                                  (delete-file item)))
                            items))))

            ;; d3des, rfb (headers) and turbojpeg-jni are preserved, since they
            ;; are not packaged and fairly small.
            (delete-all-but "common" "d3des" "rfb" "turbojpeg-jni")
            ;; Delete bundled headers which aren't used.
            (delete-all-but "unix/Xvnc/include" "tvnc_version.h.in")
            ;; This 243 lines of code C library is used by
            ;; unix/Xvnc/programs/Xserver/os/xsha1.c.
            (delete-all-but "unix/Xvnc/lib" "CMakeLists.txt" "libsha1")
            (delete-file-recursively "unix/Xvnc/extras")))

The above cleans up (remove) the unused sources. This sometimes uncover issues such as the use of the bundled headers instead of the ones from the system (which it did; see below).

       (sha256
        (base32
         "182amp471qvr2cn2rbw97zpbkh9q7mf92w1r25cg4apx5k26m7c3"))))
    (build-system cmake-build-system)
    (arguments
     (list
      #:tests? #f                       ;no test suite
      #:configure-flags
      ;; Use system libraries.
      #~(list "-DTVNC_SYSTEMLIBS=1"
              "-DTVNC_SYSTEMX11=1"
              "-DTVNC_DLOPENSSL=0"
              (string-append "-DDRI_DRIVER_PATH="
                             (search-input-directory %build-inputs "lib/dri"))
              (string-append "-DXKB_BASE_DIRECTORY="
                             (search-input-directory %build-inputs
                                                     "share/X11/xkb"))
              ;; Help the build system to find the system pixman headers.
              (string-append "-DCMAKE_C_FLAGS=-I"
                             (search-input-directory %build-inputs
                                                     "include/pixman-1")))

After deleting the unused bundled sources, the pixman headers would be missing.

      #:phases
      #~(modify-phases %standard-phases
          (add-after 'unpack 'patch-build-system
            (lambda* (#:key inputs #:allow-other-keys)
              ;; The build system wrongly assumes that the Xfont2, fontenc and
              ;; pixman-1 libraries are installed in the same prefix as
              ;; libx11.
              (substitute* "unix/Xvnc/CMakeLists.txt"
                (("string\\(REGEX REPLACE.*X11_Xfont2_LIB.*")
                 (format #f "set(X11_Xfont2_LIB ~a)~%"
                         (search-input-file inputs "lib/libXfont2.so")))
                (("string\\(REGEX REPLACE.*X11_Fontenc_LIB.*")
                 (format #f "set(X11_Fontenc_LIB ~a)~%"
                         (search-input-file inputs "lib/libfontenc.so")))
                (("string\\(REGEX REPLACE.*X11_Pixman_LIB.*")
                 (format #f "set(X11_Pixman_LIB ~a)~%"
                         (search-input-file inputs "lib/libpixman-1.so"))))

These should be searched by CMake independently rather than assumed to live where Xorg is.

              (substitute* "unix/Xvnc/programs/Xserver/CMakeLists.txt"
                ;; The default rule file name must have changed from 'xorg' to
                ;; 'base' for xkeyboard-config.  Without this change, running
                ;; Xvnc would fail with the error "XKB: Failed to compile
                ;; keymap"
                (("set\\(DEFAULT_XKB_DFLT_RULES.*)")
                 "set(DEFAULT_XKB_DFLT_RULES \"base\")")
                ;; XXX: This somehow overrides the user-specified
                ;; XKB_BASE_DIRECTORY.
                (("set\\(DEFAULT_XKB_BASE_DIRECTORY .*)")
                 (format #f "set(DEFAULT_XKB_BASE_DIRECTORY \"~a\")"
                         (search-input-directory inputs "share/X11/xkb")))
                (("set\\(DEFAULT_XKB_BIN_DIRECTORY .*)")
                 (format #f "set(DEFAULT_XKB_BIN_DIRECTORY \"~a\")"
                         (dirname (search-input-file inputs
                                                     "bin/xkbcomp")))))
              (substitute* "unix/Xvnc/programs/Xserver/dix/CMakeLists.txt"
                ;; This is needed, otherwise the same error as above would
                ;; occur.  Mimic xorg-server's "--with-xkb-output=/tmp"
                ;; configuration.
                (("-DCOMPILEDDEFAULTFONTPATH=\".*\"")
                 "-DCOMPILEDDEFAULTFONTPATH=/tmp"))))

It'd be nice if we could set them from CMake (top level) directly. They should honor what the user specified.

The rest is pretty Guix-specific, similar to what Nix does or other functional (non-FHS) package manager would need to do.

          (add-after 'unpack 'patch-vncviewer
            (lambda* (#:key inputs #:allow-other-keys)
              (define openjdk #$(this-package-input "openjdk"))
              (substitute* "unix/vncviewer/vncviewer.in"
                (("\\$BINDIR/../java/jre")
                 openjdk)
                ;; Avoid resorting to grep and sed to locate libjawt.so.
                (("^_TMP=.*")
                 (string-append "_TMP=" openjdk "/lib\n")))))
          (add-after 'unpack 'patch-vncserver
            (lambda* (#:key inputs #:allow-other-keys)
              (substitute* "unix/vncserver.in"
                ;; Add sane Guix System default locations for X11 fonts.
                (("'/usr/share/X11/fonts'" all)
                 (format #f "'~a', '~a', ~a"
                         "/run/current-system/profile/share/fonts/X11"
                         (string-append #$(this-package-input "font-alias")
                                        "share/fonts/X11")
                         all))
                ;; Add sane Guix System default locations for XKB layouts.
                ;; Note: the directory must be appended to the list, as the
                ;; last one to be searched wins.
                (("'/opt/X11/share/X11/xkb'" all)
                 (format #f "~a, '~a/share/X11/xkb', '~a'"
                         all #$(this-package-input "xkeyboard-config")
                         "/run/current-system/profile/share/X11/xkb"))
                ;; Likewise for the xkbcompdirs.
                (("'/opt/X11/bin'" all)
                 (format #f "~a, '~a'" all
                         (dirname (search-input-file inputs "bin/xkbcomp"))))
                ;; Likewise for dridirs.
                (("push\\(@dridirs, '/usr/local/lib/dri').*" all)
                 (format #f "~apush(@dridirs, '~a');~%" all
                         (dirname (search-input-file
                                   inputs "lib/dri/swrast_dri.so"))))
                ;; Likewise for registrydirs.
                (("push\\(@registrydirs, '/opt/X11/lib/xorg').*" all)
                 (format #f "~apush(@registrydirs, '~a');~%" all
                         (dirname (search-input-file
                                   inputs "lib/xorg/protocol.txt")))))))
          (add-after 'unpack 'patch-xstartup.turbovnc
            (lambda* (#:key inputs #:allow-other-keys)
              (substitute* "unix/xstartup.turbovnc"
                (("DBUS_LAUNCH=[[:graph:]]+")
                 (format #f "DBUS_LAUNCH=~a"
                         (search-input-file inputs "bin/dbus-launch")))
                (("XSESSIONSDIR=[[:graph:]]+")
                 (format #f "XSESSIONSDIR=~a"
                         "/run/current-system/profile/share/xsessions"))
                (("GREP=[[:graph:]]+")
                 (format #f "GREP=~a"
                         (search-input-file inputs "bin/grep")))
                (("SED=[[:graph:]]+")
                 (format #f "SED=~a"
                         (search-input-file inputs "bin/sed")))
                ;; There's no /etc/X11/xinit/Xsession file on Guix System, so
                ;; attempt a better guess.
                (("XSESSION=[[:graph:]]+")
                 "XSESSION=$HOME/.xsession")
                (("TVNC_SSHAGENT=[[:graph:]]+")
                 (format #f "TVNC_SSHAGENT=~a"
                         (search-input-file inputs "bin/ssh-agent")))
                (("TVNC_VGLRUN=\"vglrun" all)
                 (string-append "TVNC_VGLRUN="
                                (search-input-file inputs "bin/vglrun") all)))))
          (add-after 'install 'wrap-vncserver
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (wrap-script (search-input-file outputs "bin/vncserver")
                (list "PATH" 'prefix
                      (map (lambda (p)
                             (dirname (search-input-file inputs p)))
                           '("bin/uname" ;coreutils
                             "bin/xauth"
                             "bin/xdpyinfo"))))))
          (add-after 'install 'wrap-xstartup.turbovnc
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (wrap-script (search-input-file outputs "bin/xstartup.turbovnc")
                (list "PATH" 'prefix
                      (map (lambda (p)
                             (dirname (search-input-file inputs p)))
                           '("bin/uname" ;coreutils
                             ;; These are used as the fallback when no desktop
                             ;; session was found.
                             "bin/twm"
                             "bin/xsetroot"
                             "bin/xterm")))))))))
    (native-inputs (list `(,openjdk "jdk") python))
    (inputs
     (list dbus
           font-alias
           freetype
           guile-3.0
           libfontenc
           libjpeg-turbo
           libx11
           libxdamage
           libxext
           libxfont2
           libxi
           libxkbfile
           linux-pam
           mesa
           openjdk
           openssh
           openssl
           perl
           pixman
           twm
           virtualgl
           xauth
           xdpyinfo
           xkbcomp
           xkeyboard-config
           xorg-server
           xorgproto
           xsetroot
           xterm
           xtrans
           zlib))
    (home-page "https://turbovnc.org/")
    (synopsis "TightVNC-compatible remote desktop software")
    (description "TurboVNC is a high-speed version of VNC derived from
TightVNC.  It contains a variant of Tight encoding that is tuned to maximize
performance for image-intensive applications (such as VirtualGL, video
applications, and image editors) while still providing excellent performance
for other types of applications.")
    (license license:gpl2+)))
dcommander commented 2 years ago

It'd be nice if the big Java dependencies such as jsch could be used from the system.

Several issues with that:

  1. I am unaware of any operating system that provides JSch or the other Java dependencies.
  2. Java JAR files are not like shared libraries in that they don't provide a means for API/ABI versioning. Thus, even if the operating system provided all of the Java dependencies, there would be no sane way for the TurboVNC Viewer to ensure that the system's version of those dependencies had the necessary interfaces.
  3. Since the original JSch source base is unmaintained, I had to add some features to it in order to support the TurboVNC Viewer, and I have since ported additional features from the JSch fork that is actively maintained. Thus, TurboVNC's version of JSch exists only in TurboVNC. It is so tightly integrated into the viewer that trying to support arbitrary external versions of it would be a nightmare, even if such were possible.

For those reasons, it is best to imagine the Java dependencies as an inseparable part of the TurboVNC Viewer source code, which is how they are treated. For a variety of other reasons, the usage of the TurboVNC Viewer requires that VncViewer.jar be fully self-contained.

        ;; d3des, rfb (headers) and turbojpeg-jni are preserved, since they
        ;; are not packaged and fairly small.

More importantly, they are critical to the correct operation of TurboVNC and are not provided by external libraries. TurboVNC has quite a few internal libraries and headers that are intentional and inseparable.

  ;; Use system libraries.
  #~(list "-DTVNC_SYSTEMLIBS=1"
          "-DTVNC_SYSTEMX11=1"
          "-DTVNC_DLOPENSSL=0"

You should also set TJPEG_INCLUDE_DIR and TJPEG_LIBRARY (for example, to /usr/include and -lturbojpeg, respectively) in order to link dynamically with the system's installation of libjpeg-turbo. The default is to link statically with an installation of the official libjpeg-turbo SDK under /opt/libjpeg-turbo. Also, you probably want to pass -DTVNC_INCLUDEJRE=0 to prevent the build system from embedding a JRE into the TurboVNC installation directory, which is unnecessary if you are using the system's JRE.

          (string-append "-DDRI_DRIVER_PATH="
                         (search-input-directory %build-inputs "lib/dri"))
          (string-append "-DXKB_BASE_DIRECTORY="
                         (search-input-directory %build-inputs
                                                 "share/X11/xkb"))

It's unclear what %build-inputs is, but those two directories are supposed to point to a system location, such as a directory under /usr/share/X11. You should also set FONT_ENCODINGS_DIRECTORY and SERVER_MISC_CONFIG_PATH, if those differ from their default values.

          ;; Help the build system to find the system pixman headers.
          (string-append "-DCMAKE_C_FLAGS=-I"
                         (search-input-directory %build-inputs
                                                 "include/pixman-1")))


After deleting the unused bundled sources, the pixman headers would be missing.

I see that issue and will fix it.

            (("string\\(REGEX REPLACE.*X11_Xfont2_LIB.*")
             (format #f "set(X11_Xfont2_LIB ~a)~%"
                     (search-input-file inputs "lib/libXfont2.so")))
            (("string\\(REGEX REPLACE.*X11_Fontenc_LIB.*")
             (format #f "set(X11_Fontenc_LIB ~a)~%"
                     (search-input-file inputs "lib/libfontenc.so")))
            (("string\\(REGEX REPLACE.*X11_Pixman_LIB.*")
             (format #f "set(X11_Pixman_LIB ~a)~%"
                     (search-input-file inputs "lib/libpixman-1.so"))))


These should be searched by CMake independently rather than assumed to live where Xorg is.

Are there any systems that install those libraries in a different directory than the one in which libX11 is installed? I have never seen such a system.

          (substitute* "unix/Xvnc/programs/Xserver/CMakeLists.txt"
            ;; The default rule file name must have changed from 'xorg' to
            ;; 'base' for xkeyboard-config.  Without this change, running
            ;; Xvnc would fail with the error "XKB: Failed to compile
            ;; keymap"
            (("set\\(DEFAULT_XKB_DFLT_RULES.*)")
             "set(DEFAULT_XKB_DFLT_RULES \"base\")")
            ;; XXX: This somehow overrides the user-specified
            ;; XKB_BASE_DIRECTORY.
            (("set\\(DEFAULT_XKB_BASE_DIRECTORY .*)")
             (format #f "set(DEFAULT_XKB_BASE_DIRECTORY \"~a\")"
                     (search-input-directory inputs "share/X11/xkb")))
            (("set\\(DEFAULT_XKB_BIN_DIRECTORY .*)")
             (format #f "set(DEFAULT_XKB_BIN_DIRECTORY \"~a\")"
                     (dirname (search-input-file inputs
                                                 "bin/xkbcomp")))))
          (substitute* "unix/Xvnc/programs/Xserver/dix/CMakeLists.txt"
            ;; This is needed, otherwise the same error as above would
            ;; occur.  Mimic xorg-server's "--with-xkb-output=/tmp"
            ;; configuration.
            (("-DCOMPILEDDEFAULTFONTPATH=\".*\"")
             "-DCOMPILEDDEFAULTFONTPATH=/tmp"))))


It'd be nice if we could set them from CMake (top level) directly. They should honor what the user specified.

The build system provides CMake variables (XKB_BASE_DIRECTORY, XKB_BIN_DIRECTORY, XKB_DFLT_LAYOUT, XKB_DFLT_MODEL, XKB_DEFAULT_OPTIONS, XKB_DFLT_RULES, XKB_DFLT_VARIANT) for precisely that purpose. Are those insufficient?

      (add-after 'unpack 'patch-vncviewer
        (lambda* (#:key inputs #:allow-other-keys)
          (define openjdk #$(this-package-input "openjdk"))
          (substitute* "unix/vncviewer/vncviewer.in"
            (("\\$BINDIR/../java/jre")
             openjdk)

This is unnecessary. Just build with -DTVNC_INCLUDEJRE=0.

            ;; Avoid resorting to grep and sed to locate libjawt.so.
            (("^_TMP=.*")
             (string-append "_TMP=" openjdk "/lib\n")))))

I don't know what you mean by resorting to grep and sed, but the vncviewer script finds libjawt.so by querying the JRE for the location of that library. It shouldn't be necessary to muck with that.

      (add-after 'unpack 'patch-vncserver
        (lambda* (#:key inputs #:allow-other-keys)
          (substitute* "unix/vncserver.in"
            ;; Add sane Guix System default locations for X11 fonts.
            (("'/usr/share/X11/fonts'" all)
             (format #f "'~a', '~a', ~a"
                     "/run/current-system/profile/share/fonts/X11"
                     (string-append #$(this-package-input "font-alias")
                                    "share/fonts/X11")
                     all))
            ;; Add sane Guix System default locations for XKB layouts.
            ;; Note: the directory must be appended to the list, as the
            ;; last one to be searched wins.
            (("'/opt/X11/share/X11/xkb'" all)
             (format #f "~a, '~a/share/X11/xkb', '~a'"
                     all #$(this-package-input "xkeyboard-config")
                     "/run/current-system/profile/share/X11/xkb"))
            ;; Likewise for the xkbcompdirs.
            (("'/opt/X11/bin'" all)
             (format #f "~a, '~a'" all
                     (dirname (search-input-file inputs "bin/xkbcomp"))))
            ;; Likewise for dridirs.
            (("push\\(@dridirs, '/usr/local/lib/dri').*" all)
             (format #f "~apush(@dridirs, '~a');~%" all
                     (dirname (search-input-file
                               inputs "lib/dri/swrast_dri.so"))))
            ;; Likewise for registrydirs.
            (("push\\(@registrydirs, '/opt/X11/lib/xorg').*" all)
             (format #f "~apush(@registrydirs, '~a');~%" all
                     (dirname (search-input-file
                               inputs "lib/xorg/protocol.txt")))))))

Does Guix somehow know the correct locations of all of those directories for every distribution on which it can run? If so, then this seems like it should be best handled by introducing specific CMake variables or even making vncserver Guix-aware. But if you're just searching the operating system for the correct directories, then I don't see the advantage of doing that at build time rather than at run time, as vncserver already does.

      (add-after 'unpack 'patch-xstartup.turbovnc
        (lambda* (#:key inputs #:allow-other-keys)
          (substitute* "unix/xstartup.turbovnc"
            (("DBUS_LAUNCH=[[:graph:]]+")
             (format #f "DBUS_LAUNCH=~a"
                     (search-input-file inputs "bin/dbus-launch")))
            (("XSESSIONSDIR=[[:graph:]]+")
             (format #f "XSESSIONSDIR=~a"
                     "/run/current-system/profile/share/xsessions"))
            (("GREP=[[:graph:]]+")
             (format #f "GREP=~a"
                     (search-input-file inputs "bin/grep")))
            (("SED=[[:graph:]]+")
             (format #f "SED=~a"
                     (search-input-file inputs "bin/sed")))

Do these really need to be different than the defaults set by xstartup.turbovnc? If so, then it's probably also best handled by introducing new CMake variables.

            ;; There's no /etc/X11/xinit/Xsession file on Guix System, so
            ;; attempt a better guess.
            (("XSESSION=[[:graph:]]+")
             "XSESSION=$HOME/.xsession")

This is not the correct approach. If there is no Xsession script, then XSESSION should be blank. In the unmodified xstartup.turbovnc script, XSESSION will be blank if neither /etc/X11/xinit/Xsession nor /etc/X11/Xsession exists.

            (("TVNC_SSHAGENT=[[:graph:]]+")
             (format #f "TVNC_SSHAGENT=~a"
                     (search-input-file inputs "bin/ssh-agent")))
            (("TVNC_VGLRUN=\"vglrun" all)
             (string-append "TVNC_VGLRUN="
                            (search-input-file inputs "bin/vglrun") all)))))

Similar comment to above: Are there any systems on which these files are not installed under /usr/bin? Unless this fixes a specific problem with a specific system, then why do it? Any changes I make to xstartup.turbovnc would likely break this.

(synopsis "TightVNC-compatible remote desktop software")
(description "TurboVNC is a high-speed version of VNC derived from

TightVNC. It contains a variant of Tight encoding that is tuned to maximize performance for image-intensive applications (such as VirtualGL, video applications, and image editors) while still providing excellent performance for other types of applications.")

Can you use the summary from our own packages? The synopsis above makes it sound like we're just a TightVNC clone.

Apteryks commented 2 years ago

Hi, and thanks for your feedback.

Sorry if the formatting is not great, I'd be more at ease if I could have replied by email directly (does Github handle that correctly?).

About using system-provided Java libraries:

Several issues with that:

I am unaware of any operating system that provides JSch or the other Java dependencies.

Guix has one: guix show java-jsch:

name: java-jsch
version: 0.1.55
outputs:
+ out: everything else
systems: x86_64-linux
dependencies: unzip@6.0
location: gnu/packages/java.scm:6850:2
homepage: http://www.jcraft.com/jsch/
license: Modified BSD
synopsis: Pure Java implementation of SSH2  
description: JSch is a pure Java implementation of SSH2.  JSch allows you to connect to an SSH server
+ and use port forwarding, X11 forwarding, file transfer, etc., and you can integrate its functionality
+ into your own Java programs.

Java JAR files are not like shared libraries in that they don't provide a means for API/ABI versioning. Thus, even if the operating system provided all of the Java dependencies, there would be no sane way for the TurboVNC Viewer to ensure that the system's version of those dependencies had the necessary interfaces.

That would be true for a traditional distribution, but not for those based on functional package managing like Guix, which effectively captures the exact dependency graph (and ensures dependents get rebuilt when any of their dependency changes).

Since the original JSch source base is unmaintained, I had to add some features to it in order to support the TurboVNC Viewer, and I have since ported additional features from the JSch fork that is actively maintained. Thus, TurboVNC's version of JSch exists only in TurboVNC. It is so tightly integrated into the viewer that trying to support arbitrary external versions of it would be a nightmare, even if such were possible.

OK, thanks for the information. I had assumed the bundled libraries were stock.

[...]

You should also set TJPEG_INCLUDE_DIR and TJPEG_LIBRARY (for example, to /usr/include and -lturbojpeg, respectively) in order to link dynamically with the system's installation of libjpeg-turbo.

The build system seems to handle that correctly without my intervention:

-- TJPEG_INCLUDE_DIR = /gnu/store/g5hf1zhqlcyx9vw3q1xa52bgddaqsfm5-libjpeg-turbo-2.0.5/include
-- Performing Test TURBOJPEG_WORKS
-- Performing Test TURBOJPEG_WORKS - Failed
-- Could not link with official TurboJPEG library /opt/libjpeg-turbo/lib64/libturbojpeg.a.  Checking whether the operating system supplies it ...
-- Performing Test SYSTEM_TURBOJPEG_WORKS
-- Performing Test SYSTEM_TURBOJPEG_WORKS - Success
-- TJPEG_LIBRARY = turbojpeg

Also, you probably want to pass -DTVNC_INCLUDEJRE=0 to prevent the build system from embedding a JRE into the TurboVNC installation directory, which is unnecessary if you are using the system's JRE.

This also:

Custom JRE disabled (TVNC_INCLUDEJRE = OFF)

It's unclear what %build-inputs is, but those two directories are supposed to point to a system location, such as a directory under /usr/share/X11. You should also set FONT_ENCODINGS_DIRECTORY and SERVER_MISC_CONFIG_PATH, if those differ from their default values.

There's no system file hierarchy on Guix as on most traditional GNU/Linux distributions; there's a system profile with a few things installed/propagated there by default, but xorg/xkb is not exposed as such. Hence, we directly refer to the locations of the packages that provide files; e.g. /gnu/store/8mszv7v6kqdyavpvf8zb7kkagaan5vri-xkeyboard-config-2.34/share/X11/xkb for the XKB_BASE_DIRECTORY. I've now given a value to SERVER_MISC_CONFIG_PATH; I don't use the bundled libfontenc package, so FONT_ENCODINGS_DIRECTORY is not needed.

[...]

Are there any systems that install those libraries in a different directory than the one in which libX11 is installed? I have never seen such a system.

Welcome to this new era of functional package management, where each package has a dedicated, unique prefix derived from its content:

$ guix build libxfont libfontenc pixman libx11
/gnu/store/7r3wb90mwfandbflikn60xa1v4vl9xm4-libx11-1.7.3.1-doc
/gnu/store/fa43ijbrb96x08621qigxxiphp503lsi-libx11-1.7.3.1
/gnu/store/j8x167zaka2h6pxk7wiq5zkg67hzf8a2-pixman-0.40.0
/gnu/store/v6ymi501n3dvqvsgngmskn6z2gfaj4sm-libfontenc-1.1.4
/gnu/store/hyfnp6p82hxpbj5mcgyw7nfh3fk68vpv-libxfont-2.0.4

$ tree /gnu/store/hyfnp6p82hxpbj5mcgyw7nfh3fk68vpv-libxfont-2.0.4
/gnu/store/hyfnp6p82hxpbj5mcgyw7nfh3fk68vpv-libxfont-2.0.4
├── include
│   └── X11
│       └── fonts
│           └── libxfont2.h
├── lib
│   ├── libXfont2.la
│   ├── libXfont2.so -> libXfont2.so.2.0.0
│   ├── libXfont2.so.2 -> libXfont2.so.2.0.0
│   ├── libXfont2.so.2.0.0
│   └── pkgconfig
│       └── xfont2.pc
└── share
    └── doc
        └── libxfont-2.0.4
            └── COPYING

It's a rather daring leap from the FHS, but it opens a whole new class of opportunities (and yes, a few challenges :-)). I only know NixOS and Guix System as distributions based on a functional package manager, but there may be others.

[...]

The build system provides CMake variables (XKB_BASE_DIRECTORY, XKB_BIN_DIRECTORY, XKB_DFLT_LAYOUT, XKB_DFLT_MODEL, XKB_DEFAULT_OPTIONS, XKB_DFLT_RULES, XKB_DFLT_VARIANT) for precisely that purpose. Are those insufficient?

I previously thought I had experienced that passing -DXKB_BASE_DIRECTORY=... macro to CMake would not be honored, but this was a mistake on my side. Thanks for spotting it!

[...] About vncviewer:

This is unnecessary. Just build with -DTVNC_INCLUDEJRE=0. I'm using this hack to fix the value of JAVA to the exact reference of java, so that it can be used without being on PATH.

[...]

I don't know what you mean by resorting to grep and sed, but the vncviewer script finds libjawt.so by querying the JRE for the location of that library. It shouldn't be necessary to muck with that.

I meant that _TMP=$JAVA -XshowSettings:properties -version 2>&1 | grep sun.boot.library.path | sed s/.*=\ //g`` is a bit complex and requires grep and sed to be on PATH when I can readily point it to the absolute location of that libjawt.so library at build time :-).

[...]

Does Guix somehow know the correct locations of all of those directories for every distribution on which it can run?

Yes, because it doesn't use them :-). When you guix install turbovnc on Debian for example, it comes with its own dependencies that it refers to under /gnu/store/.... Everything is fixed.

If so, then this seems like it should be best handled by introducing specific CMake variables or even making vncserver Guix-aware. But if you're just searching the operating system for the correct directories, then I don't see the advantage of doing that at build time rather than at run time, as vncserver already does.

Making it Guix-aware doesn't sound great, but making it more configurable could be useful.

[...] About the xstartup-turbovnc changes:

Do these really need to be different than the defaults set by xstartup.turbovnc? If so, then it's probably also best handled by introducing new CMake variables.

The default values are correct on a FHS system, but Guix isn't one so the /usr/bin and similar references needs to be patched. Commands found on PATH are also typically patch, as this make things more robust (work in any environment, which may lack grep on PATH, etc.).

About setting XSESSION to $HOME/.xession:

This is not the correct approach. If there is no Xsession script, then XSESSION should be blank. In the unmodified xstartup.turbovnc script, XSESSION will be blank if neither /etc/X11/xinit/Xsession nor /etc/X11/Xsession exists.

OK. I thought it could be nice to have the user .xsession loaded. Isn't ~/.xsession a user-local version of /etc/X11/xinit/Xsession (a system global one) ?

The other comments were also about the path of commands, needing to be adjusted on Guix due to not following the FHS.

Can you use the summary from our own packages? The synopsis above makes it sound like we're just a TightVNC clone.

Sure! I thought stressing that TurboVNC was "TightVNC-compatible" was an important characteristic given that TigerVNC is more common/established.

Thanks again for all the feedback!

dcommander commented 2 years ago

That would be true for a traditional distribution, but not for those based on functional package managing like Guix, which effectively captures the exact dependency graph (and ensures dependents get rebuilt when any of their dependency changes).

Great, but most people who build the TurboVNC Viewer will not be using Guix, and there is no way to capture that same dependency graph in our own build system. With a DSO, backward-incompatible ABI changes will not be introduced without incrementing the major version number. Java JARs have no such contract, however, so there is nothing that prevents JSch 0.1.55 from having different interfaces than 0.1.54. With a DSO, you essentially have two levels of exposure. A function can be exposed only to other parts of the library, or it can be exposed to calling applications (through, e.g., a linker script.) In Java, there is no such concept. If you make a method or variable public because another package in your source tree needs to access it, then applications can access it as well. Thus, the simple act of renaming one of those methods or variables could break an application. And yes, applications shouldn't use undocumented public methods or variables, but Java has no way of enforcing that.

You should also set TJPEG_INCLUDE_DIR and TJPEG_LIBRARY (for example, to /usr/include and -lturbojpeg, respectively) in order to link dynamically with the system's installation of libjpeg-turbo.

The build system seems to handle that correctly without my intervention:

You're right. I forgot that I introduced a fallback mechanism some years ago.

Welcome to this new era of functional package management, where each package has a dedicated, unique prefix derived from its content:

It's a rather daring leap from the FHS, but it opens a whole new class of opportunities (and yes, a few challenges :-)). I only know NixOS and Guix System as distributions based on a functional package manager, but there may be others.

There are certainly tradeoffs to that approach, and it goes without saying that a lot of Linux software assumes a shared library and binary path and will thus encounter problems under Guix.

I'm using this hack to fix the value of JAVA to the exact reference of java, so that it can be used without being on PATH.

I don't know what you mean by resorting to grep and sed, but the vncviewer script finds libjawt.so by querying the JRE for the location of that library. It shouldn't be necessary to muck with that.

I meant that _TMP=$JAVA -XshowSettings:properties -version 2>&1 | grep sun.boot.library.path | sed s/.*=\ //g`` is a bit complex and requires grep and sed to be on PATH when I can readily point it to the absolute location of that libjawt.so library at build time :-).

Do these really need to be different than the defaults set by xstartup.turbovnc? If so, then it's probably also best handled by introducing new CMake variables.

The default values are correct on a FHS system, but Guix isn't one so the /usr/bin and similar references needs to be patched. Commands found on PATH are also typically patch, as this make things more robust (work in any environment, which may lack grep on PATH, etc.).

OK, that's fair. TurboVNC is designed more like an enterprise application whereby the same binary can run on multiple platforms, so it is only accommodating of specific systems and window managers. I'll think about how it might be possible to be more accommodating of an environment like Guix that has no concept of shared binary/library directories. I will create a new comment for that.

Does Guix somehow know the correct locations of all of those directories for every distribution on which it can run?

Yes, because it doesn't use them :-). When you guix install turbovnc on Debian for example, it comes with its own dependencies that it refers to under /gnu/store/.... Everything is fixed.

If so, then this seems like it should be best handled by introducing specific CMake variables or even making vncserver Guix-aware. But if you're just searching the operating system for the correct directories, then I don't see the advantage of doing that at build time rather than at run time, as vncserver already does.

Making it Guix-aware doesn't sound great, but making it more configurable could be useful.

Yeah, I thought that Guix might use fixed paths under /gnu/store, but it doesn't, so that's a non-starter.

OK. I thought it could be nice to have the user .xsession loaded. Isn't ~/.xsession a user-local version of /etc/X11/xinit/Xsession (a system global one) ?

The reason why xstartup.turbovnc executes the Xsession script is that it is necessary on certain distributions (Ubuntu, for instance) to invoke the window manager through Xsession. Otherwise, a lot of the dbus/XDG stuff doesn't get set up correctly, and this can prevent modern window managers from working properly in TurboVNC (or it can prevent multiple instances of the window manager from running under the same user account.) ~/.xsession is eventually invoked by Xsession, but only after Xsession sets up all of the aforementioned dbus/XDG stuff. The lack of an Xsession script may not be an issue for a Guix-native environment, but if one intends to use Guix on, say, Ubuntu, then the correct operation of TurboVNC will depend on invoking the system's Xsession script.

dcommander commented 2 years ago

Accommodating Non-FHS Environments in TurboVNC

Please let me know if I've missed anything.

1. DRI driver path, XKB base directory, XKB binary directory, X.org registry path

The TurboVNC build system already has CMake variables (DRI_DRIVER_PATH, XKB_BASE_DIRECTORY, XKB_BIN_DIRECTORY, SERVER_MISC_CONFIG_PATH) that can be used to statically set these paths for Xvnc, but the vncserver script overrides the paths at run time. I propose that, if a new CMake variable (TVNC_STATIC_XORG_PATHS or something like that) is set, then the vncserver script should not override those paths. This would benefit distribution-specific TurboVNC builds in FHS environments as well.

2. Xfont2, libfontenc, Pixman include and library paths

The problem is that CMake has no mechanism to search for these libraries independently. If Guix allows each independent X11 library (libXau, libICE, libXext, libXdmcp, etc.) to be installed in a separate directory, then presumably its version of CMake's FindX11 module is heavily modified in order to accommodate that. (Note that this is one area of skepticism I have regarding the Guix environment: the ability of Guix contributors to stay abreast of breaking changes in upstream software, most of which assumes a FHS environment.) If each X11 library has its own independent include and library path, then I don't know how external applications (applications built outside of the Guix environment) are supposed to use the X11 libraries/headers that Guix provides. Are they expected to manually include all of the various Guix X11 paths, which may change with a package upgrade? Does Guix at least have a shared pkg-config path? The idea behind pkg-config (or CMake's package config files) is that it frees application developers from having to know the exact directories in which every dependency is installed, but if they have to know the exact directories in which every package config file is installed, then that defeats the purpose.

3. Font path, RGB database path

The TurboVNC build system does not currently have CMake variables that can be used to statically set these paths for Xvnc, but it should. Then a new CMake variable could be used to signal the vncserver script not to search for those paths, per above. This would benefit distribution-specific TurboVNC builds in FHS environments as well.

4. X sessions directory

This could be accommodated by introducing a new CMake variable (TVNC_XSESSIONS_PATH, set to "" by default) that will, if set, signal the xstartup.turbovnc script not to search for that directory. This would benefit distribution-specific TurboVNC builds in FHS environments as well.

5. Java paths

CMake already knows the location of java and libjawt.so from the JDK that was used to build the TurboVNC Viewer. A new CMake variable (TVNC_SYSTEMJAVA?) could be introduced that signals the vncviewer script to use hard-coded directories for java and libjawt.so. (By default, we can't assume that TurboVNC will be built and run with the same implementation of Java.) However, this would mainly only benefit non-FHS environments.

6. Applications assumed to be in $PATH or under /usr/bin

These could be accommodated by introducing CMake variables that are set to "" by default. However, this would mainly only benefit non-FHS environments, and it would significantly impact the maintainability of our scripts. (Basically, I don't want to have to add a new CMake variable every time I refer to an external program in one of my scripts. It would be a lot easier sell if we were talking about accommodating a shared binary path that isn't necessarily in the $PATH, such as /usr/local/bin on FreeBSD.)

dbus-launch: TVNC_DBUS_LAUNCH_PATH grep: TVNC_GREP_PATH sed: TVNC_SED_PATH ssh-agent: TVNC_SSH_AGENT_PATH twm: TVNC_TWM_PATH uname: TVNC_UNAME_PATH vglrun: TVNC_VGLRUN_PATH xauth: TVNC_XAUTH_PATH xdpyinfo: TVNC_XDPYINFO_PATH xsetroot: TVNC_XSETROOT_PATH xterm: TVNC_XTERM_PATH

Summary

I think that Items 1, 3, and 4 are a good idea, as well as Item 2 once I get a better understanding of it. I think that Items 5-6 are, at least for the moment, best handled downstream.

Apteryks commented 2 years ago

Hi,

I replied by email but apparently that doesn't work; copying below:

DRC notifications@github.com writes:

Accommodating Non-FHS Environments in TurboVNC

Please let me know if I've missed anything.

1. DRI driver path, XKB base directory, XKB binary directory, X.org registry path

The TurboVNC build system already has CMake variables (DRI_DRIVER_PATH, XKB_BASE_DIRECTORY, XKB_BIN_DIRECTORY, SERVER_MISC_CONFIG_PATH) that can be used to statically set these paths for Xvnc, but the vncserver script overrides the paths at run time. I propose that, if a new CMake variable (TVNC_STATIC_XORG_PATHS or something like that) is set, then the vncserver script should not override those paths. This would benefit distribution-specific TurboVNC builds in FHS environments as well.

This sounds useful.

2. Xfont2, libfontenc, Pixman include and library paths

The problem is that CMake has no mechanism to search for these libraries independently. If Guix allows each independent X11 library (libXau, libICE, libXext, libXdmcp, etc.) to be installed in a separate directory, then presumably its version of CMake's FindX11 module is heavily modified in order to accommodate that.

All of these packages come with pkg-config files, so CMake's pkg_check_modules can be used to locate them:

$ find $(guix build libxau libice libxext libxdmcp) -name '*.pc' /gnu/store/dfzp4rhkzqqagx3djn2kcnaflz1m8446-libxdmcp-1.1.3/lib/pkgconfig/xdmcp.pc /gnu/store/4fhg8f8c6q647v7pysbng3j30frg0hcl-libxext-1.3.4/lib/pkgconfig/xext.pc /gnu/store/7jca8p2brd88lssfxzr00hy8rqdi6j51-libice-1.0.10/lib/pkgconfig/ice.pc /gnu/store/9k6slxs8ynz46h85bcy3zk2mx0nn8rpf-libxau-1.0.9/lib/pkgconfig/xau.pc

(Note that this is one area of skepticism I have regarding the Guix environment: the ability of Guix contributors to stay abreast of breaking changes in upstream software, most of which assumes a FHS environment.) If each X11 library has its own independent include and library path, then I don't know how external applications (applications built outside of the Guix environment) are supposed to use the X11 libraries/headers that Guix provides.

Applications built outside of Guix won't easily be able to find or make use of the Guix libraries. It's the other way around that is valuable: applications built on Guix can run on any GNU/Linux system.

Also note that as a user, you can 'guix install libx11', then its includes are made available from ~/.guix-profile/include and provided you have a toolchain in the same profile, the environment variable C_INCLUDE_PATH contains the directory, such that GCC can find the headers. The same is true for using libraries; LIBRARY_PATH would be set to include ~/.guix-profile/lib, for example.

Are they expected to manually include all of the various Guix X11 paths, which may change with a package upgrade? Does Guix at least have a shared pkg-config path? The idea behind pkg-config (or CMake's package config files) is that it frees application developers from having to know the exact directories in which every dependency is installed, but if they have to know the exact directories in which every package config file is installed, then that defeats the purpose.

pkg-config is usable in Guix because the dependencies listed as 'Requires' or 'Requires-private' in the .pc files are propagated, and made discoverable via the PKG_CONFIG_PATH environment variable.

3. Font path, RGB database path

The TurboVNC build system does not currently have CMake variables that can be used to statically set these paths for Xvnc, but it should. Then a new CMake variable could be used to signal the vncserver script not to search for those paths, per above. This would benefit distribution-specific TurboVNC builds in FHS environments as well.

That'd be useful, yes!

4. X sessions directory

This could be accommodated by introducing a new CMake variable (TVNC_XSESSIONS_PATH, set to "" by default) that will, if set, signal the xstartup.turbovnc script not to search for that directory. This would benefit distribution-specific TurboVNC builds in FHS environments as well.

That sounds like an improvement as well.

5. Java paths

CMake already knows the location of java and libjawt.so from the JDK that was used to build the TurboVNC Viewer. A new CMake variable (TVNC_SYSTEMJAVA?) could be introduced that signals the vncviewer script to use hard-coded directories for java and libjawt.so. (By default, we can't assume that TurboVNC will be built and run with the same implementation of Java.) However, this would mainly only benefit non-FHS environments.

Right. This would help for Nix and Guix, and any other non-FHS distributions.

6. Applications assumed to be in $PATH or under /usr/bin

These could be accommodated by introducing CMake variables that are set to "" by default. However, this would mainly only benefit non-FHS environments, and it would significantly impact the maintainability of our scripts. (Basically, I don't want to have to add a new CMake variable every time I refer to an external program in one of my scripts. It would be a lot easier sell if )

dbus-launch: TVNC_DBUS_LAUNCH_PATH grep: TVNC_GREP_PATH sed: TVNC_SED_PATH ssh-agent: TVNC_SSH_AGENT_PATH twm: TVNC_TWM_PATH uname: TVNC_UNAME_PATH vglrun: TVNC_VGLRUN_PATH xauth: TVNC_XAUTH_PATH xdpyinfo: TVNC_XDPYINFO_PATH xsetroot: TVNC_XSETROOT_PATH xterm: TVNC_XTERM_PATH

Being able to specify them via CMake variables would be useful for non-FHS distributions. A lesser alternative would be to look the tools from PATH, so that non-FHS distributions could wrap the script with the tools on PATH.

Summary

I think that Items 1, 3, and 4 are a good idea, as well as Item 2 once I get a better understanding of it. I think that Items 5-6 are, at least for the moment, best handled downstream.

OK. Yes, 2 seems like it could work with what I wrote above (making use of pkg-config to locate them).

Thanks!

dcommander commented 2 years ago

b4e1ffcdbfe8dc98036a16022cbcc422385c1834 should fix the issues with finding Xfont2, fontenc, and Pixman. c58cdb2b7fe72685f97dee5872336f32a40fa04a adds new CMake variables that can be used to set all of the X.org internal paths statically and instruct vncserver to use those paths rather than detecting the appropriate values at run time.

This should eliminate the need to:

Regarding xstartup.turbovnc, I need to think about how best to address those issues in a way that doesn't create an undue maintenance burden for me. I don't have time to go down that particular rabbit hole right now but am leaving this open until I do. Those changes may be more disruptive and thus may not land until 3.1.

dcommander commented 2 years ago

Follow-up questions regarding potential improvements to xstartup.turbovnc:

  1. Does which under a Guix environment return the correct paths for various Guix-installed utilities? If so, is which guaranteed to be in the PATH?
  2. Assuming that someone installs the Guix implementation of TurboVNC on a FHS operating system such as Ubuntu, does Guix still provide separate copies of dbus-launch, grep, sed, ssh-agent, and uname? (I assume so but wanted to make sure.)

If the answer to all questions i "yes", then using which would seem to be an appropriate solution.

dcommander commented 2 years ago

@Apteryks Your feedback regarding https://github.com/TurboVNC/turbovnc/commit/b4e1ffcdbfe8dc98036a16022cbcc422385c1834 and https://github.com/TurboVNC/turbovnc/commit/c58cdb2b7fe72685f97dee5872336f32a40fa04a is appreciated, as well as answers to my questions above.

Apteryks commented 2 years ago

@dcommander Hi! Yes, I've been caught in other things but I'll try putting these new changes to the test very soon. Thanks again!

Apteryks commented 2 years ago

Hi!

Regarding your first question, which returns the path of the commands if they are on PATH. In Guix, which itself is not guaranteed to be on PATH, so references to it in scripts are typically patched with the POSIX command -v equivalent, or substituted altogether with the absolute path of the of the command it tries to locate.

Answering your second question, Guix would provide the copies of anything it refers to, so in this case yes, it'd include a reference to the Guix dbus-launch, grep, sed, ssh-agent and uname commands, since they are referenced by their absolute store paths (captured in the dependency closure of turbovnc).

If you are curious about how it all works, I can make a guix pack of turbovnc available, as a simple compressed tarball or .deb package if you'd like to experiment with it on foreign distributions such as Debian or the likes.

Apteryks commented 2 years ago

For fun, the complete dependency closure of turbovnc on Guix looks like so:

$ guix size /gnu/store/qv5w5mfgbahzabh1p7rz59ysmk8yfqs8-turbovnc-3.0.1
store item                                                       total    self
/gnu/store/r07a0cdd8zcxsgkqxqbngia72s5r6vww-openjdk-17.0.3         597.0   301.4  25.7%
/gnu/store/lcqz4q3834bjd3dlc8zsr95mvzz9n006-mesa-21.3.8            411.6   169.6  14.5%
/gnu/store/6pdzpmxg5afzss6dlivq8z84sfa31x22-llvm-11.0.0            221.5   149.5  12.8%
/gnu/store/qar3sks5fwzm91bl3d3ngyrvxs7ipj5z-python-3.9.9           155.3    63.7   5.4%
/gnu/store/hy6abswwv4d89zp464fw52z65fkzr7h5-perl-5.34.0            147.7    58.6   5.0%
/gnu/store/cnfsv9ywaacyafkqdqsv2ry8f01yr7a9-guile-3.0.7            129.1    52.0   4.4%
/gnu/store/hmsmhiiwp653niiz4ws5jm9y1vdq7kip-ghostscript-with-cups-9.54.0   219.1    39.1   3.3%
/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33              38.3    36.6   3.1%
/gnu/store/094bbaq6glba86h1d4cj16xhdi6fk2jl-gcc-10.3.0-lib          71.7    33.4   2.9%
/gnu/store/b7sk5vld43cmnz3ak7vzfg1r403p5qdr-eudev-3.2.11           102.2    17.7   1.5%
/gnu/store/vqdsrvs9jbn0ix2a58s99jwkh74124y5-coreutils-minimal-8.32    88.0    16.4   1.4%
/gnu/store/d251rfgc9nm2clzffzhgiipdvfvzkvwi-coreutils-8.32          88.0    16.4   1.4%
/gnu/store/bnsf9il448hl5xjavbhq3rcx355svz2v-glib-2.70.2             98.1    15.3   1.3%
/gnu/store/4g8fi4ii4ikdbfns46cd1a21bpx32fi5-cups-2.3.3op2          292.8    13.1   1.1%
/gnu/store/dvyfhfa1g0iblc8zh11cybgw5y4q7wgw-cups-minimal-2.3.3op2   156.6    13.0   1.1%
/gnu/store/814kl9vms5ahfs32yr6s6siq35lkvjpi-xorg-server-21.1.4     466.9    10.2   0.9%
/gnu/store/gkjna040y14xvk4y5mcccvjkkmdcvmnv-font-dejavu-2.37         9.8     9.8   0.8%
/gnu/store/7nlzk7n90ib3llblxlpz725ym3k05gdj-util-linux-2.37.2-lib    80.7     9.0   0.8%
/gnu/store/7gd1gvhj255xaqz0m0q904jbr9lxqsp8-poppler-21.07.0        138.2     7.3   0.6%
/gnu/store/50lhj5br3q0h3pg35a8yn5k3m5lpvh7w-qpdf-10.0.1             80.1     6.0   0.5%
/gnu/store/9rrnm5hdjw7cy96a2a9rfgh6y08wsbmf-ncurses-6.2.20210619    77.6     5.9   0.5%
/gnu/store/8mszv7v6kqdyavpvf8zb7kkagaan5vri-xkeyboard-config-2.34     5.8     5.8   0.5%
/gnu/store/zl9wf0zwq2ka9rpmayp53hnp2mn460xf-gnutls-3.7.2           143.4     5.6   0.5%
/gnu/store/3mvz2djpd1y2dda0lf237gn9mmclmd19-openssl-1.1.1q          77.2     5.5   0.5%
/gnu/store/kxb43qxp7yd6ljkjfbv1jv5h0y28prnr-openssh-8.9p1          135.0     5.5   0.5%
/gnu/store/s603s36g96jdmkm983lpwxm7r7zprcib-font-ghostscript-8.11     4.5     4.5   0.4%
/gnu/store/qv5w5mfgbahzabh1p7rz59ysmk8yfqs8-turbovnc-3.0.1        1171.1     4.0   0.3%
/gnu/store/c895mr23n2vl74q8r4siarppvs2vvgjz-mit-krb5-1.19.2         82.2     3.9   0.3%
/gnu/store/8ifrp37vn4gg135szmb30wbygsvxljk7-virtualgl-2.6.2        424.6     3.7   0.3%
/gnu/store/cd5may6imj4g0w61jd98j8wq93cd58sr-cups-filters-1.28.9    279.6     3.5   0.3%
/gnu/store/jp6027624wl2f4xx5yz1vjzd2b9yvwl9-elfutils-0.183          77.8     3.5   0.3%
/gnu/store/x1jd7pqfn9ilb6x97azcfq1fhjr63p0z-p11-kit-0.23.22         76.4     3.4   0.3%
/gnu/store/a7djvq9li9x94d37a9hialn3bcwzm1bd-libepoxy-1.5.5         414.9     3.3   0.3%
/gnu/store/690qz3fg334dpwn3pn6k59n4wc943p2b-gawk-5.1.0              76.0     3.3   0.3%
/gnu/store/xmzx5mzv4863yw9kmr2ykndgp37p8if0-sqlite-3.36.0           82.3     3.2   0.3%
/gnu/store/v8raqm2shh9azkl71107p53j55hir306-libxcb-1.14             75.3     3.0   0.3%
/gnu/store/fa43ijbrb96x08621qigxxiphp503lsi-libx11-1.7.3.1          78.2     2.8   0.2%
/gnu/store/fwbiihd2sbhai63y1pvvdh0f2bakfzrf-gmp-6.2.1               74.4     2.7   0.2%
/gnu/store/ak70pk2hjks17cx7zjdmdmzpcpiy9gpi-freetype-2.10.4         77.3     2.3   0.2%
/gnu/store/hkhbq2q1gfs970gsp2nhsmcqb4vmv2xr-libunistring-0.9.10     74.0     2.3   0.2%
/gnu/store/g5hf1zhqlcyx9vw3q1xa52bgddaqsfm5-libjpeg-turbo-2.0.5     73.9     2.2   0.2%
/gnu/store/n0sd9hghs18pjsj72023r1spa9wxccc2-libevent-2.1.12         73.8     2.1   0.2%
/gnu/store/m0hlywbxyinqrzl4sjkw4hhj5q73v7v5-cairo-1.16.0           124.7     2.0   0.2%
/gnu/store/g3y6ifhm0751vgsxv90yipfw6mk189kj-libxml2-2.9.12          75.9     2.0   0.2%
/gnu/store/l6wqlkha4nl5ds7hinbrhmq31v90cia2-linux-pam-1.5.1         74.6     1.9   0.2%
/gnu/store/nfxcjvv9c2q6in9x52kkkayqv38k00ai-alsa-lib-1.2.4          73.9     1.7   0.1%
/gnu/store/g6x8z3xg4dfp3fpajph2k56nf52igvbd-libxaw-1.0.14           90.8     1.7   0.1%
/gnu/store/az6bkcsnsd426nsvndrzgvygmqh24mh6-avahi-0.8              111.8     1.7   0.1%
/gnu/store/720rj90bch716isd8z7lcwrnvz28ap4y-bash-static-5.1.8        1.7     1.7   0.1%
/gnu/store/di5bqb45hi5lvp2q08hlxqjdcl9phjb1-pcre-8.45               73.4     1.7   0.1%
/gnu/store/wcwls45278gzpjvwlvrrs1y7h30g44xh-readline-8.1.1          79.0     1.4   0.1%
/gnu/store/3kl94m3ksm45a880b6lnn3kagk857lj9-libgcrypt-1.8.8         75.1     1.4   0.1%
/gnu/store/343iqv9hvbvzp2in0hs03dvygccrcapl-libtiff-4.3.0           77.5     1.4   0.1%
/gnu/store/df6ixzpiyy8s4mg5976gnaqwd79n05mj-glu-9.0.1              412.9     1.3   0.1%
/gnu/store/3x3dl71d4xm6y4hjwq110hmfyfx0xc6j-zstd-1.5.0-lib          72.9     1.2   0.1%
/gnu/store/2b3blhwbag1ial0dhxw7wh4zjxl0cqpk-pkg-config-0.29.2       72.8     1.1   0.1%
/gnu/store/yl859fgb86zgl0zsvbhxdpms945aazip-dbus-1.12.20            79.6     1.1   0.1%
/gnu/store/c8isj4jq6knv0icfgr43di6q3nvdzkx7-xz-5.2.5                73.7     1.1   0.1%
/gnu/store/aggsb6j1svxp70xlll4rqnx5f2pzz794-xz-5.2.5                73.7     1.1   0.1%
/gnu/store/pilv2s68v4xamxwk1ahfy7q32j6wnf7l-libgpg-error-1.42       73.7     1.0   0.1%
/gnu/store/chfwin3a4qp1znnpsjbmydr2jbzk0d6y-bash-minimal-5.1.8      72.7     1.0   0.1%
/gnu/store/72r6baww47gv2nkpmjmdp26s9q5bamm0-libfido2-1.11.0        108.9     1.0   0.1%
/gnu/store/4y5m9lb8k3qkb1y9m02sw9w9a6hacd16-bash-minimal-5.1.8      39.3     1.0   0.1%
/gnu/store/c1nvl9hcgl09nysmy1qqsz5ljiarxdjs-libdrm-2.4.107          77.2     1.0   0.1%
/gnu/store/manq4lcakkcakcg14rsi7467qw4c5frj-nettle-3.7.3            75.3     1.0   0.1%
/gnu/store/lpim1fdk5raidsps78ivwd285fwnfi8h-xterm-370              118.6     0.9   0.1%
/gnu/store/apfgwvj8vgljjrmcwbhgfjbjm9d1v9jz-wayland-1.20.0          77.3     0.9   0.1%
/gnu/store/hrgqa7m498wfavq4awai3xz86ifkjxdr-grep-3.6                75.2     0.8   0.1%
/gnu/store/xjwp2hsd9256icjjybfrmznppjicywf6-grep-3.6                73.5     0.8   0.1%
/gnu/store/zcqf5w24vm70hjdvxdg65bjfrfx4nk0i-openjpeg-2.4.0          79.5     0.8   0.1%
/gnu/store/wxgv6i8g0p24q5gcyzd0yr07s8kn9680-sed-4.8                 72.5     0.8   0.1%
/gnu/store/2lczkxbdbzh4gk7wh91bzrqrk7h5g1dl-libgc-8.0.4             72.4     0.7   0.1%
/gnu/store/j8x167zaka2h6pxk7wiq5zkg67hzf8a2-pixman-0.40.0           72.4     0.7   0.1%
/gnu/store/0r3c0idpjmbbc2yz36xzaqqxn0f0sn0l-libxt-1.2.1             88.4     0.7   0.1%
/gnu/store/0dhvl2lvb7gsrbjf5jq5pd7hdvznsazz-lcms-2.12               78.2     0.7   0.1%
/gnu/store/rcf4x7z82xrpn4bs0lnw1mc68xnngsj2-fontconfig-minimal-2.13.94    88.1     0.6   0.1%
/gnu/store/qia4ap8j15qmg3w1cd96fla1wjarqdw6-libedit-20191231-3.1    78.2     0.6   0.1%
/gnu/store/k7ggkq158dsszcnx9x16qn0lcawkvawv-gdbm-1.20               72.3     0.6   0.0%
/gnu/store/dbj1i7q1cprbx6ar3q35z2a9g6hphzgm-pciutils-3.7.0          76.1     0.6   0.0%
/gnu/store/p7iq81hxxyk9zy7a9dngbf16zm8d4klx-libpng-1.6.37           73.4     0.5   0.0%
/gnu/store/7b5qsjh2cbhwnqbdicvl81496k7b0g0j-libbsd-0.10.0           72.2     0.5   0.0%
/gnu/store/fjq8aca46v502mrgvrfhvif0xb6m4fz0-libidn2-2.3.1           74.4     0.5   0.0%
/gnu/store/s3hl12jxz9ybs7nsy7kq7ybzz7qnzmsg-bzip2-1.0.8             73.1     0.4   0.0%
/gnu/store/gzmwrl6cb8nxmc68hpgqzblng2kamkgc-bzip2-1.0.8             73.1     0.4   0.0%
/gnu/store/7jca8p2brd88lssfxzr00hy8rqdi6j51-libice-1.0.10           72.5     0.4   0.0%
/gnu/store/l08jvzxm3mjcb68ylfg0xx9wgnfphdj9-libxmu-1.1.3            88.9     0.4   0.0%
/gnu/store/vpbhfx3in1armf40mxvq9qclvv8ajncq-expat-2.4.7             72.0     0.4   0.0%
/gnu/store/mnyjwhyxcaf03ny05wy6sdh1np2isjw8-alsa-topology-conf-1.2.4     0.3     0.3   0.0%
/gnu/store/vh4g56m35wwlfg300s4qafykxjy09511-kmod-29                 75.5     0.3   0.0%
/gnu/store/a7ggx0af69gv4k5mr1k617p4vy9kgx2v-libcap-2.62             72.0     0.3   0.0%
/gnu/store/cb7v30lpnylkzkvix0nzpgqgcia0gfiw-libsm-1.2.3             81.8     0.3   0.0%
/gnu/store/hyfnp6p82hxpbj5mcgyw7nfh3fk68vpv-libxfont-2.0.4          77.6     0.2   0.0%
/gnu/store/9qd5mybvkha5cqv7sw0d3rrkpjgp4xzk-xcb-util-wm-0.4.1       75.6     0.2   0.0%
/gnu/store/ifvy0gvkmkpamdjyhmvp870ycyz874vk-xkbcomp-1.4.5           84.4     0.2   0.0%
/gnu/store/8qv5kb2fgm4c3bf70zcg9l6hkf3qzpw9-zlib-1.2.11             71.9     0.2   0.0%
/gnu/store/4gcznd9r1r3hlmkb2m7s1a37radgnspn-libtasn1-4.17.0         71.9     0.2   0.0%
/gnu/store/r9g06yq7b1as0ijbqh6hkjnwxdlfyg1n-twm-1.0.12              89.2     0.2   0.0%
/gnu/store/hy5a7z9bxn19mq3vwcsc4p8waq4kws2f-alsa-ucm-conf-1.2.4      0.2     0.2   0.0%
/gnu/store/5j27qq75nrbrvn2w3bi2jy8ivs03s8bd-libxkbfile-1.1.0        78.4     0.2   0.0%
/gnu/store/px3cc4a61rpw9lzzvq28i9yzw9y1pv9j-jbig2dec-0.19           71.9     0.2   0.0%
/gnu/store/kjbk349qgfc9a8p9d5cgjkxcw2q3lv9z-libxpm-3.5.13           88.8     0.2   0.0%
/gnu/store/wgqhlc12qvlwiklam7hz2r311fdcqfim-libffi-3.3              71.8     0.2   0.0%
/gnu/store/9dq8qb91wxsxzwiqmxq5gcvd37dzyk4p-libcbor-0.9.0           71.8     0.2   0.0%
/gnu/store/4fhg8f8c6q647v7pysbng3j30frg0hcl-libxext-1.3.4           78.3     0.1   0.0%
/gnu/store/dfzp4rhkzqqagx3djn2kcnaflz1m8446-libxdmcp-1.1.3          72.3     0.1   0.0%
/gnu/store/3s0xcy15rkh08y8cd50skbs5b4js8zb5-libxi-1.7.10            78.4     0.1   0.0%
/gnu/store/zk9bcddj5jyi07zikh9h5ybwc7isag2d-libdaemon-0.14          71.8     0.1   0.0%
/gnu/store/6i0764hydy0l1qk5m9mdd9zw2zz72qbm-libxft-2.3.3            94.8     0.1   0.0%
/gnu/store/r6jh7gpvavfka5q01vz9b7m028wkgm3f-libxtst-1.2.3           78.5     0.1   0.0%
/gnu/store/4d0ssibbd2glk1vc93zj738awmy22xad-giflib-5.2.1            71.8     0.1   0.0%
/gnu/store/p30n7i9jcwzf9iz2009vfb7sgx30bv76-libpciaccess-0.16       76.2     0.1   0.0%
/gnu/store/x6lxw8vlzdgdzz4i7dlknjfg6flndiap-libxvmc-1.0.12          78.5     0.1   0.0%
/gnu/store/jh778dla5w316bsfc63q8fnhn87j81lw-libxrender-0.9.10       78.2     0.1   0.0%
/gnu/store/25k894kwhf4ljw1nl9rz6rm0c9sz5qaz-libxrandr-1.5.2         78.5     0.1   0.0%
/gnu/store/6x1qq5wjz844q6crxr09ybkq8gbvmqrs-libpaper-1.1.24         72.8     0.1   0.0%
/gnu/store/mx0bsijgajia8b0s7zfsc135ichy111d-libxcursor-1.2.0        78.4     0.1   0.0%
/gnu/store/cwb01p80b3d3dz3sbwl5zzi7jm93s2np-libxv-1.0.11            78.4     0.1   0.0%
/gnu/store/k04pcgdvdipdc37cc6xvm33pcglbb8rz-libsigsegv-2.13         71.7     0.1   0.0%
/gnu/store/b2blwggwacjwm1six8gldbzw1zz7bj2w-xauth-1.1.2             89.0     0.1   0.0%
/gnu/store/z8w0dw2frdmlryc43wpckrlp7kl8xnfh-xcb-util-image-0.4.0    75.4     0.1   0.0%
/gnu/store/9zv5ky4sc5xfvn10ppk69ngxf0pkfv2x-luit-1.1.1              78.5     0.1   0.0%
/gnu/store/vw8kaj9kmvr8rdirhlcyyrj0danf278m-xdpyinfo-1.3.3          78.8     0.1   0.0%
/gnu/store/q6vpz865i2zs98sswdr5d1vp7lsij8aj-libxxf86dga-1.1.5       78.4     0.0   0.0%
/gnu/store/kdrl0zydxg29fxz03wff6s7nji3wp1mb-libxxf86vm-1.1.4        78.3     0.0   0.0%
/gnu/store/7rwz6yjir4ysnhskcw5k8azksjwqd6pa-libxfixes-6.0.0         78.2     0.0   0.0%
/gnu/store/66pkgn3sr3pqs5q4gjjia7j1wbiwn6xb-xcb-util-0.4.0          75.4     0.0   0.0%
/gnu/store/v6ymi501n3dvqvsgngmskn6z2gfaj4sm-libfontenc-1.1.4        71.9     0.0   0.0%
/gnu/store/q63g2vxhkb27x79rv6n8nbyviavjcs1p-libxcvt-0.1.1           71.7     0.0   0.0%
/gnu/store/wb6xisgffpf6fywipsg8clx2ypgb27c8-xsetroot-1.1.2          89.2     0.0   0.0%
/gnu/store/w6f5p570ajgidj7zga3395iks1cycqxk-xcb-util-renderutil-0.3.9    75.4     0.0   0.0%
/gnu/store/qzyp6p8gmxlpvd7wmijz5zn3cqmg4342-libxcomposite-0.4.5     78.2     0.0   0.0%
/gnu/store/6h8skg2n4gpbi0bwfmw6qyh03phic6dm-libxinerama-1.1.4       78.3     0.0   0.0%
/gnu/store/9k6slxs8ynz46h85bcy3zk2mx0nn8rpf-libxau-1.0.9            71.7     0.0   0.0%
/gnu/store/hbymc5z6rpj0m1a00iglc779kdnbglf0-libxshmfence-1.3        71.7     0.0   0.0%
/gnu/store/jqj45izzr5m40k6r8wrnsd542h8jaj07-xcb-util-keysyms-0.4.0    75.4     0.0   0.0%
/gnu/store/mhs4wss4yi51wcb9hqg5lag6liv24bd7-font-alias-1.0.4         0.0     0.0   0.0%
total: 1171.1 MiB

We can see that openjdk accounts for 25.7% of its disk size, which is large.

Apteryks commented 2 years ago

@dcommander for your info, there is now a turbovnc package in GNU Guix: https://git.savannah.gnu.org/cgit/guix.git/commit/?id=3baeae63b6dbfb157bf49518a591a31f1b9a4561. Thank you for your patience and efforts. The final package definition is much cleaner than the original one.

dcommander commented 2 years ago

Looks good. I honestly don't think that any modifications I made to xstartup.turbovnc would allow you to clean it up much more, so for now, I'm closing this as completed.

Apteryks commented 1 year ago

Hi!

DRC @.***> writes:

Accommodating Non-FHS Environments in TurboVNC

Please let me know if I've missed anything.

1. DRI driver path, XKB base directory, XKB binary directory, X.org registry path

The TurboVNC build system already has CMake variables (DRI_DRIVER_PATH, XKB_BASE_DIRECTORY, XKB_BIN_DIRECTORY, SERVER_MISC_CONFIG_PATH) that can be used to statically set these paths for Xvnc, but the vncserver script overrides the paths at run time. I propose that, if a new CMake variable (TVNC_STATIC_XORG_PATHS or something like that) is set, then the vncserver script should not override those paths. This would benefit distribution-specific TurboVNC builds in FHS environments as well.

This sounds useful.

2. Xfont2, libfontenc, Pixman include and library paths

The problem is that CMake has no mechanism to search for these libraries independently. If Guix allows each independent X11 library (libXau, libICE, libXext, libXdmcp, etc.) to be installed in a separate directory, then presumably its version of CMake's FindX11 module is heavily modified in order to accommodate that.

All of these packages come with pkg-config files, so CMake's pkg_check_modules can be used to locate them:

--8<---------------cut here---------------start------------->8--- $ find $(guix build libxau libice libxext libxdmcp) -name '*.pc' /gnu/store/dfzp4rhkzqqagx3djn2kcnaflz1m8446-libxdmcp-1.1.3/lib/pkgconfig/xdmcp.pc /gnu/store/4fhg8f8c6q647v7pysbng3j30frg0hcl-libxext-1.3.4/lib/pkgconfig/xext.pc /gnu/store/7jca8p2brd88lssfxzr00hy8rqdi6j51-libice-1.0.10/lib/pkgconfig/ice.pc /gnu/store/9k6slxs8ynz46h85bcy3zk2mx0nn8rpf-libxau-1.0.9/lib/pkgconfig/xau.pc --8<---------------cut here---------------end--------------->8---

(Note that this is one area of skepticism I have regarding the Guix environment: the ability of Guix contributors to stay abreast of breaking changes in upstream software, most of which assumes a FHS environment.) If each X11 library has its own independent include and library path, then I don't know how external applications (applications built outside of the Guix environment) are supposed to use the X11 libraries/headers that Guix provides.

Applications built outside of Guix won't easily be able to find or make use of the Guix libraries. It's the other way around that is valuable: applications built on Guix can run on any GNU/Linux system.

Also note that as a user, you can 'guix install libx11', then its includes are made available from ~/.guix-profile/include and provided you have a toolchain in the same profile, the environment variable C_INCLUDE_PATH contains the directory, such that GCC can find the headers. The same is true for using libraries; LIBRARY_PATH would be set to include ~/.guix-profile/lib, for example.

Are they expected to manually include all of the various Guix X11 paths, which may change with a package upgrade? Does Guix at least have a shared pkg-config path? The idea behind pkg-config (or CMake's package config files) is that it frees application developers from having to know the exact directories in which every dependency is installed, but if they have to know the exact directories in which every package config file is installed, then that defeats the purpose.

pkg-config is usable in Guix because the dependencies listed as 'Requires' or 'Requires-private' in the .pc files are propagated, and made discoverable via the PKG_CONFIG_PATH environment variable.

3. Font path, RGB database path

The TurboVNC build system does not currently have CMake variables that can be used to statically set these paths for Xvnc, but it should. Then a new CMake variable could be used to signal the vncserver script not to search for those paths, per above. This would benefit distribution-specific TurboVNC builds in FHS environments as well.

That'd be useful, yes!

4. X sessions directory

This could be accommodated by introducing a new CMake variable (TVNC_XSESSIONS_PATH, set to "" by default) that will, if set, signal the xstartup.turbovnc script not to search for that directory. This would benefit distribution-specific TurboVNC builds in FHS environments as well.

That sounds an improvement as well.

5. Java paths

CMake already knows the location of java and libjawt.so from the JDK that was used to build the TurboVNC Viewer. A new CMake variable (TVNC_SYSTEMJAVA?) could be introduced that signals the vncviewer script to use hard-coded directories for java and libjawt.so. (By default, we can't assume that TurboVNC will be built and run with the same implementation of Java.) However, this would mainly only benefit non-FHS environments.

Right. This would help for Nix and Guix, and any other non-FHS distributions.

6. Applications assumed to be in $PATH or under /usr/bin

These could be accommodated by introducing CMake variables that are set to "" by default. However, this would mainly only benefit non-FHS environments, and it would significantly impact the maintainability of our scripts. (Basically, I don't want to have to add a new CMake variable every time I refer to an external program in one of my scripts. It would be a lot easier sell if )

dbus-launch: TVNC_DBUS_LAUNCH_PATH grep: TVNC_GREP_PATH sed: TVNC_SED_PATH ssh-agent: TVNC_SSH_AGENT_PATH twm: TVNC_TWM_PATH uname: TVNC_UNAME_PATH vglrun: TVNC_VGLRUN_PATH xauth: TVNC_XAUTH_PATH xdpyinfo: TVNC_XDPYINFO_PATH xsetroot: TVNC_XSETROOT_PATH xterm: TVNC_XTERM_PATH

Being able to specify them via CMake variables would be useful for non-FHS distributions. A lesser alternative would be to look the tools from PATH, so that non-FHS distributions could wrap the script with the tools on PATH.

Summary

I think that Items 1, 3, and 4 are a good idea, as well as Item 2 once I get a better understanding of it. I think that Items 5-6 are, at least for the moment, best handled downstream.

OK. Yes, 2 seems like it could work with what I wrote above (making use of pkg-config to locate them).

Thank you.

Maxim