1{ stdenv, lib, requireFile, makeWrapper, substituteAll, p7zip
2, gawk, utillinux, xorg, glib, dbus-glib, zlib
3, kernel ? null, libsOnly ? false
4, undmg, fetchurl
5, libelf
6}:
7
8assert (!libsOnly) -> kernel != null;
9# Disable for kernels 4.15 and above due to compatibility issues
10assert kernel != null -> stdenv.lib.versionOlder kernel.version "4.15";
11
12let xorgFullVer = (builtins.parseDrvName xorg.xorgserver.name).version;
13 xorgVer = lib.concatStringsSep "." (lib.take 2 (lib.splitString "." xorgFullVer));
14 x64 = if stdenv.system == "x86_64-linux" then true
15 else if stdenv.system == "i686-linux" then false
16 else throw "Parallels Tools for Linux only support {x86-64,i686}-linux targets";
17in
18stdenv.mkDerivation rec {
19 version = "${prl_major}.2.1-41615";
20 prl_major = "12";
21 name = "prl-tools-${version}";
22
23 # We download the full distribution to extract prl-tools-lin.iso from
24 # => ${dmg}/Parallels\ Desktop.app/Contents/Resources/Tools/prl-tools-lin.iso
25 src = fetchurl {
26 url = "https://download.parallels.com/desktop/v${prl_major}/${version}/ParallelsDesktop-${version}.dmg";
27 sha256 = "1jwzwif69qlhmfky9kigjaxpxfj0lyrl1iyrpqy4iwqvajdgbbym";
28 };
29
30 hardeningDisable = [ "pic" "format" ];
31
32 # also maybe python2 to generate xorg.conf
33 nativeBuildInputs = [ p7zip undmg ] ++ lib.optionals (!libsOnly) [ makeWrapper ] ++ kernel.moduleBuildDependencies;
34
35 inherit libsOnly;
36
37 unpackPhase = ''
38 undmg < "${src}"
39
40 export sourceRoot=prl-tools-build
41 7z x "Parallels Desktop.app/Contents/Resources/Tools/prl-tools-lin.iso" -o$sourceRoot
42 if test -z "$libsOnly"; then
43 ( cd $sourceRoot/kmods; tar -xaf prl_mod.tar.gz )
44 fi
45 ( cd $sourceRoot/tools; tar -xaf prltools${if x64 then ".x64" else ""}.tar.gz )
46 '';
47
48 kernelVersion = if libsOnly then "" else (builtins.parseDrvName kernel.name).version;
49 kernelDir = if libsOnly then "" else "${kernel.dev}/lib/modules/${kernelVersion}";
50 scriptPath = lib.concatStringsSep ":" (lib.optionals (!libsOnly) [ "${utillinux}/bin" "${gawk}/bin" ]);
51
52 buildPhase = ''
53 if test -z "$libsOnly"; then
54 ( # kernel modules
55 cd kmods
56 make -f Makefile.kmods \
57 KSRC=$kernelDir/source \
58 HEADERS_CHECK_DIR=$kernelDir/source \
59 KERNEL_DIR=$kernelDir/build \
60 SRC=$kernelDir/build \
61 KVER=$kernelVersion
62 )
63
64 # Xorg config (maybe would be useful for other versions)
65 #python2 installer/xserver-config.py xorg ${xorgVer} /dev/null parallels.conf
66 fi
67 '';
68
69 libPath = with xorg;
70 stdenv.lib.makeLibraryPath ([ stdenv.cc.cc libXrandr libXext libX11 libXcomposite libXinerama ]
71 ++ lib.optionals (!libsOnly) [ libXi glib dbus-glib zlib ]);
72
73
74 installPhase = ''
75 if test -z "$libsOnly"; then
76 ( # kernel modules
77 cd kmods
78 mkdir -p $out/lib/modules/${kernelVersion}/extra
79 cp prl_eth/pvmnet/prl_eth.ko $out/lib/modules/${kernelVersion}/extra
80 cp prl_tg/Toolgate/Guest/Linux/prl_tg/prl_tg.ko $out/lib/modules/${kernelVersion}/extra
81 cp prl_fs/SharedFolders/Guest/Linux/prl_fs/prl_fs.ko $out/lib/modules/${kernelVersion}/extra
82 cp prl_fs_freeze/Snapshot/Guest/Linux/prl_freeze/prl_fs_freeze.ko $out/lib/modules/${kernelVersion}/extra
83 )
84 fi
85
86 ( # tools
87 cd tools
88 mkdir -p $out/lib
89
90 if test -z "$libsOnly"; then
91 # install binaries
92 for i in bin/* sbin/prl_nettool sbin/prl_snapshot; do
93 install -Dm755 $i $out/$i
94 done
95 # other binaries
96 for i in xorg.7.1/usr/bin/*; do
97 cp $i $out/bin
98 done
99
100 for i in $out/bin/* $out/sbin/*; do
101 patchelf \
102 --interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
103 --set-rpath "$out/lib:$libPath" \
104 $i || true
105 done
106
107 mkdir -p $out/bin
108 install -Dm755 ../installer/prlfsmountd.sh $out/sbin/prlfsmountd
109 wrapProgram $out/sbin/prlfsmountd \
110 --prefix PATH ':' "$scriptPath"
111
112 for i in lib/*.a; do
113 cp $i $out/lib
114 done
115
116 for i in xorg.7.1/usr/lib/libprl_wmouse_watcher.*; do
117 cp $i $out/lib
118 done
119
120 mkdir -p $out/lib/udev/rules.d
121 for i in *.rules; do
122 sed 's,/bin/bash,${stdenv.shell},g' $i > $out/lib/udev/rules.d/$i
123 done
124
125 (
126 cd xorg.${xorgVer}
127 # Install the X modules.
128 (
129 cd x-server/modules
130 for i in */*; do
131 install -Dm755 $i $out/lib/xorg/modules/$i
132 done
133 )
134 (
135 cd usr/lib
136 libGLXname=$(echo libglx.so*)
137 install -Dm755 $libGLXname $out/lib/xorg/modules/extensions/$libGLXname
138 ln -s $libGLXname $out/lib/xorg/modules/extensions/libglx.so
139 ln -s $libGLXname $out/lib/xorg/modules/extensions/libglx.so.1
140 )
141 )
142 fi
143
144 for i in xorg.7.1/usr/lib/libGL.*; do
145 cp $i $out/lib
146 done
147
148 cd $out
149 find -name \*.so\* -type f -exec \
150 patchelf --set-rpath "$out/lib:$libPath" {} \;
151
152 cd lib
153 libGLname=$(echo libGL.so*)
154 ln -s $libGLname libGL.so
155 ln -s $libGLname libGL.so.1
156 )
157 '';
158
159 dontStrip = true;
160 dontPatchELF = true;
161
162 meta = with stdenv.lib; {
163 description = "Parallels Tools for Linux guests";
164 homepage = https://parallels.com;
165 platforms = [ "i686-linux" "x86_64-linux" ];
166 license = licenses.unfree;
167 # I was making this package blindly and requesting testing from the real user,
168 # so I can't even test it by myself and won't provide future updates.
169 maintainers = with maintainers; [ abbradar ];
170 };
171}