1# Copyright 2021 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 15import("//build_overrides/pigweed.gni") 16 17import("$dir_pw_build/python_action.gni") 18 19# GN target that creates update bundles. 20# 21# Args: 22# out: Filename at which to output the serialized update bundle. 23# targets: List of targets mapping filenames to target names. 24# persist: Optional boolean; if true, the raw tuf repo will be persisted to 25# disk in the target out dir in addition to being serialized as a bundle. 26# user_manifest: Optional path to an extra user-defined manifest file; if 27# provided, this file will be included as a target payload, but handled 28# specially. See the following file for details: 29# pw_software_update/public/pw_software_update/bundled_update_backend.h 30# targets_metadata_version: Optional manually-specified int version number for 31# the targets metadata. 32# targets_metadata_version_file: Optional manually-specified path/to/file 33# containing int version number for the targets metadata. Cannot be 34# specified together with targets_metadata_version 35# signed_root_metadata: Optional path to a .pb file containing a serialized 36# SignedRootMetadata (generated and signed via the tools in the 37# pw_software_update Python module). 38# 39# Each target in targets should be a string formatted as follows: 40# "/path/to/file > target_name" 41 42template("pw_update_bundle") { 43 assert(defined(invoker.out), "An output path must be provided via 'out'") 44 assert(defined(invoker.targets), 45 "A list of targets must be provided via 'targets'") 46 pw_python_action(target_name) { 47 _delimiter = ">" 48 forward_variables_from(invoker, 49 [ 50 "deps", 51 "public_deps", 52 ]) 53 _out_path = invoker.out 54 _persist_path = "" 55 if (defined(invoker.persist) && invoker.persist) { 56 _persist_path = "${target_out_dir}/${target_name}/tuf_repo" 57 } 58 module = "pw_software_update.update_bundle" 59 python_deps = [ "$dir_pw_software_update/py" ] 60 args = [ 61 "--out", 62 rebase_path(_out_path), 63 "--targets", 64 ] 65 outputs = [ _out_path ] 66 67 foreach(tuf_target, invoker.targets) { 68 # Remove possible spaces around the delimiter before splitting 69 tuf_target = string_replace(tuf_target, " $_delimiter", _delimiter) 70 tuf_target = string_replace(tuf_target, "$_delimiter ", _delimiter) 71 72 tuf_target_list = [] 73 tuf_target_list = string_split(tuf_target, _delimiter) 74 tuf_target_path = rebase_path(tuf_target_list[0], root_build_dir) 75 tuf_target_name = tuf_target_list[1] 76 assert(tuf_target_name != "user_manifest", 77 "The target name 'user_manifest' is reserved for special use.") 78 args += [ "${tuf_target_path} > ${tuf_target_name}" ] 79 if (_persist_path != "") { 80 outputs += [ "${_persist_path}/${tuf_target_name}" ] 81 } 82 } 83 84 if (defined(invoker.user_manifest)) { 85 args += [ rebase_path(invoker.user_manifest, root_build_dir) + 86 " > user_manifest" ] 87 } 88 89 if (_persist_path != "") { 90 args += [ 91 "--persist", 92 rebase_path(_persist_path), 93 ] 94 } 95 96 if (defined(invoker.targets_metadata_version)) { 97 args += [ 98 "--targets-metadata-version", 99 invoker.targets_metadata_version, 100 ] 101 } 102 103 if (defined(invoker.targets_metadata_version_file)) { 104 args += [ 105 "--targets-metadata-version-file", 106 rebase_path(invoker.targets_metadata_version_file), 107 ] 108 } 109 110 assert( 111 !(defined(invoker.targets_metadata_version_file) && 112 defined(invoker.targets_metadata_version)), 113 "Only one of targets_metadata_version and targets_metadata_version_file can be specified") 114 115 if (defined(invoker.signed_root_metadata)) { 116 args += [ 117 "--signed-root-metadata", 118 rebase_path(invoker.signed_root_metadata), 119 ] 120 } 121 } 122} 123