| #!/usr/bin/env python3.8 |
| # Copyright 2022 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import glob |
| import os |
| import sys |
| import shutil |
| import subprocess |
| import argparse |
| import re |
| import json |
| |
| # Where all prebuilt debug binaries go. |
| PREBUILT_BUILD_ID_DIR = "prebuilt/.build-id" |
| |
| parser = argparse.ArgumentParser( |
| description="Upload Intel media driver to CIPD") |
| |
| parser.add_argument("--out-dir", required=True) |
| parser.add_argument("--dry-run", action="store_true") |
| parser.add_argument("--ignore-branch", action="store_true") |
| parser.add_argument("--ignore-rebuild", action="store_true") |
| parser.add_argument("--ignore-buildtype", action="store_true") |
| parser.add_argument("--debug", action="store_true") |
| |
| args = parser.parse_args() |
| |
| dir_path = os.path.dirname(os.path.realpath(__file__)) |
| |
| fuchsia_root = os.path.abspath(os.path.join(dir_path, "../../../../")) |
| |
| out_dir = os.path.abspath(args.out_dir) |
| |
| if not os.path.exists(out_dir): |
| print("Out dir: %s doesn't exist" % out_dir) |
| sys.exit(1) |
| |
| debug_suffix = "" |
| if args.debug: |
| debug_suffix = "-debug" |
| |
| |
| class CommonDriver(object): |
| |
| def CalculateGitRevision(self): |
| self.git_rev = subprocess.check_output( |
| ["git", "-C", self.git_repo_location, "rev-parse", |
| "HEAD"]).decode("utf-8").strip() |
| |
| # Ignore commits on local branch |
| self.fuchsia_git_rev = subprocess.check_output( |
| ["git", "-C", fuchsia_root, "merge-base", "origin/master", |
| "HEAD"]).decode("utf-8").strip() |
| |
| |
| class IntelDriver(CommonDriver): |
| |
| def __init__(self, repo_name): |
| self.public = True |
| self.driver_type = "intel-gen" |
| self.repo_name = repo_name |
| self.git_repo_location = "%s/third_party/%s/" % ( |
| fuchsia_root, repo_name) |
| |
| self.file_name = "codec_runner_intel_gen.far" |
| self.input_name = "obj/third_party/intel/media-driver/fuchsia/codec_runner_intel_gen.far" |
| |
| self.platform = "x64" |
| platform_suffix = "-" + self.platform |
| |
| # Package dir is in the out directory to avoid dirtying source directories. |
| self.package_dir = os.path.join( |
| out_dir, "build-intel-media-driver", |
| "codec_runner_intel_gen" + debug_suffix) |
| package_name_base = "third_party/intel/media-driver/codec_runner_intel_gen" |
| self.package_name = "fuchsia/" + package_name_base + debug_suffix + platform_suffix |
| self.prebuilt_path = "prebuilt/" + package_name_base + debug_suffix + platform_suffix |
| |
| self.symbol_package_name = "fuchsia/" + package_name_base + debug_suffix + "-debug-symbols" + platform_suffix |
| self.symbol_package_dir = self.package_dir + "-symbols" |
| self.symbol_input_names = [ |
| "build-intel-media-driver/install/strip/iHD_drv_video.so.debug", |
| "build-intel-media-driver/install/strip/libva-magma.so.2.debug", |
| "build-intel-media-driver/install/strip/libigdgmm.so.11.debug", |
| "build-intel-media-driver/install/strip/libva.so.2.debug", |
| ] |
| # Path to unstripped codec_runner_intel_gen varies depending on whether variants are used in |
| # the build. binaries.json knows the correct path. |
| with open(os.path.join(out_dir, "binaries.json"), "r") as binaries: |
| binary_json = json.load(binaries) |
| for entry in binary_json: |
| if not entry["os"] == "fuchsia": |
| continue |
| if not entry["type"] == "executable": |
| continue |
| if not entry["label"].startswith( |
| "//third_party/intel/media-driver/fuchsia:codec_runner_intel_gen_exe(" |
| ): |
| continue |
| self.symbol_input_names.append(entry["debug"]) |
| |
| def GnArgs(self): |
| return { |
| "is_debug": args.debug, |
| "intel_media_driver_debug": args.debug, |
| } |
| |
| |
| driver_list = [IntelDriver("intel/media-driver")] |
| dir_path = os.path.join(fuchsia_root, "third_party/intel/media-driver/fuchsia") |
| |
| os.chdir(dir_path) |
| |
| for driver in driver_list: |
| current_head = subprocess.check_output( |
| ["git", "-C", driver.git_repo_location, "rev-parse", "--short", |
| "HEAD"]).decode("utf-8").strip() |
| jiri_head = subprocess.check_output( |
| [ |
| "git", "-C", driver.git_repo_location, "rev-parse", "--short", |
| "JIRI_HEAD" |
| ]).decode("utf-8").strip() |
| |
| if current_head != jiri_head: |
| print( |
| "Git repo %s HEAD is commit %s (JIRI_HEAD is commit %s)" % |
| (driver.repo_name, current_head, jiri_head)) |
| if args.ignore_branch: |
| print("Ignoring") |
| else: |
| print("Use --ignore-branch flag to upload anyway") |
| sys.exit(1) |
| |
| for driver in driver_list: |
| target_name = driver.input_name |
| # Force ninja dry-run. Output can be on stderr on new ninja versions or |
| # stdout on old versions. |
| ninja_output = subprocess.check_output( |
| [ |
| os.path.join( |
| fuchsia_root, "prebuilt/third_party/ninja/linux-x64/ninja"), |
| "-C", out_dir, "-v", "-n", target_name |
| ], |
| stderr=subprocess.STDOUT).decode("utf-8") |
| |
| if "ninja: no work to do." not in ninja_output: |
| print("Ninja reported work needed to be done for %s" % target_name) |
| if args.ignore_rebuild: |
| print("Ignoring") |
| else: |
| print("Use --ignore-rebuild flag to upload anyway") |
| sys.exit(1) |
| |
| for driver in driver_list: |
| gn_args = driver.GnArgs() |
| gn_arg_mismatch = False |
| gn_output_json = subprocess.check_output( |
| [ |
| os.path.join(fuchsia_root, "prebuilt/third_party/gn/linux-x64/gn"), |
| "args", |
| out_dir, |
| "--short", |
| "--list", |
| "--json", |
| ]).decode("utf-8") |
| |
| gn_output = json.loads(gn_output_json) |
| gn_arg_vars = set(gn_args.keys()) |
| |
| for gn_variable in gn_output: |
| var_name = gn_variable["name"] |
| if var_name in gn_args: |
| value = gn_variable["default"]["value"] |
| if "current" in gn_variable: |
| value = gn_variable["current"]["value"] |
| expected_val = "true" if gn_args[var_name] else "false" |
| if value != expected_val: |
| print( |
| "GN argument \"{}\" should have a value of \"{}\" but has a value of \"{}\"" |
| .format(var_name, expected_val, value)) |
| gn_arg_mismatch = True |
| gn_arg_vars.remove(var_name) |
| |
| if gn_arg_vars: |
| print( |
| "Missing variable(s) \"{}\" from GN arguments".format( |
| ",".join(gn_arg_vars))) |
| gn_arg_mismatch = True |
| |
| if gn_arg_mismatch: |
| if args.ignore_buildtype: |
| print("Ignoring") |
| else: |
| print("Use --ignore-buildtype flag to upload anyway") |
| sys.exit(1) |
| |
| for driver in driver_list: |
| full_name = os.path.join(driver.package_dir, driver.file_name) |
| |
| source_file_name = os.path.join(out_dir, driver.input_name) |
| try: |
| os.remove(full_name) |
| except: |
| pass |
| try: |
| os.mkdir(driver.package_dir) |
| except: |
| pass |
| shutil.copyfile(source_file_name, full_name) |
| shutil.copyfile( |
| "../LICENSE.md", os.path.join(driver.package_dir, "LICENSE")) |
| |
| buildidtool = os.path.join( |
| fuchsia_root, "prebuilt/tools/buildidtool/linux-x64/buildidtool") |
| cipd_path = os.path.join(fuchsia_root, ".jiri_root/bin/cipd") |
| jiri_path = os.path.join(fuchsia_root, ".jiri_root/bin/jiri") |
| |
| # See |
| # https://fuchsia.dev/fuchsia-src/development/prebuilt_packages/publish_prebuilt_packages_to_cipd |
| # for symbol directory format |
| for driver in driver_list: |
| if not driver.symbol_package_name: |
| continue |
| try: |
| shutil.rmtree(driver.symbol_package_dir) |
| except: |
| pass |
| try: |
| os.mkdir(driver.symbol_package_dir) |
| except: |
| pass |
| for i, symbol_input_name in enumerate(driver.symbol_input_names): |
| subprocess.check_output( |
| [ |
| buildidtool, "-entry", |
| ".debug=" + os.path.join(out_dir, symbol_input_name), |
| "-build-id-dir", driver.symbol_package_dir, |
| "-stamp=" + os.path.join( |
| out_dir, |
| "build-intel-media-driver-stamp-" + debug_suffix + str(i)) |
| ]) |
| |
| for driver in driver_list: |
| driver.CalculateGitRevision() |
| |
| |
| def cipd_upload(package_dir, package_name, git_rev, fuchsia_git_rev): |
| cipd_command = ( |
| "%s create -in %s -name %s -ref latest -install-mode copy " |
| "-tag git_revision:%s -tag fuchsia_git_revision:%s") % ( |
| cipd_path, package_dir, package_name, git_rev, fuchsia_git_rev) |
| print(cipd_command) |
| if not args.dry_run: |
| subprocess.check_call(cipd_command.split(" ")) |
| |
| |
| for driver in driver_list: |
| cipd_upload( |
| driver.package_dir, driver.package_name, driver.git_rev, |
| driver.fuchsia_git_rev) |
| if driver.symbol_package_name: |
| cipd_upload( |
| driver.symbol_package_dir, driver.symbol_package_name, |
| driver.git_rev, driver.fuchsia_git_rev) |
| |
| print("Modifying jiri manifests") |
| |
| public_manifest = "integration/fuchsia/prebuilts" |
| |
| |
| def print_latest_package_info( |
| package_name, prebuilt_path, manifest_path, attributes=None): |
| cipd_command = "%s describe %s -version latest" % (cipd_path, package_name) |
| cipd_output = subprocess.check_output(cipd_command.split()).decode("utf-8") |
| cipd_output = [x for x in cipd_output.split("\n") if "Instance ID:" in x] |
| package_id = re.search(r"Instance ID: +([0-9a-zA-Z_\-]+)", |
| cipd_output[0]).group(1) |
| if attributes: |
| attrib_string = '\n attributes="' + attributes + '"' |
| else: |
| attrib_string = "" |
| print( |
| ( |
| """ |
| <package name="%s" |
| path="%s" |
| version="%s"%s/> |
| """ % (package_name, prebuilt_path, package_id, attrib_string))[1:-1]) |
| os.system( |
| "%s edit -package='%s=%s' %s" % |
| (jiri_path, package_name, package_id, os.path.join(fuchsia_root, manifest_path))) |
| |
| |
| for driver in driver_list: |
| print_latest_package_info( |
| driver.package_name, driver.prebuilt_path, public_manifest) |
| |
| for driver in driver_list: |
| if driver.symbol_package_name: |
| print_latest_package_info( |
| driver.symbol_package_name, PREBUILT_BUILD_ID_DIR, public_manifest, |
| "debug-symbols,debug-symbols-x64,debug-symbols-" + |
| driver.driver_type) |