1{
2 lib,
3 clangStdenv,
4 cargo,
5 copyDesktopItems,
6 fetchFromGitHub,
7 flutter,
8 ffmpeg,
9 gst_all_1,
10 fuse3,
11 libXtst,
12 libaom,
13 libopus,
14 libpulseaudio,
15 libva,
16 libvdpau,
17 libvpx,
18 libxkbcommon,
19 libyuv,
20 pam,
21 makeDesktopItem,
22 rustPlatform,
23 libayatana-appindicator,
24 rustc,
25 rustfmt,
26 xdotool,
27 xdg-user-dirs,
28 pipewire,
29 cargo-expand,
30 yq,
31 callPackage,
32}:
33let
34 flutterRustBridge = rustPlatform.buildRustPackage rec {
35 pname = "flutter_rust_bridge_codegen";
36 version = "1.80.1"; # https://github.com/rustdesk/rustdesk/blob/1.3.2/.github/workflows/bridge.yml#L10
37
38 src = fetchFromGitHub {
39 owner = "fzyzcjy";
40 repo = "flutter_rust_bridge";
41 rev = "v${version}";
42 hash = "sha256-SbwqWapJbt6+RoqRKi+wkSH1D+Wz7JmnVbfcfKkjt8Q=";
43 };
44
45 patches = [
46 ./update-flutter-dev-path.patch
47 ];
48
49 cargoHash = "sha256-4khuq/DK4sP98AMHyr/lEo1OJdqLujOIi8IgbKBY60Y=";
50 cargoBuildFlags = [
51 "--package"
52 "flutter_rust_bridge_codegen"
53 ];
54 doCheck = false;
55 };
56
57 ffigen = callPackage ./ffigen {
58 inherit flutter;
59 };
60
61 sharedLibraryExt = rustc.stdenv.hostPlatform.extensions.sharedLibrary;
62
63in
64flutter.buildFlutterApplication rec {
65 pname = "rustdesk";
66 version = "1.4.0";
67
68 src = fetchFromGitHub {
69 owner = "rustdesk";
70 repo = "rustdesk";
71 tag = version;
72 fetchSubmodules = true;
73 hash = "sha256-fuS2ENrMlzk1AIZGZp4M3ZbsHks5TFW2pRQEGzsTThQ=";
74 };
75
76 strictDeps = true;
77 env.VCPKG_ROOT = "/homeless-shelter"; # idk man, makes the build go since https://github.com/21pages/hwcodec/commit/1873c34e3da070a462540f61c0b782b7ab15dc84
78
79 # Configure the Flutter/Dart build
80 sourceRoot = "${src.name}/flutter";
81 # curl https://raw.githubusercontent.com/rustdesk/rustdesk/1.3.9/flutter/pubspec.lock | yq > pubspec.lock.json
82 pubspecLock = lib.importJSON ./pubspec.lock.json;
83 gitHashes = {
84 dash_chat_2 = "sha256-J5Bc6CeCoRGN870aNEVJ2dkQNb+LOIZetfG2Dsfz5Ow=";
85 desktop_multi_window = "sha256-NOe0jMcH02c0TDTtv62OMTR/qDPnRQrRe73vXDuEq8Q=";
86 dynamic_layouts = "sha256-eFp1YVI6vI2HRgtE5nTqGZIylB226H0O8kuxy9ypuf8=";
87 flutter_gpu_texture_renderer = "sha256-EZa1FOMbcwdVs/m0vsUvlHv+MifPby4I97ZFe1bqmwQ=";
88 window_manager = "sha256-40mwj4D8W2xW8C7RshTjOhelOiLPM7uU9rsF4NvQn8c=";
89 window_size = "sha256-XelNtp7tpZ91QCEcvewVphNUtgQX7xrp5QP0oFo6DgM=";
90 texture_rgba_renderer = "sha256-V/bmT/5x+Bt7kdjLTkgkoXdBcFVXxPyp9kIUhf+Rnt4=";
91 uni_links = "sha256-O2BgNwu5HFRQyaNkskWHORx8pZhdwEjtljvw1+zFzfo=";
92 };
93
94 # Configure the Rust build
95 cargoRoot = "..";
96 cargoDeps = rustPlatform.fetchCargoVendor {
97 inherit
98 pname
99 version
100 src
101 patches
102 ;
103 hash = "sha256-9DjfGfTs8/J9XPZmWXCibyRib1/abnWzznQn6A5Tw2I=";
104 };
105
106 dontCargoBuild = true;
107 cargoBuildFlags = "--lib";
108 cargoBuildType = "release";
109 cargoBuildFeatures = [
110 "flutter"
111 "hwcodec"
112 "linux-pkg-config"
113 ];
114
115 nativeBuildInputs = [
116 # flutter_rust_bridge_codegen
117 cargo
118 copyDesktopItems
119 rustfmt
120 # Rust
121 rustPlatform.cargoSetupHook
122 rustPlatform.cargoBuildHook
123 cargo-expand
124 rustPlatform.bindgenHook
125 ffigen
126 yq
127 ];
128
129 buildInputs = [
130 ffmpeg
131 fuse3
132 gst_all_1.gst-plugins-base
133 gst_all_1.gstreamer
134 libXtst
135 libaom
136 libopus
137 libpulseaudio
138 libva
139 libvdpau
140 libvpx
141 pipewire
142 libxkbcommon
143 libyuv
144 pam
145 xdotool
146 ];
147
148 prePatch = ''
149 chmod -R +w ..
150 cd ..
151 '';
152
153 patches = [
154 ./make-build-reproducible.patch
155 ];
156
157 prepareBuildRunner = ''
158 cp ${./build-runner.sh} build_runner
159 substituteInPlace build_runner \
160 --replace-fail "@bash@" "$SHELL"
161 chmod +x build_runner
162 export PATH=$PATH:$PWD
163 '';
164
165 postPatch = ''
166 cd flutter
167 if [ $cargoDepsCopy ]; then # That will be inherited to buildDartPackage and it doesn't have cargoDepsCopy
168 substituteInPlace $cargoDepsCopy/libappindicator-sys-*/src/lib.rs \
169 --replace-fail "libayatana-appindicator3.so.1" "${lib.getLib libayatana-appindicator}/lib/libayatana-appindicator3.so.1"
170 # Disable static linking of ffmpeg since https://github.com/21pages/hwcodec/commit/1873c34e3da070a462540f61c0b782b7ab15dc84
171 sed -i 's/static=//g' $cargoDepsCopy/hwcodec-*/build.rs
172 fi
173
174 substituteInPlace ../Cargo.toml --replace-fail ", \"staticlib\", \"rlib\"" ""
175 '';
176
177 preBuild = ''
178 # Build the Flutter/Rust bridge bindings
179 cat <<EOF > bridge.yml
180 rust_input:
181 - "../src/flutter_ffi.rs"
182 dart_output:
183 - "./lib/generated_bridge.dart"
184 llvm_path:
185 - "${lib.getLib clangStdenv.cc.cc}"
186 dart_format_line_length: 80
187 llvm_compiler_opts: "-I ${lib.getLib clangStdenv.cc.cc}/lib/clang/${lib.versions.major clangStdenv.cc.version}/include -I ${clangStdenv.cc.libc_dev}/include"
188 EOF
189 runHook prepareBuildRunner
190 RUST_LOG=info ${flutterRustBridge}/bin/flutter_rust_bridge_codegen bridge.yml
191
192 # Build the Rust shared library
193 cd ..
194 preBuild=() # prevent loops
195 cargoBuildHook
196 mv ./target/*/release/liblibrustdesk${sharedLibraryExt} ./target/release/liblibrustdesk${sharedLibraryExt}
197 cd flutter
198 '';
199
200 postInstall = ''
201 mkdir -p $out/share/polkit-1/actions $out/share/icons/hicolor/{256x256,scalable}/apps
202 cp ../res/128x128@2x.png $out/share/icons/hicolor/256x256/apps/rustdesk.png
203 cp ../res/scalable.svg $out/share/icons/hicolor/scalable/apps/rustdesk.svg
204 '';
205
206 extraWrapProgramArgs = ''
207 --prefix PATH : ${lib.makeBinPath [ xdg-user-dirs ]}
208 '';
209
210 desktopItems = [
211 (makeDesktopItem {
212 name = "rustdesk";
213 desktopName = "RustDesk";
214 genericName = "Remote Desktop";
215 comment = "Remote Desktop";
216 exec = "rustdesk %u";
217 icon = "rustdesk";
218 terminal = false;
219 type = "Application";
220 startupNotify = true;
221 categories = [
222 "Network"
223 "RemoteAccess"
224 "GTK"
225 ];
226 keywords = [ "internet" ];
227 actions.new-window = {
228 name = "Open a New Window";
229 exec = "rustdesk %u";
230 };
231 })
232 (makeDesktopItem {
233 name = "rustdesk-link";
234 desktopName = "RustDeskURL Scheme Handler";
235 noDisplay = true;
236 mimeTypes = [ "x-scheme-handler/rustdesk" ];
237 tryExec = "rustdesk";
238 exec = "rustdesk %u";
239 icon = "rustdesk";
240 terminal = false;
241 type = "Application";
242 startupNotify = false;
243 })
244 ];
245
246 meta = {
247 description = "Virtual / remote desktop infrastructure for everyone! Open source TeamViewer / Citrix alternative";
248 homepage = "https://rustdesk.com";
249 changelog = "https://github.com/rustdesk/rustdesk/releases/${version}";
250 license = lib.licenses.agpl3Only;
251 teams = [ lib.teams.helsinki-systems ];
252 mainProgram = "rustdesk";
253 platforms = lib.platforms.linux; # should work on darwin as well but I have no machine to test with
254 };
255}