1{
2 stdenv,
3 lib,
4 pkg-config,
5 fetchFromGitLab,
6 gitUpdater,
7 ffmpeg_6,
8
9 # for daemon
10 autoreconfHook,
11 perl, # for pod2man
12 alsa-lib,
13 asio,
14 dbus,
15 sdbus-cpp,
16 fmt,
17 gmp,
18 gnutls,
19 llhttp,
20 jack,
21 jsoncpp,
22 libarchive,
23 libgit2,
24 libnatpmp,
25 libpulseaudio,
26 libupnp,
27 msgpack-cxx,
28 openssl,
29 restinio,
30 secp256k1,
31 speex,
32 udev,
33 webrtc-audio-processing_0_3,
34 yaml-cpp,
35 zlib,
36
37 # for dhtnet
38 expected-lite,
39
40 # for client
41 cmake,
42 git,
43 networkmanager, # for libnm
44 python3,
45 qttools, # for translations
46 wrapQtAppsHook,
47 libnotify,
48 qt5compat,
49 qtbase,
50 qtdeclarative,
51 qrencode,
52 qtmultimedia,
53 qtnetworkauth,
54 qtpositioning,
55 qtsvg,
56 qtwebengine,
57 qtwebchannel,
58 wrapGAppsHook3,
59 withWebengine ? true,
60
61 # for pjsip
62 fetchFromGitHub,
63 pjsip,
64
65 # for opendht
66 opendht,
67}:
68
69stdenv.mkDerivation rec {
70 pname = "jami";
71 version = "20250718.0";
72
73 src = fetchFromGitLab {
74 domain = "git.jami.net";
75 owner = "savoirfairelinux";
76 repo = "jami-client-qt";
77 rev = "stable/${version}";
78 hash = "sha256-EEiuymfu28bJ6pfBKwlsCGDq7XlKGZYK+2WjPJ+tcxw=";
79 fetchSubmodules = true;
80 };
81
82 pjsip-jami = pjsip.overrideAttrs (old: {
83 version = "sfl-2.15-unstable-2025-02-24";
84
85 src = fetchFromGitHub {
86 owner = "savoirfairelinux";
87 repo = "pjproject";
88 rev = "37130c943d59f25a71935803ea2d84515074a237";
89 hash = "sha256-7gAiriuooqqF38oajAuD/Lj5trn/9VMkCGOumcV45NA=";
90 };
91
92 configureFlags = [
93 "--disable-sound"
94 "--enable-video"
95 "--enable-ext-sound"
96 "--disable-android-mediacodec"
97 "--disable-speex-aec"
98 "--disable-g711-codec"
99 "--disable-l16-codec"
100 "--disable-gsm-codec"
101 "--disable-g722-codec"
102 "--disable-g7221-codec"
103 "--disable-speex-codec"
104 "--disable-ilbc-codec"
105 "--disable-opencore-amr"
106 "--disable-silk"
107 "--disable-sdl"
108 "--disable-ffmpeg"
109 "--disable-v4l2"
110 "--disable-openh264"
111 "--disable-resample"
112 "--disable-libwebrtc"
113 "--with-gnutls=yes"
114 ]
115 ++ lib.optionals stdenv.hostPlatform.isLinux [ "--enable-epoll" ];
116
117 buildInputs = old.buildInputs ++ [ gnutls ];
118 });
119
120 opendht-jami = opendht.override {
121 enableProxyServerAndClient = true;
122 enablePushNotifications = true;
123 };
124
125 dhtnet = stdenv.mkDerivation {
126 pname = "dhtnet";
127 version = "unstable-2025-05-26";
128
129 src = fetchFromGitLab {
130 domain = "git.jami.net";
131 owner = "savoirfairelinux";
132 repo = "dhtnet";
133 rev = "6c5ee3a21556d668d047cdedb5c4b746c3c6bdb2";
134 hash = "sha256-uweYSEysVMUC7DhI9BhS1TDZ6ZY7WQ9JS3ZF9lKA4Fo=";
135 };
136
137 postPatch = ''
138 substituteInPlace dependencies/build.py \
139 --replace-fail \
140 "wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp -O" \
141 "cp ${expected-lite}/include/nonstd/expected.hpp"
142 '';
143
144 nativeBuildInputs = [
145 cmake
146 pkg-config
147 ];
148
149 buildInputs = [
150 asio
151 fmt
152 gnutls
153 llhttp
154 jsoncpp
155 libupnp
156 msgpack-cxx
157 opendht-jami
158 openssl
159 pjsip-jami
160 python3
161 restinio
162 ];
163
164 cmakeFlags = [
165 "-DBUILD_SHARED_LIBS=Off"
166 "-DBUILD_BENCHMARKS=Off"
167 "-DBUILD_TOOLS=Off"
168 "-DBUILD_TESTING=Off"
169 "-DBUILD_DEPENDENCIES=Off"
170 "-DBUILD_EXAMPLE=Off"
171 ];
172
173 meta = with lib; {
174 description = "Lightweight Peer-to-Peer Communication Library";
175 license = licenses.gpl3Only;
176 platforms = platforms.linux;
177 maintainers = [ maintainers.linsui ];
178 };
179 };
180
181 daemon = stdenv.mkDerivation {
182 pname = "jami-daemon";
183 inherit src version meta;
184 sourceRoot = "${src.name}/daemon";
185
186 # Fix for libgit2 breaking changes
187 postPatch = ''
188 substituteInPlace src/jamidht/conversationrepository.cpp \
189 --replace-fail "git_commit* const" "const git_commit*"
190 '';
191
192 nativeBuildInputs = [
193 autoreconfHook
194 pkg-config
195 perl
196 ];
197
198 buildInputs = [
199 alsa-lib
200 asio
201 dbus
202 dhtnet
203 sdbus-cpp
204 fmt
205 ffmpeg_6
206 gmp
207 gnutls
208 llhttp
209 jack
210 jsoncpp
211 libarchive
212 libgit2
213 libnatpmp
214 libpulseaudio
215 libupnp
216 msgpack-cxx
217 opendht-jami
218 openssl
219 pjsip-jami
220 restinio
221 secp256k1
222 speex
223 udev
224 webrtc-audio-processing_0_3
225 yaml-cpp
226 zlib
227 ];
228
229 enableParallelBuilding = true;
230 };
231
232 qwindowkit-src = fetchFromGitHub {
233 owner = "stdware";
234 repo = "qwindowkit";
235 rev = "758b00cb6c2d924be3a1ea137ec366dc33a5132d";
236 hash = "sha256-qpVsF4gUX2noG9nKgjNP7FCEe59okZtDA8R/aZOef7Q=";
237 fetchSubmodules = true;
238 };
239
240 postPatch = ''
241 sed -i -e '/GIT_REPOSITORY/,+1c SOURCE_DIR ''${CMAKE_CURRENT_SOURCE_DIR}/qwindowkit' extras/build/cmake/contrib_tools.cmake
242 sed -i -e 's/if(DISTRO_NEEDS_QMSETUP_PATCH)/if(TRUE)/' CMakeLists.txt
243 cp -R --no-preserve=mode,ownership ${qwindowkit-src} qwindowkit
244 '';
245
246 preConfigure = ''
247 echo 'const char VERSION_STRING[] = "${version}";' > src/app/version.h
248 # Currently the daemon is still built seperately but jami expects it in CMAKE_INSTALL_PREFIX
249 # This can be removed in future versions when JAMICORE_AS_SUBDIR is on
250 mkdir -p $out
251 ln -s ${daemon} $out/daemon
252 '';
253
254 dontWrapGApps = true;
255
256 nativeBuildInputs = [
257 wrapGAppsHook3
258 wrapQtAppsHook
259 pkg-config
260 cmake
261 git
262 python3
263 qttools
264 ];
265
266 buildInputs = [
267 ffmpeg_6
268 libnotify
269 networkmanager
270 qtbase
271 qt5compat
272 qrencode
273 qtnetworkauth
274 qtdeclarative
275 qtmultimedia
276 qtpositioning
277 qtsvg
278 qtwebchannel
279 ]
280 ++ lib.optionals withWebengine [ qtwebengine ];
281
282 cmakeFlags = lib.optionals (!withWebengine) [ "-DWITH_WEBENGINE=false" ];
283
284 qtWrapperArgs = [
285 # With wayland the titlebar is not themed and the wmclass is wrong.
286 "--set-default QT_QPA_PLATFORM xcb"
287 ];
288
289 preFixup = ''
290 qtWrapperArgs+=("''${gappsWrapperArgs[@]}")
291 '';
292
293 passthru.updateScript = gitUpdater { rev-prefix = "stable/"; };
294
295 meta = with lib; {
296 homepage = "https://jami.net/";
297 description = "Free and universal communication platform that respects the privacy and freedoms of its users";
298 mainProgram = "jami";
299 license = licenses.gpl3Plus;
300 platforms = platforms.linux;
301 maintainers = [ maintainers.linsui ];
302 };
303}