1#!/usr/bin/env python 2"""Downloads a prebuilt gn binary to a place where gn.py can find it.""" 3 4from __future__ import print_function 5 6import io 7import os 8try: 9 # In Python 3, we need the module urllib.reqest. In Python 2, this 10 # functionality was in the urllib2 module. 11 from urllib import request as urllib_request 12except ImportError: 13 import urllib2 as urllib_request 14import sys 15import zipfile 16 17 18def download_and_unpack(url, output_dir, gn): 19 """Download an archive from url and extract gn from it into output_dir.""" 20 print('downloading %s ...' % url, end='') 21 sys.stdout.flush() 22 data = urllib_request.urlopen(url).read() 23 print(' done') 24 zipfile.ZipFile(io.BytesIO(data)).extract(gn, path=output_dir) 25 26 27def set_executable_bit(path): 28 mode = os.stat(path).st_mode 29 mode |= (mode & 0o444) >> 2 # Copy R bits to X. 30 os.chmod(path, mode) # No-op on Windows. 31 32 33def get_platform(): 34 import platform 35 if sys.platform == 'darwin': 36 return 'mac-amd64' if platform.machine() != 'arm64' else 'mac-arm64' 37 if platform.machine() not in ('AMD64', 'x86_64'): 38 return None 39 if sys.platform.startswith('linux'): 40 return 'linux-amd64' 41 if sys.platform == 'win32': 42 return 'windows-amd64' 43 44 45def main(): 46 platform = get_platform() 47 if not platform: 48 print('no prebuilt binary for', sys.platform) 49 return 1 50 dirname = os.path.join(os.path.dirname(__file__), 'bin', platform) 51 if not os.path.exists(dirname): 52 os.makedirs(dirname) 53 54 url = 'https://chrome-infra-packages.appspot.com/dl/gn/gn/%s/+/latest' 55 gn = 'gn' + ('.exe' if sys.platform == 'win32' else '') 56 if platform == 'mac-arm64': # For https://openradar.appspot.com/FB8914243 57 try: os.remove(os.path.join(dirname, gn)) 58 except OSError: pass 59 download_and_unpack(url % platform, dirname, gn) 60 set_executable_bit(os.path.join(dirname, gn)) 61 62 63if __name__ == '__main__': 64 sys.exit(main()) 65