1let
2 # `ides.json` is handwritten and contains information that doesn't change across updates, like maintainers and other metadata
3 # `versions.json` contains everything generated/needed by the update script version numbers, build numbers and tarball hashes
4 ideInfo = builtins.fromJSON (builtins.readFile ./bin/ides.json);
5 versions = builtins.fromJSON (builtins.readFile ./bin/versions.json);
6in
7
8{
9 lib,
10 stdenv,
11 callPackage,
12 fetchurl,
13
14 jdk,
15 zlib,
16 python3,
17 lldb,
18 dotnetCorePackages,
19 maven,
20 openssl,
21 expat,
22 libxcrypt,
23 libxcrypt-legacy,
24 fontconfig,
25 libxml2,
26 runCommand,
27 musl,
28 R,
29 libgcc,
30 lttng-ust_2_12,
31 xz,
32 xorg,
33 libGL,
34
35 libICE,
36 libSM,
37 libX11,
38
39 vmopts ? null,
40 forceWayland ? false,
41}:
42
43let
44 inherit (stdenv.hostPlatform) system;
45
46 products = versions.${system} or (throw "Unsupported system: ${system}");
47
48 dotnet-sdk = dotnetCorePackages.sdk_8_0-source;
49
50 package = if stdenv.hostPlatform.isDarwin then ./bin/darwin.nix else ./bin/linux.nix;
51 mkJetBrainsProductCore = callPackage package { inherit vmopts; };
52 mkMeta = meta: fromSource: {
53 inherit (meta) homepage longDescription;
54 description =
55 meta.description
56 + lib.optionalString meta.isOpenSource (
57 if fromSource then " (built from source)" else " (patched binaries from jetbrains)"
58 );
59 maintainers = map (x: lib.maintainers."${x}") meta.maintainers;
60 teams = [ lib.teams.jetbrains ];
61 license = if meta.isOpenSource then lib.licenses.asl20 else lib.licenses.unfree;
62 sourceProvenance =
63 if fromSource then
64 [ lib.sourceTypes.fromSource ]
65 else
66 (
67 if stdenv.hostPlatform.isDarwin then
68 [ lib.sourceTypes.binaryNativeCode ]
69 else
70 [ lib.sourceTypes.binaryBytecode ]
71 );
72 };
73
74 mkJetBrainsProduct =
75 {
76 pname,
77 fromSource ? false,
78 extraWrapperArgs ? [ ],
79 extraLdPath ? [ ],
80 extraBuildInputs ? [ ],
81 extraTests ? { },
82 }:
83 mkJetBrainsProductCore {
84 inherit
85 pname
86 jdk
87 extraBuildInputs
88 ;
89 extraWrapperArgs =
90 extraWrapperArgs
91 ++ lib.optionals (stdenv.hostPlatform.isLinux && forceWayland) [
92 ''--add-flags "\''${WAYLAND_DISPLAY:+-Dawt.toolkit.name=WLToolkit}"''
93 ];
94 extraLdPath = extraLdPath ++ lib.optionals (stdenv.hostPlatform.isLinux) [ libGL ];
95 src =
96 if fromSource then
97 communitySources."${pname}"
98 else
99 fetchurl {
100 url = products."${pname}".url;
101 sha256 = products."${pname}".sha256;
102 };
103 version = if fromSource then communitySources."${pname}".version else products."${pname}".version;
104 buildNumber =
105 if fromSource then communitySources."${pname}".buildNumber else products."${pname}".build_number;
106 inherit (ideInfo."${pname}") wmClass product;
107 productShort = ideInfo."${pname}".productShort or ideInfo."${pname}".product;
108 meta = mkMeta ideInfo."${pname}".meta fromSource;
109 passthru.tests = extraTests // {
110 plugins = callPackage ./plugins/tests.nix { ideName = pname; };
111 };
112 libdbm =
113 if ideInfo."${pname}".meta.isOpenSource then
114 communitySources."${pname}".libdbm
115 else
116 communitySources.idea-community.libdbm;
117 fsnotifier =
118 if ideInfo."${pname}".meta.isOpenSource then
119 communitySources."${pname}".fsnotifier
120 else
121 communitySources.idea-community.fsnotifier;
122 };
123
124 communitySources = callPackage ./source { };
125
126 buildIdea =
127 args:
128 mkJetBrainsProduct (
129 args
130 // {
131 extraLdPath = [ zlib ];
132 extraWrapperArgs = [
133 ''--set M2_HOME "${maven}/maven"''
134 ''--set M2 "${maven}/maven/bin"''
135 ];
136 }
137 );
138
139 buildPycharm =
140 args:
141 (mkJetBrainsProduct args).overrideAttrs (
142 finalAttrs: previousAttrs:
143 lib.optionalAttrs stdenv.hostPlatform.isLinux {
144 buildInputs =
145 with python3.pkgs;
146 (previousAttrs.buildInputs or [ ])
147 ++ [
148 python3
149 setuptools
150 ];
151 preInstall = ''
152 echo "compiling cython debug speedups"
153 if [[ -d plugins/python-ce ]]; then
154 ${python3.interpreter} plugins/python-ce/helpers/pydev/setup_cython.py build_ext --inplace
155 else
156 ${python3.interpreter} plugins/python/helpers/pydev/setup_cython.py build_ext --inplace
157 fi
158 '';
159 # See https://www.jetbrains.com/help/pycharm/2022.1/cython-speedups.html
160 }
161 );
162
163in
164rec {
165 # Sorted alphabetically
166
167 aqua = mkJetBrainsProduct {
168 pname = "aqua";
169 extraBuildInputs = [
170 stdenv.cc.cc
171 lldb
172 ];
173 };
174
175 clion =
176 (mkJetBrainsProduct {
177 pname = "clion";
178 extraBuildInputs =
179 lib.optionals (stdenv.hostPlatform.isLinux) [
180 fontconfig
181 python3
182 stdenv.cc.cc
183 openssl
184 libxcrypt-legacy
185 lttng-ust_2_12
186 musl
187 ]
188 ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64) [
189 expat
190 libxml2
191 xz
192 ];
193 }).overrideAttrs
194 (attrs: {
195 postInstall =
196 (attrs.postInstall or "")
197 + lib.optionalString (stdenv.hostPlatform.isLinux) ''
198 (
199 cd $out/clion
200
201 for dir in plugins/clion-radler/DotFiles/linux-*; do
202 rm -rf $dir/dotnet
203 ln -s ${dotnet-sdk}/share/dotnet $dir/dotnet
204 done
205 )
206 '';
207
208 postFixup =
209 (attrs.postFixup or "")
210 + lib.optionalString (stdenv.hostPlatform.isLinux) ''
211 (
212 cd $out/clion
213
214 # I think the included gdb has a couple of patches, so we patch it instead of replacing
215 ls -d $PWD/bin/gdb/linux/*/lib/python3.8/lib-dynload/* |
216 xargs patchelf \
217 --replace-needed libssl.so.10 libssl.so \
218 --replace-needed libcrypto.so.10 libcrypto.so
219
220 ls -d $PWD/bin/lldb/linux/*/lib/python3.8/lib-dynload/* |
221 xargs patchelf \
222 --replace-needed libssl.so.10 libssl.so \
223 --replace-needed libcrypto.so.10 libcrypto.so
224 )
225 '';
226 });
227
228 datagrip = mkJetBrainsProduct {
229 pname = "datagrip";
230 extraBuildInputs = [ stdenv.cc.cc ];
231 };
232
233 dataspell =
234 let
235 libr = runCommand "libR" { } ''
236 mkdir -p $out/lib
237 ln -s ${R}/lib/R/lib/libR.so $out/lib/libR.so
238 '';
239 in
240 mkJetBrainsProduct {
241 pname = "dataspell";
242 extraBuildInputs = [
243 libgcc
244 libr
245 stdenv.cc.cc
246 ];
247 };
248
249 gateway = mkJetBrainsProduct {
250 pname = "gateway";
251 extraBuildInputs = [ libgcc ];
252 };
253
254 goland =
255 (mkJetBrainsProduct {
256 pname = "goland";
257 extraWrapperArgs = [
258 # fortify source breaks build since delve compiles with -O0
259 ''--prefix CGO_CPPFLAGS " " "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0"''
260 ];
261 extraBuildInputs = [
262 libgcc
263 stdenv.cc.cc
264 ];
265 }).overrideAttrs
266 (attrs: {
267 postFixup =
268 (attrs.postFixup or "")
269 + lib.optionalString stdenv.hostPlatform.isLinux ''
270 interp="$(cat $NIX_CC/nix-support/dynamic-linker)"
271 patchelf --set-interpreter $interp $out/goland/plugins/go-plugin/lib/dlv/linux/dlv
272 chmod +x $out/goland/plugins/go-plugin/lib/dlv/linux/dlv
273 '';
274 });
275
276 idea-community-bin = buildIdea {
277 pname = "idea-community";
278 extraBuildInputs = [ stdenv.cc.cc ];
279 };
280
281 idea-community-src = buildIdea {
282 pname = "idea-community";
283 extraBuildInputs = [ stdenv.cc.cc ];
284 fromSource = true;
285 };
286
287 idea-community =
288 if stdenv.hostPlatform.isDarwin || stdenv.hostPlatform.isAarch64 then
289 idea-community-bin
290 else
291 idea-community-src;
292
293 idea-ultimate = buildIdea {
294 pname = "idea-ultimate";
295 extraBuildInputs = [
296 stdenv.cc.cc
297 lldb
298 musl
299 ];
300 };
301
302 mps = mkJetBrainsProduct { pname = "mps"; };
303
304 phpstorm = mkJetBrainsProduct {
305 pname = "phpstorm";
306 extraBuildInputs = [
307 stdenv.cc.cc
308 musl
309 ];
310 };
311
312 pycharm-community-bin = buildPycharm { pname = "pycharm-community"; };
313
314 pycharm-community-src = buildPycharm {
315 pname = "pycharm-community";
316 fromSource = true;
317 };
318
319 pycharm-community =
320 if stdenv.hostPlatform.isDarwin then pycharm-community-bin else pycharm-community-src;
321
322 pycharm-professional = buildPycharm {
323 pname = "pycharm-professional";
324 extraBuildInputs = [ musl ];
325 };
326
327 rider =
328 (mkJetBrainsProduct {
329 pname = "rider";
330 extraBuildInputs = [
331 fontconfig
332 stdenv.cc.cc
333 openssl
334 libxcrypt
335 lttng-ust_2_12
336 musl
337 ]
338 ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64) [
339 expat
340 libxml2
341 xz
342 ];
343 extraLdPath = lib.optionals (stdenv.hostPlatform.isLinux) [
344 # Avalonia dependencies needed for dotMemory
345 libICE
346 libSM
347 libX11
348 ];
349 }).overrideAttrs
350 (attrs: {
351 postInstall =
352 (attrs.postInstall or "")
353 + lib.optionalString (stdenv.hostPlatform.isLinux) ''
354 (
355 cd $out/rider
356
357 ls -d $PWD/plugins/cidr-debugger-plugin/bin/lldb/linux/*/lib/python3.8/lib-dynload/* |
358 xargs patchelf \
359 --replace-needed libssl.so.10 libssl.so \
360 --replace-needed libcrypto.so.10 libcrypto.so \
361 --replace-needed libcrypt.so.1 libcrypt.so
362
363 for dir in lib/ReSharperHost/linux-*; do
364 rm -rf $dir/dotnet
365 ln -s ${dotnet-sdk}/share/dotnet $dir/dotnet
366 done
367 )
368 '';
369 });
370
371 ruby-mine = mkJetBrainsProduct {
372 pname = "ruby-mine";
373 extraBuildInputs = [
374 stdenv.cc.cc
375 musl
376 ];
377 };
378
379 rust-rover =
380 (mkJetBrainsProduct {
381 pname = "rust-rover";
382 extraBuildInputs =
383 lib.optionals (stdenv.hostPlatform.isLinux) [
384 python3
385 openssl
386 libxcrypt-legacy
387 fontconfig
388 xorg.libX11
389 ]
390 ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64) [
391 expat
392 libxml2
393 xz
394 ];
395 }).overrideAttrs
396 (attrs: {
397 postFixup =
398 (attrs.postFixup or "")
399 + lib.optionalString (stdenv.hostPlatform.isLinux) ''
400 (
401 cd $out/rust-rover
402
403 # Copied over from clion (gdb seems to have a couple of patches)
404 ls -d $PWD/bin/gdb/linux/*/lib/python3.8/lib-dynload/* |
405 xargs patchelf \
406 --replace-needed libssl.so.10 libssl.so \
407 --replace-needed libcrypto.so.10 libcrypto.so
408
409 ls -d $PWD/bin/lldb/linux/*/lib/python3.8/lib-dynload/* |
410 xargs patchelf \
411 --replace-needed libssl.so.10 libssl.so \
412 --replace-needed libcrypto.so.10 libcrypto.so
413 )
414 '';
415 });
416
417 webstorm = mkJetBrainsProduct {
418 pname = "webstorm";
419 extraBuildInputs = [
420 stdenv.cc.cc
421 musl
422 ];
423 };
424
425 writerside = mkJetBrainsProduct {
426 pname = "writerside";
427 extraBuildInputs = [
428 stdenv.cc.cc
429 musl
430 ];
431 };
432
433 plugins = callPackage ./plugins { };
434
435}