| # -*- coding: utf-8 -*- |
| |
| import os |
| import sys |
| import shutil |
| import tarfile |
| import urllib2 |
| import hashlib |
| import argparse |
| |
| EXTERNAL_DIR = os.path.realpath(os.path.normpath(os.path.dirname(__file__))) |
| |
| class SourcePackage: |
| def __init__(self, url, filename, checksum, dstDir, postExtract=None): |
| self.url = url |
| self.filename = filename |
| self.checksum = checksum |
| self.dstDir = dstDir |
| self.postExtract = postExtract |
| |
| def computeChecksum (data): |
| return hashlib.sha256(data).hexdigest() |
| |
| def clean (pkg): |
| srcPath = os.path.join(EXTERNAL_DIR, pkg.dstDir) |
| |
| for entry in os.listdir(srcPath): |
| if entry == "CMakeLists.txt": |
| continue |
| |
| fullPath = os.path.join(srcPath, entry) |
| |
| if os.path.isfile(fullPath): |
| os.unlink(fullPath) |
| elif os.path.isdir(fullPath): |
| shutil.rmtree(fullPath, ignore_errors=False) |
| |
| def fetch (pkg): |
| print "Fetching %s" % pkg.url |
| |
| req = urllib2.urlopen(pkg.url) |
| data = req.read() |
| checksum = computeChecksum(data) |
| dstPath = os.path.join(EXTERNAL_DIR, pkg.filename) |
| |
| if checksum != pkg.checksum: |
| raise Exception("Checksum mismatch for %s, exepected %s, got %s" % (pkg.filename, pkg.checksum, checksum)) |
| |
| out = open(dstPath, 'wb') |
| out.write(data) |
| out.close() |
| |
| def extract (pkg): |
| print "Extracting %s to %s" % (pkg.filename, pkg.dstDir) |
| |
| srcPath = os.path.join(EXTERNAL_DIR, pkg.filename) |
| tmpPath = os.path.join(EXTERNAL_DIR, ".extract-tmp-%s" % pkg.dstDir) |
| dstPath = os.path.join(EXTERNAL_DIR, pkg.dstDir) |
| archive = tarfile.open(srcPath) |
| |
| if os.path.exists(tmpPath): |
| shutil.rmtree(tmpPath, ignore_errors=False) |
| |
| os.mkdir(tmpPath) |
| |
| archive.extractall(tmpPath) |
| archive.close() |
| |
| extractedEntries = os.listdir(tmpPath) |
| if len(extractedEntries) != 1 or not os.path.isdir(os.path.join(tmpPath, extractedEntries[0])): |
| raise Exception("%s doesn't contain single top-level directory") % pkg.filename |
| |
| topLevelPath = os.path.join(tmpPath, extractedEntries[0]) |
| |
| for entry in os.listdir(topLevelPath): |
| if os.path.exists(os.path.join(dstPath, entry)): |
| print " skipping %s" % entry |
| continue |
| |
| shutil.move(os.path.join(topLevelPath, entry), dstPath) |
| |
| shutil.rmtree(tmpPath, ignore_errors=True) |
| |
| if pkg.postExtract != None: |
| pkg.postExtract(dstPath) |
| |
| def postExtractLibpng (path): |
| shutil.copy(os.path.join(path, "scripts", "pnglibconf.h.prebuilt"), |
| os.path.join(path, "pnglibconf.h")) |
| |
| PACKAGES = [ |
| SourcePackage("http://zlib.net/zlib-1.2.8.tar.gz", |
| "zlib-1.2.8.tar.gz", |
| "36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d", |
| "zlib"), |
| SourcePackage("ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng16/libpng-1.6.16.tar.gz", |
| "libpng-1.6.14.tar.gz", |
| "02f96b6bad5a381d36d7ba7a5d9be3b06f7fe6c274da00707509c23592a073ad", |
| "libpng", |
| postExtract = postExtractLibpng), |
| ] |
| |
| def parseArgs (): |
| parser = argparse.ArgumentParser(description = "Fetch external sources") |
| parser.add_argument('--clean-only', dest='cleanOnly', action='store_true', default=False, |
| help='Clean only, do not fetch/extract') |
| parser.add_argument('--keep-archive', dest='keepArchive', action='store_true', default=False, |
| help='Keep archive after extracting') |
| return parser.parse_args() |
| |
| if __name__ == "__main__": |
| args = parseArgs() |
| |
| for pkg in PACKAGES: |
| clean(pkg) |
| |
| if args.cleanOnly: |
| continue |
| |
| fetch(pkg) |
| extract(pkg) |
| |
| if not args.keepArchive: |
| os.unlink(os.path.join(EXTERNAL_DIR, pkg.filename)) |