lol
at 24.11-pre 288 lines 9.8 kB view raw
1{ lib, stdenv, fetchurl, substituteAll 2, pkg-config, autoreconfHook 3, cups, zlib, libjpeg, libusb1, python3Packages, sane-backends 4, dbus, file, ghostscript, usbutils 5, net-snmp, openssl, perl, nettools, avahi 6, bash, util-linux 7# To remove references to gcc-unwrapped 8, removeReferencesTo, qt5 9, withQt5 ? true 10, withPlugin ? false 11, withStaticPPDInstall ? false 12}: 13 14let 15 16 pname = "hplip"; 17 version = "3.23.8"; 18 19 src = fetchurl { 20 url = "mirror://sourceforge/hplip/${pname}-${version}.tar.gz"; 21 hash = "sha256-98wF9ijAz9dQ5UrkFDHB390p6XaC8YtcW6XLLFtLG0Y="; 22 }; 23 24 plugin = fetchurl { 25 url = "https://developers.hp.com/sites/default/files/${pname}-${version}-plugin.run"; 26 hash = "sha256-frsgye3f0M3HE2trKRlfFvMnDEwe+z74IumCdVPrcSY="; 27 }; 28 29 hplipState = substituteAll { 30 inherit version; 31 src = ./hplip.state; 32 }; 33 34 hplipPlatforms = { 35 i686-linux = "x86_32"; 36 x86_64-linux = "x86_64"; 37 armv6l-linux = "arm32"; 38 armv7l-linux = "arm32"; 39 aarch64-linux = "arm64"; 40 }; 41 42 hplipArch = hplipPlatforms.${stdenv.hostPlatform.system} 43 or (throw "HPLIP not supported on ${stdenv.hostPlatform.system}"); 44 45 pluginArches = [ "x86_32" "x86_64" "arm32" "arm64" ]; 46 47in 48 49assert withPlugin -> builtins.elem hplipArch pluginArches 50 || throw "HPLIP plugin not supported on ${stdenv.hostPlatform.system}"; 51 52python3Packages.buildPythonApplication { 53 inherit pname version src; 54 format = "other"; 55 56 buildInputs = [ 57 libjpeg 58 cups 59 libusb1 60 sane-backends 61 dbus 62 file 63 ghostscript 64 net-snmp 65 openssl 66 perl 67 zlib 68 avahi 69 ] ++ lib.optionals withQt5 [ 70 qt5.qtwayland 71 ]; 72 73 nativeBuildInputs = [ 74 pkg-config 75 removeReferencesTo 76 autoreconfHook 77 ] ++ lib.optional withQt5 qt5.wrapQtAppsHook; 78 79 pythonPath = with python3Packages; [ 80 dbus 81 pillow 82 pygobject3 83 reportlab 84 usbutils 85 sip4 86 dbus-python 87 distro 88 ] ++ lib.optionals withQt5 [ 89 pyqt5 90 pyqt5-sip 91 enum-compat 92 ]; 93 94 makeWrapperArgs = [ "--prefix" "PATH" ":" "${nettools}/bin" ]; 95 96 patches = [ 97 # HPLIP's getSystemPPDs() function relies on searching for PPDs below common FHS 98 # paths, and hp-setup crashes if none of these paths actually exist (which they 99 # don't on NixOS). Add the equivalent NixOS path, /var/lib/cups/path/share. 100 # See: https://github.com/NixOS/nixpkgs/issues/21796 101 ./hplip-3.20.11-nixos-cups-ppd-search-path.patch 102 103 # Remove all ImageProcessor functionality since that is closed source 104 (fetchurl { 105 url = "https://web.archive.org/web/20230226174550/https://sources.debian.org/data/main/h/hplip/3.22.10+dfsg0-1/debian/patches/0028-Remove-ImageProcessor-binary-installs.patch"; 106 sha256 = "sha256:18njrq5wrf3fi4lnpd1jqmaqr7ph5d7jxm7f15b1wwrbxir1rmml"; 107 }) 108 109 # Revert changes that break compilation under -Werror=format-security 110 ./revert-snprintf-change.patch 111 ]; 112 113 postPatch = '' 114 # https://github.com/NixOS/nixpkgs/issues/44230 115 substituteInPlace createPPD.sh \ 116 --replace ppdc "${cups}/bin/ppdc" \ 117 --replace "gzip -c" "gzip -cn" 118 119 # HPLIP hardcodes absolute paths everywhere. Nuke from orbit. 120 find . -type f -exec sed -i \ 121 -e s,/etc/hp,$out/etc/hp,g \ 122 -e s,/etc/sane.d,$out/etc/sane.d,g \ 123 -e s,/usr/include/libusb-1.0,${libusb1.dev}/include/libusb-1.0,g \ 124 -e s,/usr/share/hal/fdi/preprobe/10osvendor,$out/share/hal/fdi/preprobe/10osvendor,g \ 125 -e s,/usr/lib/systemd/system,$out/lib/systemd/system,g \ 126 -e s,/var/lib/hp,$out/var/lib/hp,g \ 127 -e s,/usr/bin/perl,${perl}/bin/perl,g \ 128 -e s,/usr/bin/file,${file}/bin/file,g \ 129 -e s,/usr/bin/gs,${ghostscript}/bin/gs,g \ 130 -e s,/usr/share/cups/fonts,${ghostscript}/share/ghostscript/fonts,g \ 131 -e "s,ExecStart=/usr/bin/python /usr/bin/hp-config_usb_printer,ExecStart=$out/bin/hp-config_usb_printer,g" \ 132 -e s,Exec=/usr/bin/hp-uiscan,Exec=hp-uiscan,g \ 133 -e s,Icon=/usr/share/icons/Humanity/devices/48/printer.svg,Icon=printer,g \ 134 -e s,Icon=@abs_datadir@/hplip/data/images/128x128/hp_logo.png,Icon=hp_logo,g \ 135 {} + 136 137 echo 'AUTOMAKE_OPTIONS = foreign' >> Makefile.am 138 ''; 139 140 configureFlags = let out = placeholder "out"; in 141 [ 142 "--with-hpppddir=${out}/share/cups/model/HP" 143 "--with-cupsfilterdir=${out}/lib/cups/filter" 144 "--with-cupsbackenddir=${out}/lib/cups/backend" 145 "--with-icondir=${out}/share/applications" 146 "--with-systraydir=${out}/xdg/autostart" 147 "--with-mimedir=${out}/etc/cups" 148 "--enable-policykit" 149 "--disable-qt4" 150 151 # remove ImageProcessor usage, it causes segfaults, see 152 # https://bugs.launchpad.net/hplip/+bug/1788706 153 # https://bugs.launchpad.net/hplip/+bug/1787289 154 "--disable-imageProcessor-build" 155 ] 156 ++ lib.optional withStaticPPDInstall "--enable-cups-ppd-install" 157 ++ lib.optional withQt5 "--enable-qt5" 158 ; 159 160 # Prevent 'ppdc: Unable to find include file "<font.defs>"' which prevent 161 # generation of '*.ppd' files. 162 # This seems to be a 'ppdc' issue when the tool is run in a hermetic sandbox. 163 # Could not find how to fix the problem in 'ppdc' so this is a workaround. 164 CUPS_DATADIR = "${cups}/share/cups"; 165 166 makeFlags = let out = placeholder "out"; in [ 167 "halpredir=${out}/share/hal/fdi/preprobe/10osvendor" 168 "rulesdir=${out}/etc/udev/rules.d" 169 "policykit_dir=${out}/share/polkit-1/actions" 170 "policykit_dbus_etcdir=${out}/etc/dbus-1/system.d" 171 "policykit_dbus_sharedir=${out}/share/dbus-1/system-services" 172 "hplip_confdir=${out}/etc/hp" 173 "hplip_statedir=${out}/var/lib/hp" 174 ]; 175 176 postConfigure = '' 177 # don't save timestamp, in order to improve reproducibility 178 substituteInPlace Makefile \ 179 --replace "GZIP_ENV = --best" "GZIP_ENV = --best -n" 180 ''; 181 182 enableParallelBuilding = true; 183 enableParallelInstalling = false; 184 185 # 186 # Running `hp-diagnose_plugin -g` can be used to diagnose 187 # issues with plugins. 188 # 189 postInstall = '' 190 for resolution in 16x16 32x32 64x64 128x128 256x256; do 191 mkdir -p $out/share/icons/hicolor/$resolution/apps 192 ln -s $out/share/hplip/data/images/$resolution/hp_logo.png \ 193 $out/share/icons/hicolor/$resolution/apps/hp_logo.png 194 done 195 '' + lib.optionalString withPlugin '' 196 sh ${plugin} --noexec --keep 197 cd plugin_tmp 198 199 cp plugin.spec $out/share/hplip/ 200 201 mkdir -p $out/share/hplip/data/firmware 202 cp *.fw.gz $out/share/hplip/data/firmware 203 204 mkdir -p $out/share/hplip/data/plugins 205 cp license.txt $out/share/hplip/data/plugins 206 207 mkdir -p $out/share/hplip/prnt/plugins 208 for plugin in lj hbpl1; do 209 cp $plugin-${hplipArch}.so $out/share/hplip/prnt/plugins 210 chmod 0755 $out/share/hplip/prnt/plugins/$plugin-${hplipArch}.so 211 ln -s $out/share/hplip/prnt/plugins/$plugin-${hplipArch}.so \ 212 $out/share/hplip/prnt/plugins/$plugin.so 213 done 214 215 mkdir -p $out/share/hplip/scan/plugins 216 for plugin in bb_soap bb_marvell bb_soapht bb_escl; do 217 cp $plugin-${hplipArch}.so $out/share/hplip/scan/plugins 218 chmod 0755 $out/share/hplip/scan/plugins/$plugin-${hplipArch}.so 219 ln -s $out/share/hplip/scan/plugins/$plugin-${hplipArch}.so \ 220 $out/share/hplip/scan/plugins/$plugin.so 221 done 222 223 mkdir -p $out/share/hplip/fax/plugins 224 for plugin in fax_marvell; do 225 cp $plugin-${hplipArch}.so $out/share/hplip/fax/plugins 226 chmod 0755 $out/share/hplip/fax/plugins/$plugin-${hplipArch}.so 227 ln -s $out/share/hplip/fax/plugins/$plugin-${hplipArch}.so \ 228 $out/share/hplip/fax/plugins/$plugin.so 229 done 230 231 mkdir -p $out/var/lib/hp 232 cp ${hplipState} $out/var/lib/hp/hplip.state 233 ''; 234 235 # The installed executables are just symlinks into $out/share/hplip, 236 # but wrapPythonPrograms ignores symlinks. We cannot replace the Python 237 # modules in $out/share/hplip with wrapper scripts because they import 238 # each other as libraries. Instead, we emulate wrapPythonPrograms by 239 # 1. Calling patchPythonProgram on the original script in $out/share/hplip 240 # 2. Making our own wrapper pointing directly to the original script. 241 dontWrapPythonPrograms = true; 242 # We also avoid double wrapping in case we add qt5 support 243 dontWrapQtApps = true; 244 preFixup = '' 245 buildPythonPath "$out $pythonPath" 246 247 for bin in $out/bin/*; do 248 py=$(readlink -m $bin) 249 rm $bin 250 echo "patching \`$py'..." 251 patchPythonScript "$py" 252 echo "wrapping \`$bin'..." 253 ${if withQt5 then "makeQtWrapper" else "makeWrapper"} "$py" "$bin" \ 254 --prefix PATH ':' "$program_PATH" \ 255 --set PYTHONNOUSERSITE "true" \ 256 $makeWrapperArgs 257 done 258 ''; 259 260 postFixup = '' 261 substituteInPlace $out/etc/hp/hplip.conf --replace /usr $out 262 # Patch udev rules: 263 # with plugin, they upload firmware to printers, 264 # without plugin, they complain about the missing plugin. 265 substituteInPlace $out/etc/udev/rules.d/56-hpmud.rules \ 266 --replace {,${bash}}/bin/sh \ 267 --replace /usr/bin/nohup "" \ 268 --replace {,${util-linux}/bin/}logger \ 269 --replace {/usr,$out}/bin 270 remove-references-to -t ${stdenv.cc.cc} $(readlink -f $out/lib/*.so) 271 ''; 272 273 # There are some binaries there, which reference gcc-unwrapped otherwise. 274 stripDebugList = [ 275 "share/hplip" "lib/cups/backend" "lib/cups/filter" python3Packages.python.sitePackages "lib/sane" 276 ]; 277 278 meta = with lib; { 279 description = "Print, scan and fax HP drivers for Linux"; 280 homepage = "https://developers.hp.com/hp-linux-imaging-and-printing"; 281 downloadPage = "https://sourceforge.net/projects/hplip/files/hplip/"; 282 license = if withPlugin 283 then licenses.unfree 284 else with licenses; [ mit bsd2 gpl2Plus ]; 285 platforms = [ "i686-linux" "x86_64-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" ]; 286 maintainers = with maintainers; [ ttuegel arthsmn ]; 287 }; 288}