blob: d0d3ffcd08ea7b6556ab1601ccd1366bb07d5dec [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/dart.gni")
import("//build/dart/toolchain.gni")
import("//build/sdk/sdk_atom.gni")
import("//third_party/flutter/lib/ui/dart_ui.gni")
import("//topaz/public/dart-pkg/fuchsia/sdk_ext.gni")
import("//topaz/public/dart-pkg/zircon/sdk_ext.gni")
import("//topaz/public/lib/ui/flutter/sdk_ext/sdk_ext.gni")
declare_args() {
# Whether to use the analysis server instead of the CLI.
use_analysis_server = false
}
# Defines a Dart library
#
# Parameters
#
# sources
# The list of public sources in this library, i.e. Dart files in lib/ but
# not in lib/src/. These sources must be within source_dir.
#
# package_root (optional)
# Path to the directory hosting the library.
# This is useful for generated content, and can be ignored otherwise.
# Defaults to ".".
#
# package_name (optional)
# Name of the Dart package. This is used as an identifier in code that
# depends on this library.
#
# 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)
# Path to the directory containing the package sources, relative to
# package_root.
# Defaults to "lib".
#
# deps (optional)
# List of labels for Dart libraries this library depends on.
#
# non_dart_deps (optional)
# List of labels this library depends on that are not Dart libraries. 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.
#
# sdk_category (optional)
# Publication level of the library in SDKs.
# See //build/sdk/sdk_atom.gni.
#
# Example of usage:
#
# dart_library("baz") {
# package_name = "foo.bar.baz"
#
# sources = [
# "blah.dart",
# ]
#
# deps = [
# "//foo/bar/owl",
# ]
# }
if (current_toolchain == dart_toolchain) {
template("dart_library") {
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"
package_root = "."
if (defined(invoker.package_root)) {
package_root = invoker.package_root
}
source_dir = "$package_root/lib"
if (defined(invoker.source_dir)) {
source_dir = "$package_root/${invoker.source_dir}"
}
# Dependencies of the umbrella group for the targets in this file.
group_deps = []
dot_packages_target_name = "${target_name}_dot_packages"
group_deps += [ ":$dot_packages_target_name" ]
action(dot_packages_target_name) {
script = "//build/dart/gen_dot_packages.py"
deps = []
package_files = []
foreach(dep, dart_deps) {
deps += [ "${dep}_dot_packages" ]
dep_gen_dir = get_label_info(dep, "target_gen_dir")
dep_name = get_label_info(dep, "name")
package_files += [ "$dep_gen_dir/$dep_name.packages" ]
}
if (defined(invoker.non_dart_deps)) {
public_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",
]
sources = package_files + [
# Require a manifest file, allowing the analysis service to identify the
# package.
"$package_root/pubspec.yaml",
]
outputs = [
dot_packages_file,
]
args = [
"--out",
rebase_path(dot_packages_file),
"--source-dir",
rebase_path(source_dir),
"--deps",
] + rebase_path(package_files)
if (defined(package_name)) {
args += [
"--package-name",
package_name,
]
} else {
args += [
"--package-label",
target_label,
]
}
}
source_target_name = "${target_name}_identify_sources"
group_deps += [ ":$source_target_name" ]
source_file = "$target_gen_dir/$target_name.sources"
assert(defined(invoker.sources), "Public sources must be defined")
action(source_target_name) {
script = "//build/dart/identify_sources.py"
inputs = [
gen_snapshot,
]
outputs = [
source_file,
]
depfile = "$target_gen_dir/$target_name.d"
args = [
"--gen-snapshot",
rebase_path(gen_snapshot),
"--sources",
] + rebase_path(invoker.sources, "", source_dir) +
[
"--packages",
rebase_path(dot_packages_file),
"--source-dir",
rebase_path(source_dir),
"--output",
rebase_path(source_file),
"--depfile",
rebase_path(depfile),
"--depname",
rebase_path(source_file, root_build_dir),
"--url-mapping",
"dart:zircon," + rebase_path(zircon_sdk_ext_lib),
"dart:fuchsia," + rebase_path(fuchsia_sdk_ext_lib),
"dart:mozart.internal," + rebase_path(mozart_dart_sdk_ext_lib),
"dart:ui," + rebase_path(dart_ui_path),
]
deps = gen_snapshot_deps + [
":$dot_packages_target_name",
]
}
with_analysis =
!defined(invoker.disable_analysis) || !invoker.disable_analysis
if (with_analysis) {
options_file = "$package_root/analysis_options.yaml"
invocation_file = "$target_gen_dir/$target_name.analyzer.sh"
invocation_target_name = "${target_name}_analysis_runner"
group_deps += [ ":$invocation_target_name" ]
dart_analyzer_binary = "$dart_sdk/bin/dartanalyzer"
action(invocation_target_name) {
script = "//build/dart/gen_analyzer_invocation.py"
deps = dart_sdk_deps + [
":$dot_packages_target_name",
":$source_target_name",
]
inputs = [
dart_analyzer_binary,
dot_packages_file,
options_file,
source_file,
]
outputs = [
invocation_file,
]
args = [
"--out",
rebase_path(invocation_file),
"--source-file",
rebase_path(source_file),
"--dot-packages",
rebase_path(dot_packages_file),
"--dartanalyzer",
rebase_path(dart_analyzer_binary),
"--dart-sdk",
rebase_path(dart_sdk),
"--options",
rebase_path(options_file),
]
if (defined(package_name)) {
args += [
"--package-name",
package_name,
]
} else {
args += [
"--package-label",
target_label,
]
}
}
analysis_target_name = "${target_name}_analysis"
group_deps += [ ":$analysis_target_name" ]
if (use_analysis_server) {
action(analysis_target_name) {
runner_label = "//build/dart/analyzer($host_toolchain)"
runner_out_dir = get_label_info(runner_label, "root_out_dir")
script = "$runner_out_dir/dart-tools/analyzer"
server_snapshot = "$dart_sdk/bin/snapshots/analysis_server.dart.snapshot"
depfile = "$target_gen_dir/$target_name.analysis.d"
output_file = "$target_gen_dir/$target_name.analyzed"
log_file = "$target_gen_dir/$target_name.analysis_logs"
inputs = [
options_file,
]
# TODO(pylaligand): restore this pool.
# pool = "//build/dart:analysis_pool($dart_toolchain)"
outputs = [
output_file,
]
# TODO(pylaligand): have the analysis server analyze individual files.
# It currently only understands directories.
args = [
"--package-root",
rebase_path("."),
"--source-dir",
rebase_path(source_dir, "."),
"--server-snapshot",
rebase_path(server_snapshot),
"--sdk-dir",
rebase_path(dart_sdk_dir),
"--stamp",
rebase_path(output_file),
"--depname",
rebase_path(output_file, root_build_dir),
"--depfile",
rebase_path(depfile),
"--cache-path",
rebase_path("$root_out_dir/analysis-cache"),
"--log-file",
rebase_path(log_file),
]
deps = dart_sdk_deps + [
":$dot_packages_target_name",
dart_sdk_label,
runner_label,
]
}
} else { # Use the analyzer CLI.
action(analysis_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 = [
dart_analyzer_binary,
dot_packages_file,
options_file,
source_file,
]
outputs = [
output_file,
]
args = [
"--source-file",
rebase_path(source_file),
"--dot-packages",
rebase_path(dot_packages_file),
"--dartanalyzer",
rebase_path(dart_analyzer_binary),
"--dart-sdk",
rebase_path(dart_sdk),
"--options",
rebase_path(options_file),
"--stamp",
rebase_path(output_file),
"--depname",
rebase_path(output_file, root_build_dir),
"--depfile",
rebase_path(depfile),
]
deps = dart_sdk_deps + [
":$dot_packages_target_name",
":$source_target_name",
]
}
}
}
group(target_name) {
# dart_deps are added here to ensure they are fully built.
# Up to this point, only the targets generating .packages had been
# depended on.
deps = dart_deps
public_deps = group_deps
}
################################################
# SDK support
#
if (defined(invoker.sdk_category) && invoker.sdk_category != "excluded") {
assert(
defined(invoker.package_name),
"Dart libraries published in SDKs must have an explicit package name")
atom_name = invoker.package_name
# Dependencies that should normally be included in any SDK containing this
# target.
sdk_deps = []
# Path to manifest files for third-party dependencies.
third_party_specs = []
if (defined(invoker.deps)) {
sorted_deps =
exec_script("//build/dart/sdk/sort_deps.py", invoker.deps, "scope")
foreach(dep, sorted_deps.local) {
full_label = get_label_info(dep, "label_no_toolchain")
sdk_deps += [ "${full_label}_sdk" ]
}
foreach(dep, sorted_deps.third_party) {
path = get_label_info(dep, "dir")
third_party_specs += [ rebase_path("$path/pubspec.yaml") ]
}
}
# Build a manifest file listing third-party dependencies of this package.
# This will make it easier to build the final published package.
third_party_spec_target_name = "${target_name}_third_party_spec"
third_party_spec_file = "$target_gen_dir/${target_name}_3p.yaml"
action(third_party_spec_target_name) {
script = "//build/dart/sdk/gen_3p_manifest.py"
outputs = [
third_party_spec_file,
]
args = [
"--out",
rebase_path(third_party_spec_file),
"--name",
atom_name,
"--specs",
] + third_party_specs
}
# List all the sources which will be included in the package.
sdk_sources_target_name = "${target_name}_sdk_sources"
sdk_sources_file = "$target_gen_dir/${target_name}_sdk_sources.txt"
action(sdk_sources_target_name) {
script = "//build/dart/sdk/list_sources.py"
inputs = [
source_file,
]
outputs = [
sdk_sources_file,
]
args = [
"--out",
rebase_path(sdk_sources_file),
"--source-list",
rebase_path(source_file),
"--source-dir",
rebase_path(source_dir),
]
deps = [
":$source_target_name",
]
}
sdk_atom("${target_name}_sdk") {
domain = "dart"
name = atom_name
category = invoker.sdk_category
deps = sdk_deps
non_sdk_deps = [
":$sdk_sources_target_name",
":$third_party_spec_target_name",
]
file_manifest = sdk_sources_file
files = [
{
source = third_party_spec_file
dest = "third_party/pubspec.yaml"
},
]
}
}
}
} else { # Not the Dart toolchain.
template("dart_library") {
group(target_name) {
not_needed(invoker, "*")
public_deps = [
":$target_name($dart_toolchain)",
]
}
}
}