mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-11 04:07:21 +03:00
29ddeaa81a
XQuartz ships an older freetype that still has a top-level "ft2build.h" header file. Homebrew's freetype is newer and does not have this file, it only has "freetype2/ft2build.h". setup.py finds the header in XQuartz first, but Homebrew's compiler wrappers intentionally strip out the XQuartz include paths during the build unless the package depends on it explicitly. We want to prefer Homebrew's freetype anyway, so if it's installed, let's not even bother to search the XQuartz paths.
689 lines
26 KiB
Python
689 lines
26 KiB
Python
# > pyroma .
|
|
# ------------------------------
|
|
# Checking .
|
|
# Found Pillow
|
|
# ------------------------------
|
|
# Final rating: 10/10
|
|
# Your cheese is so fresh most people think it's a cream: Mascarpone
|
|
# ------------------------------
|
|
from __future__ import print_function
|
|
import glob
|
|
import os
|
|
import platform as plat
|
|
import re
|
|
import struct
|
|
import sys
|
|
|
|
from distutils.command.build_ext import build_ext
|
|
from distutils import sysconfig
|
|
from setuptools import Extension, setup, find_packages
|
|
|
|
|
|
_IMAGING = (
|
|
"decode", "encode", "map", "display", "outline", "path")
|
|
|
|
_LIB_IMAGING = (
|
|
"Access", "AlphaComposite", "Antialias", "Bands", "BitDecode", "Blend",
|
|
"Chops", "Convert", "ConvertYCbCr", "Copy", "Crc32", "Crop", "Dib", "Draw",
|
|
"Effects", "EpsEncode", "File", "Fill", "Filter", "FliDecode",
|
|
"Geometry", "GetBBox", "GifDecode", "GifEncode", "HexDecode",
|
|
"Histo", "JpegDecode", "JpegEncode", "LzwDecode", "Matrix",
|
|
"ModeFilter", "MspDecode", "Negative", "Offset", "Pack",
|
|
"PackDecode", "Palette", "Paste", "Quant", "QuantOctree", "QuantHash",
|
|
"QuantHeap", "PcdDecode", "PcxDecode", "PcxEncode", "Point",
|
|
"RankFilter", "RawDecode", "RawEncode", "Storage", "SunRleDecode",
|
|
"TgaRleDecode", "Unpack", "UnpackYCC", "UnsharpMask", "XbmDecode",
|
|
"XbmEncode", "ZipDecode", "ZipEncode", "TiffDecode", "Incremental",
|
|
"Jpeg2KDecode", "Jpeg2KEncode")
|
|
|
|
|
|
def _add_directory(path, dir, where=None):
|
|
if dir is None:
|
|
return
|
|
dir = os.path.realpath(dir)
|
|
if os.path.isdir(dir) and dir not in path:
|
|
if where is None:
|
|
path.append(dir)
|
|
else:
|
|
path.insert(where, dir)
|
|
|
|
|
|
def _find_include_file(self, include):
|
|
for directory in self.compiler.include_dirs:
|
|
if os.path.isfile(os.path.join(directory, include)):
|
|
return 1
|
|
return 0
|
|
|
|
|
|
def _find_library_file(self, library):
|
|
# Fix for 3.2.x <3.2.4, 3.3.0, shared lib extension is the python shared
|
|
# lib extension, not the system shared lib extension: e.g. .cpython-33.so
|
|
# vs .so. See Python bug http://bugs.python.org/16754
|
|
if 'cpython' in self.compiler.shared_lib_extension:
|
|
existing = self.compiler.shared_lib_extension
|
|
self.compiler.shared_lib_extension = "." + existing.split('.')[-1]
|
|
ret = self.compiler.find_library_file(
|
|
self.compiler.library_dirs, library)
|
|
self.compiler.shared_lib_extension = existing
|
|
return ret
|
|
else:
|
|
return self.compiler.find_library_file(
|
|
self.compiler.library_dirs, library)
|
|
|
|
|
|
def _lib_include(root):
|
|
# map root to (root/lib, root/include)
|
|
return os.path.join(root, "lib"), os.path.join(root, "include")
|
|
|
|
|
|
def _read(file):
|
|
return open(file, 'rb').read()
|
|
|
|
try:
|
|
import _tkinter
|
|
except (ImportError, OSError):
|
|
# pypy emits an oserror
|
|
_tkinter = None
|
|
|
|
|
|
NAME = 'Pillow'
|
|
VERSION = '2.4.0'
|
|
TCL_ROOT = None
|
|
JPEG_ROOT = None
|
|
JPEG2K_ROOT = None
|
|
ZLIB_ROOT = None
|
|
TIFF_ROOT = None
|
|
FREETYPE_ROOT = None
|
|
LCMS_ROOT = None
|
|
|
|
|
|
class pil_build_ext(build_ext):
|
|
|
|
class feature:
|
|
zlib = jpeg = tiff = freetype = tcl = tk = lcms = webp = webpmux = None
|
|
jpeg2000 = None
|
|
required = []
|
|
|
|
def require(self, feat):
|
|
return feat in self.required
|
|
def want(self, feat):
|
|
return getattr(self, feat) is None
|
|
|
|
def __iter__(self):
|
|
for x in dir(self):
|
|
if x[1] != '_':
|
|
yield x
|
|
|
|
feature = feature()
|
|
|
|
user_options = build_ext.user_options + [
|
|
('disable-%s' % x, None, 'Disable support for %s' % x)
|
|
for x in feature
|
|
] + [
|
|
('enable-%s' % x, None, 'Enable support for %s' % x)
|
|
for x in feature
|
|
]
|
|
|
|
def initialize_options(self):
|
|
build_ext.initialize_options(self)
|
|
for x in self.feature:
|
|
setattr(self, 'disable_%s' % x, None)
|
|
setattr(self, 'enable_%s' % x, None)
|
|
|
|
def finalize_options(self):
|
|
build_ext.finalize_options(self)
|
|
for x in self.feature:
|
|
if getattr(self, 'disable_%s' % x):
|
|
setattr(self.feature, x, False)
|
|
if getattr(self, 'enable_%s' % x):
|
|
raise ValueError(
|
|
'Conflicting options: --enable-%s and --disable-%s'
|
|
% (x, x))
|
|
if getattr(self, 'enable_%s' % x):
|
|
self.feature.required.append(x)
|
|
|
|
def build_extensions(self):
|
|
|
|
global TCL_ROOT
|
|
|
|
library_dirs = []
|
|
include_dirs = []
|
|
|
|
_add_directory(include_dirs, "libImaging")
|
|
|
|
#
|
|
# add configured kits
|
|
|
|
for root in (TCL_ROOT, JPEG_ROOT, JPEG2K_ROOT, TIFF_ROOT, ZLIB_ROOT,
|
|
FREETYPE_ROOT, LCMS_ROOT):
|
|
if isinstance(root, type(())):
|
|
lib_root, include_root = root
|
|
else:
|
|
lib_root = include_root = root
|
|
_add_directory(library_dirs, lib_root)
|
|
_add_directory(include_dirs, include_root)
|
|
|
|
# respect CFLAGS/LDFLAGS
|
|
for k in ('CFLAGS', 'LDFLAGS'):
|
|
if k in os.environ:
|
|
for match in re.finditer(r'-I([^\s]+)', os.environ[k]):
|
|
_add_directory(include_dirs, match.group(1))
|
|
for match in re.finditer(r'-L([^\s]+)', os.environ[k]):
|
|
_add_directory(library_dirs, match.group(1))
|
|
|
|
# include, rpath, if set as environment variables:
|
|
for k in ('C_INCLUDE_PATH', 'CPATH', 'INCLUDE'):
|
|
if k in os.environ:
|
|
for d in os.environ[k].split(os.path.pathsep):
|
|
_add_directory(include_dirs, d)
|
|
|
|
for k in ('LD_RUN_PATH', 'LIBRARY_PATH', 'LIB'):
|
|
if k in os.environ:
|
|
for d in os.environ[k].split(os.path.pathsep):
|
|
_add_directory(library_dirs, d)
|
|
|
|
prefix = sysconfig.get_config_var("prefix")
|
|
if prefix:
|
|
_add_directory(library_dirs, os.path.join(prefix, "lib"))
|
|
_add_directory(include_dirs, os.path.join(prefix, "include"))
|
|
|
|
#
|
|
# add platform directories
|
|
|
|
if sys.platform == "cygwin":
|
|
# pythonX.Y.dll.a is in the /usr/lib/pythonX.Y/config directory
|
|
_add_directory(library_dirs, os.path.join(
|
|
"/usr/lib", "python%s" % sys.version[:3], "config"))
|
|
|
|
elif sys.platform == "darwin":
|
|
# attempt to make sure we pick freetype2 over other versions
|
|
_add_directory(include_dirs, "/sw/include/freetype2")
|
|
_add_directory(include_dirs, "/sw/lib/freetype2/include")
|
|
# fink installation directories
|
|
_add_directory(library_dirs, "/sw/lib")
|
|
_add_directory(include_dirs, "/sw/include")
|
|
# darwin ports installation directories
|
|
_add_directory(library_dirs, "/opt/local/lib")
|
|
_add_directory(include_dirs, "/opt/local/include")
|
|
|
|
# if Homebrew is installed, use its lib and include directories
|
|
import subprocess
|
|
try:
|
|
prefix = subprocess.check_output(['brew', '--prefix']).strip()
|
|
except:
|
|
# Homebrew not installed
|
|
prefix = None
|
|
|
|
ft_prefix = None
|
|
|
|
if prefix:
|
|
# add Homebrew's include and lib directories
|
|
_add_directory(library_dirs, os.path.join(prefix, 'lib'))
|
|
_add_directory(include_dirs, os.path.join(prefix, 'include'))
|
|
ft_prefix = os.path.join(prefix, 'opt', 'freetype')
|
|
|
|
if ft_prefix and os.path.isdir(ft_prefix):
|
|
# freetype might not be linked into Homebrew's prefix
|
|
_add_directory(library_dirs, os.path.join(ft_prefix, 'lib'))
|
|
_add_directory(include_dirs, os.path.join(ft_prefix, 'include'))
|
|
else:
|
|
# fall back to freetype from XQuartz if Homebrew's freetype is missing
|
|
_add_directory(library_dirs, "/usr/X11/lib")
|
|
_add_directory(include_dirs, "/usr/X11/include")
|
|
|
|
elif sys.platform.startswith("linux"):
|
|
arch_tp = (plat.processor(), plat.architecture()[0])
|
|
if arch_tp == ("x86_64","32bit"):
|
|
# 32 bit build on 64 bit machine.
|
|
_add_directory(library_dirs, "/usr/lib/i386-linux-gnu")
|
|
else:
|
|
for platform_ in arch_tp:
|
|
|
|
if not platform_:
|
|
continue
|
|
|
|
if platform_ in ["x86_64", "64bit"]:
|
|
_add_directory(library_dirs, "/lib64")
|
|
_add_directory(library_dirs, "/usr/lib64")
|
|
_add_directory(library_dirs, "/usr/lib/x86_64-linux-gnu")
|
|
break
|
|
elif platform_ in ["i386", "i686", "32bit"]:
|
|
_add_directory(library_dirs, "/usr/lib/i386-linux-gnu")
|
|
break
|
|
elif platform_ in ["aarch64"]:
|
|
_add_directory(library_dirs, "/usr/lib64")
|
|
_add_directory(library_dirs, "/usr/lib/aarch64-linux-gnu")
|
|
break
|
|
elif platform_ in ["arm", "armv7l"]:
|
|
_add_directory(library_dirs, "/usr/lib/arm-linux-gnueabi")
|
|
break
|
|
elif platform_ in ["ppc64"]:
|
|
_add_directory(library_dirs, "/usr/lib64")
|
|
_add_directory(library_dirs, "/usr/lib/ppc64-linux-gnu")
|
|
_add_directory(library_dirs, "/usr/lib/powerpc64-linux-gnu")
|
|
break
|
|
elif platform_ in ["ppc"]:
|
|
_add_directory(library_dirs, "/usr/lib/ppc-linux-gnu")
|
|
_add_directory(library_dirs, "/usr/lib/powerpc-linux-gnu")
|
|
break
|
|
elif platform_ in ["s390x"]:
|
|
_add_directory(library_dirs, "/usr/lib64")
|
|
_add_directory(library_dirs, "/usr/lib/s390x-linux-gnu")
|
|
break
|
|
elif platform_ in ["s390"]:
|
|
_add_directory(library_dirs, "/usr/lib/s390-linux-gnu")
|
|
break
|
|
else:
|
|
raise ValueError(
|
|
"Unable to identify Linux platform: `%s`" % platform_)
|
|
|
|
# XXX Kludge. Above /\ we brute force support multiarch. Here we
|
|
# try Barry's more general approach. Afterward, something should
|
|
# work ;-)
|
|
self.add_multiarch_paths()
|
|
|
|
elif sys.platform.startswith("gnu"):
|
|
self.add_multiarch_paths()
|
|
|
|
elif sys.platform.startswith("netbsd"):
|
|
_add_directory(library_dirs, "/usr/pkg/lib")
|
|
_add_directory(include_dirs, "/usr/pkg/include")
|
|
|
|
# FIXME: check /opt/stuff directories here?
|
|
|
|
#
|
|
# locate tkinter libraries
|
|
|
|
if _tkinter:
|
|
TCL_VERSION = _tkinter.TCL_VERSION[:3]
|
|
|
|
if _tkinter and not TCL_ROOT:
|
|
# we have Tkinter but the TCL_ROOT variable was not set;
|
|
# try to locate appropriate Tcl/Tk libraries
|
|
PYVERSION = sys.version[0] + sys.version[2]
|
|
TCLVERSION = TCL_VERSION[0] + TCL_VERSION[2]
|
|
roots = [
|
|
# common installation directories, mostly for Windows
|
|
# (for Unix-style platforms, we'll check in well-known
|
|
# locations later)
|
|
os.path.join("/py" + PYVERSION, "Tcl"),
|
|
os.path.join("/python" + PYVERSION, "Tcl"),
|
|
"/Tcl", "/Tcl" + TCLVERSION, "/Tcl" + TCL_VERSION,
|
|
os.path.join(os.environ.get("ProgramFiles", ""), "Tcl"), ]
|
|
for TCL_ROOT in roots:
|
|
TCL_ROOT = os.path.abspath(TCL_ROOT)
|
|
if os.path.isfile(os.path.join(TCL_ROOT, "include", "tk.h")):
|
|
# FIXME: use distutils logging (?)
|
|
print("--- using Tcl/Tk libraries at", TCL_ROOT)
|
|
print("--- using Tcl/Tk version", TCL_VERSION)
|
|
TCL_ROOT = _lib_include(TCL_ROOT)
|
|
break
|
|
else:
|
|
TCL_ROOT = None
|
|
|
|
# add standard directories
|
|
|
|
# look for tcl specific subdirectory (e.g debian)
|
|
if _tkinter:
|
|
tcl_dir = "/usr/include/tcl" + TCL_VERSION
|
|
if os.path.isfile(os.path.join(tcl_dir, "tk.h")):
|
|
_add_directory(include_dirs, tcl_dir)
|
|
|
|
# standard locations
|
|
_add_directory(library_dirs, "/usr/local/lib")
|
|
_add_directory(include_dirs, "/usr/local/include")
|
|
|
|
_add_directory(library_dirs, "/usr/lib")
|
|
_add_directory(include_dirs, "/usr/include")
|
|
|
|
# on Windows, look for the OpenJPEG libraries in the location that
|
|
# the official installed puts them
|
|
if sys.platform == "win32":
|
|
_add_directory(library_dirs,
|
|
os.path.join(os.environ.get("ProgramFiles", ""),
|
|
"OpenJPEG 2.0", "lib"))
|
|
_add_directory(include_dirs,
|
|
os.path.join(os.environ.get("ProgramFiles", ""),
|
|
"OpenJPEG 2.0", "include"))
|
|
|
|
#
|
|
# insert new dirs *before* default libs, to avoid conflicts
|
|
# between Python PYD stub libs and real libraries
|
|
|
|
self.compiler.library_dirs = library_dirs + self.compiler.library_dirs
|
|
self.compiler.include_dirs = include_dirs + self.compiler.include_dirs
|
|
|
|
#
|
|
# look for available libraries
|
|
|
|
feature = self.feature
|
|
|
|
if feature.want('zlib'):
|
|
if _find_include_file(self, "zlib.h"):
|
|
if _find_library_file(self, "z"):
|
|
feature.zlib = "z"
|
|
elif sys.platform == "win32" and _find_library_file(self, "zlib"):
|
|
feature.zlib = "zlib" # alternative name
|
|
|
|
if feature.want('jpeg'):
|
|
if _find_include_file(self, "jpeglib.h"):
|
|
if _find_library_file(self, "jpeg"):
|
|
feature.jpeg = "jpeg"
|
|
elif (
|
|
sys.platform == "win32" and
|
|
_find_library_file(self, "libjpeg")):
|
|
feature.jpeg = "libjpeg" # alternative name
|
|
|
|
if feature.want('jpeg2000'):
|
|
if _find_include_file(self, "openjpeg-2.0/openjpeg.h"):
|
|
if _find_library_file(self, "openjp2"):
|
|
feature.jpeg2000 = "openjp2"
|
|
|
|
if feature.want('tiff'):
|
|
if _find_library_file(self, "tiff"):
|
|
feature.tiff = "tiff"
|
|
if sys.platform == "win32" and _find_library_file(self, "libtiff"):
|
|
feature.tiff = "libtiff"
|
|
if sys.platform == "darwin" and _find_library_file(self, "libtiff"):
|
|
feature.tiff = "libtiff"
|
|
|
|
if feature.want('freetype'):
|
|
if _find_library_file(self, "freetype"):
|
|
# look for freetype2 include files
|
|
freetype_version = 0
|
|
for dir in self.compiler.include_dirs:
|
|
if os.path.isfile(os.path.join(dir, "ft2build.h")):
|
|
freetype_version = 21
|
|
dir = os.path.join(dir, "freetype2")
|
|
break
|
|
dir = os.path.join(dir, "freetype2")
|
|
if os.path.isfile(os.path.join(dir, "ft2build.h")):
|
|
freetype_version = 21
|
|
break
|
|
if os.path.isdir(os.path.join(dir, "freetype")):
|
|
freetype_version = 20
|
|
break
|
|
if freetype_version:
|
|
feature.freetype = "freetype"
|
|
feature.freetype_version = freetype_version
|
|
if dir:
|
|
_add_directory(self.compiler.include_dirs, dir, 0)
|
|
|
|
if feature.want('lcms'):
|
|
if _find_include_file(self, "lcms2.h"):
|
|
if _find_library_file(self, "lcms2"):
|
|
feature.lcms = "lcms"
|
|
|
|
if _tkinter and _find_include_file(self, "tk.h"):
|
|
# the library names may vary somewhat (e.g. tcl84 or tcl8.4)
|
|
version = TCL_VERSION[0] + TCL_VERSION[2]
|
|
if feature.want('tcl'):
|
|
if _find_library_file(self, "tcl" + version):
|
|
feature.tcl = "tcl" + version
|
|
elif _find_library_file(self, "tcl" + TCL_VERSION):
|
|
feature.tcl = "tcl" + TCL_VERSION
|
|
if feature.want('tk'):
|
|
if _find_library_file(self, "tk" + version):
|
|
feature.tk = "tk" + version
|
|
elif _find_library_file(self, "tk" + TCL_VERSION):
|
|
feature.tk = "tk" + TCL_VERSION
|
|
|
|
if feature.want('webp'):
|
|
if (_find_include_file(self, "webp/encode.h") and
|
|
_find_include_file(self, "webp/decode.h")):
|
|
if _find_library_file(self, "webp"): # in googles precompiled zip it is call "libwebp"
|
|
feature.webp = "webp"
|
|
|
|
if feature.want('webpmux'):
|
|
if (_find_include_file(self, "webp/mux.h") and
|
|
_find_include_file(self, "webp/demux.h")):
|
|
if _find_library_file(self, "webpmux") and _find_library_file(self, "webpdemux"):
|
|
feature.webpmux = "webpmux"
|
|
|
|
for f in feature:
|
|
if not getattr(feature, f) and feature.require(f):
|
|
raise ValueError(
|
|
'--enable-%s requested but %s not found, aborting.'
|
|
% (f, f))
|
|
|
|
#
|
|
# core library
|
|
|
|
files = ["_imaging.c"]
|
|
for file in _IMAGING:
|
|
files.append(file + ".c")
|
|
for file in _LIB_IMAGING:
|
|
files.append(os.path.join("libImaging", file + ".c"))
|
|
|
|
libs = []
|
|
defs = []
|
|
if feature.jpeg:
|
|
libs.append(feature.jpeg)
|
|
defs.append(("HAVE_LIBJPEG", None))
|
|
if feature.jpeg2000:
|
|
libs.append(feature.jpeg2000)
|
|
defs.append(("HAVE_OPENJPEG", None))
|
|
if sys.platform == "win32":
|
|
defs.append(("OPJ_STATIC", None))
|
|
if feature.zlib:
|
|
libs.append(feature.zlib)
|
|
defs.append(("HAVE_LIBZ", None))
|
|
if feature.tiff:
|
|
libs.append(feature.tiff)
|
|
defs.append(("HAVE_LIBTIFF", None))
|
|
if sys.platform == "win32":
|
|
libs.extend(["kernel32", "user32", "gdi32"])
|
|
if struct.unpack("h", "\0\1".encode('ascii'))[0] == 1:
|
|
defs.append(("WORDS_BIGENDIAN", None))
|
|
|
|
exts = [(Extension(
|
|
"PIL._imaging", files, libraries=libs, define_macros=defs))]
|
|
|
|
#
|
|
# additional libraries
|
|
|
|
if feature.freetype:
|
|
defs = []
|
|
if feature.freetype_version == 20:
|
|
defs.append(("USE_FREETYPE_2_0", None))
|
|
exts.append(Extension(
|
|
"PIL._imagingft", ["_imagingft.c"], libraries=["freetype"],
|
|
define_macros=defs))
|
|
|
|
if os.path.isfile("_imagingtiff.c") and feature.tiff:
|
|
exts.append(Extension(
|
|
"PIL._imagingtiff", ["_imagingtiff.c"], libraries=["tiff"]))
|
|
|
|
if os.path.isfile("_imagingcms.c") and feature.lcms:
|
|
extra = []
|
|
if sys.platform == "win32":
|
|
extra.extend(["user32", "gdi32"])
|
|
exts.append(Extension(
|
|
"PIL._imagingcms", ["_imagingcms.c"], libraries=["lcms2"] + extra))
|
|
|
|
if os.path.isfile("_webp.c") and feature.webp:
|
|
libs = ["webp"]
|
|
defs = []
|
|
|
|
if feature.webpmux:
|
|
defs.append(("HAVE_WEBPMUX", None))
|
|
libs.append("webpmux")
|
|
libs.append("webpdemux")
|
|
|
|
exts.append(Extension(
|
|
"PIL._webp", ["_webp.c"], libraries=libs, define_macros=defs))
|
|
|
|
if sys.platform == "darwin":
|
|
# locate Tcl/Tk frameworks
|
|
frameworks = []
|
|
framework_roots = [
|
|
"/Library/Frameworks",
|
|
"/System/Library/Frameworks"]
|
|
for root in framework_roots:
|
|
if (
|
|
os.path.exists(os.path.join(root, "Tcl.framework")) and
|
|
os.path.exists(os.path.join(root, "Tk.framework"))):
|
|
print("--- using frameworks at %s" % root)
|
|
frameworks = ["-framework", "Tcl", "-framework", "Tk"]
|
|
dir = os.path.join(root, "Tcl.framework", "Headers")
|
|
_add_directory(self.compiler.include_dirs, dir, 0)
|
|
dir = os.path.join(root, "Tk.framework", "Headers")
|
|
_add_directory(self.compiler.include_dirs, dir, 1)
|
|
break
|
|
if frameworks:
|
|
exts.append(Extension(
|
|
"PIL._imagingtk", ["_imagingtk.c", "Tk/tkImaging.c"],
|
|
extra_compile_args=frameworks, extra_link_args=frameworks))
|
|
feature.tcl = feature.tk = 1 # mark as present
|
|
elif feature.tcl and feature.tk:
|
|
exts.append(Extension(
|
|
"PIL._imagingtk", ["_imagingtk.c", "Tk/tkImaging.c"],
|
|
libraries=[feature.tcl, feature.tk]))
|
|
|
|
if os.path.isfile("_imagingmath.c"):
|
|
exts.append(Extension("PIL._imagingmath", ["_imagingmath.c"]))
|
|
|
|
self.extensions[:] = exts
|
|
|
|
build_ext.build_extensions(self)
|
|
|
|
#
|
|
# sanity and security checks
|
|
|
|
unsafe_zlib = None
|
|
|
|
if feature.zlib:
|
|
unsafe_zlib = self.check_zlib_version(self.compiler.include_dirs)
|
|
|
|
self.summary_report(feature, unsafe_zlib)
|
|
|
|
def summary_report(self, feature, unsafe_zlib):
|
|
|
|
print("-" * 68)
|
|
print("PIL SETUP SUMMARY")
|
|
print("-" * 68)
|
|
print("version Pillow %s" % VERSION)
|
|
v = sys.version.split("[")
|
|
print("platform %s %s" % (sys.platform, v[0].strip()))
|
|
for v in v[1:]:
|
|
print(" [%s" % v.strip())
|
|
print("-" * 68)
|
|
|
|
options = [
|
|
(feature.tcl and feature.tk, "TKINTER"),
|
|
(feature.jpeg, "JPEG"),
|
|
(feature.jpeg2000, "OPENJPEG (JPEG2000)"),
|
|
(feature.zlib, "ZLIB (PNG/ZIP)"),
|
|
(feature.tiff, "LIBTIFF"),
|
|
(feature.freetype, "FREETYPE2"),
|
|
(feature.lcms, "LITTLECMS2"),
|
|
(feature.webp, "WEBP"),
|
|
(feature.webpmux, "WEBPMUX"), ]
|
|
|
|
all = 1
|
|
for option in options:
|
|
if option[0]:
|
|
print("--- %s support available" % option[1])
|
|
else:
|
|
print("*** %s support not available" % option[1])
|
|
if option[1] == "TKINTER" and _tkinter:
|
|
version = _tkinter.TCL_VERSION
|
|
print("(Tcl/Tk %s libraries needed)" % version)
|
|
all = 0
|
|
|
|
if feature.zlib and unsafe_zlib:
|
|
print("")
|
|
print("*** Warning: zlib", unsafe_zlib)
|
|
print("may contain a security vulnerability.")
|
|
print("*** Consider upgrading to zlib 1.2.3 or newer.")
|
|
print("*** See: http://www.kb.cert.org/vuls/id/238678")
|
|
print(" http://www.kb.cert.org/vuls/id/680620")
|
|
print(" http://www.gzip.org/zlib/advisory-2002-03-11.txt")
|
|
print("")
|
|
|
|
print("-" * 68)
|
|
|
|
if not all:
|
|
print("To add a missing option, make sure you have the required")
|
|
print("library, and set the corresponding ROOT variable in the")
|
|
print("setup.py script.")
|
|
print("")
|
|
|
|
print("To check the build, run the selftest.py script.")
|
|
print("")
|
|
|
|
def check_zlib_version(self, include_dirs):
|
|
# look for unsafe versions of zlib
|
|
for dir in include_dirs:
|
|
zlibfile = os.path.join(dir, "zlib.h")
|
|
if os.path.isfile(zlibfile):
|
|
break
|
|
else:
|
|
return
|
|
for line in open(zlibfile).readlines():
|
|
m = re.match('#define\s+ZLIB_VERSION\s+"([^"]*)"', line)
|
|
if not m:
|
|
continue
|
|
if m.group(1) < "1.2.3":
|
|
return m.group(1)
|
|
|
|
# http://hg.python.org/users/barry/rev/7e8deab93d5a
|
|
def add_multiarch_paths(self):
|
|
# Debian/Ubuntu multiarch support.
|
|
# https://wiki.ubuntu.com/MultiarchSpec
|
|
# self.build_temp
|
|
tmpfile = os.path.join(self.build_temp, 'multiarch')
|
|
if not os.path.exists(self.build_temp):
|
|
os.makedirs(self.build_temp)
|
|
ret = os.system(
|
|
'dpkg-architecture -qDEB_HOST_MULTIARCH > %s 2> /dev/null' %
|
|
tmpfile)
|
|
try:
|
|
if ret >> 8 == 0:
|
|
fp = open(tmpfile, 'r')
|
|
multiarch_path_component = fp.readline().strip()
|
|
_add_directory(
|
|
self.compiler.library_dirs,
|
|
'/usr/lib/' + multiarch_path_component)
|
|
_add_directory(
|
|
self.compiler.include_dirs,
|
|
'/usr/include/' + multiarch_path_component)
|
|
finally:
|
|
os.unlink(tmpfile)
|
|
|
|
setup(
|
|
name=NAME,
|
|
version=VERSION,
|
|
description='Python Imaging Library (Fork)',
|
|
long_description=(
|
|
_read('README.rst') + b'\n' +
|
|
_read('CHANGES.rst')).decode('utf-8'),
|
|
author='Alex Clark (fork author)',
|
|
author_email='aclark@aclark.net',
|
|
url='http://python-imaging.github.io/',
|
|
classifiers=[
|
|
"Development Status :: 6 - Mature",
|
|
"Topic :: Multimedia :: Graphics",
|
|
"Topic :: Multimedia :: Graphics :: Capture :: Digital Camera",
|
|
"Topic :: Multimedia :: Graphics :: Capture :: Scanners",
|
|
"Topic :: Multimedia :: Graphics :: Capture :: Screen Capture",
|
|
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
|
|
"Topic :: Multimedia :: Graphics :: Viewers",
|
|
"Programming Language :: Python :: 2",
|
|
"Programming Language :: Python :: 2.6",
|
|
"Programming Language :: Python :: 2.7",
|
|
"Programming Language :: Python :: 3",
|
|
"Programming Language :: Python :: 3.2",
|
|
"Programming Language :: Python :: 3.3", ],
|
|
cmdclass={"build_ext": pil_build_ext},
|
|
ext_modules=[Extension("PIL._imaging", ["_imaging.c"])],
|
|
include_package_data=True,
|
|
packages=find_packages(),
|
|
scripts=glob.glob("Scripts/pil*.py"),
|
|
test_suite='PIL.tests',
|
|
keywords=["Imaging",],
|
|
license='Standard PIL License',
|
|
zip_safe=True,
|
|
)
|
|
|