# Copyright 2017 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/chromeos/ui_mode.gni")
import("//third_party/closure_compiler/closure_args.gni")
if (is_chromeos_ash) {
declare_args() {
# Enable closure type-checking for Chrome's web technology-based UI. This
# enables the webui_closure_compile target which does a no-op without this
# flag enabled. Requires Java.
enable_js_type_check = is_chromeos_ash
}
}
script_path = "//third_party/closure_compiler"
compiler_path = "$script_path/compiler/compiler.jar"
externs_path = "$script_path/externs"
interfaces_path = "$script_path/interfaces"
chrome_externs = "$externs_path/chrome.js"
polymer_externs = "$externs_path/polymer-1.0.js"
# Defines a target that creates an ordering for .js files to be used by
# js_binary to compile.
#
# Variables:
# sources:
# List of Javascript files to include in the library. Uses target_name.js by
# default.
#
# deps:
# List of js_library targets to depend on
#
# extra_deps:
# List of any other rules to depend on. E.g. a rule that generates js source
# files
#
# extra_public_deps
# List of other targets to expose as public dependencies.
#
# externs_list:
# A list of .js files to pass to the compiler as externs
#
# extra_sources:
# A list of .js files to pass to the compiler as interfaces
#
# Example:
# js_library("apple_tree") {
# sources = ["tree_main.js"]
# deps = [
# ":branch",
# ":trunk",
# ":root",
# ]
# }
template("js_library") {
action(target_name) {
script = "$script_path/js_library.py"
forward_variables_from(invoker,
[
"deps",
"externs_list",
"extra_deps",
"extra_public_deps",
"extra_sources",
"sources",
"testonly",
"visibility",
])
inputs = [ "$script_path/compiler.py" ]
output_file = "$target_gen_dir/$target_name.js_library"
outputs = [ output_file ]
args = [ "--output" ] + [ rebase_path(output_file, root_build_dir) ]
if (!defined(sources)) {
sources = [ target_name + ".js" ]
}
args += [ "--sources" ] + rebase_path(sources, root_build_dir)
if (defined(extra_sources)) {
args += rebase_path(extra_sources, root_build_dir)
sources += extra_sources
}
if (defined(deps)) {
args += [ "--deps" ]
foreach(dep, deps) {
# Get the output path for each dep
dep_gen_dir = get_label_info(dep, "target_gen_dir")
dep_name = get_label_info(dep, "name")
dep_output_path = "$dep_gen_dir/$dep_name.js_library"
args += [ rebase_path(dep_output_path, root_build_dir) ]
}
}
if (defined(externs_list)) {
args += [ "--externs" ] + rebase_path(externs_list, root_build_dir)
sources += externs_list
}
if (defined(extra_deps)) {
if (!defined(deps)) {
deps = []
}
deps += extra_deps
}
if (defined(extra_public_deps)) {
public_deps = extra_public_deps
}
}
}
# Defines a target that compiles javascript files using the Closure compiler.
# This will produce a minified javascript output file. Additional checks and
# optimizations can be configured using the closure_flags attribute.
#
# Variables:
# sources:
# List of .js files to compile. Will be target_name.js by default. Use
# sources = [] to specify no input files (when making a target that just
# group compiles other targets, for example).
#
# deps:
# List of js_library rules to depend on
#
# outputs:
# If chunks is not specified, a file to write the compiled .js to.
# If chunks is specified, a directory to write the compiled .js to.
# Only takes in a single file or directory, but must be placed in a list.
#
# bootstrap_file:
# A .js files to include before all others
#
# config_files:
# A list of .js files to include after the bootstrap_file but before all
# others
#
# closure_flags:
# A list of custom flags to pass to the Closure compiler. Do not include
# the leading dashes
#
# externs_list:
# A list of .js files to pass to the compiler as externs
#
# chunks:
# Unused in chromium/src but used downstream.
# A boolean indicating that a chunk should be created for each input file
# (or target_name.js), along with a common_chunk.js for shared code.
# Requires outputs refer to a directory and chunk_suffix be provided.
#
# chunk_suffix:
# Unused in chromium/src but used downstream.
# The suffix appended to a source when naming a chunk, since it may not
# have the same name as the source. By default, creates target_name_chunk.js.
#
# Example:
# js_binary("tree") {
# sources = ["tree_main.js"]
# deps = [":apple_tree"]
# outputs = [ "$target_gen_dir/tree.js" ]
# bootstrap_file = "bootstrap.js"
# config_files = [
# "config1.js",
# "config2.js",
# ]
# closure_flags = ["jscomp_error=undefinedVars"]
# externs_list = [ "externs.js" ]
# }
template("js_binary") {
action(target_name) {
script = "$script_path/js_binary.py"
forward_variables_from(invoker,
[
"bootstrap_file",
"checks_only",
"chunks",
"chunk_suffix",
"closure_flags",
"config_files",
"deps",
"externs_list",
"extra_deps",
"is_polymer3",
"outputs",
"sources",
"testonly",
])
args = [
"--compiler",
rebase_path(compiler_path, root_build_dir),
]
if (!defined(outputs)) {
if (defined(chunks) && chunks) {
outputs = [ "$target_gen_dir/" ]
} else {
outputs = [ "$target_gen_dir/$target_name.js" ]
}
}
args += [ "--output" ] + rebase_path(outputs, root_build_dir)
if (!defined(sources)) {
sources = [ "$target_name.js" ]
}
if (defined(deps)) {
args += [ "--deps" ]
foreach(dep, deps) {
# Get the output path for each dep
dep_gen_dir = get_label_info(dep, "target_gen_dir")
dep_name = get_label_info(dep, "name")
dep_output_path = "$dep_gen_dir/$dep_name.js_library"
args += [ rebase_path(dep_output_path, root_build_dir) ]
}
}
args += [ "--sources" ] + rebase_path(sources, root_build_dir)
if (defined(bootstrap_file)) {
args += [
"--bootstrap",
rebase_path(bootstrap_file, root_build_dir),
]
sources += [ bootstrap_file ]
}
if (defined(config_files)) {
args += [ "--config" ] + rebase_path(config_files, root_build_dir)
sources += config_files
}
if (defined(chunks) && chunks) {
args += [ "--chunks" ]
assert(defined(chunk_suffix), "Need chunk_suffix with chunks")
args += [
"--chunk_suffix",
chunk_suffix,
]
}
if (defined(checks_only) && checks_only) {
args += [ "--checks-only" ]
}
# |minifying_closure_args| from
# //third_party/closure_compiler/closure_args.gni
if (!defined(closure_flags)) {
closure_flags = default_closure_args
}
closure_flags += js_modules_args
is_polymer3 = defined(is_polymer3) && is_polymer3
if (is_polymer3) {
closure_flags += polymer3_args
}
args += [ "--flags" ] + closure_flags
args += [
"--externs",
rebase_path("$chrome_externs", root_build_dir),
]
inputs = [
"$script_path/closure_args.gni",
chrome_externs,
compiler_path,
]
# |polymer_externs| should only be added for Polymer versions 1 and 2. For
# Polymer3, Polymer sources are directly passed to the compiler instead.
if (!is_polymer3) {
args += [ rebase_path("$polymer_externs", root_build_dir) ]
inputs += [ polymer_externs ]
}
if (defined(externs_list)) {
args += rebase_path(externs_list, root_build_dir)
sources += externs_list
}
if (defined(extra_deps)) {
if (!defined(deps)) {
deps = []
}
deps += extra_deps
}
}
}
# js_type_check is only supported on ChromeOS Ash.
if (is_chromeos_ash) {
# Defines a target that compiles a group of js_library targets.
template("js_type_check") {
if (enable_js_type_check) {
js_binary(target_name) {
sources = []
checks_only = true
forward_variables_from(invoker,
[
"closure_flags",
"deps",
"is_polymer3",
"testonly",
])
}
} else {
not_needed(invoker, "*")
group(target_name) {
}
}
}
}
# These externs files depend on each other (often in a cyclical way), and
# therefore makes more sense to add all of them as a dependency together.
chrome_extension_public_externs = [
"$externs_path/events.js",
"$externs_path/extension_types.js",
"$externs_path/runtime.js",
"$externs_path/tabs.js",
"$externs_path/windows.js",
]