[llvm] r352420 - gn build: Add get.py script to download prebuilt gn, make gn.py run downloaded gn if gn is not on PATH

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 28 11:54:41 PST 2019


Author: nico
Date: Mon Jan 28 11:54:41 2019
New Revision: 352420

URL: http://llvm.org/viewvc/llvm-project?rev=352420&view=rev
Log:
gn build: Add get.py script to download prebuilt gn, make gn.py run downloaded gn if gn is not on PATH

Prebuilts are available for x86_64 Linux, macOS, Windows. The script always
pulls the latest GN version.

Differential Revision: https://reviews.llvm.org/D57256

Added:
    llvm/trunk/utils/gn/.gitignore
    llvm/trunk/utils/gn/get.py
Modified:
    llvm/trunk/utils/gn/README.rst
    llvm/trunk/utils/gn/gn.py

Added: llvm/trunk/utils/gn/.gitignore
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/.gitignore?rev=352420&view=auto
==============================================================================
--- llvm/trunk/utils/gn/.gitignore (added)
+++ llvm/trunk/utils/gn/.gitignore Mon Jan 28 11:54:41 2019
@@ -0,0 +1 @@
+bin

Modified: llvm/trunk/utils/gn/README.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/README.rst?rev=352420&r1=352419&r2=352420&view=diff
==============================================================================
--- llvm/trunk/utils/gn/README.rst (original)
+++ llvm/trunk/utils/gn/README.rst Mon Jan 28 11:54:41 2019
@@ -42,7 +42,11 @@ Quick start
 
 GN only works in the monorepo layout.
 
-#. Obtain a `gn binary <https://gn.googlesource.com/gn/#getting-started>`_.
+#. Obtain a gn binary. If gn is not already on your PATH, run
+   `llvm/utils/gn/get.py` to download a prebuilt gn binary if you're on a 64-bit
+   X86 system running Linux, macOS, or Windows, or `build gn yourself
+   <https://gn.googlesource.com/gn/#getting-started>`_ if you're on a different
+   platform or don't want to trust prebuilt binaries.
 
 #. In the root of the monorepo, run `llvm/utils/gn/gn.py gen out/gn`.
    `out/gn` is the build directory, it can have any name, and you can have as

Added: llvm/trunk/utils/gn/get.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/get.py?rev=352420&view=auto
==============================================================================
--- llvm/trunk/utils/gn/get.py (added)
+++ llvm/trunk/utils/gn/get.py Mon Jan 28 11:54:41 2019
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+"""Downloads a prebuilt gn binary to a place where gn.py can find it."""
+
+from __future__ import print_function
+
+import os
+import urllib2
+import sys
+import tempfile
+import zipfile
+
+
+def download_url(url, output_file):
+    """Download url into output_file."""
+    print('downloading %s ...' % url, end='')
+    sys.stdout.flush()
+    output_file.write(urllib2.urlopen(url).read())
+    print(' done')
+
+
+def download_and_unpack(url, output_dir, gn):
+    """Download an archive from url and extract gn from it into output_dir."""
+    with tempfile.TemporaryFile() as f:
+        download_url(url, f)
+        f.seek(0)
+        zipfile.ZipFile(f).extract(gn, path=output_dir)
+
+
+def set_executable_bit(path):
+    mode = os.stat(path).st_mode
+    mode |= (mode & 0o444) >> 2 # Copy R bits to X.
+    os.chmod(path, mode) # No-op on Windows.
+
+
+def get_platform():
+    if os.uname()[4] != 'x86_64':
+        return None
+    if sys.platform.startswith('linux'):
+        return 'linux-amd64'
+    if sys.platform == 'darwin':
+        return 'mac-amd64'
+    if sys.platform == 'win32':
+        return 'windows-amd64'
+
+
+def main():
+    platform = get_platform()
+    if not platform:
+        print('no prebuilt binary for', sys.platform)
+        return 1
+
+    dirname = os.path.join(os.path.dirname(__file__), 'bin', platform)
+    if not os.path.exists(dirname):
+        os.makedirs(dirname)
+
+    url = 'https://chrome-infra-packages.appspot.com/dl/gn/gn/%s/+/latest'
+    gn = 'gn' + ('.exe' if sys.platform == 'win32' else '')
+    download_and_unpack(url % platform, dirname, gn)
+    set_executable_bit(os.path.join(dirname, gn))
+
+
+if __name__ == '__main__':
+    sys.exit(main())

Modified: llvm/trunk/utils/gn/gn.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/gn.py?rev=352420&r1=352419&r2=352420&view=diff
==============================================================================
--- llvm/trunk/utils/gn/gn.py (original)
+++ llvm/trunk/utils/gn/gn.py Mon Jan 28 11:54:41 2019
@@ -15,10 +15,38 @@ THIS_DIR = os.path.dirname(__file__)
 ROOT_DIR = os.path.join(THIS_DIR, '..', '..', '..')
 
 
+def get_platform():
+    if os.uname()[4] != 'x86_64':
+        return None
+    if sys.platform.startswith('linux'):
+        return 'linux-amd64'
+    if sys.platform == 'darwin':
+        return 'mac-amd64'
+    if sys.platform == 'win32':
+        return 'windows-amd64'
+
+
+def print_no_gn(mention_get):
+    print('gn binary not found in PATH')
+    if mention_get:
+        print('run llvm/utils/gn/get.py to download a binary and try again, or')
+    print('follow https://gn.googlesource.com/gn/#getting-started')
+    return 1
+
+
 def main():
-    # Find real gn executable. For now, just assume it's on PATH.
-    # FIXME: Probably need to append '.exe' on Windows.
+    # Find real gn executable.
     gn = 'gn'
+    if subprocess.call([gn, '--version'], stdout=open(os.devnull, 'w'),
+                                          stderr=subprocess.STDOUT) != 0:
+        # Not on path. See if get.py downloaded a prebuilt binary and run that
+        # if it's there, or suggest to run get.py if it isn't.
+        platform = get_platform()
+        if not platform:
+            return print_no_gn(mention_get=False)
+        gn = os.path.join(os.path.dirname(__file__), 'bin', platform, 'gn')
+        if not os.path.exists(gn + ('.exe' if platform == 'windows' else '')):
+            return print_no_gn(mention_get=True)
 
     # Compute --dotfile= and --root= args to add.
     extra_args = []




More information about the llvm-commits mailing list