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