# Copyright 2019 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("gn_configs.gni")
import("gn_sdk_configs.gni")
import("package_tool.gni")
# Define a Fuchsia component package target.
#
# Parameters
#
# package_name: [Optional]
# Name of the package. Defaults to target_name.
#
# Type: string
#
# excluded_paths: [Optional]
# List of glob expressions which, when matched, excludes files or
# directories from the package.
#
# Examples:
# */foo Matches files named "foo" in any subdirectory.
# foo Matches a file named "foo" in the root directory.
# *.foo Matches any file ending with ".foo"
#
# Type: list of paths, wildcards supported.
#
# excluded_files: [Optional] [Deprecated]
# List of files to exclude from the package.
#
# Type: list of file paths
#
# excluded_dirs: [Optional] [Deprecated]
# List of directories to exclude from the package.
#
# Type: list of file paths
#
# fidl_ref_out_dir: [Optional]
# Directory for writing out $package_name_all_fidl_refs.txt
# that contains the paths to the internal representation (IR) of every
# FIDL interface referenced in the package. Defaults to $root_build_dir/fidl_refs.
#
# ids_txt_output_path: [Optional]
# Path to write out the ids.txt file for the symbols in the binaries.
# Defaults to `${target_gen_dir}/${package_name}/ids.txt`
#
# Type: file path
#
# subpackages: [Optional]
# A list of `fuchsia_package` or `fuchsia_sdk_package` targets.
# Type: list of targets
#
# deps
# Required: List of fuchsia_component() targets that this
# package contains.
#
template("fuchsia_package") {
if (!defined(invoker.package_name)) {
package_name = target_name
} else {
package_name = invoker.package_name
}
if (!defined(invoker.excluded_paths)) {
excluded_paths = []
} else {
excluded_paths = invoker.excluded_paths
}
if (defined(invoker.excluded_files)) {
foreach(exclusion, invoker.excluded_files) {
excluded_paths += [ "${exclusion}" ]
}
}
if (defined(invoker.excluded_dirs)) {
foreach(exclusion, invoker.excluded_dirs) {
excluded_paths += [ "${exclusion}/*" ]
}
}
if (!defined(invoker.fidl_ref_out_dir)) {
fidl_ref_out_dir = "$root_build_dir/fidl_refs"
} else {
fidl_ref_out_dir = invoker.fidl_ref_out_dir
}
_depfile = "${target_gen_dir}/${target_name}_stamp.d"
# target names
_manifest_target = "${target_name}__archive-manifest"
_metadata_target = "${target_name}__archive-metadata"
_packaged_components_metadata_target =
"${target_name}__packaged_components_metadata"
_symbol_index_target = "${target_name}__symbol_index"
# output values
_pkg_out_dir = "${target_gen_dir}/${package_name}"
_runtime_deps_file = "$_pkg_out_dir/${package_name}.runtime_deps"
_archive_manifest = "$_pkg_out_dir/${package_name}.manifest"
_build_ids_file = "$_pkg_out_dir/ids.txt"
if (defined(invoker.ids_txt_output_path)) {
_build_ids_file = invoker.ids_txt_output_path
}
_package_file = "$_pkg_out_dir/package"
_fidl_json_refs_file = "${fidl_ref_out_dir}/${package_name}_all_fidl_refs.txt"
_symbol_index_file = "$_pkg_out_dir/${package_name}.symbol-index.json"
_packaged_components_metadata_file =
"${target_gen_dir}/${package_name}_packaged_components_metadata.json"
_package_deps = []
if (defined(invoker.deps)) {
_package_deps += invoker.deps
}
if (defined(invoker.data_deps)) {
_package_deps += invoker.data_deps
}
_subpackages = []
if (defined(invoker.subpackages)) {
_subpackages += invoker.subpackages
}
# Generates a JSON file containing the contents of each of the
# components being included in this package.
generated_file(_packaged_components_metadata_target) {
forward_variables_from(invoker, [ "testonly" ])
outputs = [ _packaged_components_metadata_file ]
data_keys = [ "contents" ]
output_conversion = "json"
deps = _package_deps
}
#
# A generated file that lists all of the .fidl.json files
# used in this package. This is useful for tools that need
# to decode fidl.
generated_file("${package_name}_all_fidl_refs") {
testonly = true
deps = _package_deps
outputs = [ _fidl_json_refs_file ]
data_keys = [ "fidl_json" ]
}
# Generates a file listing all subpackages.
if (_subpackages != []) {
_subpackages_manifest_target = "${target_name}__subpackages_manifest"
_subpackages_manifest_file =
"${target_gen_dir}/${package_name}_subpackages_manifest.json"
fuchsia_package_tool_subpackages_manifest(_subpackages_manifest_target) {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":$_metadata_target" ]
subpackages = _subpackages
outputs = [ _subpackages_manifest_file ]
}
}
action(_manifest_target) {
forward_variables_from(invoker, [ "testonly" ])
script = gn_sdk_root + "/prepare_package_inputs.py"
inputs = [
_runtime_deps_file,
_packaged_components_metadata_file,
]
outputs = [
_archive_manifest,
_build_ids_file,
_package_file,
]
data_deps = _package_deps
deps = _package_deps
deps += [ ":${_packaged_components_metadata_target}" ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
# Use a depfile to trigger package rebuilds if any of the files (static
# assets, shared libraries, etc.) included by the package have changed.
depfile = _depfile
args = [
"--root-dir",
rebase_path("//", root_build_dir),
"--out-dir",
rebase_path(root_out_dir, root_build_dir),
"--app-name",
package_name,
"--runtime-deps-file",
rebase_path(_runtime_deps_file, root_build_dir),
"--depfile-path",
rebase_path(_depfile, root_build_dir),
"--manifest-path",
rebase_path(_archive_manifest, root_build_dir),
"--build-ids-file",
rebase_path(_build_ids_file, root_build_dir),
"--json-file",
rebase_path(_packaged_components_metadata_file),
]
if (fuchsia_sdk_readelf_exec != "") {
args += [
"--readelf-exec",
rebase_path(fuchsia_sdk_readelf_exec, root_build_dir),
]
}
foreach(exclusion, excluded_paths) {
args += [
"--exclude-path",
exclusion,
]
}
write_runtime_deps = _runtime_deps_file
# Allows ids.txt paths to be collected by dependent targets.
metadata = {
ids_txt_paths = [ _build_ids_file ]
}
}
# Creates a Fuchsia metadata package.
fuchsia_package_tool(_metadata_target) {
forward_variables_from(invoker, [ "testonly" ])
package_name = package_name
command = "build"
archive_manifest = _archive_manifest
if (_subpackages != []) {
subpackages_manifest = _subpackages_manifest_file
deps = [ ":$_subpackages_manifest_target" ] + _subpackages
}
public_deps = [ ":$_manifest_target" ]
}
# Creates a Fuchsia metadata package archive.
fuchsia_package_tool(target_name) {
forward_variables_from(invoker, [ "testonly" ])
package_name = package_name
command = "archive"
archive_manifest = _archive_manifest
public_deps = [
":$_metadata_target",
":$_symbol_index_target",
]
}
# Create a .symbol-index.json that indexes the ids.txt above. This file will be registered
# automatically during the publishing of the package.
generated_file(_symbol_index_target) {
outputs = [ _symbol_index_file ]
output_conversion = "json"
contents = {
ids_txts = [
{
path = rebase_path(_build_ids_file, _pkg_out_dir)
build_dir = rebase_path(root_build_dir, _pkg_out_dir)
},
]
}
}
}