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.3.0-55895";
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-Bs1hgEr5y9TYMGPXGrIOmqMgeyc6wHVo1x7OijTYifY=";
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 ] ++ kernel.moduleBuildDependencies;
68
69 buildInputs = [
70 dbus-glib
71 fuse
72 glib
73 xorg.libX11
74 xorg.libXcomposite
75 xorg.libXext
76 xorg.libXrandr
77 xorg.libXi
78 xorg.libXinerama
79 zlib
80 ];
81
82 runtimeDependencies = [
83 glib
84 xorg.libXrandr
85 ];
86
87 unpackPhase = ''
88 runHook preUnpack
89
90 undmg $src
91 export sourceRoot=prl-tools-build
92 7z x "Parallels Desktop.app/Contents/Resources/Tools/prl-tools-lin${lib.optionalString stdenv.hostPlatform.isAarch64 "-arm"}.iso" -o$sourceRoot
93 ( cd $sourceRoot/kmods; tar -xaf prl_mod.tar.gz )
94
95 runHook postUnpack
96 '';
97
98 buildPhase = ''
99 runHook preBuild
100
101 ( # kernel modules
102 cd kmods
103 make -f Makefile.kmods \
104 KSRC=${kernelDir}/source \
105 HEADERS_CHECK_DIR=${kernelDir}/source \
106 KERNEL_DIR=${kernelDir}/build \
107 SRC=${kernelDir}/build \
108 KVER=${kernelVersion}
109 )
110
111 runHook postBuild
112 '';
113
114 installPhase = ''
115 runHook preInstall
116
117 ( # kernel modules
118 cd kmods
119 mkdir -p $out/lib/modules/${kernelVersion}/extra
120 cp prl_fs_freeze/Snapshot/Guest/Linux/prl_freeze/prl_fs_freeze.ko $out/lib/modules/${kernelVersion}/extra
121 cp prl_tg/Toolgate/Guest/Linux/prl_tg/prl_tg.ko $out/lib/modules/${kernelVersion}/extra
122 ${lib.optionalString stdenv.hostPlatform.isAarch64 "cp prl_notifier/Installation/lnx/prl_notifier/prl_notifier.ko $out/lib/modules/${kernelVersion}/extra"}
123 )
124
125 ( # tools
126 cd tools/tools${
127 if stdenv.hostPlatform.isAarch64 then
128 "-arm64"
129 else if stdenv.hostPlatform.isx86_64 then
130 "64"
131 else
132 "32"
133 }
134 mkdir -p $out/lib
135
136 # prltoolsd contains hardcoded /bin/bash path
137 # we're lucky because it uses only -c command
138 # => replace to /bin/sh
139 bbe -e "s:/bin/bash:/bin/sh\x00\x00:" -o bin/prltoolsd.tmp bin/prltoolsd
140 rm -f bin/prltoolsd
141 mv bin/prltoolsd.tmp bin/prltoolsd
142
143 # install binaries
144 for i in bin/* sbin/prl_nettool sbin/prl_snapshot; do
145 # also patch binaries to replace /usr/bin/XXX to XXX
146 # here a two possible cases:
147 # 1. it is uses as null terminated string and should be truncated by null;
148 # 2. it is uses inside shell script and should be truncated by space.
149 for p in bin/* sbin/prl_nettool sbin/prl_snapshot sbin/prlfsmountd; do
150 p=$(basename $p)
151 bbe -e "s:/usr/bin/$p\x00:./$p\x00\x00\x00\x00\x00\x00\x00\x00:" -o $i.tmp $i
152 bbe -e "s:/usr/sbin/$p\x00:./$p\x00\x00\x00\x00\x00\x00\x00\x00 :" -o $i $i.tmp
153 bbe -e "s:/usr/bin/$p:$p :" -o $i.tmp $i
154 bbe -e "s:/usr/sbin/$p:$p :" -o $i $i.tmp
155 done
156
157 install -Dm755 $i $out/$i
158 done
159
160 install -Dm755 ../../tools/prlfsmountd.sh $out/sbin/prlfsmountd
161 install -Dm755 ../../tools/prlbinfmtconfig.sh $out/sbin/prlbinfmtconfig
162 for f in $out/bin/* $out/sbin/*; do
163 wrapProgram $f \
164 --prefix LD_LIBRARY_PATH ':' "${libPath}" \
165 --prefix PATH ':' "${scriptPath}"
166 done
167
168 for i in lib/libPrl*.0.0; do
169 cp $i $out/lib
170 ln -s $out/$i $out/''${i%.0.0}
171 done
172
173 substituteInPlace ../99prltoolsd-hibernate \
174 --replace "/bin/bash" "${bash}/bin/bash"
175
176 mkdir -p $out/etc/pm/sleep.d
177 install -Dm644 ../99prltoolsd-hibernate $out/etc/pm/sleep.d
178 )
179
180 runHook postInstall
181 '';
182
183 passthru.updateScript = ./update.sh;
184
185 meta = with lib; {
186 description = "Parallels Tools for Linux guests";
187 homepage = "https://parallels.com";
188 license = licenses.unfree;
189 maintainers = with maintainers; [
190 wegank
191 codgician
192 ];
193 platforms = platforms.linux;
194 };
195})