nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 stdenv,
3 lib,
4 fetchFromGitHub,
5 fetchurl,
6 jdk,
7 ant,
8 stripJavaArchivesHook,
9 libusb-compat-0_1,
10 libusb1,
11 unzip,
12 zlib,
13 ncurses,
14 readline,
15 withGui ? false,
16 gtk3,
17 wrapGAppsHook3,
18 withTeensyduino ? false,
19 # Packages needed for Teensyduino
20 upx,
21 fontconfig,
22 libxxf86vm,
23 libxinerama,
24 libxft,
25 libxext,
26 libx11,
27 libsm,
28 gcc,
29 atk,
30 glib,
31 pango,
32 gdk-pixbuf,
33 gtk2,
34 libpng12,
35 expat,
36 freetype,
37 cairo,
38 udev,
39}:
40
41assert withTeensyduino -> withGui;
42let
43 externalDownloads = import ./downloads.nix {
44 inherit fetchurl;
45 inherit (lib) optionalAttrs;
46 inherit (stdenv.hostPlatform) system;
47 };
48 # Some .so-files are later copied from .jar-s to $HOME, so patch them beforehand
49 patchelfInJars =
50 lib.optional (stdenv.hostPlatform.system == "aarch64-linux") {
51 jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar";
52 file = "libs/linux/libjSSC-2.8_aarch64.so";
53 }
54 ++ lib.optional (builtins.match "armv[67]l-linux" stdenv.hostPlatform.system != null) {
55 jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar";
56 file = "libs/linux/libjSSC-2.8_armhf.so";
57 }
58 ++ lib.optional (stdenv.hostPlatform.system == "x86_64-linux") {
59 jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar";
60 file = "libs/linux/libjSSC-2.8_x86_64.so";
61 }
62 ++ lib.optional (stdenv.hostPlatform.system == "i686-linux") {
63 jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar";
64 file = "libs/linux/libjSSC-2.8_x86.so";
65 };
66 # abiVersion 6 is default, but we need 5 for `avrdude_bin` executable
67 ncurses5 = ncurses.override { abiVersion = "5"; };
68 teensy_libpath = lib.makeLibraryPath [
69 atk
70 cairo
71 expat
72 fontconfig
73 freetype
74 gcc.cc.lib
75 gdk-pixbuf
76 glib
77 gtk2
78 libpng12
79 libusb-compat-0_1
80 pango
81 udev
82 libsm
83 libx11
84 libxext
85 libxft
86 libxinerama
87 libxxf86vm
88 zlib
89 ];
90 teensy_architecture =
91 if stdenv.hostPlatform.isx86_32 then
92 "linux32"
93 else if stdenv.hostPlatform.isx86_64 then
94 "linux64"
95 else if stdenv.hostPlatform.isAarch64 then
96 "linuxaarch64"
97 else if stdenv.hostPlatform.isAarch32 then
98 "linuxarm"
99 else
100 throw "${stdenv.hostPlatform.system} is not supported in teensy";
101
102in
103stdenv.mkDerivation rec {
104 pname =
105 (if withTeensyduino then "teensyduino" else "arduino") + lib.optionalString (!withGui) "-core";
106 version = "1.8.19";
107
108 src = fetchFromGitHub {
109 owner = "arduino";
110 repo = "Arduino";
111 rev = version;
112 sha256 = "sha256-I+PvfGc5F8H/NJOGRa18z7dKyKcO8I8Cg7Tj5yxkYAQ=";
113 };
114
115 teensyduino_version = "156";
116 teensyduino_src = fetchurl {
117 url = "https://www.pjrc.com/teensy/td_${teensyduino_version}/TeensyduinoInstall.${teensy_architecture}";
118 sha256 =
119 {
120 linux64 = "sha256-4DbhmmYrx+rCBpDrYFaC0A88Qv9UEeNlQAkFi3zAstk=";
121 linux32 = "sha256-DlRPOtDxmMPv2Qzhib7vNZdKNZCxmm9YmVNnwUKXK/E=";
122 linuxarm = "sha256-d+DbpER/4lFPcPDFeMG5f3WaUGn8pFchdIDo7Hm0XWs=";
123 linuxaarch64 = "sha256-8keQzhWq7QlAGIbfHEe3lfxpJleMMvBORuPaNrLmM6Y=";
124 }
125 .${teensy_architecture} or (throw "No arduino binaries for ${teensy_architecture}");
126 };
127 # Used because teensyduino requires jars be a specific size
128 arduino_dist_src = fetchurl {
129 url = "https://downloads.arduino.cc/arduino-${version}-${teensy_architecture}.tar.xz";
130 sha256 =
131 {
132 linux64 = "sha256-62i93B0cASC+L8oTUKA+40Uxzzf1GEeyEhC25wVFvJs=";
133 linux32 = "sha256-wSxtx3BqXMQCeWQDK8PHkWLlQqQM1Csao8bIk98FrFg=";
134 linuxarm = "sha256-lJ/R1ePq7YtDk3bvloFcn8jswrJH+L63tvH5QpTqfXs=";
135 linuxaarch64 = "sha256-gm8cDjLKNfpcaeO7fw6Kyv1TnWV/ZmH4u++nun9X6jo=";
136 }
137 .${teensy_architecture} or (throw "No arduino binaries for ${teensy_architecture}");
138 };
139
140 # the glib setup hook will populate GSETTINGS_SCHEMAS_PATH,
141 # wrapGAppHooks (among other things) adds it to XDG_DATA_DIRS
142 # so 'save as...' works:
143 nativeBuildInputs = [
144 glib
145 stripJavaArchivesHook
146 wrapGAppsHook3
147 unzip
148 ];
149 buildInputs = [
150 jdk
151 ant
152 libusb-compat-0_1
153 libusb1
154 zlib
155 ncurses5
156 readline
157 ]
158 ++ lib.optionals withTeensyduino [ upx ];
159 downloadSrcList = builtins.attrValues externalDownloads;
160 downloadDstList = builtins.attrNames externalDownloads;
161
162 buildPhase = ''
163 # Copy pre-downloaded files to proper locations
164 download_src=($downloadSrcList)
165 download_dst=($downloadDstList)
166 while [[ "''${#download_src[@]}" -ne 0 ]]; do
167 file_src=''${download_src[0]}
168 file_dst=''${download_dst[0]}
169 mkdir -p $(dirname $file_dst)
170 download_src=(''${download_src[@]:1})
171 download_dst=(''${download_dst[@]:1})
172 cp -v $file_src $file_dst
173 done
174
175 # Deliberately break build.xml's download statement in order to cause
176 # an error if anything needed is missing from download.nix.
177 substituteInPlace build/build.xml \
178 --replace 'ignoreerrors="true"' 'ignoreerrors="false"'
179
180 cd ./arduino-core && ant
181 cd ../build && ant
182 cd ..
183 '';
184
185 # This will be patched into `arduino` wrapper script
186 # Java loads gtk dynamically, so we need to provide it using LD_LIBRARY_PATH
187 dynamicLibraryPath = lib.makeLibraryPath [ gtk3 ];
188 javaPath = lib.makeBinPath [ jdk ];
189
190 # Everything else will be patched into rpath
191 rpath = lib.makeLibraryPath [
192 zlib
193 libusb-compat-0_1
194 libusb1
195 readline
196 ncurses5
197 stdenv.cc.cc
198 ];
199
200 installPhase = ''
201 mkdir -p $out/share/arduino
202 cp -r ./build/linux/work/* "$out/share/arduino/"
203 echo -n ${version} > $out/share/arduino/lib/version.txt
204
205 ${lib.optionalString withGui ''
206 mkdir -p $out/bin
207 substituteInPlace $out/share/arduino/arduino \
208 --replace "JAVA=java" "JAVA=$javaPath/java" \
209 --replace "LD_LIBRARY_PATH=" "LD_LIBRARY_PATH=$dynamicLibraryPath:"
210 ln -sr "$out/share/arduino/arduino" "$out/bin/arduino"
211
212 cp -r build/shared/icons $out/share/arduino
213 mkdir -p $out/share/applications
214 cp build/linux/dist/desktop.template $out/share/applications/arduino.desktop
215 substituteInPlace $out/share/applications/arduino.desktop \
216 --replace '<BINARY_LOCATION>' "$out/bin/arduino" \
217 --replace '<ICON_NAME>' "$out/share/arduino/icons/128x128/apps/arduino.png"
218 ''}
219
220 ${lib.optionalString withTeensyduino ''
221 # Back up the original jars
222 mv $out/share/arduino/lib/arduino-core.jar $out/share/arduino/lib/arduino-core.jar.bak
223 mv $out/share/arduino/lib/pde.jar $out/share/arduino/lib/pde.jar.bak
224 # Extract jars from the arduino distributable package
225 mkdir arduino_dist
226 cd arduino_dist
227 tar xfJ ${arduino_dist_src} arduino-${version}/lib/arduino-core.jar arduino-${version}/lib/pde.jar
228 cd ..
229 # Replace the built jars with the official arduino jars
230 mv arduino_dist/arduino-${version}/lib/{arduino-core,pde}.jar $out/share/arduino/lib/
231 # Delete the directory now that the jars are copied out
232 rm -r arduino_dist
233 # Extract and patch the Teensyduino installer
234 cp ${teensyduino_src} ./TeensyduinoInstall.${teensy_architecture}
235 chmod +w ./TeensyduinoInstall.${teensy_architecture}
236 upx -d ./TeensyduinoInstall.${teensy_architecture}
237 patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
238 --set-rpath "${teensy_libpath}" \
239 ./TeensyduinoInstall.${teensy_architecture}
240 chmod +x ./TeensyduinoInstall.${teensy_architecture}
241 ./TeensyduinoInstall.${teensy_architecture} --dir=$out/share/arduino
242 # Check for successful installation
243 [ -d $out/share/arduino/hardware/teensy ] || exit 1
244 # After the install, copy the built jars back
245 mv $out/share/arduino/lib/arduino-core.jar.bak $out/share/arduino/lib/arduino-core.jar
246 mv $out/share/arduino/lib/pde.jar.bak $out/share/arduino/lib/pde.jar
247 ''}
248 '';
249
250 # So we don't accidentally mess with firmware files
251 dontStrip = true;
252 dontPatchELF = true;
253
254 preFixup = ''
255 for file in $(find $out -type f \( -perm /0111 -o -name \*.so\* \) ); do
256 patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$file" || true
257 patchelf --set-rpath ${rpath}:$out/lib $file || true
258 done
259
260 ${lib.concatMapStringsSep "\n" (
261 { jar, file }:
262 ''
263 jar xvf $out/${jar} ${file}
264 patchelf --set-rpath $rpath ${file}
265 jar uvf $out/${jar} ${file}
266 rm -f ${file}
267 ''
268 ) patchelfInJars}
269
270 # avrdude_bin is linked against libtinfo.so.5
271 mkdir $out/lib/
272 ln -s ${lib.makeLibraryPath [ ncurses5 ]}/libtinfo.so.5 $out/lib/libtinfo.so.5
273
274 ${lib.optionalString withTeensyduino ''
275 # Patch the Teensy loader binary
276 patchelf --debug \
277 --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
278 --set-rpath "${teensy_libpath}" \
279 $out/share/arduino/hardware/tools/teensy{,_ports,_reboot,_restart,_serialmon}
280 ''}
281 '';
282
283 meta = {
284 description = "Open-source electronics prototyping platform";
285 mainProgram = "arduino";
286 homepage = "https://www.arduino.cc/";
287 license = if withTeensyduino then lib.licenses.unfreeRedistributable else lib.licenses.gpl2;
288 sourceProvenance = with lib.sourceTypes; [
289 binaryBytecode
290 binaryNativeCode
291 ];
292 platforms = lib.platforms.linux;
293 maintainers = with lib.maintainers; [
294 antono
295 auntie
296 robberer
297 bjornfor
298 bergey
299 ];
300 };
301}