# 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("gn_configs.gni")
import("gn_sdk_configs.gni")
declare_args() {
# TODO(fxbug.dev/93346): After soft-migration: required offers = [ "fuchsia.logger.LogSink" ]
fuchsia_cmc_compile_must_offer_protocol = []
fuchsia_cmc_compile_must_use_protocol = []
}
# Internal template for the cmc tool.
#
# Invokes cmc
#
# Example:
#
# ```
# _cmc_tool("validate") {
# inputs = [ manifest ]
# outputs = [ stamp_file ]
#
# args = [
# "--stamp",
# rebase_path(stamp_file, root_build_dir),
# "validate",
# rebase_path(invoker.manifest),
# ]
# }
# ```
#
# Parameters:
#
# inputs (required)
# List of files that are input for cmc.
# Type: list(path)
#
# outputs (required)
# List paths that are output for the run of cmc.
# Type: list(path)
#
# args (required)
# List command line args for cmc.
# Type: list(path)
#
# depfile
# deps
# public_deps
# testonly
# visibility
#
template("_cmc_tool") {
action(target_name) {
forward_variables_from(invoker,
[
"depfile",
"deps",
"public_deps",
"testonly",
"visibility",
])
script = gn_sdk_root + "/gn_run_binary.py"
_cmc_tool_path = "${fuchsia_tool_dir}/cmc"
assert(defined(invoker.inputs), "inputs is a required parameter.")
assert(defined(invoker.outputs), "outputs is a required parameter.")
assert(defined(invoker.args), "args is a required parameter.")
inputs =
[
_cmc_tool_path,
# Depend on the SDK hash, to ensure rebuild if the SDK tools change.
fuchsia_sdk_manifest_file,
] + invoker.inputs
outputs = invoker.outputs
args = [ rebase_path(_cmc_tool_path, root_build_dir) ] + invoker.args
}
}
# Compiles a Components Framework manifest (.cml) file to .cm
#
# Example:
#
# ```
# cmc_compile(_compiled_manifest_target) {
# forward_variables_from(invoker, [ "deps" ])
# manifest = rebase_path(manifest)
# }
# ```
#
# Parameters:
#
# manifest (required)
# The input Component Framework manifest source (.cml) file.
# The file must have the extension ".cml".
#
# output_file (optional)
# Full path of the output file to generate. If not provided, it will be
# derived from target_name and output_name.
#
# output_name (optional)
# Name of the output file to generate. Defaults to $target_name.
# This should not include a file extension (.cm)
#
# required_offers (optional)
# [list of strings] The set of protocols that should be offered to every child.
#
# required_uses (optional)
# [list of strings] The set of protocols that each child must use.
#
# deps
# public_deps
# testonly
# visibility
#
template("cmc_compile") {
assert(defined(invoker.manifest), "manifest file required")
if (defined(invoker.output_file)) {
output_file = invoker.output_file
} else {
output_name = get_path_info(invoker.manifest, "name")
if (defined(invoker.output_name)) {
output_name = invoker.output_name
}
# Output in a subdir with `target_name` to avoid collisions when a
# manifest file is re-used for multiple component targets.
output_file = "$target_gen_dir/$target_name/$output_name.cm"
}
_cmc_tool(target_name) {
forward_variables_from(invoker,
[
"deps",
"manifest",
"public_deps",
"testonly",
"visibility",
"required_offers",
"required_uses",
])
inputs = [ manifest ]
outputs = [ output_file ]
depfile = "$target_gen_dir/$target_name/$target_name.d"
args = [
"compile",
rebase_path(manifest, root_build_dir),
"--output",
rebase_path(output_file, root_build_dir),
"--includeroot",
rebase_path("//", root_build_dir),
"--includepath",
rebase_path("$fuchsia_sdk/pkg/", root_build_dir),
"--includepath",
get_path_info(invoker.manifest, "dir"),
"--depfile",
rebase_path(depfile, root_build_dir),
]
if (defined(invoker.config_values_package_path)) {
args += [
"--config-package-path",
invoker.config_values_package_path,
]
}
if (!defined(invoker.required_offers)) {
required_offers = fuchsia_cmc_compile_must_offer_protocol
}
foreach(offer, required_offers) {
args += [
"--must-offer-protocol",
offer,
]
}
if (!defined(invoker.required_uses)) {
required_uses = fuchsia_cmc_compile_must_use_protocol
}
foreach(use_decl, required_uses) {
args += [
"--must-use-protocol",
use_decl,
]
}
}
}
# Merges multiple component manifest files into one.
#
# Combines mutliple component manifests into a single manifest.
# This is useful for merging fragments of sandbox configurations into
# a single component manifest.
#
# Example
#
# ```
# cmc_merge("combined_cml") {
# sources = ["sandbox.cml", "services.cml", "program.cml"]
# output_name = "my-component.cml"
# }
# ```
#
# Parameters
#
# sources
# The list of cml files to merge together.
#
# Type: list of strings (filepath)
#
# output_name [optional]
# The name of the merged cml file. This file is created in $target_out_dir.
# If not specified, $target_name.cml is used.
#
# Type: string
#
# Standard parameters:
# deps
# testonly
# visibility
#
template("cmc_merge") {
_cmc_tool(target_name) {
forward_variables_from(invoker,
[
"deps",
"output_name",
"sources",
"testonly",
"visibility",
])
if (!defined(output_name)) {
output_name = "${target_name}.cml"
}
merged_output = "${target_out_dir}/${output_name}"
inputs = invoker.sources
outputs = [ merged_output ]
args = [
"merge",
"--output",
rebase_path(merged_output, root_build_dir),
]
foreach(source, sources) {
args += [ rebase_path(source, root_build_dir) ]
}
}
}