258 строки
9.5 KiB
Plaintext
258 строки
9.5 KiB
Plaintext
# Copyright 2018 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
# Creates a group() that lists Python sources as |data|.
|
|
# Having such targets serves two purposes:
|
|
# 1) Causes files to be included in runtime_deps, so that they are uploaded to
|
|
# swarming when running tests remotely.
|
|
# 2) Causes "gn analyze" to know about all Python inputs so that tests will be
|
|
# re-run when relevant Python files change.
|
|
#
|
|
# All non-trivial Python scripts should use a "pydeps" file to track their
|
|
# sources. To create a .pydep file for a target in //example:
|
|
#
|
|
# build/print_python_deps.py \
|
|
# --root example \
|
|
# --output example/$target_name.pydeps \
|
|
# path/to/your/script.py
|
|
#
|
|
# Keep the .pydep file up-to-date by adding to //PRESUBMIT.py under one of:
|
|
# _ANDROID_SPECIFIC_PYDEPS_FILES, _GENERIC_PYDEPS_FILES
|
|
#
|
|
# Variables
|
|
# pydeps_file: Path to .pydeps file to read sources from (optional).
|
|
# data: Additional files to include in data. E.g. non-.py files needed by the
|
|
# library, or .py files that are conditionally / lazily imported.
|
|
#
|
|
# Example
|
|
# python_library("my_library_py") {
|
|
# pydeps_file = "my_library.pydeps"
|
|
# data = [ "foo.dat" ]
|
|
# }
|
|
template("python_library") {
|
|
group(target_name) {
|
|
forward_variables_from(invoker,
|
|
[
|
|
"data_deps",
|
|
"deps",
|
|
"testonly",
|
|
"visibility",
|
|
])
|
|
|
|
if (defined(invoker.pydeps_file)) {
|
|
# Read and filter out comments.
|
|
_pydeps_lines = read_file(invoker.pydeps_file, "list lines")
|
|
_pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])
|
|
|
|
# Dependencies are listed relative to the pydeps file directory, but data
|
|
# parameter expects paths that are relative to the current BUILD.gn
|
|
_script_dir = get_path_info(invoker.pydeps_file, "dir")
|
|
_rebased_pydeps_entries = rebase_path(_pydeps_entries, ".", _script_dir)
|
|
|
|
# Even though the .pydep file is not used at runtime, it must be added
|
|
# so that "gn analyze" will mark the target as changed when .py files
|
|
# are removed but none are added or modified.
|
|
data = _rebased_pydeps_entries + [ invoker.pydeps_file ]
|
|
} else {
|
|
data = []
|
|
}
|
|
if (defined(invoker.data)) {
|
|
data += invoker.data
|
|
}
|
|
}
|
|
}
|
|
|
|
# This is a wrapper around action() that ensures that the script is
|
|
# run under a Python2 executable, even if the main script_executable is
|
|
# Python3.
|
|
#
|
|
# It supports all of action()'s arguments.
|
|
#
|
|
# TODO(crbug.com/1112471): Remove this once everything runs cleanly under
|
|
# Python3.
|
|
template("python2_action") {
|
|
action(target_name) {
|
|
# Forward all variables. Ensure that testonly and visibility are forwarded
|
|
# explicitly, since this performs recursive scope lookups, which is
|
|
# required to ensure their definition from scopes above the caller are
|
|
# properly handled. All other variables are forwarded with "*", which
|
|
# doesn't perform recursive lookups at all. See https://crbug.com/862232
|
|
forward_variables_from(invoker,
|
|
[
|
|
"testonly",
|
|
"visibility",
|
|
])
|
|
forward_variables_from(invoker,
|
|
"*",
|
|
[
|
|
"script",
|
|
"inputs",
|
|
"args",
|
|
"testonly",
|
|
"visibility",
|
|
])
|
|
|
|
script = "//build/util/python2_action.py"
|
|
if (!defined(invoker.inputs)) {
|
|
inputs = [ invoker.script ]
|
|
} else {
|
|
inputs = [ invoker.script ] + invoker.inputs
|
|
}
|
|
args = [ rebase_path(invoker.script, root_build_dir) ] + invoker.args
|
|
}
|
|
}
|
|
|
|
# This is a wrapper around action() that ensures that the script is
|
|
# run under a Python2 executable, even if the main script_executable is
|
|
# Python3.
|
|
#
|
|
# It supports all of action()'s arguments.
|
|
#
|
|
# TODO(crbug.com/1112471): Remove this once everything runs cleanly under
|
|
# Python3.
|
|
template("python2_action_foreach") {
|
|
action_foreach(target_name) {
|
|
# Forward all variables. Ensure that testonly and visibility are forwarded
|
|
# explicitly, since this performs recursive scope lookups, which is
|
|
# required to ensure their definition from scopes above the caller are
|
|
# properly handled. All other variables are forwarded with "*", which
|
|
# doesn't perform recursive lookups at all. See https://crbug.com/862232
|
|
forward_variables_from(invoker,
|
|
[
|
|
"testonly",
|
|
"visibility",
|
|
])
|
|
forward_variables_from(invoker,
|
|
"*",
|
|
[
|
|
"script",
|
|
"inputs",
|
|
"args",
|
|
"testonly",
|
|
"visibility",
|
|
])
|
|
|
|
script = "//build/run_under_python2.py"
|
|
if (!defined(invoker.inputs)) {
|
|
inputs = [ invoker.script ]
|
|
} else {
|
|
inputs = [ invoker.script ] + invoker.inputs
|
|
}
|
|
args = [ rebase_path(invoker.script, root_build_dir) ] + invoker.args
|
|
}
|
|
}
|
|
|
|
# A template used for actions that execute a Python script, which has an
|
|
# associated .pydeps file. In other words:
|
|
#
|
|
# - This is very similar to just an action(), except that |script| must point
|
|
# to a Python script (e.g. "//build/.../foo.py") that has a corresponding
|
|
# .pydeps file in the source tree (e.g. "//build/.../foo.pydeps").
|
|
#
|
|
# - The .pydeps file contains a list of python dependencies (imports really)
|
|
# and is generated _manually_ by using a command like:
|
|
#
|
|
# build/print_python_deps.py --inplace build/android/gyp/foo.py
|
|
#
|
|
# Example
|
|
# action_with_pydeps("create_foo") {
|
|
# script = "myscript.py"
|
|
# args = [...]
|
|
# }
|
|
template("action_with_pydeps") {
|
|
action(target_name) {
|
|
# Forward all variables. Ensure that testonly and visibility are forwarded
|
|
# explicitly, since this performs recursive scope lookups, which is
|
|
# required to ensure their definition from scopes above the caller are
|
|
# properly handled. All other variables are forwarded with "*", which
|
|
# doesn't perform recursive lookups at all. See https://crbug.com/862232
|
|
forward_variables_from(invoker,
|
|
[
|
|
"testonly",
|
|
"visibility",
|
|
])
|
|
forward_variables_from(invoker,
|
|
"*",
|
|
[
|
|
"testonly",
|
|
"visibility",
|
|
])
|
|
|
|
# Read and filter out comments.
|
|
# Happens every time the template is instantiated, but benchmarking shows no
|
|
# perceivable impact on overall 'gn gen' speed.
|
|
_pydeps_file = invoker.script + "deps"
|
|
|
|
_pydeps_lines =
|
|
read_file(_pydeps_file, "list lines") # https://crbug.com/1102058
|
|
_pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])
|
|
|
|
if (!defined(inputs)) {
|
|
inputs = []
|
|
}
|
|
|
|
# Dependencies are listed relative to the script directory, but inputs
|
|
# expects paths that are relative to the current BUILD.gn
|
|
_script_dir = get_path_info(_pydeps_file, "dir")
|
|
inputs += rebase_path(_pydeps_entries, ".", _script_dir)
|
|
|
|
if (defined(run_under_python2) && run_under_python2) {
|
|
inputs += [ invoker.script ]
|
|
_args = args
|
|
args = []
|
|
args = [ rebase_path(invoker.script, root_build_dir) ] + _args
|
|
script = "//build/run_under_python2.py"
|
|
}
|
|
}
|
|
}
|
|
|
|
template("action_foreach_with_pydeps") {
|
|
action_foreach(target_name) {
|
|
# Forward all variables. Ensure that testonly and visibility are forwarded
|
|
# explicitly, since this performs recursive scope lookups, which is
|
|
# required to ensure their definition from scopes above the caller are
|
|
# properly handled. All other variables are forwarded with "*", which
|
|
# doesn't perform recursive lookups at all. See https://crbug.com/862232
|
|
forward_variables_from(invoker,
|
|
[
|
|
"testonly",
|
|
"visibility",
|
|
])
|
|
forward_variables_from(invoker,
|
|
"*",
|
|
[
|
|
"testonly",
|
|
"visibility",
|
|
])
|
|
|
|
# Read and filter out comments.
|
|
# Happens every time the template is instantiated, but benchmarking shows no
|
|
# perceivable impact on overall 'gn gen' speed.
|
|
if (defined(invoker.deps_file)) {
|
|
_pydeps_file = invoker.deps_file
|
|
} else {
|
|
_pydeps_file = invoker.script + "deps"
|
|
}
|
|
_pydeps_lines = read_file(_pydeps_file, "list lines")
|
|
_pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])
|
|
|
|
if (!defined(inputs)) {
|
|
inputs = []
|
|
}
|
|
|
|
# Dependencies are listed relative to the script directory, but inputs
|
|
# expects paths that are relative to the current BUILD.gn
|
|
_script_dir = get_path_info(script, "dir")
|
|
inputs += rebase_path(_pydeps_entries, ".", _script_dir)
|
|
|
|
if (defined(run_under_python2) && run_under_python2) {
|
|
inputs += [ invoker.script ]
|
|
_args = args
|
|
args = []
|
|
args = [ rebase_path(invoker.script, root_build_dir) ] + _args
|
|
script = "//build/run_under_python2.py"
|
|
}
|
|
}
|
|
}
|