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