1{
2 config,
3 stdenv,
4 lib,
5 fetchurl,
6 fetchpatch2,
7 pkg-config,
8 zlib,
9 expat,
10 openssl,
11 autoconf,
12 libjpeg,
13 libpng,
14 libtiff,
15 freetype,
16 fontconfig,
17 libpaper,
18 jbig2dec,
19 libiconv,
20 ijs,
21 lcms2,
22 callPackage,
23 bash,
24 buildPackages,
25 openjpeg,
26 fixDarwinDylibNames,
27 cupsSupport ? config.ghostscript.cups or (!stdenv.hostPlatform.isDarwin),
28 cups,
29 x11Support ? cupsSupport,
30 xorg, # with CUPS, X11 only adds very little
31 dynamicDrivers ? true,
32
33 # for passthru.tests
34 graphicsmagick,
35 imagemagick,
36 libspectre,
37 lilypond,
38 pstoedit,
39 python3,
40}:
41
42let
43 fonts = stdenv.mkDerivation {
44 name = "ghostscript-fonts";
45
46 srcs = [
47 (fetchurl {
48 url = "mirror://sourceforge/gs-fonts/ghostscript-fonts-std-8.11.tar.gz";
49 hash = "sha256-DrbzVhGfLkmyVjIQhS4X9X+dzFdV81Cmmkag1kGgxAE=";
50 })
51 (fetchurl {
52 url = "mirror://gnu/ghostscript/gnu-gs-fonts-other-6.0.tar.gz";
53 hash = "sha256-gUbMzEaZ/p2rhBRGvdFwOfR2nJA+zrVECRiLkgdUqrM=";
54 })
55 # ... add other fonts here
56 ];
57
58 installPhase = ''
59 mkdir "$out"
60 mv -v * "$out/"
61 '';
62 };
63
64in
65stdenv.mkDerivation rec {
66 pname = "ghostscript${lib.optionalString x11Support "-with-X"}";
67 version = "10.05.1";
68
69 src = fetchurl {
70 url = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs${
71 lib.replaceStrings [ "." ] [ "" ] version
72 }/ghostscript-${version}.tar.xz";
73 hash = "sha256-IvK9yhXCiDDJcVzdxcKW6maJi/2rC2BKTgvP6wOvbK0=";
74 };
75
76 patches = [
77 ./urw-font-files.patch
78 ./doc-no-ref.diff
79
80 # Support SOURCE_DATE_EPOCH for reproducible builds
81 (fetchpatch2 {
82 url = "https://salsa.debian.org/debian/ghostscript/-/raw/01e895fea033cc35054d1b68010de9818fa4a8fc/debian/patches/2010_add_build_timestamp_setting.patch";
83 hash = "sha256-XTKkFKzMR2QpcS1YqoxzJnyuGk/l/Y2jdevsmbMtCXA=";
84 })
85 ];
86
87 outputs = [
88 "out"
89 "man"
90 "doc"
91 "fonts"
92 ];
93
94 enableParallelBuilding = true;
95
96 depsBuildBuild = [
97 buildPackages.stdenv.cc
98 ];
99
100 nativeBuildInputs = [
101 pkg-config
102 autoconf
103 zlib
104 ]
105 ++ lib.optional cupsSupport cups
106 ++ lib.optional stdenv.hostPlatform.isDarwin fixDarwinDylibNames;
107
108 buildInputs = [
109 zlib
110 expat
111 openssl
112 libjpeg
113 libpng
114 libtiff
115 freetype
116 fontconfig
117 libpaper
118 jbig2dec
119 libiconv
120 ijs
121 lcms2
122 bash
123 openjpeg
124 ]
125 ++ lib.optionals x11Support [
126 xorg.libICE
127 xorg.libX11
128 xorg.libXext
129 xorg.libXt
130 ]
131 ++ lib.optional cupsSupport cups;
132
133 preConfigure = ''
134 # https://ghostscript.com/doc/current/Make.htm
135 export CCAUX=$CC_FOR_BUILD
136 ${lib.optionalString cupsSupport ''export CUPSCONFIG="${cups.dev}/bin/cups-config"''}
137
138 rm -rf jpeg libpng zlib jasper expat tiff lcms2mt jbig2dec freetype cups/libs ijs openjpeg
139
140 sed "s@if ( test -f \$(INCLUDE)[^ ]* )@if ( true )@; s@INCLUDE=/usr/include@INCLUDE=/no-such-path@" -i base/unix-aux.mak
141 sed "s@^ZLIBDIR=.*@ZLIBDIR=${zlib.dev}/include@" -i configure.ac
142
143 # Sidestep a bug in autoconf-2.69 that sets the compiler for all checks to
144 # $CXX after the part for the vendored copy of tesseract.
145 # `--without-tesseract` is already passed to the outer ./configure, here we
146 # make sure it is also passed to its recursive invocation for buildPlatform
147 # checks when cross-compiling.
148 substituteInPlace configure.ac \
149 --replace-fail "--without-x" "--without-x --without-tesseract"
150
151 autoconf
152 ''
153 + lib.optionalString stdenv.hostPlatform.isDarwin ''
154 export DARWIN_LDFLAGS_SO_PREFIX=$out/lib/
155 '';
156
157 configureFlags = [
158 "--with-system-libtiff"
159 "--without-tesseract"
160 ]
161 ++ lib.optionals dynamicDrivers [
162 "--enable-dynamic"
163 "--disable-hidden-visibility"
164 ]
165 ++ lib.optionals x11Support [
166 "--with-x"
167 ]
168 ++ lib.optionals cupsSupport [
169 "--enable-cups"
170 ];
171
172 # make check does nothing useful
173 doCheck = false;
174
175 # don't build/install statically linked bin/gs
176 buildFlags = [
177 "so"
178 ]
179 # without -headerpad, the following error occurs on Darwin when compiling with X11 support (as of 10.02.0)
180 # error: install_name_tool: changing install names or rpaths can't be redone for: [...]libgs.dylib.10 (the program must be relinked, and you may need to use -headerpad or -headerpad_max_install_names)
181 ++ lib.optional (x11Support && stdenv.hostPlatform.isDarwin) "LDFLAGS=-headerpad_max_install_names";
182 installTargets = [ "soinstall" ];
183
184 postInstall = ''
185 ln -s gsc "$out"/bin/gs
186
187 cp -r Resource "$out/share/ghostscript/${version}"
188
189 mkdir -p $fonts/share/fonts
190 cp -rv ${fonts}/* "$fonts/share/fonts/"
191 ln -s "$fonts/share/fonts" "$out/share/ghostscript/fonts"
192 '';
193
194 # validate dynamic linkage
195 doInstallCheck = true;
196 installCheckPhase = ''
197 runHook preInstallCheck
198
199 $out/bin/gs --version
200 $out/bin/gsx --version
201 pushd examples
202 for f in *.{ps,eps,pdf}; do
203 echo "Rendering $f"
204 $out/bin/gs \
205 -dNOPAUSE \
206 -dBATCH \
207 -sDEVICE=bitcmyk \
208 -sOutputFile=/dev/null \
209 -r600 \
210 -dBufferSpace=100000 \
211 $f
212 done
213 popd # examples
214
215 runHook postInstallCheck
216 '';
217
218 passthru.tests = {
219 test-corpus-render = callPackage ./test-corpus-render.nix { };
220 inherit
221 graphicsmagick
222 imagemagick
223 libspectre
224 lilypond
225 pstoedit
226 ;
227 inherit (python3.pkgs) matplotlib;
228 };
229
230 meta = {
231 homepage = "https://www.ghostscript.com/";
232 description = "PostScript interpreter (mainline version)";
233 longDescription = ''
234 Ghostscript is the name of a set of tools that provides (i) an
235 interpreter for the PostScript language and the PDF file format,
236 (ii) a set of C procedures (the Ghostscript library) that
237 implement the graphics capabilities that appear as primitive
238 operations in the PostScript language, and (iii) a wide variety
239 of output drivers for various file formats and printers.
240 '';
241 license = lib.licenses.agpl3Plus;
242 platforms = lib.platforms.all;
243 maintainers = [ lib.maintainers.tobim ];
244 mainProgram = "gs";
245 };
246}