blob: 76db24b0ad243e01b25a9a4d5ff398d8fd09de27 [file] [log] [blame]
# Copyright 2016 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/dart/toolchain.gni")
# Defines a Dart package
#
# Parameters
#
# package_name (optional)
# Name of the dart package. This is used as an identifier in code that
# depends on this package. In general, this should correspond to the path to
# the package. I.e. a dart package in //foo/bar/baz should have the package
# name "foo.bar.baz"
#
# package_label (optional)
# Label to infer package name from.
#
# infer_package_name (optional)
# Infer the package name based on the path to the package.
#
# NOTE: Exactly one of package_name, package_label, or infer_package_name
# must be set.
#
# source_dir (optional)
# Directory containing the package sources. Defaults to "lib".
#
# deps (optional)
# List of labels for Dart packages this package depends on.
#
# non_dart_deps (optional)
# List of labels this package depends on that are not Dart packages. This
# includes things like actions that generate Dart code. It typically doesn't
# need to be set.
# Note that these labels *must* have an explicit toolchain attached.
#
# disable_analysis (optional)
# Prevents analysis from being run on this target.
#
# extra_analyzer_sources (optional)
# Additional source paths to pass to the analyzer.
#
# generated_code (optional)
# Boolean indicating that this package contains generated code. This option
# relaxes some constraints around package structure.
# Defaults to false.
# TODO(pylaligand): get rid of this option post-FIDL 2.0.
#
# Example of usage:
#
# dart_package("baz") {
# package_name = "foo.bar.baz"
# deps = [
# "//foo/bar/owl"
# ]
# }
if (current_toolchain == dart_toolchain) {
template("dart_package") {
if (defined(invoker.package_name)) {
package_name = invoker.package_name
} else if (defined(invoker.package_label)) {
target_label = invoker.package_label
} else if (defined(invoker.infer_package_name) && invoker.infer_package_name) {
target_label = get_label_info(":$target_name", "label_no_toolchain")
} else {
assert(false, "Must specify either a package_name or infer_package_name")
}
dart_deps = []
if (defined(invoker.deps)) {
foreach(dep, invoker.deps) {
dart_deps += [ get_label_info(dep, "label_no_toolchain") ]
}
}
dot_packages_file = "$target_gen_dir/$target_name.packages"
source_dir = "lib"
if (defined(invoker.source_dir)) {
source_dir = invoker.source_dir
}
with_analysis =
!defined(invoker.disable_analysis) || !invoker.disable_analysis
if (with_analysis) {
dot_packages_target_name = "${target_name}_dot_packages"
options_file = "analysis_options.yaml"
} else {
dot_packages_target_name = target_name
}
action(dot_packages_target_name) {
script = "//build/dart/gen_dot_packages.py"
deps = dart_deps
if (defined(invoker.non_dart_deps)) {
deps += invoker.non_dart_deps
}
inputs = [
# This file contributes to the script and needs to be listed as an input.
"//build/dart/label_to_package_name.py",
]
if (!defined(invoker.generated_code) || !invoker.generated_code) {
# Require a manifest file, allowing the analysis service to identify the
# package.
inputs += [ "pubspec.yaml" ]
}
if (with_analysis) {
# Require an options file. This allows the analysis service to pick the
# correct set of options for this target.
inputs += [ options_file ]
}
outputs = [
dot_packages_file,
]
depfile = "$dot_packages_file.d"
args = [
"--out",
rebase_path(dot_packages_file, root_build_dir),
"--source-dir",
rebase_path(source_dir),
"--root-build-dir",
rebase_path(root_build_dir),
"--root-gen-dir",
rebase_path(root_gen_dir),
"--depfile",
rebase_path(depfile),
]
if (defined(package_name)) {
args += [
"--package-name",
package_name,
]
} else {
args += [
"--package-label",
target_label,
]
}
args += [ "--deps" ] + dart_deps
}
if (with_analysis) {
invocation_file = "$target_gen_dir/$target_name.analyzer.sh"
invocation_target_name = "${target_name}_invocation"
dart_sdk_label = "//third_party/dart:create_host_sdk"
dart_sdk_dir = "$dart_sdk_root_out_dir/dart-sdk"
dart_analyzer_binary = "$dart_sdk_dir/bin/dartanalyzer"
action(invocation_target_name) {
script = "//build/dart/gen_analyzer_invocation.py"
deps = dart_deps + [
":$dot_packages_target_name",
dart_sdk_label,
]
inputs = [
options_file,
]
outputs = [
invocation_file,
]
args = [
"--out",
rebase_path(invocation_file),
"--source-dir",
rebase_path(source_dir),
"--dot-packages",
rebase_path(dot_packages_file),
"--dartanalyzer",
rebase_path(dart_analyzer_binary),
"--dart-sdk",
rebase_path(dart_sdk_dir),
"--options",
rebase_path(options_file),
]
if (defined(package_name)) {
args += [
"--package-name",
package_name,
]
} else {
args += [
"--package-label",
target_label,
]
}
if (defined(invoker.extra_analyzer_sources)) {
args += invoker.extra_analyzer_sources
}
}
action(target_name) {
script = "//build/dart/run_analysis.py"
depfile = "$target_gen_dir/$target_name.analysis.d"
output_file = "$target_gen_dir/$target_name.analyzed"
inputs = [
options_file,
]
outputs = [
output_file,
]
args = [
"--source-dir",
rebase_path(source_dir),
"--dot-packages",
rebase_path(dot_packages_file),
"--dartanalyzer",
rebase_path(dart_analyzer_binary),
"--dart-sdk",
rebase_path(dart_sdk_dir),
"--options",
rebase_path(options_file),
"--stamp",
rebase_path(output_file),
"--depname",
rebase_path(output_file, root_build_dir),
"--depfile",
rebase_path(depfile),
]
deps = [
":$invocation_target_name",
dart_sdk_label,
]
}
}
}
} else { # Not the Dart toolchain.
template("dart_package") {
group(target_name) {
not_needed(invoker, "*")
public_deps = [
":$target_name($dart_toolchain)"
]
}
}
}