44from distutils import version
55from distutils .core import Extension
66import glob
7- import io
87import multiprocessing
98import os
109import re
1312import sys
1413import warnings
1514from textwrap import fill
16-
15+ import shutil
1716import versioneer
1817
1918
2019PY3min = (sys .version_info [0 ] >= 3 )
2120PY32min = (PY3min and sys .version_info [1 ] >= 2 or sys .version_info [0 ] > 3 )
2221
2322
23+ def _get_home ():
24+ """Find user's home directory if possible.
25+ Otherwise, returns None.
26+
27+ :see:
28+ http://mail.python.org/pipermail/python-list/2005-February/325395.html
29+ """
30+ try :
31+ if not PY3min and sys .platform == 'win32' :
32+ path = os .path .expanduser (b"~" ).decode (sys .getfilesystemencoding ())
33+ else :
34+ path = os .path .expanduser ("~" )
35+ except ImportError :
36+ # This happens on Google App Engine (pwd module is not present).
37+ pass
38+ else :
39+ if os .path .isdir (path ):
40+ return path
41+ for evar in ('HOME' , 'USERPROFILE' , 'TMP' ):
42+ path = os .environ .get (evar )
43+ if path is not None and os .path .isdir (path ):
44+ return path
45+ return None
46+
47+
48+ def _get_xdg_cache_dir ():
49+ """
50+ Returns the XDG cache directory, according to the `XDG
51+ base directory spec
52+ <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
53+ """
54+ path = os .environ .get ('XDG_CACHE_HOME' )
55+ if path is None :
56+ path = _get_home ()
57+ if path is not None :
58+ path = os .path .join (path , '.cache' , 'matplotlib' )
59+ return path
60+
61+
2462# This is the version of FreeType to use when building a local
2563# version. It must match the value in
2664# lib/matplotlib.__init__.py and also needs to be changed below in the
71109 config .get ("directories" , "basedirlist" ).split (',' )]
72110
73111 if config .has_option ('test' , 'local_freetype' ):
74- options ['local_freetype' ] = config .get ("test" , "local_freetype" )
112+ options ['local_freetype' ] = config .getboolean ("test" , "local_freetype" )
75113else :
76114 config = None
77115
116+ lft = bool (os .environ .get ('MPLLOCALFREETYPE' , False ))
117+ options ['local_freetype' ] = lft or options .get ('local_freetype' , False )
118+
78119
79120def get_win32_compiler ():
80121 """
@@ -1008,21 +1049,56 @@ def do_custom_build(self):
10081049
10091050 tarball = 'freetype-{0}.tar.gz' .format (LOCAL_FREETYPE_VERSION )
10101051 tarball_path = os .path .join ('build' , tarball )
1052+ try :
1053+ tarball_cache_dir = _get_xdg_cache_dir ()
1054+ tarball_cache_path = os .path .join (tarball_cache_dir , tarball )
1055+ except :
1056+ # again, do not really care if this fails
1057+ tarball_cache_dir = None
1058+ tarball_cache_path = None
10111059 if not os .path .isfile (tarball_path ):
1012- tarball_url = 'http://download.savannah.gnu.org/releases/freetype/{0}' .format (tarball )
1013-
1014- print ("Downloading {0}" .format (tarball_url ))
1015- if sys .version_info [0 ] == 2 :
1016- from urllib import urlretrieve
1017- else :
1018- from urllib .request import urlretrieve
1019-
1020- if not os .path .exists ('build' ):
1021- os .makedirs ('build' )
1022- urlretrieve (tarball_url , tarball_path )
1060+ if (tarball_cache_path is not None and
1061+ os .path .isfile (tarball_cache_path )):
1062+ if get_file_hash (tarball_cache_path ) == LOCAL_FREETYPE_HASH :
1063+ try :
1064+ # fail on Lpy, oh well
1065+ os .makedirs ('build' , exist_ok = True )
1066+ shutil .copy (tarball_cache_path , tarball_path )
1067+ print ('Using cached tarball: {}'
1068+ .format (tarball_cache_path ))
1069+ except :
1070+ # If this fails, oh well just re-download
1071+ pass
1072+
1073+ if not os .path .isfile (tarball_path ):
1074+ url_fmt = (
1075+ 'http://download.savannah.gnu.org/releases/freetype/{0}' )
1076+ tarball_url = url_fmt .format (tarball )
1077+
1078+ print ("Downloading {0}" .format (tarball_url ))
1079+ if sys .version_info [0 ] == 2 :
1080+ from urllib import urlretrieve
1081+ else :
1082+ from urllib .request import urlretrieve
1083+
1084+ if not os .path .exists ('build' ):
1085+ os .makedirs ('build' )
1086+ urlretrieve (tarball_url , tarball_path )
1087+ if get_file_hash (tarball_path ) == LOCAL_FREETYPE_HASH :
1088+ try :
1089+ # this will fail on LPy, oh well
1090+ os .makedirs (tarball_cache_dir , exist_ok = True )
1091+ shutil .copy (tarball_cache_path , tarball_path )
1092+ print ('Cached tarball at: {}'
1093+ .format (tarball_cache_path ))
1094+ except :
1095+ # again, we do not care if this fails, can
1096+ # always re download
1097+ pass
10231098
10241099 if get_file_hash (tarball_path ) != LOCAL_FREETYPE_HASH :
1025- raise IOError ("{0} does not match expected hash." .format (tarball ))
1100+ raise IOError (
1101+ "{0} does not match expected hash." .format (tarball ))
10261102
10271103 print ("Building {0}" .format (tarball ))
10281104 if sys .platform != 'win32' :
@@ -1048,7 +1124,7 @@ def do_custom_build(self):
10481124:: move to the "normal" path for the unix builds...
10491125mkdir %FREETYPE%\\ objs\\ .libs
10501126:: REMINDER: fix when changing the version
1051- copy %FREETYPE%\\ objs\\ {vc20xx}\\ {xXX}\\ freetype261.lib %FREETYPE%\\ objs\\ .libs\\ libfreetype.lib
1127+ copy %FREETYPE%\\ objs\\ {vc20xx}\\ {xXX}\\ freetype261.lib %FREETYPE%\\ objs\\ .libs\\ libfreetype.lib
10521128if errorlevel 1 (
10531129 rem This is a py27 version, which has a different location for the lib file :-/
10541130 copy %FREETYPE%\\ objs\\ win32\\ {vc20xx}\\ freetype261.lib %FREETYPE%\\ objs\\ .libs\\ libfreetype.lib
0 commit comments