blob: 585169d2abf73e8a8d7a56c3fe86a7dc1679a398 [file] [log] [blame]
# Copyright 2017 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.
# Defines an SDK element.
#
# Parameters
#
# domain
# Name of the domain this element too.
# Domains regroup elements of similar nature. Language-based domains are
# most common.
#
# name (optional)
# Name of the element.
# Must be unique within the given domain.
#
# name_file (optional)
# Path to a file containing the name of the element.
# This should be used when the element's name requires some computation in
# its own build target.
#
# NOTE: Exactly one of `name` or `name_file` must be set.
#
# category
# Describes the availability of the atom.
# Possible values, from most restrictive to least restrictive:
# - excluded : the atom may not be included in SDKs;
# - experimental : the atom is available with no quality guarantee;
# - internal : the atom is exposed within the Fuchsia tree;
# - partner : the atom may be used by select partners;
# - public : the atom may be included in published SDKs.
#
# files (optional)
# List of scopes describing the contents of this element.
# See the "File scopes" section for how to describe files.
# At least one of "files" and "file_mappings" must be set.
#
# file_manifest (optional)
# File containing a description of the files contributing to this element.
# Lines in this file should be formatted as "prefix:destination=source". See
# the next section for expected values of "source" and "destination"; note
# that sources in a manifest file must be passed as absolute paths. "prefix"
# is either "packaged" for files which need to be added to Fuchsia packages,
# or "internal" for files that are not.
# This parameter is useful to specify files that are only known at build
# time.
# At least one of "files" and "file_mappings" must be set.
#
# source_dir (optional)
# If set, path to the base directory of the sources.
# This is useful if the sources are generated and therefore not hosted
# directly under the directory where the GN rules are declared.
#
# deps (optional)
# List of GN labels for other SDK elements this element depends on at build
# time.
# These labels must point to "sdk_atom" targets.
#
# package_deps (optional)
# List of GN labels for other SDK elements this element depends on at
# runtime.
# These labels must point to "sdk_atom" targets.
#
# non_sdk_deps (optional)
# List of GN labels which this target needs built.
#
# tags (optional)
# List of strings characterizing this element.
# Examples: "service:networking", "language:rust", "layer:garnet"
#
# manifest_file (optional)
# Path to the manifest to generate.
#
# File scopes
#
# Each scope describe a file to be added to the SDK element. The supported
# attributes are:
#
# source (required)
# Path to the original file.
# This path may be absolute or relative to the target's directory.
#
# dest (optional)
# Destination path of the file relative to the element's base directory in
# the SDK.
# This attribute is required unless "source" points to a file located under
# the target's source directory, in which case the relative path of that
# file to the target's directory will be used as the default value.
#
# packaged (optional)
# Whether this file should be added to Fuchsia packages.
template("sdk_atom") {
assert(defined(invoker.domain), "Must define a domain name")
domain_name = invoker.domain
assert(defined(invoker.category), "Must define an SDK category")
category = invoker.category
if (defined(invoker.name)) {
name_args = [
"--name",
invoker.name,
]
} else if (defined(invoker.name_file)) {
name_args = [
"--name-file",
rebase_path(invoker.name_file),
]
} else {
assert(false, "Must specify either name or name_file")
}
gn_deps = []
if (defined(invoker.non_sdk_deps)) {
gn_deps = invoker.non_sdk_deps
}
dep_manifests = []
if (defined(invoker.deps)) {
gn_deps += invoker.deps
foreach(dep, invoker.deps) {
gen_dir = get_label_info(dep, "target_gen_dir")
name = get_label_info(dep, "name")
dep_manifests += [ rebase_path("$gen_dir/$name.sdk") ]
}
}
package_dep_manifests = []
if (defined(invoker.package_deps)) {
gn_deps += invoker.package_deps
foreach(dep, invoker.package_deps) {
gen_dir = get_label_info(dep, "target_gen_dir")
name = get_label_info(dep, "name")
dep_manifests += [ rebase_path("$gen_dir/$name.sdk") ]
}
}
assert(defined(invoker.files) || defined(invoker.file_manifest),
"At least one of 'files' and 'file_manifest' must be defined")
file_mappings = []
file_inputs = []
if (defined(invoker.files)) {
foreach(file, invoker.files) {
assert(defined(file.source), "File $file does not specify a source.")
file_inputs += [ file.source ]
source = rebase_path(file.source)
destination = ""
if (defined(file.dest)) {
destination = file.dest
}
prefix = "internal"
if (defined(file.packaged)) {
prefix = "packaged"
}
file_mappings += [ "$prefix:$destination=$source" ]
}
}
source_dir = "."
if (defined(invoker.source_dir)) {
source_dir = invoker.source_dir
}
tags = []
if (defined(invoker.tags)) {
tags = invoker.tags
}
full_label = get_label_info(":$target_name", "label_with_toolchain")
# Builds a manifest representing this element.
action(target_name) {
forward_variables_from(invoker, [ "testonly" ])
if (defined(invoker.manifest_file)) {
manifest = invoker.manifest_file
} else {
manifest = "$target_gen_dir/$target_name.sdk"
}
script = "//build/sdk/create_atom_manifest.py"
deps = gn_deps
inputs = dep_manifests + file_inputs + [
# Imported by the action's script.
"//build/sdk/sdk_common.py",
]
outputs = [
manifest,
]
args = name_args + [
"--domain",
domain_name,
"--out",
rebase_path(manifest),
"--base",
rebase_path(source_dir),
"--gn-label",
full_label,
"--category",
category,
"--deps",
] + dep_manifests + [ "--package-deps" ] + package_dep_manifests +
[ "--files" ] + file_mappings + [ "--tags" ] + tags
if (defined(invoker.file_manifest)) {
inputs += [ invoker.file_manifest ]
args += [
"--file-manifest",
rebase_path(invoker.file_manifest),
]
}
}
}