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