1{
2 stdenv,
3 fetchurl,
4 lib,
5 mkDerivation,
6 antiword,
7 aspell,
8 bison,
9 catdoc,
10 catdvi,
11 chmlib,
12 djvulibre,
13 file,
14 gawk,
15 ghostscript,
16 gnugrep,
17 gnused,
18 gnutar,
19 groff,
20 gzip,
21 libiconv,
22 libwpd,
23 libxslt,
24 lyx,
25 makeWrapper,
26 meson,
27 ninja,
28 perl,
29 perlPackages,
30 pkg-config,
31 poppler-utils,
32 python3Packages,
33 qtbase,
34 qttools,
35 unrtf,
36 untex,
37 unzip,
38 which,
39 xapian,
40 zlib,
41 withGui ? true,
42 withPython ? with stdenv; buildPlatform.canExecute hostPlatform,
43}:
44
45let
46 filters = {
47 # "binary-name = package" where:
48 # - "${package}/bin/${binary-name}" is the full path to the binary
49 # - occurrences of `"${binary-name}"` in recoll's filters should be fixed up
50 awk = gawk;
51 antiword = antiword;
52 catppt = catdoc;
53 catdvi = catdvi;
54 djvused = djvulibre;
55 djvutxt = djvulibre;
56 egrep = gnugrep;
57 groff = groff;
58 gunzip = gzip;
59 iconv = libiconv;
60 pdftotext = poppler-utils;
61 ps2ascii = ghostscript;
62 sed = gnused;
63 tar = gnutar;
64 unzip = unzip;
65 xls2csv = catdoc;
66 xsltproc = libxslt;
67 unrtf = unrtf;
68 untex = untex;
69 wpd2html = libwpd;
70 perl = perl.passthru.withPackages (p: [ p.ImageExifTool ]);
71 };
72 filterPath = lib.makeBinPath (map lib.getBin (builtins.attrValues filters));
73 useInotify = if stdenv.hostPlatform.isLinux then "true" else "false";
74in
75
76mkDerivation rec {
77 pname = "recoll";
78 version = "1.43.2";
79
80 src = fetchurl {
81 url = "https://www.recoll.org/${pname}-${version}.tar.gz";
82 hash = "sha256-FbDXknumjktcikOfAe4FKtPmggJGGHasq8dpD+8mNzE=";
83 };
84
85 mesonFlags = [
86 "-Drecollq=true"
87 "-Dwebkit=false"
88 "-Dsystemd=false"
89
90 # this leaks into the final `librecoll-*.so` binary, so we need
91 # to be sure it is taken from `pkgs.file` rather than `stdenv`,
92 # especially when cross-compiling
93 "-Dfile-command=${file}/bin/file"
94
95 ]
96 ++ lib.optionals (!withPython) [
97 "-Dpython-module=false"
98 "-Dpython-chm=false"
99 ]
100 ++ lib.optionals (!withGui) [
101 "-Dqtgui=false"
102 "-Dx11mon=false"
103 ]
104 ++ [
105 "-Dinotify=${useInotify}"
106 ];
107
108 env.NIX_CFLAGS_COMPILE = toString [
109 "-fpermissive" # libxml2-2.12 changed const qualifiers
110 ];
111
112 patches = [
113 # use the same configure based build for darwin as linux
114 ./0001-no-qtgui-darwin-bundle.patch
115 ];
116
117 nativeBuildInputs = [
118 makeWrapper
119 meson
120 ninja
121 pkg-config
122 which
123 ]
124 ++ lib.optionals withGui [
125 qtbase
126 qttools
127 ]
128 ++ lib.optionals withPython [
129 python3Packages.setuptools
130 ];
131
132 buildInputs = [
133 aspell
134 bison
135 chmlib
136 ]
137 ++ lib.optionals withPython [
138 python3Packages.python
139 python3Packages.mutagen
140 ]
141 ++ [
142 xapian
143 zlib
144 file
145 ]
146 ++ lib.optionals withGui [
147 qtbase
148 ]
149 ++ lib.optionals stdenv.hostPlatform.isDarwin [
150 libiconv
151 ];
152
153 qtWrapperArgs = [
154 "--prefix PATH : ${filterPath}"
155 ];
156
157 # the filters search through ${PATH} using a sh proc 'checkcmds' for the
158 # filtering utils. Short circuit this by replacing the filtering command with
159 # the absolute path to the filtering command.
160 postInstall = ''
161 substituteInPlace $out/lib/*/site-packages/recoll/rclconfig.py --replace /usr/share/recoll $out/share/recoll
162 substituteInPlace $out/share/recoll/filters/rclconfig.py --replace /usr/share/recoll $out/share/recoll
163 for f in $out/share/recoll/filters/* ; do
164 if [[ ! "$f" =~ \.zip$ ]]; then
165 ''
166 + lib.concatStrings (
167 lib.mapAttrsToList (k: v: (''
168 substituteInPlace $f --replace '"${k}"' '"${lib.getBin v}/bin/${k}"'
169 '')) filters
170 )
171 + ''
172 substituteInPlace $f --replace '"pstotext"' '"${lib.getBin ghostscript}/bin/ps2ascii"'
173 substituteInPlace $f --replace /usr/bin/perl ${
174 lib.getBin (perl.passthru.withPackages (p: [ p.ImageExifTool ]))
175 }/bin/perl
176 fi
177 done
178 wrapProgram $out/share/recoll/filters/rclaudio.py \
179 --prefix PYTHONPATH : $PYTHONPATH
180 wrapProgram $out/share/recoll/filters/rcljoplin.py \
181 --prefix PYTHONPATH : $out/${python3Packages.python.sitePackages}
182 wrapProgram $out/share/recoll/filters/rclimg \
183 --prefix PERL5LIB : "${with perlPackages; makeFullPerlPath [ ImageExifTool ]}"
184 ''
185 + lib.optionalString stdenv.hostPlatform.isLinux ''
186 substituteInPlace $f --replace '"lyx"' '"${lib.getBin lyx}/bin/lyx"'
187 ''
188 + lib.optionalString (stdenv.hostPlatform.isDarwin && withGui) ''
189 mkdir $out/Applications
190 mv $out/bin/recoll.app $out/Applications
191 '';
192
193 # create symlink after fixup to prevent double wrapping of recoll
194 postFixup = lib.optionalString (stdenv.hostPlatform.isDarwin && withGui) ''
195 ln -s ../Applications/recoll.app/Contents/MacOS/recoll $out/bin/recoll
196 '';
197
198 enableParallelBuilding = false; # XXX: -j44 tried linking befoire librecoll had been created
199
200 meta = with lib; {
201 description = "Full-text search tool";
202 longDescription = ''
203 Recoll is an Xapian frontend that can search through files, archive
204 members, email attachments.
205 '';
206 homepage = "https://www.recoll.org";
207 changelog = "https://www.recoll.org/pages/release-history.html";
208 license = licenses.gpl2Plus;
209 platforms = platforms.unix;
210 maintainers = with maintainers; [
211 jcumming
212 ehmry
213 ];
214
215 # `Makefile.am` assumes the ability to run the hostPlatform's python binary at build time
216 broken = withPython && (with stdenv; !buildPlatform.canExecute hostPlatform);
217 };
218}