xref: /llvm-project/llvm/utils/gn/get.py (revision b71edfaa4ec3c998aadb35255ce2f60bba2940b0)
10ff3cc20SNico Weber#!/usr/bin/env python3
2285becfaSNico Weber"""Downloads a prebuilt gn binary to a place where gn.py can find it."""
3285becfaSNico Weber
4d59857c3SNico Weberimport io
5285becfaSNico Weberimport os
6285becfaSNico Weberimport sys
70ff3cc20SNico Weberimport urllib.request
8285becfaSNico Weberimport zipfile
9285becfaSNico Weber
10285becfaSNico Weber
11285becfaSNico Weberdef download_and_unpack(url, output_dir, gn):
12285becfaSNico Weber    """Download an archive from url and extract gn from it into output_dir."""
13*b71edfaaSTobias Hieta    print("downloading %s ..." % url, end="")
14d59857c3SNico Weber    sys.stdout.flush()
150ff3cc20SNico Weber    data = urllib.request.urlopen(url).read()
16*b71edfaaSTobias Hieta    print(" done")
17d59857c3SNico Weber    zipfile.ZipFile(io.BytesIO(data)).extract(gn, path=output_dir)
18285becfaSNico Weber
19285becfaSNico Weber
20285becfaSNico Weberdef set_executable_bit(path):
21285becfaSNico Weber    mode = os.stat(path).st_mode
22285becfaSNico Weber    mode |= (mode & 0o444) >> 2  # Copy R bits to X.
23285becfaSNico Weber    os.chmod(path, mode)  # No-op on Windows.
24285becfaSNico Weber
25285becfaSNico Weber
26285becfaSNico Weberdef get_platform():
2738e6bcc1SNico Weber    import platform
28*b71edfaaSTobias Hieta
29*b71edfaaSTobias Hieta    if sys.platform == "darwin":
30*b71edfaaSTobias Hieta        return "mac-amd64" if platform.machine() != "arm64" else "mac-arm64"
31*b71edfaaSTobias Hieta    if platform.machine() not in ("AMD64", "x86_64"):
32285becfaSNico Weber        return None
33*b71edfaaSTobias Hieta    if sys.platform.startswith("linux"):
34*b71edfaaSTobias Hieta        return "linux-amd64"
35*b71edfaaSTobias Hieta    if sys.platform == "win32":
36*b71edfaaSTobias Hieta        return "windows-amd64"
37285becfaSNico Weber
38285becfaSNico Weber
39285becfaSNico Weberdef main():
40285becfaSNico Weber    platform = get_platform()
41285becfaSNico Weber    if not platform:
42*b71edfaaSTobias Hieta        print("no prebuilt binary for", sys.platform)
43*b71edfaaSTobias Hieta        print("build it yourself with:")
44*b71edfaaSTobias Hieta        print("  rm -rf /tmp/gn &&")
45*b71edfaaSTobias Hieta        print("  pushd /tmp && git clone https://gn.googlesource.com/gn &&")
46*b71edfaaSTobias Hieta        print("  cd gn && build/gen.py && ninja -C out gn && popd &&")
47*b71edfaaSTobias Hieta        print("  cp /tmp/gn/out/gn somewhere/on/PATH")
48285becfaSNico Weber        return 1
49*b71edfaaSTobias Hieta    dirname = os.path.join(os.path.dirname(__file__), "bin", platform)
50285becfaSNico Weber    if not os.path.exists(dirname):
51285becfaSNico Weber        os.makedirs(dirname)
52285becfaSNico Weber
53*b71edfaaSTobias Hieta    url = "https://chrome-infra-packages.appspot.com/dl/gn/gn/%s/+/latest"
54*b71edfaaSTobias Hieta    gn = "gn" + (".exe" if sys.platform == "win32" else "")
55*b71edfaaSTobias Hieta    if platform == "mac-arm64":  # For https://openradar.appspot.com/FB8914243
56*b71edfaaSTobias Hieta        try:
57*b71edfaaSTobias Hieta            os.remove(os.path.join(dirname, gn))
58*b71edfaaSTobias Hieta        except OSError:
59*b71edfaaSTobias Hieta            pass
60285becfaSNico Weber    download_and_unpack(url % platform, dirname, gn)
61285becfaSNico Weber    set_executable_bit(os.path.join(dirname, gn))
62285becfaSNico Weber
63285becfaSNico Weber
64*b71edfaaSTobias Hietaif __name__ == "__main__":
65285becfaSNico Weber    sys.exit(main())
66