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