nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 autoPatchelfHook,
5 boost186,
6 cmake,
7 copyDesktopItems,
8 imagemagick,
9 fetchpatch,
10 fetchzip,
11 killall,
12 libjpeg,
13 libpng,
14 libtiff,
15 libtool,
16 libusb1,
17 makeDesktopItem,
18 qt5,
19
20 withGui ? true,
21 withNonFreePlugins ? false,
22}:
23
24let
25 pname = "epsonscan2";
26 description = "Epson Scan 2 scanner driver for many modern Epson scanners and multifunction printers";
27 # Epson updates projects without changing their version numbers.
28 # There can be multiple different packages identified by the same
29 #version, so we also tag them with the month and year shown in
30 # the Epson download page.
31 version = "6.7.90.0-2026-01";
32
33 system = stdenv.hostPlatform.system;
34
35 src = fetchzip {
36 url = "https://download3.ebz.epson.net/dsc/f/03/00/17/08/06/1babf9876ebb16956420a601b92ee28b57cd7db7/epsonscan2-6.7.80.0-1.src.tar.gz";
37 hash = "sha256-SHNpnVyoFTwLu3drlL8MFKj/NCKy5U0UDqP08f7u1R4=";
38 };
39 bundle =
40 {
41 "x86_64-linux" = fetchzip {
42 name = "${pname}-bundle";
43 url = "https://download3.ebz.epson.net/dsc/f/03/00/17/08/12/9f3fec0ae80aa5c36f5170377ebcc38c93251e23/epsonscan2-bundle-6.7.80.0.x86_64.deb.tar.gz";
44 hash = "sha256-Smjp2PRcsNN9nP3W++HmKOw85zZj20zEIFEEVSO8lDo=";
45 };
46 }
47 ."${system}" or (throw "Unsupported system: ${system}");
48
49in
50stdenv.mkDerivation {
51 inherit pname src version;
52
53 patches = [
54 ./build.patch
55 ./gcc15.patch
56 (fetchpatch {
57 url = "https://github.com/flathub/net.epson.epsonscan2/raw/f9eb99109e63dbed907f46e36f435e46d7c01aad/patches/0002-Fix-crash.patch";
58 hash = "sha256-Al5DkVnCBNoMtex4G3Zm7uZwTvnWGAjOk5xh/U9WyNU=";
59 })
60 # At the time of writing, some flathub patches are not updated to work with 6.7.90.0-1 (2026/01/01)
61 ./xdg-open.patch # Rebase of https://github.com/flathub/net.epson.epsonscan2/blob/master/patches/0003-Use-XDG-open-to-open-the-directory.patch
62 ./fix-oob-container-access.patch # Rebase of https://github.com/flathub/net.epson.epsonscan2/blob/master/patches/0004-Fix-a-crash-on-an-OOB-container-access.patch
63 (fetchpatch {
64 url = "https://github.com/flathub/net.epson.epsonscan2/raw/f9eb99109e63dbed907f46e36f435e46d7c01aad/patches/0005-Added-missing-headers.patch";
65 hash = "sha256-YJjCI8UNzLciSq9IfcHxiF4isFGM9A5Hn7Kxao/+lpQ=";
66 })
67 ];
68
69 postPatch = ''
70 substituteInPlace src/Controller/Src/Scanner/Engine.cpp \
71 --replace-fail '@KILLALL@' ${lib.getExe killall}
72
73 substituteInPlace src/Controller/Src/Filter/GetOrientation.cpp \
74 --replace-fail '@OCR_ENGINE_GETROTATE@' $out/libexec/epsonscan2-ocr/ocr-engine-getrotate
75 '';
76
77 nativeBuildInputs = [
78 cmake
79 ]
80 ++ lib.optionals withGui [
81 imagemagick # to make icons
82 qt5.wrapQtAppsHook
83 ]
84 ++ lib.optionals withNonFreePlugins [
85 autoPatchelfHook
86 ];
87
88 buildInputs = [
89 boost186 # uses Boost.Optional but epsonscan2 is pre-C++11.
90 libjpeg
91 libpng
92 libtiff
93 libusb1
94 ]
95 ++ lib.optionals withGui [
96 copyDesktopItems
97 qt5.qtbase
98 ]
99 ++ lib.optionals withNonFreePlugins [
100 libtool.lib
101 ];
102
103 cmakeFlags = [
104 # The non-free (Debian) packages uses this directory structure so do the same when compiling
105 # from source so we can easily merge them.
106 "-DCMAKE_INSTALL_LIBDIR=lib/${system}-gnu"
107 # There are many CMakeLists.txt files with various minimum versions. It's much easier to set this
108 # here, instead of substituting those everywhere
109 "-DCMAKE_POLICY_VERSION_MINIMUM=3.10"
110 ]
111 ++ lib.optionals (!withGui) [
112 "-DNO_GUI=ON"
113 ];
114
115 doInstallCheck = true;
116
117 postInstall = ''
118 # But when we put all the libraries in lib/${system}-gnu, then SANE can't find the
119 # required libraries so create a symlink to where it expects them to be.
120 mkdir -p $out/lib/sane
121 for file in $out/lib/${system}-gnu/sane/*.so.*; do
122 ln -s $file $out/lib/sane/
123 done
124 ''
125 + lib.optionalString withGui ''
126 # The icon file extension is .ico but it's actually a png!
127 mkdir -p $out/share/icons/hicolor/{48x48,128x128}/apps
128 magick $src/Resources/Icons/escan2_app.ico -resize 48x48 -delete 1,2,3 $out/share/icons/hicolor/48x48/apps/epsonscan2.png
129 magick $src/Resources/Icons/escan2_app.ico -resize 128x128 -delete 1,2,3 $out/share/icons/hicolor/128x128/apps/epsonscan2.png
130 ''
131 + lib.optionalString withNonFreePlugins ''
132 ar xf ${bundle}/plugins/epsonscan2-non-free-plugin_*.deb
133 tar Jxf data.tar.xz
134 cp -r usr/* $out
135 '';
136
137 desktopItems = lib.optionals withGui [
138 (makeDesktopItem {
139 name = "epsonscan2";
140 exec = "epsonscan2";
141 icon = "epsonscan2";
142 desktopName = "Epson Scan 2";
143 genericName = "Epson Scan 2";
144 comment = description;
145 categories = [
146 "Graphics"
147 "Scanning"
148 ];
149 })
150 ];
151
152 meta = {
153 inherit description;
154 mainProgram = "epsonscan2";
155 longDescription = ''
156 The Epson Scan 2 scanner driver, including optional non-free plugins such
157 as OCR and network scanning.
158
159 To use the SANE backend:
160 ```nix
161 {
162 hardware.sane.extraBackends = [ pkgs.epsonscan2 ];
163 }
164 ```
165
166 Overrides can be used to customise this package. For example, to enable
167 non-free plugins and disable the Epson GUI:
168 ```nix
169 pkgs.epsonscan2.override {
170 withNonFreePlugins = true;
171 withGui = false;
172 }
173 ```
174 '';
175 homepage = "https://support.epson.net/linux/en/epsonscan2.php";
176 platforms = lib.systems.inspect.patternLogicalAnd lib.systems.inspect.patterns.isLinux lib.systems.inspect.patterns.isx86_64;
177 sourceProvenance =
178 with lib.sourceTypes;
179 [ fromSource ] ++ lib.optionals withNonFreePlugins [ binaryNativeCode ];
180 license = with lib.licenses; if withNonFreePlugins then unfree else lgpl21Plus;
181 maintainers = with lib.maintainers; [ james-atkins ];
182 };
183}