staruml: 6.3.0 -> 6.3.1 (#365170)
[NixPkgs.git] / pkgs / applications / science / electronics / kicad / default.nix
blobedfcf61c1a2542106145aee010f6a2be4d85ff1e
2   lib,
3   stdenv,
4   runCommand,
5   newScope,
6   fetchFromGitLab,
7   makeWrapper,
8   symlinkJoin,
9   callPackage,
10   callPackages,
12   adwaita-icon-theme,
13   dconf,
14   gtk3,
15   wxGTK32,
16   librsvg,
17   cups,
18   gsettings-desktop-schemas,
19   hicolor-icon-theme,
21   unzip,
22   jq,
24   pname ? "kicad",
25   stable ? true,
26   testing ? false,
27   withNgspice ? !stdenv.hostPlatform.isDarwin,
28   libngspice,
29   withScripting ? true,
30   python3,
31   addons ? [ ],
32   debug ? false,
33   sanitizeAddress ? false,
34   sanitizeThreads ? false,
35   with3d ? true,
36   withI18n ? true,
37   srcs ? { },
40 # `addons`: https://dev-docs.kicad.org/en/addons/
42 # ```nix
43 # kicad = pkgs.kicad.override {
44 #   addons = with pkgs.kicadAddons; [ kikit kikit-library ];
45 # };
46 # ```
48 # The `srcs` parameter can be used to override the kicad source code
49 # and all libraries, which are otherwise inaccessible
50 # to overlays since most of the kicad build expression has been
51 # refactored into base.nix, most of the library build expressions have
52 # been refactored into libraries.nix. Overrides are only applied when
53 # building `kicad-unstable`. The `srcs` parameter has
54 # no effect for stable `kicad`. `srcs` takes an attribute set in which
55 # any of the following attributes are meaningful (though none are
56 # mandatory): "kicad", "kicadVersion", "symbols", "templates",
57 # "footprints", "packages3d", and "libVersion". "kicadVersion" and
58 # "libVersion" should be set to a string with the desired value for
59 # the version attribute in kicad's `mkDerivation` and the version
60 # attribute in any of the library's `mkDerivation`, respectively.
61 # "kicad", "symbols", "templates", "footprints", and "packages3d"
62 # should be set to an appropriate fetcher (e.g. `fetchFromGitLab`).
63 # So, for example, a possible overlay for kicad is:
65 # final: prev:
67 # {
68 #   kicad-unstable = (prev.kicad-unstable.override {
69 #     srcs = {
70 #       kicadVersion = "2020-10-08";
71 #       kicad = prev.fetchFromGitLab {
72 #         group = "kicad";
73 #         owner = "code";
74 #         repo = "kicad";
75 #         rev = "fd22fe8e374ce71d57e9f683ba996651aa69fa4e";
76 #         sha256 = "sha256-F8qugru/jU3DgZSpQXQhRGNFSk0ybFRkpyWb7HAGBdc=";
77 #       };
78 #     };
79 #   });
80 # }
82 let
83   baseName =
84     if (testing) then
85       "kicad-testing"
86     else if (stable) then
87       "kicad"
88     else
89       "kicad-unstable";
90   versionsImport = import ./versions.nix;
92   # versions.nix does not provide us with version, src and rev. We
93   # need to turn this into approprate fetcher calls.
94   kicadSrcFetch = fetchFromGitLab {
95     group = "kicad";
96     owner = "code";
97     repo = "kicad";
98     rev = versionsImport.${baseName}.kicadVersion.src.rev;
99     sha256 = versionsImport.${baseName}.kicadVersion.src.sha256;
100   };
102   libSrcFetch =
103     name:
104     fetchFromGitLab {
105       group = "kicad";
106       owner = "libraries";
107       repo = "kicad-${name}";
108       rev = versionsImport.${baseName}.libVersion.libSources.${name}.rev;
109       sha256 = versionsImport.${baseName}.libVersion.libSources.${name}.sha256;
110     };
112   # only override `src` or `version` if building `kicad-unstable` with
113   # the appropriate attribute defined in `srcs`.
114   srcOverridep = attr: (!stable && builtins.hasAttr attr srcs);
116   # use default source and version (as defined in versions.nix) by
117   # default, or use the appropriate attribute from `srcs` if building
118   # unstable with `srcs` properly defined.
119   kicadSrc = if srcOverridep "kicad" then srcs.kicad else kicadSrcFetch;
120   kicadVersion =
121     if srcOverridep "kicadVersion" then
122       srcs.kicadVersion
123     else
124       versionsImport.${baseName}.kicadVersion.version;
126   libSrc = name: if srcOverridep name then srcs.${name} else libSrcFetch name;
127   # TODO does it make sense to only have one version for all libs?
128   libVersion =
129     if srcOverridep "libVersion" then
130       srcs.libVersion
131     else
132       versionsImport.${baseName}.libVersion.version;
134   wxGTK = wxGTK32;
135   python = python3;
136   wxPython = python.pkgs.wxpython;
137   addonPath = "addon.zip";
138   addonsDrvs = map (pkg: pkg.override { inherit addonPath python3; }) addons;
140   addonsJoined =
141     runCommand "addonsJoined"
142       {
143         inherit addonsDrvs;
144         nativeBuildInputs = [
145           unzip
146           jq
147         ];
148       }
149       ''
150         mkdir $out
152         for pkg in $addonsDrvs; do
153           unzip $pkg/addon.zip -d unpacked
155           folder_name=$(jq .identifier unpacked/metadata.json --raw-output | tr . _)
156           for d in unpacked/*; do
157             if [ -d "$d" ]; then
158               dest=$out/share/kicad/scripting/$(basename $d)/$folder_name
159               mkdir -p $(dirname $dest)
161               mv $d $dest
162             fi
163           done
164           rm -r unpacked
165         done
166       '';
168   inherit (lib)
169     concatStringsSep
170     flatten
171     optionalString
172     optionals
173     ;
175 stdenv.mkDerivation rec {
177   # Common libraries, referenced during runtime, via the wrapper.
178   passthru.libraries = callPackages ./libraries.nix { inherit libSrc; };
179   passthru.callPackage = newScope { inherit addonPath python3; };
180   base = callPackage ./base.nix {
181     inherit stable testing baseName;
182     inherit kicadSrc kicadVersion;
183     inherit wxGTK python wxPython;
184     inherit withNgspice withScripting withI18n;
185     inherit debug sanitizeAddress sanitizeThreads;
186   };
188   inherit pname;
189   version = if (stable) then kicadVersion else builtins.substring 0 10 src.src.rev;
191   src = base;
192   dontUnpack = true;
193   dontConfigure = true;
194   dontBuild = true;
195   dontFixup = true;
197   pythonPath =
198     optionals (withScripting) [
199       wxPython
200       python.pkgs.six
201       python.pkgs.requests
202     ]
203     ++ addonsDrvs;
205   nativeBuildInputs = [ makeWrapper ] ++ optionals (withScripting) [ python.pkgs.wrapPython ];
207   # KICAD7_TEMPLATE_DIR only works with a single path (it does not handle : separated paths)
208   # but it's used to find both the templates and the symbol/footprint library tables
209   # https://gitlab.com/kicad/code/kicad/-/issues/14792
210   template_dir = symlinkJoin {
211     name = "KiCad_template_dir";
212     paths = with passthru.libraries; [
213       "${templates}/share/kicad/template"
214       "${footprints}/share/kicad/template"
215       "${symbols}/share/kicad/template"
216     ];
217   };
218   # We are emulating wrapGAppsHook3, along with other variables to the wrapper
219   makeWrapperArgs =
220     with passthru.libraries;
221     [
222       "--prefix XDG_DATA_DIRS : ${base}/share"
223       "--prefix XDG_DATA_DIRS : ${hicolor-icon-theme}/share"
224       "--prefix XDG_DATA_DIRS : ${adwaita-icon-theme}/share"
225       "--prefix XDG_DATA_DIRS : ${gtk3}/share/gsettings-schemas/${gtk3.name}"
226       "--prefix XDG_DATA_DIRS : ${gsettings-desktop-schemas}/share/gsettings-schemas/${gsettings-desktop-schemas.name}"
227       # wrapGAppsHook3 did these two as well, no idea if it matters...
228       "--prefix XDG_DATA_DIRS : ${cups}/share"
229       "--prefix GIO_EXTRA_MODULES : ${dconf}/lib/gio/modules"
230       # required to open a bug report link in firefox-wayland
231       "--set-default MOZ_DBUS_REMOTE 1"
232       "--set-default KICAD8_FOOTPRINT_DIR ${footprints}/share/kicad/footprints"
233       "--set-default KICAD8_SYMBOL_DIR ${symbols}/share/kicad/symbols"
234       "--set-default KICAD8_TEMPLATE_DIR ${template_dir}"
235     ]
236     ++ optionals (addons != [ ]) (
237       let
238         stockDataPath = symlinkJoin {
239           name = "kicad_stock_data_path";
240           paths = [
241             "${base}/share/kicad"
242             "${addonsJoined}/share/kicad"
243           ];
244         };
245       in
246       [ "--set-default NIX_KICAD8_STOCK_DATA_PATH ${stockDataPath}" ]
247     )
248     ++ optionals (with3d) [
249       "--set-default KICAD8_3DMODEL_DIR ${packages3d}/share/kicad/3dmodels"
250     ]
251     ++ optionals (withNgspice) [ "--prefix LD_LIBRARY_PATH : ${libngspice}/lib" ]
253     # infinisil's workaround for #39493
254     ++ [ "--set GDK_PIXBUF_MODULE_FILE ${librsvg}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" ];
256   # why does $makeWrapperArgs have to be added explicitly?
257   # $out and $program_PYTHONPATH don't exist when makeWrapperArgs gets set?
258   installPhase =
259     let
260       bin = if stdenv.hostPlatform.isDarwin then "*.app/Contents/MacOS" else "bin";
261       tools = [
262         "kicad"
263         "pcbnew"
264         "eeschema"
265         "gerbview"
266         "pcb_calculator"
267         "pl_editor"
268         "bitmap2component"
269       ];
270       utils = [
271         "dxf2idf"
272         "idf2vrml"
273         "idfcyl"
274         "idfrect"
275         "kicad-cli"
276       ];
277     in
278     (concatStringsSep "\n" (flatten [
279       "runHook preInstall"
281       (optionalString (withScripting) "buildPythonPath \"${base} $pythonPath\" \n")
283       # wrap each of the directly usable tools
284       (map (
285         tool:
286         "makeWrapper ${base}/${bin}/${tool} $out/bin/${tool} $makeWrapperArgs"
287         + optionalString (withScripting) " --set PYTHONPATH \"$program_PYTHONPATH\""
288       ) tools)
290       # link in the CLI utils
291       (map (util: "ln -s ${base}/${bin}/${util} $out/bin/${util}") utils)
293       "runHook postInstall"
294     ]));
296   postInstall = ''
297     mkdir -p $out/share
298     ln -s ${base}/share/applications $out/share/applications
299     ln -s ${base}/share/icons $out/share/icons
300     ln -s ${base}/share/mime $out/share/mime
301     ln -s ${base}/share/metainfo $out/share/metainfo
302   '';
304   passthru.updateScript = {
305     command = [
306       ./update.sh
307       "${pname}"
308     ];
309     supportedFeatures = [ "commit" ];
310   };
312   meta = rec {
313     description =
314       (
315         if (stable) then
316           "Open Source Electronics Design Automation suite"
317         else if (testing) then
318           "Open Source EDA suite, latest on stable branch"
319         else
320           "Open Source EDA suite, latest on master branch"
321       )
322       + (lib.optionalString (!with3d) ", without 3D models");
323     homepage = "https://www.kicad.org/";
324     longDescription = ''
325       KiCad is an open source software suite for Electronic Design Automation.
326       The Programs handle Schematic Capture, and PCB Layout with Gerber output.
327     '';
328     license = lib.licenses.gpl3Plus;
329     maintainers = with lib.maintainers; [ evils ];
330     platforms = lib.platforms.all;
331     broken = stdenv.hostPlatform.isDarwin;
332     mainProgram = "kicad";
333   };