1# Copyright 2023 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Install and check status of Zephyr.""" 15import importlib.resources 16import json 17import pathlib 18import subprocess 19import sys 20import tempfile 21 22from typing import Sequence 23 24import pw_env_setup.virtualenv_setup 25 26import pw_package.git_repo 27import pw_package.package_manager 28 29# Main branch, this commit is close to the v3.6 RC3 tag which contains some 30# bug fixes for Twister and support for GTEST_SKIP() 31_ZEPHYR_COMMIT_SHA = 'f9778472105d756fff7d1e5b54353421d356ed43' 32 33 34class Zephyr(pw_package.git_repo.GitRepo): 35 """Install and check status of Zephyr.""" 36 37 def __init__(self, *args, **kwargs): 38 super().__init__( 39 *args, 40 name='zephyr', 41 url=( 42 'https://pigweed.googlesource.com/third_party/' 43 'github/zephyrproject-rtos/zephyr' 44 ), 45 commit=_ZEPHYR_COMMIT_SHA, 46 **kwargs, 47 ) 48 49 def info(self, path: pathlib.Path) -> Sequence[str]: 50 return ( 51 f'{self.name} installed in: {path}', 52 'Enable by running "gn args out" and adding this line:', 53 f' dir_pw_third_party_zephyr = "{path}"', 54 ) 55 56 @staticmethod 57 def __populate_download_cache_from_cipd(path: pathlib.Path) -> None: 58 """Check for Zephyr SDK in cipd""" 59 package_path = path.parent.resolve() 60 core_cache_path = package_path / 'zephyr_sdk' 61 core_cache_path.mkdir(parents=True, exist_ok=True) 62 63 cipd_package_subpath = 'infra/3pp/tools/zephyr_sdk/${platform}' 64 65 # Check if the zephyr_sdk cipd package is readable 66 with tempfile.NamedTemporaryFile( 67 prefix='cipd', delete=True 68 ) as temp_json: 69 temp_json_path = pathlib.Path(temp_json.name) 70 cipd_acl_check_command = [ 71 'cipd', 72 'acl-check', 73 cipd_package_subpath, 74 '-reader', 75 '-json-output', 76 str(temp_json_path), 77 ] 78 subprocess.run(cipd_acl_check_command, capture_output=True) 79 80 # Return if no packages are readable. 81 if not temp_json_path.is_file(): 82 raise RuntimeError( 83 'Failed to verify zephyr_sdk cipd package is readable.' 84 ) 85 result_text = temp_json_path.read_text() 86 result_dict = json.loads(result_text) 87 if 'result' not in result_dict: 88 raise RuntimeError( 89 'Failed to verify zephyr_sdk cipd package is readable.' 90 ) 91 92 # Initialize cipd 93 subprocess.check_call( 94 [ 95 'cipd', 96 'init', 97 '-force', 98 str(core_cache_path), 99 ] 100 ) 101 # Install the Zephyr SDK 102 subprocess.check_call( 103 [ 104 'cipd', 105 'install', 106 cipd_package_subpath, 107 '-root', 108 str(core_cache_path), 109 '-force', 110 ] 111 ) 112 # Setup Zephyr SDK 113 subprocess.check_call( 114 [ 115 'cmake', 116 '-P', 117 str(core_cache_path / 'cmake' / 'zephyr_sdk_export.cmake'), 118 ] 119 ) 120 121 def install(self, path: pathlib.Path) -> None: 122 super().install(path) 123 124 self.__populate_download_cache_from_cipd(path) 125 with importlib.resources.path( 126 pw_env_setup.virtualenv_setup, 'constraint.list' 127 ) as constraint: 128 subprocess.check_call( 129 [ 130 sys.executable, 131 '-m', 132 'pip', 133 'install', 134 '-r', 135 f'{path}/scripts/requirements.txt', 136 '-c', 137 str(constraint), 138 ] 139 ) 140 141 142pw_package.package_manager.register(Zephyr) 143