16 , withTeensyduino ? false
17 /* Packages needed for Teensyduino */
34 assert withTeensyduino -> withGui;
36 externalDownloads = import ./downloads.nix {
38 inherit (lib) optionalAttrs;
39 inherit (stdenv.hostPlatform) system;
41 # Some .so-files are later copied from .jar-s to $HOME, so patch them beforehand
43 lib.optional (stdenv.hostPlatform.system == "aarch64-linux") { jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar"; file = "libs/linux/libjSSC-2.8_aarch64.so"; }
44 ++ lib.optional (builtins.match "armv[67]l-linux" stdenv.hostPlatform.system != null) { jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar"; file = "libs/linux/libjSSC-2.8_armhf.so"; }
45 ++ lib.optional (stdenv.hostPlatform.system == "x86_64-linux") { jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar"; file = "libs/linux/libjSSC-2.8_x86_64.so"; }
46 ++ lib.optional (stdenv.hostPlatform.system == "i686-linux") { jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar"; file = "libs/linux/libjSSC-2.8_x86.so"; }
48 # abiVersion 6 is default, but we need 5 for `avrdude_bin` executable
49 ncurses5 = ncurses.override { abiVersion = "5"; };
50 teensy_libpath = lib.makeLibraryPath [
73 if stdenv.hostPlatform.isx86_32 then "linux32"
74 else if stdenv.hostPlatform.isx86_64 then "linux64"
75 else if stdenv.hostPlatform.isAarch64 then "linuxaarch64"
76 else if stdenv.hostPlatform.isAarch32 then "linuxarm"
77 else throw "${stdenv.hostPlatform.system} is not supported in teensy";
80 stdenv.mkDerivation rec {
81 pname = (if withTeensyduino then "teensyduino" else "arduino") + lib.optionalString (!withGui) "-core";
84 src = fetchFromGitHub {
88 sha256 = "sha256-I+PvfGc5F8H/NJOGRa18z7dKyKcO8I8Cg7Tj5yxkYAQ=";
91 teensyduino_version = "156";
92 teensyduino_src = fetchurl {
93 url = "https://www.pjrc.com/teensy/td_${teensyduino_version}/TeensyduinoInstall.${teensy_architecture}";
95 linux64 = "sha256-4DbhmmYrx+rCBpDrYFaC0A88Qv9UEeNlQAkFi3zAstk=";
96 linux32 = "sha256-DlRPOtDxmMPv2Qzhib7vNZdKNZCxmm9YmVNnwUKXK/E=";
97 linuxarm = "sha256-d+DbpER/4lFPcPDFeMG5f3WaUGn8pFchdIDo7Hm0XWs=";
98 linuxaarch64 = "sha256-8keQzhWq7QlAGIbfHEe3lfxpJleMMvBORuPaNrLmM6Y=";
99 }.${teensy_architecture} or (throw "No arduino binaries for ${teensy_architecture}");
101 # Used because teensyduino requires jars be a specific size
102 arduino_dist_src = fetchurl {
103 url = "https://downloads.arduino.cc/arduino-${version}-${teensy_architecture}.tar.xz";
105 linux64 = "sha256-62i93B0cASC+L8oTUKA+40Uxzzf1GEeyEhC25wVFvJs=";
106 linux32 = "sha256-wSxtx3BqXMQCeWQDK8PHkWLlQqQM1Csao8bIk98FrFg=";
107 linuxarm = "sha256-lJ/R1ePq7YtDk3bvloFcn8jswrJH+L63tvH5QpTqfXs=";
108 linuxaarch64 = "sha256-gm8cDjLKNfpcaeO7fw6Kyv1TnWV/ZmH4u++nun9X6jo=";
109 }.${teensy_architecture} or (throw "No arduino binaries for ${teensy_architecture}");
112 # the glib setup hook will populate GSETTINGS_SCHEMAS_PATH,
113 # wrapGAppHooks (among other things) adds it to XDG_DATA_DIRS
114 # so 'save as...' works:
115 nativeBuildInputs = [ glib wrapGAppsHook unzip ];
124 ] ++ lib.optionals withTeensyduino [ upx ];
125 downloadSrcList = builtins.attrValues externalDownloads;
126 downloadDstList = builtins.attrNames externalDownloads;
129 # Copy pre-downloaded files to proper locations
130 download_src=($downloadSrcList)
131 download_dst=($downloadDstList)
132 while [[ "''${#download_src[@]}" -ne 0 ]]; do
133 file_src=''${download_src[0]}
134 file_dst=''${download_dst[0]}
135 mkdir -p $(dirname $file_dst)
136 download_src=(''${download_src[@]:1})
137 download_dst=(''${download_dst[@]:1})
138 cp -v $file_src $file_dst
141 # Deliberately break build.xml's download statement in order to cause
142 # an error if anything needed is missing from download.nix.
143 substituteInPlace build/build.xml \
144 --replace 'ignoreerrors="true"' 'ignoreerrors="false"'
146 cd ./arduino-core && ant
151 # This will be patched into `arduino` wrapper script
152 # Java loads gtk dynamically, so we need to provide it using LD_LIBRARY_PATH
153 dynamicLibraryPath = lib.makeLibraryPath [ gtk3 ];
154 javaPath = lib.makeBinPath [ jdk ];
156 # Everything else will be patched into rpath
157 rpath = lib.makeLibraryPath [ zlib libusb-compat-0_1 libusb1 readline ncurses5 stdenv.cc.cc ];
160 mkdir -p $out/share/arduino
161 cp -r ./build/linux/work/* "$out/share/arduino/"
162 echo -n ${version} > $out/share/arduino/lib/version.txt
164 ${lib.optionalString withGui ''
166 substituteInPlace $out/share/arduino/arduino \
167 --replace "JAVA=java" "JAVA=$javaPath/java" \
168 --replace "LD_LIBRARY_PATH=" "LD_LIBRARY_PATH=$dynamicLibraryPath:"
169 ln -sr "$out/share/arduino/arduino" "$out/bin/arduino"
171 cp -r build/shared/icons $out/share/arduino
172 mkdir -p $out/share/applications
173 cp build/linux/dist/desktop.template $out/share/applications/arduino.desktop
174 substituteInPlace $out/share/applications/arduino.desktop \
175 --replace '<BINARY_LOCATION>' "$out/bin/arduino" \
176 --replace '<ICON_NAME>' "$out/share/arduino/icons/128x128/apps/arduino.png"
179 ${lib.optionalString withTeensyduino ''
180 # Back up the original jars
181 mv $out/share/arduino/lib/arduino-core.jar $out/share/arduino/lib/arduino-core.jar.bak
182 mv $out/share/arduino/lib/pde.jar $out/share/arduino/lib/pde.jar.bak
183 # Extract jars from the arduino distributable package
186 tar xfJ ${arduino_dist_src} arduino-${version}/lib/arduino-core.jar arduino-${version}/lib/pde.jar
188 # Replace the built jars with the official arduino jars
189 mv arduino_dist/arduino-${version}/lib/{arduino-core,pde}.jar $out/share/arduino/lib/
190 # Delete the directory now that the jars are copied out
192 # Extract and patch the Teensyduino installer
193 cp ${teensyduino_src} ./TeensyduinoInstall.${teensy_architecture}
194 chmod +w ./TeensyduinoInstall.${teensy_architecture}
195 upx -d ./TeensyduinoInstall.${teensy_architecture}
196 patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
197 --set-rpath "${teensy_libpath}" \
198 ./TeensyduinoInstall.${teensy_architecture}
199 chmod +x ./TeensyduinoInstall.${teensy_architecture}
200 ./TeensyduinoInstall.${teensy_architecture} --dir=$out/share/arduino
201 # Check for successful installation
202 [ -d $out/share/arduino/hardware/teensy ] || exit 1
203 # After the install, copy the built jars back
204 mv $out/share/arduino/lib/arduino-core.jar.bak $out/share/arduino/lib/arduino-core.jar
205 mv $out/share/arduino/lib/pde.jar.bak $out/share/arduino/lib/pde.jar
209 # So we don't accidentally mess with firmware files
214 for file in $(find $out -type f \( -perm /0111 -o -name \*.so\* \) ); do
215 patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$file" || true
216 patchelf --set-rpath ${rpath}:$out/lib $file || true
219 ${lib.concatMapStringsSep "\n"
222 jar xvf $out/${jar} ${file}
223 patchelf --set-rpath $rpath ${file}
224 jar uvf $out/${jar} ${file}
230 # avrdude_bin is linked against libtinfo.so.5
232 ln -s ${lib.makeLibraryPath [ ncurses5 ]}/libtinfo.so.5 $out/lib/libtinfo.so.5
234 ${lib.optionalString withTeensyduino ''
235 # Patch the Teensy loader binary
237 --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
238 --set-rpath "${teensy_libpath}" \
239 $out/share/arduino/hardware/tools/teensy{,_ports,_reboot,_restart,_serialmon}
244 description = "Open-source electronics prototyping platform";
245 mainProgram = "arduino";
246 homepage = "https://www.arduino.cc/";
247 license = if withTeensyduino then licenses.unfreeRedistributable else licenses.gpl2;
248 sourceProvenance = with sourceTypes; [
252 platforms = platforms.linux;
253 maintainers = with maintainers; [ antono auntie robberer bjornfor bergey ];