blob: 684bb6b38af5dabeaef49c53969da3111447e0e9 [file] [log] [blame]
# Copyright 2020 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("//build/images/manifest.gni")
import("//src/sys/pkg/bin/pm/pm.gni")
# Defines a Fuchsia package.
# See: https://fuchsia.dev/fuchsia-src/development/components/build
#
# Fuchsia packages are a collection of any number of files (or resources), each
# with a unique path that is relative to the package's root.
# Package targets collect resources via their dependencies. These dependencies
# are typically components, which provide their component manifest as a
# resource as well as forward their own dependencies on resources. Packages
# can also depend directly on resources.
#
# Packages can be defined as a collection of pairs each representing a file in
# the package. Each pair consists of the path in the package that is assigned
# to the file, and a path relative to the build system's output directory where
# the contents of the file will be sourced from.
#
# This mapping is generated at build time, and is known as the package
# manifest. To view the package manifest, For instance assume you have defined
# a package at `path/to/project:my_package` and built it:
# ```
# $ fx build path/to/project:my_package
# ```
# You can then find the path to the generated manifest:
# ```
# $ fx gn outputs out/default path/to/project:my_package_manifest
# ```
#
# The package name is defined by the target name.
# Some rules apply to package names.
# See: https://fuchsia.dev/fuchsia-src/concepts/packages/package_url#package-name
#
# It's recommended for a package to depend on one or more `fuchsia_component()`
# targets. Typically no other dependencies are required.
#
# Example:
# ```
# fuchsia_package("my-package") {
# components = [
# ":first_component",
# ":second_component",
# ]
# }
# ```
#
# Parameters
#
# package_name (optional)
# The name of the package.
# Type: string
# Default: target_name
#
# components (optional)
# `fuchsia_component()` targets to include in the package.
# While it's possible for a package to just contain data files, or nothing
# at all, typically a package contains at least one component.
# Type: list(labels)
#
# data_deps
# deps
# public_deps
# testonly
# visibility
template("fuchsia_package") {
package_name = target_name
if (defined(invoker.package_name)) {
package_name = invoker.package_name
}
if (!defined(invoker.deps)) {
invoker.deps = []
}
if (defined(invoker.components)) {
invoker.deps += invoker.components
} else {
invoker.components = []
}
# Generate the "meta/package" file
meta_package_target = "${target_name}_meta_package"
meta_package_file = "$target_out_dir/$meta_package_target.json"
generated_file(meta_package_target) {
contents = "{\"name\":\"$package_name\",\"version\":\"0\"}"
outputs = [ meta_package_file ]
output_conversion = "string"
visibility = [ ":*" ]
}
metadata_target = "${target_name}_package_metadata"
group(metadata_target) {
forward_variables_from(invoker,
[
"data_deps",
"deps",
"public_deps",
"testonly",
])
visibility = [ ":*" ]
metadata = {
package_manifest_args = [
"--entry=meta/package=" + rebase_path(meta_package_file, root_out_dir),
"--entry-manifest=" +
get_label_info(":${invoker.target_name}", "label_no_toolchain"),
]
}
}
# Generate package manifest args
args_target = "${target_name}_manifest_args"
args_file = "$target_out_dir/$args_target"
generated_file(args_target) {
forward_variables_from(invoker,
[
"data_deps",
"deps",
"public_deps",
"testonly",
])
visibility = [ ":*" ]
deps += [ ":$metadata_target" ]
outputs = [ args_file ]
data_keys = [ "package_manifest_args" ]
output_conversion = "list lines"
}
# Generate package manifest
generate_manifest("${target_name}_manifest") {
forward_variables_from(invoker,
[
"data_deps",
"deps",
"public_deps",
"testonly",
])
visibility = [ ":*" ]
if (!defined(deps)) {
deps = []
}
deps += [ ":$meta_package_target" ] + invoker.components
sources = [ meta_package_file ]
args = [ "@" + rebase_path(args_file, root_build_dir) ]
}
# Build package
pm_build(target_name) {
forward_variables_from(invoker,
[
"data_deps",
"deps",
"public_deps",
"testonly",
"visibility",
])
manifest = ":${target_name}_manifest"
}
}