8000 Merge the FreeType and Qhull download mechanisms. · matplotlib/matplotlib@b5a3146 · GitHub
[go: up one dir, main page]

Skip to content

Commit b5a3146

Browse files
committed
Merge the FreeType and Qhull download mechanisms.
1 parent dbe44f8 commit b5a3146

File tree

3 files changed

+62
-55
lines changed

3 files changed

+62
-55
lines changed

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,3 @@ lib/z.lib
105105
#########################
106106
lib/matplotlib/backends/web_backend/node_modules/
107107
lib/matplotlib/backends/web_backend/package-lock.json
108-
109-
extern/qhull-*/

setup.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
from pathlib import Path
2929
import shutil
3030
import subprocess
31-
import tarfile
3231

3332
from setuptools import setup, find_packages, Extension
3433
from setuptools.command.build_ext import build_ext as BuildExtCommand
@@ -49,7 +48,7 @@
4948

5049
import setupext
5150
from setupext import (
52-
download_or_cache, print_raw, print_status, LOCAL_QHULL_VERSION)
51+
get_and_extract_tarball, print_raw, print_status, LOCAL_QHULL_VERSION)
5352

5453
# Get the version from versioneer
5554
import versioneer
@@ -87,24 +86,17 @@ def __init__(self, dist):
8786
"'python setup.py test'. Please run 'pytest'.")
8887

8988

90-
def _download_qhull_to(dest):
91-
url = "http://www.qhull.org/download/qhull-2020-src-8.0.2.tgz"
92-
sha = "b5c2d7eb833278881b952c8a52d20179eab87766b00b865000469a45c1838b7e"
93-
if (dest / f"qhull-{LOCAL_QHULL_VERSION}").exists():
94-
return
95-
dest.mkdir(parents=True, exist_ok=True)
96-
try:
97-
buf = download_or_cache(url, sha)
98-
except Exception:
99-
raise IOError(f"Failed to download qhull. Please download {url} and "
100-
f"extract it to {dest}.")
101-
with tarfile.open(fileobj=buf, mode="r:gz") as tf:
102-
tf.extractall(dest)
89+
def _download_qhull():
90+
toplevel = get_and_extract_tarball(
91+
urls=["http://www.qhull.org/download/qhull-2020-src-8.0.2.tgz"],
92+
sha="b5c2d7eb833278881b952c8a52d20179eab87766b00b865000469a45c1838b7e",
93+
dirname=f"qhull-{LOCAL_QHULL_VERSION}",
94+
)
10395

10496

10597
class BuildExtraLibraries(BuildExtCommand):
10698
def finalize_options(self):
107-
_download_qhull_to(Path("extern"))
99+
_download_qhull()
108100
self.distribution.ext_modules[:] = [
109101
ext
110102
for package in good_packages

setupext.py

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def _get_ssl_context():
4848
return ssl.create_default_context(cafile=certifi.where())
4949

5050

51-
def download_or_cache(url, sha):
51+
def get_from_cache_or_download(url, sha):
5252
"""
5353
Get bytes from the given url or local cache.
5454
@@ -86,7 +86,7 @@ def download_or_cache(url, sha):
8686
file_sha = _get_hash(data)
8787
if file_sha != sha:
8888
raise Exception(
89-
f"The download file does not match the expected sha. {url} was "
89+
f"The downloaded file does not match the expected sha. {url} was "
9090
f"expected to have {sha} but it had {file_sha}")
9191

9292
if cache_dir is not None: # Try to cache the downloaded file.
@@ -100,6 +100,45 @@ def download_or_cache(url, sha):
100100
return BytesIO(data)
101101

102102

103+
def get_and_extract_tarball(urls, sha, dirname):
104+
"""
105+
Obtain a tarball (from cache or download) and extract it.
106+
107+
Parameters
108+
----------
109+
urls : list[str]
110+
URLs from which download is attempted (in order of attempt), if the
111+
tarball is not in the cache yet.
112+
sha : str
113+
SHA256 hash of the tarball; used both as a cache key (by
114+
`get_from_cache_or_download`) and to validate a downloaded tarball.
115+
dirname : path-like
116+
Directory where the tarball is extracted.
117+
"""
118+
toplevel = Path("build", dirname)
119+
if not toplevel.exists(): # Download it or load it from cache.
120+
Path("build").mkdir(exist_ok=True)
121+
for url in urls:
122+
try:
123+
tar_contents = get_from_cache_or_download(url, sha)
124+
break
125+
except Exception:
126+
pass
127+
else:
128+
raise IOError(
129+
f"Failed to download any of the following: {urls}. "
130+
f"Please download one of these urls and extract it into "
131+
f"'build/' at the top-level of the source repository.")
132+
print("Extracting {}".format(urllib.parse.urlparse(url).path))
133+
with tarfile.open(fileobj=tar_contents, mode="r:gz") as tgz:
134+
if os.path.commonpath(tgz.getnames()) != dirname:
135+
raise IOError(
136+
f"The downloaded tgz file was expected to have {dirname} "
137+
f"as sole top-level directory, but that is not the case")
138+
tgz.extractall("build")
139+
return toplevel
140+
141+
103142
# SHA256 hashes of the FreeType tarballs
104143
_freetype_hashes = {
105144
'2.6.1':
@@ -515,7 +554,7 @@ def add_qhull_flags(ext):
515554
if options.get("system_qhull"):
516555
ext.libraries.append("qhull")
517556
else:
518-
qhull_path = Path(f'extern/qhull-{LOCAL_QHULL_VERSION}/src')
557+
qhull_path = Path(f'build/qhull-{LOCAL_QHULL_VERSION}/src')
519558
ext.include_dirs.insert(0, str(qhull_path))
520559
ext.sources.extend(map(str, sorted(qhull_path.glob('libqhull_r/*.c'))))
521560
if sysconfig.get_config_var("LIBM") == "-lm":
@@ -560,46 +599,24 @@ def do_custom_build(self, env):
560599
if options.get('system_freetype'):
561600
return
562601

563-
src_path = Path('build', f'freetype-{LOCAL_FREETYPE_VERSION}')
602+
tarball = f'freetype-{LOCAL_FREETYPE_VERSION}.tar.gz'
603+
src_path = get_and_extract_tarball(
604+
urls=[
605+
(f'https://downloads.sourceforge.net/project/freetype'
606+
f'/freetype2/{LOCAL_FREETYPE_VERSION}/{tarball}'),
607+
(f'https://download.savannah.gnu.org/releases/freetype'
608+
f'/{tarball}')
609+
],
610+
sha=LOCAL_FREETYPE_HASH,
611+
dirname=f'freetype-{LOCAL_FREETYPE_VERSION}',
612+
)
564613

565-
# We've already built freetype
566614
if sys.platform == 'win32':
567615
libfreetype = 'libfreetype.lib'
568616
else:
569617
libfreetype = 'libfreetype.a'
570-
571-
# bailing because it is already built
572618
if (src_path / 'objs' / '.libs' / libfreetype).is_file():
573-
return
574-
575-
# do we need to download / load the source from cache?
576-
if not src_path.exists():
577-
os.makedirs('build', exist_ok=True)
578-
579-
tarball = f'freetype-{LOCAL_FREETYPE_VERSION}.tar.gz'
580-
target_urls = [
581-
(f'https://downloads.sourceforge.net/project/freetype'
582-
f'/freetype2/{LOCAL_FREETYPE_VERSION}/{tarball}'),
583-
(f'https://download.savannah.gnu.org/releases/freetype'
584-
f'/{tarball}')
585-
]
586-
587-
for tarball_url in target_urls:
588-
try:
589-
tar_contents = download_or_cache(tarball_url,
590-
LOCAL_FREETYPE_HASH)
591-
break
592-
except Exception:
593-
pass
594-
else:
595-
raise IOError(
596-
f"Failed to download FreeType. Please download one of "
597-
f"{target_urls} and extract it into {src_path} at the "
598-
f"top-level of the source repository.")
599-
600-
print(f"Extracting {tarball}")
601-
with tarfile.open(fileobj=tar_contents, mode="r:gz") as tgz:
602-
tgz.extractall("build")
619+
return # Bail out because we have already built FreeType.
603620

604621
print(f"Building freetype in {src_path}")
605622
if sys.platform != 'win32': # compilation on non-windows

0 commit comments

Comments
 (0)
0