1# Copyright 2018 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import("//build/config/sysroot.gni") 6 7# Creates a Fuchsia .far package file containing a Fuchsia component. 8# 9# Parameters are: 10# package_name_override: Specifies the name of the package to generate, 11# if different than |target_name|. 12# archive_filename_override: Specifies the filename of the generated FAR. 13# If left unset, defaults to |package_name_override|. 14# Defaults to the target name. 15# binary: The executable target which should be launched. 16# manifest: A path to the manifest that will be used. 17# "testonly" targets default to using 18# //build/config/fuchsia/tests-with-exec.cmx. 19# Non-test targets must explicitly specify a |manifest|. 20# additional_manifests: Manifest files that should be included in the package in 21# the /meta directory. This allows to package more than one component per 22# manifest. These manifest files must specify program/binary to run, which 23# is not required for the main manifest file where this parameter is added 24# during build. 25# component_name_override: If set, specifies the name of the component. 26# By default, the component name is the same as the package name. 27# deps: Additional targets to build and include in the package (optional). 28# 29# TODO(https://crbug.com/1050703): Migrate consumers to GN SDK equivalents. 30template("cr_fuchsia_package") { 31 pkg = { 32 forward_variables_from(invoker, "*") 33 34 if (defined(package_name_override)) { 35 package_name = package_name_override 36 } else { 37 package_name = invoker.target_name 38 } 39 40 if (defined(archive_name_override)) { 41 archive_filename = archive_name_override 42 } else { 43 archive_filename = package_name 44 } 45 46 if (!defined(manifest)) { 47 assert(testonly == true) 48 49 # TODO(1019938): switch the default to tests.cmx which doesn't request 50 # the deprecated-ambient-replace-as-executable feature. 51 manifest = "//build/config/fuchsia/tests-with-exec.cmx" 52 } 53 } 54 assert(defined(pkg.binary)) 55 56 _pm_tool_path = "//third_party/fuchsia-sdk/sdk/tools/pm" 57 58 _pkg_out_dir = "${target_gen_dir}/${pkg.archive_filename}" 59 _runtime_deps_file = "$_pkg_out_dir/${pkg.archive_filename}.runtime_deps" 60 _archive_manifest = "$_pkg_out_dir/${pkg.archive_filename}.archive_manifest" 61 _build_ids_file = "$_pkg_out_dir/ids.txt" 62 _meta_far_file = "$_pkg_out_dir/meta.far" 63 _combined_far_file = "$_pkg_out_dir/${pkg.package_name}-0.far" 64 _final_far_file = "$_pkg_out_dir/${pkg.archive_filename}.far" 65 _package_info_path = "$_pkg_out_dir/package" 66 67 if (defined(pkg.component_name_override)) { 68 _generated_cmx = "$_pkg_out_dir/${pkg.component_name_override}.cmx" 69 } else { 70 _generated_cmx = "$_pkg_out_dir/${pkg.package_name}.cmx" 71 } 72 73 _write_manifest_target = "${pkg.package_name}__write_manifest" 74 _package_target = "${pkg.package_name}__pkg" 75 _bundle_target = "${pkg.package_name}__bundle" 76 77 # Generates a manifest file based on the GN runtime deps 78 # suitable for "pm" tool consumption. 79 action(_write_manifest_target) { 80 _depfile = "${target_gen_dir}/${target_name}_stamp.d" 81 82 forward_variables_from(invoker, 83 [ 84 "data", 85 "deps", 86 "testonly", 87 ]) 88 89 script = "//build/config/fuchsia/prepare_package_inputs.py" 90 91 inputs = [ 92 _runtime_deps_file, 93 pkg.manifest, 94 ] 95 96 outputs = [ 97 _archive_manifest, 98 _build_ids_file, 99 _generated_cmx, 100 ] 101 102 if (!defined(deps)) { 103 deps = [] 104 } 105 deps += [ pkg.binary ] 106 data_deps = deps 107 108 # Use a depfile to trigger package rebuilds if any of the files (static 109 # assets, shared libraries, etc.) included by the package have changed. 110 depfile = _depfile 111 112 args = [ 113 "--root-dir", 114 rebase_path("//", root_build_dir), 115 "--out-dir", 116 rebase_path(root_out_dir, root_build_dir), 117 "--app-name", 118 pkg.package_name, 119 "--app-filename", 120 get_label_info(pkg.binary, "name"), 121 "--manifest-input-path", 122 rebase_path(pkg.manifest, root_build_dir), 123 "--runtime-deps-file", 124 rebase_path(_runtime_deps_file, root_build_dir), 125 "--depfile-path", 126 rebase_path(_depfile, root_build_dir), 127 "--package-manifest-path", 128 rebase_path(_archive_manifest, root_build_dir), 129 "--component-manifest-path", 130 rebase_path(_generated_cmx, root_build_dir), 131 "--build-ids-file", 132 rebase_path(_build_ids_file, root_build_dir), 133 ] 134 135 if (defined(pkg.excluded_files)) { 136 foreach(filename, pkg.excluded_files) { 137 args += [ 138 "--exclude-file", 139 filename, 140 ] 141 } 142 } 143 144 if (defined(pkg.additional_manifests)) { 145 foreach(filename, pkg.additional_manifests) { 146 args += [ 147 "--additional-manifest", 148 rebase_path(filename), 149 ] 150 } 151 } 152 153 write_runtime_deps = _runtime_deps_file 154 } 155 156 # Creates a signed Fuchsia metadata package. 157 action(_package_target) { 158 forward_variables_from(invoker, [ "testonly" ]) 159 160 script = "//build/gn_run_binary.py" 161 162 deps = [ ":$_write_manifest_target" ] 163 164 inputs = [ 165 # Depend on the SDK hash, to ensure rebuild if the SDK tools change. 166 "//third_party/fuchsia-sdk/sdk/.hash", 167 ] 168 169 if (defined(pkg.additional_manifests)) { 170 inputs += pkg.additional_manifests 171 } 172 173 outputs = [ _meta_far_file ] 174 175 args = [ 176 rebase_path(_pm_tool_path, root_build_dir), 177 "-o", 178 rebase_path(_pkg_out_dir, root_build_dir), 179 "-m", 180 rebase_path(_archive_manifest, root_build_dir), 181 "build", 182 ] 183 } 184 185 # Creates a package containing the metadata archive and blob data. 186 action(_bundle_target) { 187 forward_variables_from(invoker, [ "testonly" ]) 188 189 script = "//build/gn_run_binary.py" 190 191 deps = [ 192 ":$_package_target", 193 ":$_write_manifest_target", 194 ] 195 196 inputs = [ 197 # Depend on the SDK hash, to ensure rebuild if the SDK tools change. 198 "//third_party/fuchsia-sdk/sdk/.hash", 199 _meta_far_file, 200 _archive_manifest, 201 ] 202 203 outputs = [ _combined_far_file ] 204 205 args = [ 206 rebase_path(_pm_tool_path, root_build_dir), 207 "-o", 208 rebase_path(_pkg_out_dir, root_build_dir), 209 "-m", 210 rebase_path(_archive_manifest, root_build_dir), 211 "archive", 212 ] 213 } 214 215 # Copies the archive to a well-known path. 216 # TODO(kmarshall): Use a 'pm' output flag to write directly to the desired 217 # file path instead. 218 copy(target_name) { 219 forward_variables_from(invoker, [ "testonly" ]) 220 221 # Allows dependent targets to make use of "ids.txt". 222 public_deps = [ ":$_write_manifest_target" ] 223 224 deps = [ ":$_bundle_target" ] 225 226 data = [ 227 _final_far_file, 228 229 # Files specified here so that they can be read by isolated testbots. 230 _package_info_path, 231 _build_ids_file, 232 ] 233 234 sources = [ _combined_far_file ] 235 outputs = [ _final_far_file ] 236 } 237} 238