|
| 1 | +import os |
| 2 | +import sys |
| 3 | + |
| 4 | +try: |
| 5 | + from urlparse import urljoin |
| 6 | + from urllib import urlretrieve, urlcleanup |
| 7 | +except ImportError: |
| 8 | + from urllib.parse import urljoin |
| 9 | + from urllib.request import urlretrieve, urlcleanup |
| 10 | + |
| 11 | + |
| 12 | +# use pre-built libraries on Windows |
| 13 | +def get_prebuilt_libs(download_dir, static_include_dirs, static_library_dirs): |
| 14 | + assert sys.platform.startswith('win') |
| 15 | + libs = download_and_extract_windows_binaries(download_dir) |
| 16 | + for ln, path in libs.items(): |
| 17 | + if ln == 'xmlsec1': |
| 18 | + i = os.path.join(path, 'include', 'xmlsec1') |
| 19 | + else: |
| 20 | + i = os.path.join(path, 'include') |
| 21 | + |
| 22 | + l = os.path.join(path, 'lib') |
| 23 | + assert os.path.exists(i), 'does not exist: %s' % i |
| 24 | + assert os.path.exists(l), 'does not exist: %s' % l |
| 25 | + static_include_dirs.append(i) |
| 26 | + static_library_dirs.append(l) |
| 27 | + |
| 28 | + |
| 29 | +def download_and_extract_windows_binaries(destdir): |
| 30 | + if sys.version_info < (3, 5): |
| 31 | + if sys.maxsize > 2147483647: |
| 32 | + url = "https://ci.appveyor.com/api/buildjobs/7q4nvmkdnu05dul6/artifacts/" |
| 33 | + suffix = "vs2008.win64" |
| 34 | + else: |
| 35 | + url = "https://ci.appveyor.com/api/buildjobs/tdpx6rprr5431ec9/artifacts/" |
| 36 | + suffix = "vs2008.win32" |
| 37 | + else: |
| 38 | + if sys.maxsize > 2147483647: |
| 39 | + url = "https://ci.appveyor.com/api/buildjobs/hij3a6776pdv2007/artifacts/" |
| 40 | + suffix = "win64" |
| 41 | + else: |
| 42 | + url = "https://ci.appveyor.com/api/buildjobs/7k878q7rvogcdyd9/artifacts/" |
| 43 | + suffix = "win32" |
| 44 | + |
| 45 | + libs = { |
| 46 | + 'libxml2': 'libxml2-2.9.4.{}.zip'.format(suffix), |
| 47 | + 'libxslt': 'libxslt-1.1.29.{}.zip'.format(suffix), |
| 48 | + 'zlib': 'zlib-1.2.8.{}.zip'.format(suffix), |
| 49 | + 'iconv': 'iconv-1.14.{}.zip'.format(suffix), |
| 50 | + 'openssl': 'openssl-1.0.1.{}.zip'.format(suffix), |
| 51 | + 'xmlsec': 'xmlsec-1.2.24.{}.zip'.format(suffix), |
| 52 | + } |
| 53 | + |
| 54 | + if not os.path.exists(destdir): |
| 55 | + os.makedirs(destdir) |
| 56 | + |
| 57 | + for ln, fn in libs.items(): |
| 58 | + srcfile = urljoin(url, fn) |
| 59 | + destfile = os.path.join(destdir, fn) |
| 60 | + if os.path.exists(destfile + ".keep"): |
| 61 | + print('Using local copy of "{}"'.format(srcfile)) |
| 62 | + else: |
| 63 | + print('Retrieving "%s" to "%s"' % (srcfile, destfile)) |
| 64 | + urlcleanup() # work around FTP bug 27973 in Py2.7.12+ |
| 65 | + urlretrieve(srcfile, destfile) |
| 66 | + |
| 67 | + libs[ln] = unpack_zipfile(destfile, destdir) |
| 68 | + |
| 69 | + return libs |
| 70 | + |
| 71 | + |
| 72 | +def find_top_dir_of_zipfile(zipfile): |
| 73 | + topdir = None |
| 74 | + files = [f.filename for f in zipfile.filelist] |
| 75 | + dirs = [d for d in files if d.endswith('/')] |
| 76 | + if dirs: |
| 77 | + dirs.sort(key=len) |
| 78 | + topdir = dirs[0] |
| 79 | + topdir = topdir[:topdir.index("/")+1] |
| 80 | + for path in files: |
| 81 | + if not path.startswith(topdir): |
| 82 | + topdir = None |
| 83 | + break |
| 84 | + assert topdir, ( |
| 85 | + "cannot determine single top-level directory in zip file %s" % |
| 86 | + zipfile.filename) |
| 87 | + return topdir.rstrip('/') |
| 88 | + |
| 89 | + |
| 90 | +def unpack_zipfile(zipfn, destdir): |
| 91 | + assert zipfn.endswith('.zip') |
| 92 | + import zipfile |
| 93 | + print('Unpacking %s into %s' % (os.path.basename(zipfn), destdir)) |
| 94 | + f = zipfile.ZipFile(zipfn) |
| 95 | + try: |
| 96 | + extracted_dir = os.path.join(destdir, find_top_dir_of_zipfile(f)) |
| 97 | + f.extractall(path=destdir) |
| 98 | + finally: |
| 99 | + f.close() |
| 100 | + assert os.path.exists(extracted_dir), 'missing: %s' % extracted_dir |
| 101 | + return extracted_dir |
0 commit comments