1#!/usr/bin/env python 2 3# Copyright 2019 Google LLC. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7""" 8update_fuchsia_sdk 9 10 Downloads both the Fuchsia SDK and Fuchsia-compatible clang 11 zip archives from chrome infra (CIPD) and extracts them to 12 the arg-provide |sdk_dir| and |clang_dir| respectively. This 13 provides the complete toolchain required to build Fuchsia binaries 14 from the Fuchsia SDK. 15 16""" 17 18import argparse 19import errno 20import logging 21import os 22import platform 23import shutil 24import subprocess 25import tempfile 26 27def MessageExit(message): 28 logging.error(message) 29 sys.exit(1) 30 31# Verify that "cipd" tool is readily available. 32def CipdLives(): 33 err_msg = "Cipd not found, please install. See: " + \ 34 "https://commondatastorage.googleapis.com/chrome-infra-docs/flat" + \ 35 "/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up" 36 try: 37 subprocess.call(["cipd", "--version"]) 38 except OSError as e: 39 if e.errno == errno.ENOENT: 40 MessageExit(err_msg) 41 else: 42 MessageExit("cipd command execution failed.") 43 44# Download and unzip CIPD package archive. 45def DownloadAndUnzip(pkg_name, version, cipd_cache_dir, output_dir): 46 pkg_suffix = pkg_name.replace('/', '-') + ".zip" 47 zip_file = tempfile.NamedTemporaryFile(suffix=pkg_suffix, delete=False) 48 cipd_cmd = "cipd pkg-fetch " + pkg_name + " -version \"" + version + "\" -out " + \ 49 zip_file.name + " -cache-dir " + cipd_cache_dir 50 unzip_cmd = "unzip -q " + zip_file.name + " -d " + output_dir 51 os.system(cipd_cmd) 52 os.system(unzip_cmd) 53 54def Main(): 55 CipdLives() 56 parser = argparse.ArgumentParser() 57 parser.add_argument("-sdk_dir", type=str, 58 help="Destination directory for the fuchsia SDK.") 59 parser.add_argument("-clang_dir", type=str, 60 help="Destination directory for the fuchsia toolchain.") 61 parser.add_argument("-overwrite_dirs", type=bool, default=False, 62 help="REMOVES existing sdk and clang dirs and makes new ones. When false " + 63 " the unzip command issue will require file overwrite confirmation.") 64 parser.add_argument("-cipd_cache_dir", type=str, default="/tmp", required=False, 65 help="Cache directory for CIPD downloads to prevent redundant downloads.") 66 parser.add_argument("-cipd_sdk_version", type=str, default="latest", required=False, 67 help="CIPD sdk version to download, e.g.: git_revision:fce11c6904c888e6d39f71e03806a540852dec41") 68 parser.add_argument("-cipd_clang_version", type=str, default="latest", required=False, 69 help="CIPD clang version to download, e.g.: git_revision:fce11c6904c888e6d39f71e03806a540852dec41") 70 args = parser.parse_args() 71 72 sdk_dir = args.sdk_dir 73 clang_dir = args.clang_dir 74 cipd_sdk_version = args.cipd_sdk_version 75 cipd_clang_version = args.cipd_clang_version 76 77 if args.overwrite_dirs: 78 dirs = [sdk_dir, clang_dir] 79 for curr_dir in dirs: 80 try: 81 if os.path.exists(curr_dir): 82 shutil.rmtree(curr_dir) 83 os.makedirs(curr_dir) 84 except OSError: 85 MessageExit("Creation of the directory %s failed" % curr_dir) 86 else: 87 # Make dirs for sdk and clang. 88 if not os.path.exists(sdk_dir): 89 os.makedirs(sdk_dir) 90 if not os.path.exists(clang_dir): 91 os.makedirs(clang_dir) 92 93 # Verify that existing dirs are writable. 94 if (not os.access(sdk_dir, os.W_OK)) or (not os.path.isdir(sdk_dir)): 95 MessageExit("Can't write to sdk dir " + sdk_dir) 96 if (not os.access(clang_dir, os.W_OK)) or (not os.path.isdir(clang_dir)): 97 MessageExit("Can't write to clang dir " + clang_dir) 98 99 ostype = platform.system() 100 if ostype == "Linux": 101 os_string = "linux-amd64" 102 elif ostype == "Darwin": 103 os_string = "mac-amd64" 104 else: 105 MessageExit("Unknown host " + ostype) 106 107 # |sdk_pkg| and |clang_pkg| below are prescribed paths defined by chrome-infra. 108 sdk_pkg = "fuchsia/sdk/core/" + os_string 109 DownloadAndUnzip(sdk_pkg, cipd_sdk_version, args.cipd_cache_dir, sdk_dir) 110 clang_pkg = "fuchsia/clang/" + os_string 111 DownloadAndUnzip(clang_pkg, cipd_clang_version, args.cipd_cache_dir, clang_dir) 112 113if __name__ == "__main__": 114 import sys 115 Main() 116