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