3
# Setup script for PIL 1.1.5 and later
5
# Usage: python setup.py install
8
import glob, os, re, struct, string, sys
10
from distutils.spawn import find_executable
12
# make it possible to run the setup script from another directory
1
from __future__ import print_function
9
from distutils.command.build_ext import build_ext
14
os.chdir(os.path.dirname(sys.argv[0]))
19
# map root to (root/lib, root/include)
20
return os.path.join(root, "lib"), os.path.join(root, "include")
22
# --------------------------------------------------------------------
25
# Use None to look for the libraries in well-known library locations.
26
# Use a string to specify a single directory, for both the library and
27
# the include files. Use a tuple to specify separate directories:
28
# (libpath, includepath). Examples:
30
# JPEG_ROOT = "/home/libraries/jpeg-6b"
31
# TIFF_ROOT = "/opt/tiff/lib", "/opt/tiff/include"
33
# If you have "lib" and "include" directories under a common parent,
34
# you can use the "libinclude" helper:
36
# TIFF_ROOT = libinclude("/opt/tiff")
45
# FIXME: add mechanism to explicitly *disable* the use of a library
47
# --------------------------------------------------------------------
51
DESCRIPTION = "Python Imaging Library"
52
AUTHOR = "Secret Labs AB (PythonWare)", "info@pythonware.com"
53
HOMEPAGE = "http://www.pythonware.com/products/pil"
54
DOWNLOAD_URL = "http://effbot.org/downloads/%s-%s.tar.gz" # name, version
56
# --------------------------------------------------------------------
12
host_platform = sysconfig.get_platform()
14
from distutils import sysconfig
15
host_platform = sys.platform
17
from setuptools import Extension, setup, find_packages
60
21
"decode", "encode", "map", "display", "outline", "path",
64
"Access", "Antialias", "Bands", "BitDecode", "Blend", "Chops",
65
"Convert", "ConvertYCbCr", "Copy", "Crc32", "Crop", "Dib", "Draw",
25
"Access", "AlphaComposite", "Antialias", "Bands", "BitDecode", "Blend",
26
"Chops", "Convert", "ConvertYCbCr", "Copy", "Crc32", "Crop", "Dib", "Draw",
66
27
"Effects", "EpsEncode", "File", "Fill", "Filter", "FliDecode",
67
28
"Geometry", "GetBBox", "GifDecode", "GifEncode", "HexDecode",
68
29
"Histo", "JpegDecode", "JpegEncode", "LzwDecode", "Matrix",
71
32
"QuantHeap", "PcdDecode", "PcxDecode", "PcxEncode", "Point",
72
33
"RankFilter", "RawDecode", "RawEncode", "Storage", "SunRleDecode",
73
34
"TgaRleDecode", "Unpack", "UnpackYCC", "UnsharpMask", "XbmDecode",
74
"XbmEncode", "ZipDecode", "ZipEncode"
77
# --------------------------------------------------------------------
81
from setup_site import *
85
# --------------------------------------------------------------------
87
from distutils import sysconfig
88
from distutils.core import Extension, setup
89
from distutils.command.build_ext import build_ext
96
def add_directory(path, dir, where=None):
35
"XbmEncode", "ZipDecode", "ZipEncode")
38
def _add_directory(path, dir, where=None):
97
39
if dir and os.path.isdir(dir) and dir not in path:
101
43
path.insert(where, dir)
103
def find_include_file(self, include):
46
def _find_include_file(self, include):
104
47
for directory in self.compiler.include_dirs:
105
48
if os.path.isfile(os.path.join(directory, include)):
109
def find_library_file(self, library):
53
def _find_library_file(self, library):
110
54
return self.compiler.find_library_file(self.compiler.library_dirs, library)
112
def find_version(filename):
57
def _find_version(filename):
113
58
for line in open(filename).readlines():
114
59
m = re.search("VERSION\s*=\s*\"([^\"]+)\"", line)
119
VERSION = find_version("PIL/Image.py")
65
def _lib_include(root):
66
# map root to (root/lib, root/include)
67
return os.path.join(root, "lib"), os.path.join(root, "include")
71
return open(file, 'rb').read()
77
print('XXXXX _tkinter not found XXXXX')
121
91
class pil_build_ext(build_ext):
93
def add_gcc_paths(self):
94
gcc = sysconfig.get_config_var('CC')
95
tmpfile = os.path.join(self.build_temp, 'gccpaths')
96
if not os.path.exists(self.build_temp):
97
os.makedirs(self.build_temp)
98
ret = os.system('%s -E -v - </dev/null 2>%s 1>/dev/null' % (gcc, tmpfile))
105
with open(tmpfile) as fp:
106
for line in fp.readlines():
107
if line.startswith("gcc version"):
109
elif line.startswith("#include <...>"):
111
elif line.startswith("End of search list"):
113
elif is_gcc and line.startswith("LIBRARY_PATH"):
114
for d in line.strip().split("=")[1].split(":"):
115
d = os.path.normpath(d)
117
_add_directory(self.compiler.library_dirs,
119
elif is_gcc and in_incdirs and '/gcc/' not in line:
120
_add_directory(self.compiler.include_dirs,
123
125
def build_extensions(self):
127
129
library_dirs = []
128
130
include_dirs = []
130
add_directory(include_dirs, "libImaging")
132
_add_directory(include_dirs, "libImaging")
135
# add configured kits
137
for root in (TCL_ROOT, JPEG_ROOT, TCL_ROOT, TIFF_ROOT, ZLIB_ROOT,
138
FREETYPE_ROOT, LCMS_ROOT):
139
if isinstance(root, type(())):
140
lib_root, include_root = root
142
lib_root = include_root = root
143
_add_directory(library_dirs, lib_root)
144
_add_directory(include_dirs, include_root)
133
147
# add platform directories
135
if sys.platform == "cygwin":
149
if host_platform == "cygwin":
136
150
# pythonX.Y.dll.a is in the /usr/lib/pythonX.Y/config directory
137
add_directory(library_dirs, os.path.join(
138
"/usr/lib", "python%s" % sys.version[:3], "config"
151
_add_directory(library_dirs, os.path.join(
152
"/usr/lib", "python%s" % sys.version[:3], "config"))
141
elif sys.platform == "darwin":
154
elif host_platform == "darwin":
142
155
# attempt to make sure we pick freetype2 over other versions
143
add_directory(include_dirs, "/sw/include/freetype2")
144
add_directory(include_dirs, "/sw/lib/freetype2/include")
156
_add_directory(include_dirs, "/sw/include/freetype2")
157
_add_directory(include_dirs, "/sw/lib/freetype2/include")
145
158
# fink installation directories
146
add_directory(library_dirs, "/sw/lib")
147
add_directory(include_dirs, "/sw/include")
159
_add_directory(library_dirs, "/sw/lib")
160
_add_directory(include_dirs, "/sw/include")
148
161
# darwin ports installation directories
149
add_directory(library_dirs, "/opt/local/lib")
150
add_directory(include_dirs, "/opt/local/include")
152
elif find_executable('dpkg-architecture'):
153
# Debian/Ubuntu multiarch support.
154
proc = subprocess.Popen(
155
'dpkg-architecture -qDEB_HOST_MULTIARCH'.split(),
156
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
157
stdout, stderr = proc.communicate()
158
multiarch_path = stdout.strip()
159
add_directory(include_dirs, '/usr/include/' + multiarch_path)
160
add_directory(library_dirs, '/usr/lib/' + multiarch_path)
162
add_directory(library_dirs, "/usr/local/lib")
162
_add_directory(library_dirs, "/opt/local/lib")
163
_add_directory(include_dirs, "/opt/local/include")
164
# freetype2 ships with X11
165
_add_directory(library_dirs, "/usr/X11/lib")
166
_add_directory(include_dirs, "/usr/X11/include")
168
elif host_platform.startswith("linux"):
170
self.add_multiarch_paths()
172
_add_directory(library_dirs, "/usr/local/lib")
163
173
# FIXME: check /opt/stuff directories here?
165
175
prefix = sysconfig.get_config_var("prefix")
167
add_directory(library_dirs, os.path.join(prefix, "lib"))
168
add_directory(include_dirs, os.path.join(prefix, "include"))
177
_add_directory(library_dirs, os.path.join(prefix, "lib"))
178
_add_directory(include_dirs, os.path.join(prefix, "include"))
171
181
# locate tkinter libraries
191
201
TCL_ROOT = os.path.abspath(TCL_ROOT)
192
202
if os.path.isfile(os.path.join(TCL_ROOT, "include", "tk.h")):
193
203
# FIXME: use distutils logging (?)
194
print "--- using Tcl/Tk libraries at", TCL_ROOT
195
print "--- using Tcl/Tk version", TCL_VERSION
196
TCL_ROOT = libinclude(TCL_ROOT)
204
print("--- using Tcl/Tk libraries at", TCL_ROOT)
205
print("--- using Tcl/Tk version", TCL_VERSION)
206
TCL_ROOT = _lib_include(TCL_ROOT)
202
# add configured kits
204
for root in (TCL_ROOT, JPEG_ROOT, TCL_ROOT, TIFF_ROOT, ZLIB_ROOT,
205
FREETYPE_ROOT, LCMS_ROOT):
206
if isinstance(root, type(())):
207
lib_root, include_root = root
209
lib_root = include_root = root
210
add_directory(library_dirs, lib_root)
211
add_directory(include_dirs, include_root)
214
212
# add standard directories
216
214
# look for tcl specific subdirectory (e.g debian)
218
216
tcl_dir = "/usr/include/tcl" + TCL_VERSION
219
217
if os.path.isfile(os.path.join(tcl_dir, "tk.h")):
220
add_directory(include_dirs, tcl_dir)
218
_add_directory(include_dirs, tcl_dir)
222
220
# standard locations
223
add_directory(library_dirs, "/usr/local/lib")
224
add_directory(include_dirs, "/usr/local/include")
221
_add_directory(library_dirs, "/usr/local/lib")
222
_add_directory(include_dirs, "/usr/local/include")
226
add_directory(library_dirs, "/usr/lib")
227
add_directory(include_dirs, "/usr/include")
224
_add_directory(library_dirs, "/usr/lib")
225
_add_directory(include_dirs, "/usr/include")
230
228
# insert new dirs *before* default libs, to avoid conflicts
240
238
zlib = jpeg = tiff = freetype = tcl = tk = lcms = None
241
239
feature = feature()
243
if find_include_file(self, "zlib.h"):
244
if find_library_file(self, "z"):
241
if _find_include_file(self, "zlib.h"):
242
if _find_library_file(self, "z"):
245
243
feature.zlib = "z"
246
elif sys.platform == "win32" and find_library_file(self, "zlib"):
247
feature.zlib = "zlib" # alternative name
244
elif host_platform == "win32" and _find_library_file(self, "zlib"):
245
feature.zlib = "zlib" # alternative name
249
if find_include_file(self, "jpeglib.h"):
250
if find_library_file(self, "jpeg"):
247
if _find_include_file(self, "jpeglib.h"):
248
if _find_library_file(self, "jpeg"):
251
249
feature.jpeg = "jpeg"
252
elif sys.platform == "win32" and find_library_file(self, "libjpeg"):
253
feature.jpeg = "libjpeg" # alternative name
250
elif host_platform == "win32" and _find_library_file(self,
252
feature.jpeg = "libjpeg" # alternative name
255
if find_library_file(self, "tiff"):
254
if _find_library_file(self, "tiff"):
256
255
feature.tiff = "tiff"
258
if find_library_file(self, "freetype"):
257
if _find_library_file(self, "freetype"):
259
258
# look for freetype2 include files
260
259
freetype_version = 0
261
260
for dir in self.compiler.include_dirs:
274
273
feature.freetype = "freetype"
275
274
feature.freetype_version = freetype_version
277
add_directory(self.compiler.include_dirs, dir, 0)
276
_add_directory(self.compiler.include_dirs, dir, 0)
279
if find_include_file(self, "lcms.h"):
280
if find_library_file(self, "lcms"):
278
if _find_include_file(self, "lcms.h"):
279
if _find_library_file(self, "lcms"):
281
280
feature.lcms = "lcms"
283
if _tkinter and find_include_file(self, "tk.h"):
282
if _tkinter and _find_include_file(self, "tk.h"):
284
283
# the library names may vary somewhat (e.g. tcl84 or tcl8.4)
285
284
version = TCL_VERSION[0] + TCL_VERSION[2]
286
if find_library_file(self, "tcl" + version):
285
if _find_library_file(self, "tcl" + version):
287
286
feature.tcl = "tcl" + version
288
elif find_library_file(self, "tcl" + TCL_VERSION):
287
elif _find_library_file(self, "tcl" + TCL_VERSION):
289
288
feature.tcl = "tcl" + TCL_VERSION
290
if find_library_file(self, "tk" + version):
289
if _find_library_file(self, "tk" + version):
291
290
feature.tk = "tk" + version
292
elif find_library_file(self, "tk" + TCL_VERSION):
291
elif _find_library_file(self, "tk" + TCL_VERSION):
293
292
feature.tk = "tk" + TCL_VERSION
298
297
files = ["_imaging.c"]
298
for file in _IMAGING:
300
299
files.append(file + ".c")
301
for file in LIBIMAGING:
300
for file in _LIB_IMAGING:
302
301
files.append(os.path.join("libImaging", file + ".c"))
310
309
libs.append(feature.zlib)
311
310
defs.append(("HAVE_LIBZ", None))
312
if sys.platform == "win32":
311
if host_platform == "win32":
313
312
libs.extend(["kernel32", "user32", "gdi32"])
314
if struct.unpack("h", "\0\1")[0] == 1:
313
if struct.unpack("h", "\0\1".encode('ascii'))[0] == 1:
315
314
defs.append(("WORDS_BIGENDIAN", None))
317
316
exts = [(Extension(
318
"_imaging", files, libraries=libs, define_macros=defs
317
"_imaging", files, libraries=libs, define_macros=defs))]
322
320
# additional libraries
327
325
defs.append(("USE_FREETYPE_2_0", None))
328
326
exts.append(Extension(
329
327
"_imagingft", ["_imagingft.c"], libraries=["freetype"],
333
330
if os.path.isfile("_imagingtiff.c") and feature.tiff:
334
331
exts.append(Extension(
335
"_imagingtiff", ["_imagingtiff.c"], libraries=["tiff"]
332
"_imagingtiff", ["_imagingtiff.c"], libraries=["tiff"]))
338
334
if os.path.isfile("_imagingcms.c") and feature.lcms:
340
if sys.platform == "win32":
336
if host_platform == "win32":
341
337
extra.extend(["user32", "gdi32"])
342
338
exts.append(Extension(
343
"_imagingcms", ["_imagingcms.c"], libraries=["lcms"] + extra
339
"_imagingcms", ["_imagingcms.c"], libraries=["lcms"] + extra))
346
if sys.platform == "darwin":
341
if host_platform == "darwin":
347
342
# locate Tcl/Tk frameworks
349
344
framework_roots = [
350
345
"/Library/Frameworks",
351
"/System/Library/Frameworks"
346
"/System/Library/Frameworks"]
353
347
for root in framework_roots:
354
348
if (os.path.exists(os.path.join(root, "Tcl.framework")) and
355
349
os.path.exists(os.path.join(root, "Tk.framework"))):
356
print "--- using frameworks at", root
350
print("--- using frameworks at %s" % root)
357
351
frameworks = ["-framework", "Tcl", "-framework", "Tk"]
358
352
dir = os.path.join(root, "Tcl.framework", "Headers")
359
add_directory(self.compiler.include_dirs, dir, 0)
353
_add_directory(self.compiler.include_dirs, dir, 0)
360
354
dir = os.path.join(root, "Tk.framework", "Headers")
361
add_directory(self.compiler.include_dirs, dir, 1)
355
_add_directory(self.compiler.include_dirs, dir, 1)
364
358
exts.append(Extension(
365
359
"_imagingtk", ["_imagingtk.c", "Tk/tkImaging.c"],
366
extra_compile_args=frameworks, extra_link_args=frameworks
368
feature.tcl = feature.tk = 1 # mark as present
360
extra_compile_args=frameworks, extra_link_args=frameworks))
361
feature.tcl = feature.tk = 1 # mark as present
369
362
elif feature.tcl and feature.tk:
370
363
exts.append(Extension(
371
364
"_imagingtk", ["_imagingtk.c", "Tk/tkImaging.c"],
372
libraries=[feature.tcl, feature.tk]
365
libraries=[feature.tcl, feature.tk]))
375
367
if os.path.isfile("_imagingmath.c"):
376
368
exts.append(Extension("_imagingmath", ["_imagingmath.c"]))
392
384
def summary_report(self, feature, unsafe_zlib):
395
print "PIL", VERSION, "SETUP SUMMARY"
397
print "version ", VERSION
398
v = string.split(sys.version, "[")
399
print "platform ", sys.platform, string.strip(v[0])
387
print("SETUP SUMMARY (Pillow %s / PIL %s)" % (VERSION, PIL_VERSION))
389
print("version %s" % VERSION)
390
v = sys.version.split("[")
391
print("platform %s %s" % (host_platform, v[0].strip()))
401
print " ", string.strip("[" + v)
393
print(" [%s" % v.strip())
405
397
(feature.tcl and feature.tk, "TKINTER"),
414
406
for option in options:
416
print "---", option[1], "support available"
408
print("--- %s support available" % option[1])
418
print "***", option[1], "support not available",
410
print("*** %s support not available" % option[1])
419
411
if option[1] == "TKINTER" and _tkinter:
420
412
version = _tkinter.TCL_VERSION
421
print "(Tcl/Tk %s libraries needed)" % version,
413
print("(Tcl/Tk %s libraries needed)" % version)
425
417
if feature.zlib and unsafe_zlib:
427
print "*** Warning: zlib", unsafe_zlib,
428
print "may contain a security vulnerability."
429
print "*** Consider upgrading to zlib 1.2.3 or newer."
430
print "*** See: http://www.kb.cert.org/vuls/id/238678"
431
print " http://www.kb.cert.org/vuls/id/680620"
432
print " http://www.gzip.org/zlib/advisory-2002-03-11.txt"
419
print("*** Warning: zlib", unsafe_zlib)
420
print("may contain a security vulnerability.")
421
print("*** Consider upgrading to zlib 1.2.3 or newer.")
422
print("*** See: http://www.kb.cert.org/vuls/id/238678")
423
print(" http://www.kb.cert.org/vuls/id/680620")
424
print(" http://www.gzip.org/zlib/advisory-2002-03-11.txt")
438
print "To add a missing option, make sure you have the required"
439
print "library, and set the corresponding ROOT variable in the"
440
print "setup.py script."
430
print("To add a missing option, make sure you have the required")
431
print("library, and set the corresponding ROOT variable in the")
432
print("setup.py script.")
443
print "To check the build, run the selftest.py script."
435
print("To check the build, run the selftest.py script.")
445
437
def check_zlib_version(self, include_dirs):
446
438
# look for unsafe versions of zlib
457
449
if m.group(1) < "1.2.3":
458
450
return m.group(1)
463
if __name__ == "__main__":
466
# add necessary to distutils (for backwards compatibility)
467
from distutils.dist import DistributionMetadata
468
DistributionMetadata.classifiers = None
469
DistributionMetadata.download_url = None
470
DistributionMetadata.platforms = None
475
author=AUTHOR[0], author_email=AUTHOR[1],
477
"Development Status :: 6 - Mature",
478
"Topic :: Multimedia :: Graphics",
479
"Topic :: Multimedia :: Graphics :: Capture :: Digital Camera",
480
"Topic :: Multimedia :: Graphics :: Capture :: Scanners",
481
"Topic :: Multimedia :: Graphics :: Capture :: Screen Capture",
482
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
483
"Topic :: Multimedia :: Graphics :: Viewers",
485
cmdclass = {"build_ext": pil_build_ext},
486
description=DESCRIPTION,
487
download_url=DOWNLOAD_URL % (NAME, VERSION),
488
ext_modules = [Extension("_imaging", ["_imaging.c"])], # dummy
490
license="Python (MIT style)",
491
long_description=DESCRIPTION,
493
package_dir={"": "PIL"},
495
platforms="Python 1.5.2 and later.",
496
scripts = glob.glob("Scripts/pil*.py"),
452
# http://hg.python.org/users/barry/rev/7e8deab93d5a
453
def add_multiarch_paths(self):
454
# Debian/Ubuntu multiarch support.
455
# https://wiki.ubuntu.com/MultiarchSpec
457
tmpfile = os.path.join(self.build_temp, 'multiarch')
458
if not os.path.exists(self.build_temp):
459
os.makedirs(self.build_temp)
460
ret = os.system('dpkg-architecture -qDEB_HOST_MULTIARCH > %s' %
463
'dpkg-architecture -qDEB_HOST_MULTIARCH > %s 2> /dev/null' %
467
fp = open(tmpfile, 'r')
468
multiarch_path_component = fp.readline().strip()
469
_add_directory(self.compiler.library_dirs,
470
'/usr/lib/' + multiarch_path_component)
471
_add_directory(self.compiler.include_dirs,
472
'/usr/include/' + multiarch_path_component)
479
description='Python Imaging Library (fork)',
481
_read('README.rst') +
482
_read('docs/INSTALL.txt') +
483
_read('docs/HISTORY.txt')).decode('utf-8'),
484
author='Alex Clark (fork author)',
485
author_email='aclark@aclark.net',
486
url='http://github.com/python-imaging/Pillow',
488
"Development Status :: 6 - Mature",
489
"Topic :: Multimedia :: Graphics",
490
"Topic :: Multimedia :: Graphics :: Capture :: Digital Camera",
491
"Topic :: Multimedia :: Graphics :: Capture :: Scanners",
492
"Topic :: Multimedia :: Graphics :: Capture :: Screen Capture",
493
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
494
"Topic :: Multimedia :: Graphics :: Viewers",
495
"Programming Language :: Python :: 2",
496
"Programming Language :: Python :: 2.6",
497
"Programming Language :: Python :: 2.7",
498
"Programming Language :: Python :: 3",
499
"Programming Language :: Python :: 3.2",
500
"Programming Language :: Python :: 3.3",
502
cmdclass={"build_ext": pil_build_ext},
503
ext_modules=[Extension("_imaging", ["_imaging.c"])],
504
packages=find_packages(),
505
scripts=glob.glob("Scripts/pil*.py"),