1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 nixosTests,
6
7 # Dependencies
8 bzip2,
9 cmake,
10 dri-pkgconfig-stub,
11 freetype,
12 libGL,
13 libgbm,
14 libjpeg_turbo,
15 makeWrapper,
16 mesa-gl-headers, # for built-in 3D software rendering using swrast
17 openjdk, # for the client with Java GUI
18 openjdk_headless, # for the server
19 openssh,
20 openssl,
21 pam,
22 perl,
23 pkg-config,
24 python3,
25 which,
26 xkbcomp,
27 xkeyboard_config,
28 xorg,
29 xterm,
30}:
31
32stdenv.mkDerivation (finalAttrs: {
33 pname = "turbovnc";
34 version = "3.2";
35
36 src = fetchFromGitHub {
37 owner = "TurboVNC";
38 repo = "turbovnc";
39 rev = finalAttrs.version;
40 hash = "sha256-CMJdUG4Dd7pbtr/KXq0hV+zR5i+L/y610O+SWJTR/zQ=";
41 };
42
43 # Notes:
44 # * SSH support does not require `openssh` on PATH, because turbovnc
45 # uses a built-in SSH client ("JSch fork"), as commented on e.g.:
46 # https://github.com/TurboVNC/turbovnc/releases/tag/3.2beta1
47 #
48 # TODO:
49 # * Build outputs that are unclear:
50 # * `-- FONT_ENCODINGS_DIRECTORY = /var/empty/share/X11/fonts/encodings`
51 # Maybe relevant what the tigervnc and tightvnc derivations
52 # do with their `fontDirectories`?
53 # * `XORG_REGISTRY_PATH = /var/empty/lib64/xorg`
54 # * The thing about xorg `protocol.txt`
55 # * Add `enableClient ? true` flag that disables the client GUI
56 # so that the server can be built without openjdk dependency.
57 # * Perhaps allow to build the client on non-Linux platforms.
58
59 nativeBuildInputs = [
60 cmake
61 makeWrapper
62 openjdk_headless
63 pkg-config
64 python3
65 ];
66
67 buildInputs = [
68 bzip2
69 dri-pkgconfig-stub
70 freetype
71 libGL # for -DTVNC_SYSTEMX11=1
72 libgbm
73 libjpeg_turbo
74 openssl
75 pam
76 perl
77 ]
78 ++ (with xorg; [
79 libfontenc # for -DTVNC_SYSTEMX11=1
80 libSM
81 libX11
82 libXdamage # for -DTVNC_SYSTEMX11=1
83 libXdmcp # for -DTVNC_SYSTEMX11=1
84 libXext
85 libXfont2 # for -DTVNC_SYSTEMX11=1
86 libxkbfile # for -DTVNC_SYSTEMX11=1
87 libxshmfence
88 libXi
89 mesa-gl-headers # for -DTVNC_SYSTEMX11=1
90 pixman # for -DTVNC_SYSTEMX11=1
91 xorgproto
92 xtrans # for -DTVNC_SYSTEMX11=1
93 ]);
94
95 postPatch = ''
96 substituteInPlace unix/Xvnc/CMakeLists.txt --replace 'string(REGEX REPLACE "X11" "Xfont2" X11_Xfont2_LIB' 'set(X11_Xfont2_LIB ${xorg.libXfont2}/lib/libXfont2.so) #'
97 substituteInPlace unix/Xvnc/CMakeLists.txt --replace 'string(REGEX REPLACE "X11" "fontenc" X11_Fontenc_LIB' 'set(X11_Fontenc_LIB ${xorg.libfontenc}/lib/libfontenc.so) #'
98 substituteInPlace unix/Xvnc/CMakeLists.txt --replace 'string(REGEX REPLACE "X11" "pixman-1" X11_Pixman_LIB' 'set(X11_Pixman_LIB ${xorg.pixman}/lib/libpixman-1.so) #'
99 '';
100
101 cmakeFlags = [
102 # For the 3D software rendering built into TurboVNC, pass the path
103 # to the swrast dri driver in Mesa.
104 # Can also be given at runtime to its `Xvnc` as:
105 # -dridir /nix/store/...-mesa-20.1.10-drivers/lib/dri/
106 "-DXORG_DRI_DRIVER_PATH=${libGL.driverLink}/lib/dri"
107 # The build system doesn't find these files automatically.
108 "-DXKB_BASE_DIRECTORY=${xkeyboard_config}/share/X11/xkb"
109 "-DXKB_BIN_DIRECTORY=${xkbcomp}/bin"
110 # use system libs
111 # TurboVNC >= 3.1.4 no longer needs overrides to use system libraries
112 # instead of bundling them, see
113 # https://github.com/TurboVNC/turbovnc/releases/tag/3.2beta1:
114 # > The TVNC_SYSTEMLIBS and TVNC_SYSTEMX11 CMake variables have been removed,
115 # > and the build system now behaves as if those variables are always on.
116 # > A new CMake variable (TVNC_ZLIBNG) can be used on x86 platforms
117 # > to disable the in-tree SIMD-accelerated zlib-ng implementation
118 # > and build against the system-supplied zlib implementation.
119 #
120 # We'd like to build against nixpkgs's `zlib-ng`, but if we pass
121 # `-DTVNC_ZLIBNG=0`, the above logic seems to imply that it looks
122 # for normal zlib as well, and the `./configure` output prints
123 # -- zlib-ng disabled (TVNC_ZLIBNG = 0)
124 # -- Found ZLIB: /nix/store/<...>/lib/libz.so (found version "1.3.1")
125 # so that seems to use normal `zlib`, even though it's not declared
126 # as a dependency here (probably it's part of `stdenv`).
127 # So for now, we use TruboVNC's in-tree `zlib-ng`.
128 # "-DTVNC_ZLIBNG=0" # not given currently as explained above
129 ];
130
131 postInstall = ''
132 # turbovnc dlopen()s libssl.so depending on the requested encryption.
133 wrapProgram $out/bin/Xvnc \
134 --prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ openssl ]}
135
136 # `twm` is the default window manager that `vncserver` tries to start,
137 # and it has minimal dependencies (no non-Xorg).
138 # (This default is written by `vncserver` to `~/.vnc/xstartup.turbovnc`,
139 # see https://github.com/TurboVNC/turbovnc/blob/ffdb57d9/unix/vncserver.in#L201.)
140 # It checks for it using `which twm`.
141 # vncserver needs also needs `xauth` and we add in `xterm` for convenience
142 wrapProgram $out/bin/vncserver \
143 --prefix PATH : ${
144 lib.makeBinPath [
145 which
146 xorg.twm
147 xorg.xauth
148 xterm
149 ]
150 }
151
152 # Patch /usr/bin/perl
153 patchShebangs $out/bin/vncserver
154
155 # The viewer is in Java and requires `JAVA_HOME` (which is a single
156 # path, cannot be multiple separated paths).
157 # For SSH support, `ssh` is required on `PATH`.
158 wrapProgram $out/bin/vncviewer \
159 --set JAVA_HOME "${lib.makeLibraryPath [ openjdk ]}/openjdk" \
160 --prefix PATH : ${lib.makeBinPath [ openssh ]}
161 '';
162
163 passthru.tests.turbovnc-headless-server = nixosTests.turbovnc-headless-server;
164
165 meta = {
166 homepage = "https://turbovnc.org/";
167 license = lib.licenses.gpl2Plus;
168 description = "High-speed version of VNC derived from TightVNC";
169 maintainers = with lib.maintainers; [ nh2 ];
170 platforms = with lib.platforms; linux;
171 changelog = "https://github.com/TurboVNC/turbovnc/blob/${finalAttrs.version}/ChangeLog.md";
172 };
173})