218 lines
6.8 KiB
Plaintext
218 lines
6.8 KiB
Plaintext
# Copyright 2020 The Pigweed Authors
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
# use this file except in compliance with the License. You may obtain a copy of
|
|
# the License at
|
|
#
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations under
|
|
# the License.
|
|
|
|
import("//build_overrides/pigweed.gni")
|
|
|
|
# Defines an action that runs a Python script.
|
|
#
|
|
# This wraps a regular Python script GN action with an invocation of a script-
|
|
# runner script that adds useful features. pw_python_action() uses the same
|
|
# actions as GN's action(), with the following additions or changes:
|
|
#
|
|
# module May be used in place of the script argument to run the
|
|
# provided Python module with `python -m` instead of a script.
|
|
# Either script or module must be provided.
|
|
#
|
|
# capture_output If true, script output is hidden unless the script fails
|
|
# with an error. Defaults to true.
|
|
#
|
|
# stamp File to touch if the script is successful. Actions that
|
|
# don't create output files can use this stamp file instead of
|
|
# creating their own placeholder file. If true, a generic file
|
|
# is used. If false or not set, no file is touched.
|
|
#
|
|
# environment Environment variables to set, passed as a list of NAME=VALUE
|
|
# strings.
|
|
#
|
|
# args Same as the standard action args, except special expressions
|
|
# may be used to extract information not normally accessible
|
|
# in GN. These include the following:
|
|
#
|
|
# <TARGET_FILE(//some/label:here)> - expands to the
|
|
# output file (such as a .a or .elf) from a GN target
|
|
# <TARGET_FILE_IF_EXISTS(//some/label:here)> - expands to
|
|
# the output file if the target exists, or nothing
|
|
# <TARGET_OBJECTS(//some/label:here)> - expands to the
|
|
# object files produced by the provided GN target
|
|
#
|
|
# python_deps Dependencies on pw_python_package or related Python targets.
|
|
#
|
|
# working_directory Switch to the provided working directory before running
|
|
# the Python script or action.
|
|
#
|
|
template("pw_python_action") {
|
|
assert(defined(invoker.script) != defined(invoker.module),
|
|
"pw_python_action requires either 'script' or 'module'")
|
|
|
|
_script_args = [
|
|
# GN root directory relative to the build directory (in which the runner
|
|
# script is invoked).
|
|
"--gn-root",
|
|
rebase_path("//", root_build_dir),
|
|
|
|
# Current directory, used to resolve relative paths.
|
|
"--current-path",
|
|
rebase_path(".", root_build_dir),
|
|
|
|
# pip lockfile, prevents pip from running in parallel with other Python
|
|
# actions.
|
|
"--lockfile",
|
|
rebase_path("$root_out_dir/pip.lock", root_build_dir),
|
|
|
|
"--default-toolchain=$default_toolchain",
|
|
"--current-toolchain=$current_toolchain",
|
|
]
|
|
|
|
if (defined(invoker.environment)) {
|
|
foreach(variable, invoker.environment) {
|
|
_script_args += [ "--env=$variable" ]
|
|
}
|
|
}
|
|
|
|
if (defined(invoker.inputs)) {
|
|
_inputs = invoker.inputs
|
|
} else {
|
|
_inputs = []
|
|
}
|
|
|
|
# List the script to run as an input so that the action is re-run when it is
|
|
# modified.
|
|
if (defined(invoker.script)) {
|
|
_inputs += [ invoker.script ]
|
|
}
|
|
|
|
if (defined(invoker.outputs)) {
|
|
_outputs = invoker.outputs
|
|
} else {
|
|
_outputs = []
|
|
}
|
|
|
|
# If a stamp file is requested, add it as an output of the runner script.
|
|
if (defined(invoker.stamp) && invoker.stamp != false) {
|
|
if (invoker.stamp == true) {
|
|
_stamp_file = "$target_gen_dir/$target_name.pw_pystamp"
|
|
} else {
|
|
_stamp_file = invoker.stamp
|
|
}
|
|
|
|
_outputs += [ _stamp_file ]
|
|
_script_args += [
|
|
"--touch",
|
|
rebase_path(_stamp_file, root_build_dir),
|
|
]
|
|
}
|
|
|
|
# Capture output or not (defaults to true).
|
|
if (!defined(invoker.capture_output) || invoker.capture_output) {
|
|
_script_args += [ "--capture-output" ]
|
|
}
|
|
|
|
if (defined(invoker.module)) {
|
|
_script_args += [
|
|
"--module",
|
|
invoker.module,
|
|
]
|
|
}
|
|
|
|
if (defined(invoker.working_directory)) {
|
|
_script_args += [
|
|
"--working-directory",
|
|
invoker.working_directory,
|
|
]
|
|
}
|
|
|
|
# "--" indicates the end of arguments to the runner script.
|
|
# Everything beyond this point is interpreted as the command and arguments
|
|
# of the Python script to run.
|
|
_script_args += [ "--" ]
|
|
|
|
if (defined(invoker.script)) {
|
|
_script_args += [ rebase_path(invoker.script, root_build_dir) ]
|
|
}
|
|
|
|
if (defined(invoker.args)) {
|
|
_script_args += invoker.args
|
|
}
|
|
|
|
if (defined(invoker._pw_action_type)) {
|
|
_action_type = invoker._pw_action_type
|
|
} else {
|
|
_action_type = "action"
|
|
}
|
|
|
|
if (defined(invoker.deps)) {
|
|
_deps = invoker.deps
|
|
} else {
|
|
_deps = []
|
|
}
|
|
|
|
if (defined(invoker.python_deps)) {
|
|
foreach(dep, invoker.python_deps) {
|
|
_deps += [ get_label_info(dep, "label_no_toolchain") + ".install(" +
|
|
get_label_info(dep, "toolchain") + ")" ]
|
|
}
|
|
|
|
# Add the base target as a dep so the action reruns when any source files
|
|
# change, even if the package does not have to be reinstalled.
|
|
_deps += invoker.python_deps
|
|
}
|
|
|
|
target(_action_type, target_name) {
|
|
_ignore_vars = [
|
|
"script",
|
|
"args",
|
|
"deps",
|
|
"inputs",
|
|
"outputs",
|
|
]
|
|
forward_variables_from(invoker, "*", _ignore_vars)
|
|
|
|
script = "$dir_pw_build/py/pw_build/python_runner.py"
|
|
args = _script_args
|
|
inputs = _inputs
|
|
outputs = _outputs
|
|
deps = _deps
|
|
}
|
|
}
|
|
|
|
# Runs pw_python_action once per file over a set of sources.
|
|
#
|
|
# This template brings pw_python_action's features to action_foreach. Usage is
|
|
# the same as pw_python_action, except that sources must be provided and source
|
|
# expansion (e.g. "{{source}}") may be used in args and outputs.
|
|
#
|
|
# See the pw_python_action and action_foreach documentation for full details.
|
|
template("pw_python_action_foreach") {
|
|
assert(defined(invoker.sources) && invoker.sources != [],
|
|
"pw_python_action_foreach requires a list of one or more sources")
|
|
|
|
pw_python_action(target_name) {
|
|
if (defined(invoker.stamp) && invoker.stamp != false) {
|
|
if (invoker.stamp == true) {
|
|
# Use source file names in the generated stamp file path so they are
|
|
# unique for each source.
|
|
stamp = "$target_gen_dir/{{source_file_part}}.pw_pystamp"
|
|
} else {
|
|
stamp = invoker.stamp
|
|
}
|
|
} else {
|
|
stamp = false
|
|
}
|
|
|
|
forward_variables_from(invoker, "*", [ "stamp" ])
|
|
|
|
_pw_action_type = "action_foreach"
|
|
}
|
|
}
|