1{ lib
2, stdenv
3, fetchurl
4, autoPatchelfHook
5, bbe
6, makeWrapper
7, p7zip
8, perl
9, undmg
10, dbus-glib
11, glib
12, xorg
13, zlib
14, kernel
15, bash
16, cups
17, gawk
18, netcat
19, timetrap
20, util-linux
21}:
22
23let
24 kernelVersion = kernel.modDirVersion;
25 kernelDir = "${kernel.dev}/lib/modules/${kernelVersion}";
26
27 libPath = lib.concatStringsSep ":" [ "${glib.out}/lib" "${xorg.libXrandr}/lib" ];
28 scriptPath = lib.concatStringsSep ":" [
29 "${bash}/bin"
30 "${cups}/sbin"
31 "${gawk}/bin"
32 "${netcat}/bin"
33 "${timetrap}/bin"
34 "${util-linux}/bin"
35 ];
36in
37stdenv.mkDerivation (finalAttrs: {
38 pname = "prl-tools";
39 version = "19.4.1-54985";
40
41 # We download the full distribution to extract prl-tools-lin.iso from
42 # => ${dmg}/Parallels\ Desktop.app/Contents/Resources/Tools/prl-tools-lin.iso
43 src = fetchurl {
44 url = "https://download.parallels.com/desktop/v${lib.versions.major finalAttrs.version}/${finalAttrs.version}/ParallelsDesktop-${finalAttrs.version}.dmg";
45 hash = "sha256-VBHCsxaMI6mfmc/iQ4hJW/592rKck9HilTX2Hq7Hb5s=";
46 };
47
48 hardeningDisable = [ "pic" "format" ];
49
50 nativeBuildInputs = [
51 autoPatchelfHook
52 bbe
53 makeWrapper
54 p7zip
55 perl
56 undmg
57 ] ++ kernel.moduleBuildDependencies;
58
59 buildInputs = [
60 dbus-glib
61 glib
62 xorg.libX11
63 xorg.libXcomposite
64 xorg.libXext
65 xorg.libXrandr
66 xorg.libXi
67 xorg.libXinerama
68 zlib
69 ];
70
71 runtimeDependencies = [
72 glib
73 xorg.libXrandr
74 ];
75
76 unpackPhase = ''
77 runHook preUnpack
78
79 undmg $src
80 export sourceRoot=prl-tools-build
81 7z x "Parallels Desktop.app/Contents/Resources/Tools/prl-tools-lin${lib.optionalString stdenv.isAarch64 "-arm"}.iso" -o$sourceRoot
82 ( cd $sourceRoot/kmods; tar -xaf prl_mod.tar.gz )
83
84 runHook postUnpack
85 '';
86
87 buildPhase = ''
88 runHook preBuild
89
90 ( # kernel modules
91 cd kmods
92 make -f Makefile.kmods \
93 KSRC=${kernelDir}/source \
94 HEADERS_CHECK_DIR=${kernelDir}/source \
95 KERNEL_DIR=${kernelDir}/build \
96 SRC=${kernelDir}/build \
97 KVER=${kernelVersion}
98 )
99
100 runHook postBuild
101 '';
102
103 installPhase = ''
104 runHook preInstall
105
106 ( # kernel modules
107 cd kmods
108 mkdir -p $out/lib/modules/${kernelVersion}/extra
109 cp prl_fs/SharedFolders/Guest/Linux/prl_fs/prl_fs.ko $out/lib/modules/${kernelVersion}/extra
110 cp prl_fs_freeze/Snapshot/Guest/Linux/prl_freeze/prl_fs_freeze.ko $out/lib/modules/${kernelVersion}/extra
111 cp prl_tg/Toolgate/Guest/Linux/prl_tg/prl_tg.ko $out/lib/modules/${kernelVersion}/extra
112 ${lib.optionalString stdenv.isAarch64
113 "cp prl_notifier/Installation/lnx/prl_notifier/prl_notifier.ko $out/lib/modules/${kernelVersion}/extra"}
114 )
115
116 ( # tools
117 cd tools/tools${if stdenv.isAarch64 then "-arm64" else if stdenv.isx86_64 then "64" else "32"}
118 mkdir -p $out/lib
119
120 # prltoolsd contains hardcoded /bin/bash path
121 # we're lucky because it uses only -c command
122 # => replace to /bin/sh
123 bbe -e "s:/bin/bash:/bin/sh\x00\x00:" -o bin/prltoolsd.tmp bin/prltoolsd
124 rm -f bin/prltoolsd
125 mv bin/prltoolsd.tmp bin/prltoolsd
126
127 # install binaries
128 for i in bin/* sbin/prl_nettool sbin/prl_snapshot; do
129 # also patch binaries to replace /usr/bin/XXX to XXX
130 # here a two possible cases:
131 # 1. it is uses as null terminated string and should be truncated by null;
132 # 2. it is uses inside shell script and should be truncated by space.
133 for p in bin/* sbin/prl_nettool sbin/prl_snapshot sbin/prlfsmountd; do
134 p=$(basename $p)
135 bbe -e "s:/usr/bin/$p\x00:./$p\x00\x00\x00\x00\x00\x00\x00\x00:" -o $i.tmp $i
136 bbe -e "s:/usr/sbin/$p\x00:./$p\x00\x00\x00\x00\x00\x00\x00\x00 :" -o $i $i.tmp
137 bbe -e "s:/usr/bin/$p:$p :" -o $i.tmp $i
138 bbe -e "s:/usr/sbin/$p:$p :" -o $i $i.tmp
139 done
140
141 install -Dm755 $i $out/$i
142 done
143
144 install -Dm755 ../../tools/prlfsmountd.sh $out/sbin/prlfsmountd
145 for f in $out/bin/* $out/sbin/*; do
146 wrapProgram $f \
147 --prefix LD_LIBRARY_PATH ':' "${libPath}" \
148 --prefix PATH ':' "${scriptPath}"
149 done
150
151 for i in lib/libPrl*.0.0; do
152 cp $i $out/lib
153 ln -s $out/$i $out/''${i%.0.0}
154 done
155
156 mkdir -p $out/share/man/man8
157 install -Dm644 ../mount.prl_fs.8 $out/share/man/man8
158
159 substituteInPlace ../99prltoolsd-hibernate \
160 --replace "/bin/bash" "${bash}/bin/bash"
161
162 mkdir -p $out/etc/pm/sleep.d
163 install -Dm644 ../99prltoolsd-hibernate $out/etc/pm/sleep.d
164 )
165
166 runHook postInstall
167 '';
168
169 meta = with lib; {
170 description = "Parallels Tools for Linux guests";
171 homepage = "https://parallels.com";
172 license = licenses.unfree;
173 maintainers = with maintainers; [ catap wegank ];
174 platforms = platforms.linux;
175 };
176})