1{ config, stdenv, lib, fetchurl, pkg-config, zlib, expat, openssl, autoconf
2, libjpeg, libpng, libtiff, freetype, fontconfig, libpaper, jbig2dec
3, libiconv, ijs, lcms2, fetchpatch, callPackage, bash, buildPackages
4, cupsSupport ? config.ghostscript.cups or (!stdenv.isDarwin), cups
5, x11Support ? cupsSupport, xlibsWrapper # with CUPS, X11 only adds very little
6}:
7
8let
9 fonts = stdenv.mkDerivation {
10 name = "ghostscript-fonts";
11
12 srcs = [
13 (fetchurl {
14 url = "mirror://sourceforge/gs-fonts/ghostscript-fonts-std-8.11.tar.gz";
15 sha256 = "00f4l10xd826kak51wsmaz69szzm2wp8a41jasr4jblz25bg7dhf";
16 })
17 (fetchurl {
18 url = "mirror://gnu/ghostscript/gnu-gs-fonts-other-6.0.tar.gz";
19 sha256 = "1cxaah3r52qq152bbkiyj2f7dx1rf38vsihlhjmrvzlr8v6cqil1";
20 })
21 # ... add other fonts here
22 ];
23
24 installPhase = ''
25 mkdir "$out"
26 mv -v * "$out/"
27 '';
28 };
29
30in
31stdenv.mkDerivation rec {
32 pname = "ghostscript";
33 version = "9.53.3";
34
35 src = fetchurl {
36 url = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs9${lib.versions.minor version}${lib.versions.patch version}/${pname}-${version}.tar.xz";
37 sha512 = "2vif3vgxa5wma16yxvhhkymk4p309y5204yykarq94r5rk890556d2lj5w7acnaa2ymkym6y0zd4vq9sy9ca2346igg2c6dxqkjr0zb";
38 };
39
40 patches = [
41 (fetchpatch {
42 url = "https://github.com/ArtifexSoftware/ghostpdl/commit/41ef9a0bc36b9db7115fbe9623f989bfb47bbade.patch";
43 sha256 = "1qpc6q1fpxshqc0mqgg36kng47kgljk50bmr8p7wn21jgfkh7m8w";
44 })
45 (fetchpatch {
46 url = "https://git.ghostscript.com/?p=ghostpdl.git;a=patch;h=a9bd3dec9fde";
47 name = "CVE-2021-3781.patch";
48 sha256 = "FvbH7cb3ZDCbNRz9DF0kDmLdF7OWNYk90wv44pimU58=";
49 })
50 ./urw-font-files.patch
51 ./doc-no-ref.diff
52 ];
53
54 outputs = [ "out" "man" "doc" ];
55
56 enableParallelBuilding = true;
57
58 depsBuildBuild = [
59 buildPackages.stdenv.cc
60 ];
61
62 nativeBuildInputs = [ pkg-config autoconf zlib ]
63 ++ lib.optional cupsSupport cups;
64
65 buildInputs = [
66 zlib expat openssl
67 libjpeg libpng libtiff freetype fontconfig libpaper jbig2dec
68 libiconv ijs lcms2 bash
69 ]
70 ++ lib.optional x11Support xlibsWrapper
71 ++ lib.optional cupsSupport cups
72 ;
73
74 preConfigure = ''
75 # https://ghostscript.com/doc/current/Make.htm
76 export CCAUX=$CC_FOR_BUILD
77 ${lib.optionalString cupsSupport ''export CUPSCONFIG="${cups.dev}/bin/cups-config"''}
78
79 # requires in-tree (heavily patched) openjpeg
80 rm -rf jpeg libpng zlib jasper expat tiff lcms2mt jbig2dec freetype cups/libs ijs
81
82 sed "s@if ( test -f \$(INCLUDE)[^ ]* )@if ( true )@; s@INCLUDE=/usr/include@INCLUDE=/no-such-path@" -i base/unix-aux.mak
83 sed "s@^ZLIBDIR=.*@ZLIBDIR=${zlib.dev}/include@" -i configure.ac
84
85 autoconf
86 '';
87
88 configureFlags = [
89 "--with-system-libtiff"
90 "--enable-dynamic"
91 ]
92 ++ lib.optional x11Support "--with-x"
93 ++ lib.optionals cupsSupport [
94 "--enable-cups"
95 ];
96
97 # make check does nothing useful
98 doCheck = false;
99
100 # don't build/install statically linked bin/gs
101 buildFlags = [ "so" ];
102 installTargets = [ "soinstall" ];
103
104 postInstall = ''
105 ln -s gsc "$out"/bin/gs
106
107 cp -r Resource "$out/share/ghostscript/${version}"
108
109 ln -s "${fonts}" "$out/share/ghostscript/fonts"
110 '' + lib.optionalString stdenv.isDarwin ''
111 for file in $out/lib/*.dylib* ; do
112 install_name_tool -id "$file" $file
113 done
114 '';
115
116 # dynamic library name only contains maj.min, eg. '9.53'
117 dylib_version = lib.versions.majorMinor version;
118 preFixup = lib.optionalString stdenv.isDarwin ''
119 install_name_tool -change libgs.dylib.$dylib_version $out/lib/libgs.dylib.$dylib_version $out/bin/gs
120 '';
121
122 # validate dynamic linkage
123 doInstallCheck = true;
124 installCheckPhase = ''
125 runHook preInstallCheck
126
127 $out/bin/gs --version
128 pushd examples
129 for f in *.{ps,eps,pdf}; do
130 echo "Rendering $f"
131 $out/bin/gs \
132 -dNOPAUSE \
133 -dBATCH \
134 -sDEVICE=bitcmyk \
135 -sOutputFile=/dev/null \
136 -r600 \
137 -dBufferSpace=100000 \
138 $f
139 done
140 popd # examples
141
142 runHook postInstallCheck
143 '';
144
145 passthru.tests.test-corpus-render = callPackage ./test-corpus-render.nix {};
146
147 meta = {
148 homepage = "https://www.ghostscript.com/";
149 description = "PostScript interpreter (mainline version)";
150 longDescription = ''
151 Ghostscript is the name of a set of tools that provides (i) an
152 interpreter for the PostScript language and the PDF file format,
153 (ii) a set of C procedures (the Ghostscript library) that
154 implement the graphics capabilities that appear as primitive
155 operations in the PostScript language, and (iii) a wide variety
156 of output drivers for various file formats and printers.
157 '';
158 license = lib.licenses.agpl3;
159 platforms = lib.platforms.all;
160 maintainers = [ lib.maintainers.viric ];
161 mainProgram = "gs";
162 };
163}