blob: 5843f2e1289a8b1b5c5261427085d54294dd050f [file] [log] [blame]
# 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("$zx/public/gn/config/standard.gni")
# Redirect dependents to dependencies in another environment (toolchain).
#
# An environment_redirect() acts like a group() with `public_deps` set (which
# we call a "redirect" target): Depending on this target means to depend on
# its dependencies. The special feature of environment_redirect() is that it
# selects an appropriate toolchain for those dependencies based on the other
# parameters described below.
#
# Parameters
#
# cpu
# Optional: Required if $current_cpu is "" (default toolchain).
# Defaults to $host_cpu in "host" or "host.*" environments.
#
# os
# Optional: Required if $current_os is "" (default toolchain).
# Defaults to $host_os in "host" or "host.*" environments.
#
# environment_label
# Optional: Required if ${toolchain.environment_label} is undefined
# (default toolchain). This is the label of an execution environment
# defined with environment(). The $deps will be resolved in one of the
# toolchains defined by that environment() invocation.
# Default: ${toolchain.environment_label}
#
# deps
# Required: These must be labels without toolchain suffix. The
# environment_redirect() target redirects its dependents to instead depend
# on this list of labels, but in the toolchain selected by the other
# parameters.
#
# variant
# Optional: Specific variant toolchain to select. If omitted, one will be
# chosen from $default_variants with the expectation that the
# environment() named by $environment_label used a `.variants` list
# including $default_variants (as is preset).
#
template("environment_redirect") {
forward_variables_from(invoker,
[
"cpu",
"environment_label",
"os",
"variant",
])
if (!defined(environment_label)) {
assert(defined(toolchain.environment_label),
"environment_redirect() needs `environment_label`" +
" in $current_toolchain")
environment_label = toolchain.environment_label
}
environment_label = get_label_info(environment_label, "label_no_toolchain")
environment = get_label_info(environment_label, "name")
# For, e.g., "host.fuzz", the base is "host".
base_environment = get_path_info(environment, "name")
if (defined(cpu)) {
assert(cpu != "", "empty `cpu` in environment_redirect()")
} else {
if (base_environment == "host") {
assert(host_cpu != "", "empty `host_cpu` in environment_redirect()")
cpu = host_cpu
} else {
assert(current_cpu != "", "empty `current_cpu` in environment_redirect()")
cpu = current_cpu
}
}
if (defined(os)) {
assert(os != "", "empty `os` in environment_redirect()")
} else {
if (base_environment == "host") {
assert(host_os != "", "empty `host_os` in environment_redirect()")
os = host_os
} else {
os = "fuchsia"
}
}
# Name construction logic must match environment.gni.
toolchain_base_name = "${environment_label}-${cpu}"
# For host environments include the OS to distinguish one from another.
# For other environments, the OS is implicit (i.e. "fuchsia" modulo EFI).
if (base_environment == "host") {
toolchain_base_name += "-${os}"
} else {
not_needed([ "os" ])
}
# If the caller didn't request a specific variant, then use the default most
# likely to be selected for an arbitrary target in the selected environment.
# That will dispatch to the correct variant for each particular target.
foreach(default, default_variants) {
if (!defined(variant) &&
(!defined(default.environment) || default.environment == [] ||
default.environment + [ environment ] - [ environment ] !=
default.environment ||
default.environment + [ base_environment ] - [ base_environment ] !=
default.environment)) {
variant = default.variant
}
}
toolchain_name = "${toolchain_base_name}-${variant}"
group(target_name) {
forward_variables_from(invoker,
[
"assert_no_deps",
"testonly",
"visibility",
])
public_deps = []
foreach(label, invoker.deps) {
foreach(label, invoker.deps) {
# The original string should not contain a "(toolchain)" suffix.
# We can't easily tell if it does, but we can tell if it has any
# suffix other than the expansion of "($current_toolchain)".
full_label = get_label_info(label, "label_with_toolchain")
bare_label = get_label_info(label, "label_no_toolchain")
assert(full_label == "$bare_label($current_toolchain)",
"environment_redirect() `deps` cannot have toolchain suffix")
public_deps += [ "$label($toolchain_name)" ]
}
}
}
}