1*61c4878aSAndroid Build Coastguard Worker# Copyright 2020 The Pigweed Authors 2*61c4878aSAndroid Build Coastguard Worker# 3*61c4878aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4*61c4878aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of 5*61c4878aSAndroid Build Coastguard Worker# the License at 6*61c4878aSAndroid Build Coastguard Worker# 7*61c4878aSAndroid Build Coastguard Worker# https://www.apache.org/licenses/LICENSE-2.0 8*61c4878aSAndroid Build Coastguard Worker# 9*61c4878aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*61c4878aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11*61c4878aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12*61c4878aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under 13*61c4878aSAndroid Build Coastguard Worker# the License. 14*61c4878aSAndroid Build Coastguard Worker 15*61c4878aSAndroid Build Coastguard Workerimport("//build_overrides/pigweed.gni") 16*61c4878aSAndroid Build Coastguard Worker 17*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_build/python_gn_args.gni") 18*61c4878aSAndroid Build Coastguard Worker 19*61c4878aSAndroid Build Coastguard Worker# Defines an action that runs a Python script. 20*61c4878aSAndroid Build Coastguard Worker# 21*61c4878aSAndroid Build Coastguard Worker# This wraps a regular Python script GN action with an invocation of a script- 22*61c4878aSAndroid Build Coastguard Worker# runner script that adds useful features. pw_python_action() uses the same 23*61c4878aSAndroid Build Coastguard Worker# actions as GN's action(), with the following additions or changes: 24*61c4878aSAndroid Build Coastguard Worker# 25*61c4878aSAndroid Build Coastguard Worker# module May be used in place of the script argument to run the 26*61c4878aSAndroid Build Coastguard Worker# provided Python module with `python -m` instead of a script. 27*61c4878aSAndroid Build Coastguard Worker# Either script or module must be provided. 28*61c4878aSAndroid Build Coastguard Worker# 29*61c4878aSAndroid Build Coastguard Worker# capture_output If true, script output is hidden unless the script fails 30*61c4878aSAndroid Build Coastguard Worker# with an error. Defaults to true. 31*61c4878aSAndroid Build Coastguard Worker# 32*61c4878aSAndroid Build Coastguard Worker# stamp File to touch if the script is successful. Actions that 33*61c4878aSAndroid Build Coastguard Worker# don't create output files can use this stamp file instead of 34*61c4878aSAndroid Build Coastguard Worker# creating their own placeholder file. If true, a generic file 35*61c4878aSAndroid Build Coastguard Worker# is used. If false or not set, no file is touched. 36*61c4878aSAndroid Build Coastguard Worker# 37*61c4878aSAndroid Build Coastguard Worker# environment Environment variables to set, passed as a list of NAME=VALUE 38*61c4878aSAndroid Build Coastguard Worker# strings. 39*61c4878aSAndroid Build Coastguard Worker# 40*61c4878aSAndroid Build Coastguard Worker# args Same as the standard action args, except special expressions 41*61c4878aSAndroid Build Coastguard Worker# may be used to extract information not normally accessible 42*61c4878aSAndroid Build Coastguard Worker# in GN. These include the following: 43*61c4878aSAndroid Build Coastguard Worker# 44*61c4878aSAndroid Build Coastguard Worker# <TARGET_FILE(//some/label:here)> - expands to the 45*61c4878aSAndroid Build Coastguard Worker# output file (such as a .a or .elf) from a GN target 46*61c4878aSAndroid Build Coastguard Worker# <TARGET_FILE_IF_EXISTS(//some/label:here)> - expands to 47*61c4878aSAndroid Build Coastguard Worker# the output file if the target exists, or nothing 48*61c4878aSAndroid Build Coastguard Worker# <TARGET_OBJECTS(//some/label:here)> - expands to the 49*61c4878aSAndroid Build Coastguard Worker# object files produced by the provided GN target 50*61c4878aSAndroid Build Coastguard Worker# 51*61c4878aSAndroid Build Coastguard Worker# python_deps Dependencies on pw_python_package or related Python targets. 52*61c4878aSAndroid Build Coastguard Worker# 53*61c4878aSAndroid Build Coastguard Worker# python_metadata_deps Python-related dependencies that are only used as deps 54*61c4878aSAndroid Build Coastguard Worker# for generating Python package metadata list, not the 55*61c4878aSAndroid Build Coastguard Worker# overall Python script action. This should rarely be 56*61c4878aSAndroid Build Coastguard Worker# used by non-Pigweed code. 57*61c4878aSAndroid Build Coastguard Worker# 58*61c4878aSAndroid Build Coastguard Worker# working_directory Switch to the provided working directory before running 59*61c4878aSAndroid Build Coastguard Worker# the Python script or action. 60*61c4878aSAndroid Build Coastguard Worker# 61*61c4878aSAndroid Build Coastguard Worker# command_launcher Arguments to prepend to the Python command, e.g. 62*61c4878aSAndroid Build Coastguard Worker# '/usr/bin/fakeroot --' to run the Python script within a 63*61c4878aSAndroid Build Coastguard Worker# fakeroot environment. 64*61c4878aSAndroid Build Coastguard Worker# 65*61c4878aSAndroid Build Coastguard Worker# venv Optional gn target of the pw_python_venv that should be used 66*61c4878aSAndroid Build Coastguard Worker# to run this action. 67*61c4878aSAndroid Build Coastguard Worker# 68*61c4878aSAndroid Build Coastguard Workertemplate("pw_python_action") { 69*61c4878aSAndroid Build Coastguard Worker assert(defined(invoker.script) != defined(invoker.module), 70*61c4878aSAndroid Build Coastguard Worker "pw_python_action requires either 'script' or 'module'") 71*61c4878aSAndroid Build Coastguard Worker 72*61c4878aSAndroid Build Coastguard Worker _script_args = [ 73*61c4878aSAndroid Build Coastguard Worker # GN root directory relative to the build directory (in which the runner 74*61c4878aSAndroid Build Coastguard Worker # script is invoked). 75*61c4878aSAndroid Build Coastguard Worker "--gn-root", 76*61c4878aSAndroid Build Coastguard Worker rebase_path("//", root_build_dir), 77*61c4878aSAndroid Build Coastguard Worker 78*61c4878aSAndroid Build Coastguard Worker # Current directory, used to resolve relative paths. 79*61c4878aSAndroid Build Coastguard Worker "--current-path", 80*61c4878aSAndroid Build Coastguard Worker rebase_path(".", root_build_dir), 81*61c4878aSAndroid Build Coastguard Worker 82*61c4878aSAndroid Build Coastguard Worker "--default-toolchain=$default_toolchain", 83*61c4878aSAndroid Build Coastguard Worker "--current-toolchain=$current_toolchain", 84*61c4878aSAndroid Build Coastguard Worker ] 85*61c4878aSAndroid Build Coastguard Worker 86*61c4878aSAndroid Build Coastguard Worker _use_build_dir_virtualenv = true 87*61c4878aSAndroid Build Coastguard Worker 88*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.environment)) { 89*61c4878aSAndroid Build Coastguard Worker foreach(variable, invoker.environment) { 90*61c4878aSAndroid Build Coastguard Worker _script_args += [ "--env=$variable" ] 91*61c4878aSAndroid Build Coastguard Worker } 92*61c4878aSAndroid Build Coastguard Worker } 93*61c4878aSAndroid Build Coastguard Worker 94*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.inputs)) { 95*61c4878aSAndroid Build Coastguard Worker _inputs = invoker.inputs 96*61c4878aSAndroid Build Coastguard Worker } else { 97*61c4878aSAndroid Build Coastguard Worker _inputs = [] 98*61c4878aSAndroid Build Coastguard Worker } 99*61c4878aSAndroid Build Coastguard Worker 100*61c4878aSAndroid Build Coastguard Worker # List the script to run as an input so that the action is re-run when it is 101*61c4878aSAndroid Build Coastguard Worker # modified. 102*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.script)) { 103*61c4878aSAndroid Build Coastguard Worker _inputs += [ invoker.script ] 104*61c4878aSAndroid Build Coastguard Worker } 105*61c4878aSAndroid Build Coastguard Worker 106*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.outputs)) { 107*61c4878aSAndroid Build Coastguard Worker _outputs = invoker.outputs 108*61c4878aSAndroid Build Coastguard Worker } else { 109*61c4878aSAndroid Build Coastguard Worker _outputs = [] 110*61c4878aSAndroid Build Coastguard Worker } 111*61c4878aSAndroid Build Coastguard Worker 112*61c4878aSAndroid Build Coastguard Worker # If a stamp file is requested, add it as an output of the runner script. 113*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.stamp) && invoker.stamp != false) { 114*61c4878aSAndroid Build Coastguard Worker if (invoker.stamp == true) { 115*61c4878aSAndroid Build Coastguard Worker _stamp_file = "$target_gen_dir/$target_name.pw_pystamp" 116*61c4878aSAndroid Build Coastguard Worker } else { 117*61c4878aSAndroid Build Coastguard Worker _stamp_file = invoker.stamp 118*61c4878aSAndroid Build Coastguard Worker } 119*61c4878aSAndroid Build Coastguard Worker 120*61c4878aSAndroid Build Coastguard Worker _outputs += [ _stamp_file ] 121*61c4878aSAndroid Build Coastguard Worker _script_args += [ 122*61c4878aSAndroid Build Coastguard Worker "--touch", 123*61c4878aSAndroid Build Coastguard Worker rebase_path(_stamp_file, root_build_dir), 124*61c4878aSAndroid Build Coastguard Worker ] 125*61c4878aSAndroid Build Coastguard Worker } 126*61c4878aSAndroid Build Coastguard Worker 127*61c4878aSAndroid Build Coastguard Worker # Capture output or not (defaults to true). 128*61c4878aSAndroid Build Coastguard Worker if (!defined(invoker.capture_output) || invoker.capture_output) { 129*61c4878aSAndroid Build Coastguard Worker _script_args += [ "--capture-output" ] 130*61c4878aSAndroid Build Coastguard Worker } 131*61c4878aSAndroid Build Coastguard Worker 132*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.module)) { 133*61c4878aSAndroid Build Coastguard Worker _script_args += [ 134*61c4878aSAndroid Build Coastguard Worker "--module", 135*61c4878aSAndroid Build Coastguard Worker invoker.module, 136*61c4878aSAndroid Build Coastguard Worker ] 137*61c4878aSAndroid Build Coastguard Worker 138*61c4878aSAndroid Build Coastguard Worker # Pip installs should only ever need to occur in the Pigweed 139*61c4878aSAndroid Build Coastguard Worker # environment. For these actions do not use the build_dir virtualenv. 140*61c4878aSAndroid Build Coastguard Worker if (invoker.module == "pip") { 141*61c4878aSAndroid Build Coastguard Worker _use_build_dir_virtualenv = false 142*61c4878aSAndroid Build Coastguard Worker } 143*61c4878aSAndroid Build Coastguard Worker } 144*61c4878aSAndroid Build Coastguard Worker 145*61c4878aSAndroid Build Coastguard Worker # Override to force using or not using the venv. 146*61c4878aSAndroid Build Coastguard Worker if (defined(invoker._pw_internal_run_in_venv)) { 147*61c4878aSAndroid Build Coastguard Worker _use_build_dir_virtualenv = invoker._pw_internal_run_in_venv 148*61c4878aSAndroid Build Coastguard Worker } 149*61c4878aSAndroid Build Coastguard Worker 150*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.working_directory)) { 151*61c4878aSAndroid Build Coastguard Worker _script_args += [ 152*61c4878aSAndroid Build Coastguard Worker "--working-directory", 153*61c4878aSAndroid Build Coastguard Worker invoker.working_directory, 154*61c4878aSAndroid Build Coastguard Worker ] 155*61c4878aSAndroid Build Coastguard Worker } 156*61c4878aSAndroid Build Coastguard Worker 157*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.command_launcher)) { 158*61c4878aSAndroid Build Coastguard Worker _script_args += [ 159*61c4878aSAndroid Build Coastguard Worker "--command-launcher", 160*61c4878aSAndroid Build Coastguard Worker invoker.command_launcher, 161*61c4878aSAndroid Build Coastguard Worker ] 162*61c4878aSAndroid Build Coastguard Worker } 163*61c4878aSAndroid Build Coastguard Worker 164*61c4878aSAndroid Build Coastguard Worker if (defined(invoker._pw_action_type)) { 165*61c4878aSAndroid Build Coastguard Worker _action_type = invoker._pw_action_type 166*61c4878aSAndroid Build Coastguard Worker } else { 167*61c4878aSAndroid Build Coastguard Worker _action_type = "action" 168*61c4878aSAndroid Build Coastguard Worker } 169*61c4878aSAndroid Build Coastguard Worker 170*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.deps)) { 171*61c4878aSAndroid Build Coastguard Worker _deps = invoker.deps 172*61c4878aSAndroid Build Coastguard Worker } else { 173*61c4878aSAndroid Build Coastguard Worker _deps = [] 174*61c4878aSAndroid Build Coastguard Worker } 175*61c4878aSAndroid Build Coastguard Worker 176*61c4878aSAndroid Build Coastguard Worker _py_metadata_deps = [] 177*61c4878aSAndroid Build Coastguard Worker 178*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.python_deps)) { 179*61c4878aSAndroid Build Coastguard Worker foreach(dep, invoker.python_deps) { 180*61c4878aSAndroid Build Coastguard Worker _deps += [ get_label_info(dep, "label_no_toolchain") + ".install(" + 181*61c4878aSAndroid Build Coastguard Worker get_label_info(dep, "toolchain") + ")" ] 182*61c4878aSAndroid Build Coastguard Worker 183*61c4878aSAndroid Build Coastguard Worker # Ensure each python_dep is added to the PYTHONPATH by depinding on the 184*61c4878aSAndroid Build Coastguard Worker # ._package_metadata subtarget. 185*61c4878aSAndroid Build Coastguard Worker _py_metadata_deps += [ get_label_info(dep, "label_no_toolchain") + 186*61c4878aSAndroid Build Coastguard Worker "._package_metadata($pw_build_PYTHON_TOOLCHAIN)" ] 187*61c4878aSAndroid Build Coastguard Worker } 188*61c4878aSAndroid Build Coastguard Worker 189*61c4878aSAndroid Build Coastguard Worker # Add the base target as a dep so the action reruns when any source files 190*61c4878aSAndroid Build Coastguard Worker # change, even if the package does not have to be reinstalled. 191*61c4878aSAndroid Build Coastguard Worker _deps += invoker.python_deps 192*61c4878aSAndroid Build Coastguard Worker _deps += _py_metadata_deps 193*61c4878aSAndroid Build Coastguard Worker } 194*61c4878aSAndroid Build Coastguard Worker 195*61c4878aSAndroid Build Coastguard Worker # Check for additional PYTHONPATH dependencies. 196*61c4878aSAndroid Build Coastguard Worker _extra_python_metadata_deps = [] 197*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.python_metadata_deps)) { 198*61c4878aSAndroid Build Coastguard Worker foreach(dep, invoker.python_metadata_deps) { 199*61c4878aSAndroid Build Coastguard Worker _extra_python_metadata_deps += 200*61c4878aSAndroid Build Coastguard Worker [ get_label_info(dep, "label_no_toolchain") + 201*61c4878aSAndroid Build Coastguard Worker "._package_metadata($pw_build_PYTHON_TOOLCHAIN)" ] 202*61c4878aSAndroid Build Coastguard Worker } 203*61c4878aSAndroid Build Coastguard Worker } 204*61c4878aSAndroid Build Coastguard Worker 205*61c4878aSAndroid Build Coastguard Worker _metadata_path_list_file = 206*61c4878aSAndroid Build Coastguard Worker "${target_gen_dir}/${target_name}_metadata_path_list.txt" 207*61c4878aSAndroid Build Coastguard Worker 208*61c4878aSAndroid Build Coastguard Worker # GN metadata only dependencies used for setting PYTHONPATH. 209*61c4878aSAndroid Build Coastguard Worker _metadata_deps = _py_metadata_deps + _extra_python_metadata_deps 210*61c4878aSAndroid Build Coastguard Worker 211*61c4878aSAndroid Build Coastguard Worker # Build a list of relative paths containing all the python 212*61c4878aSAndroid Build Coastguard Worker # package_metadata.json files we depend on. 213*61c4878aSAndroid Build Coastguard Worker _metadata_path_list_target = "${target_name}._metadata_path_list.txt" 214*61c4878aSAndroid Build Coastguard Worker generated_file(_metadata_path_list_target) { 215*61c4878aSAndroid Build Coastguard Worker data_keys = [ "pw_python_package_metadata_json" ] 216*61c4878aSAndroid Build Coastguard Worker rebase = root_build_dir 217*61c4878aSAndroid Build Coastguard Worker deps = _metadata_deps 218*61c4878aSAndroid Build Coastguard Worker outputs = [ _metadata_path_list_file ] 219*61c4878aSAndroid Build Coastguard Worker } 220*61c4878aSAndroid Build Coastguard Worker _deps += [ ":${_metadata_path_list_target}" ] 221*61c4878aSAndroid Build Coastguard Worker 222*61c4878aSAndroid Build Coastguard Worker # Set venv options if needed. 223*61c4878aSAndroid Build Coastguard Worker if (_use_build_dir_virtualenv) { 224*61c4878aSAndroid Build Coastguard Worker _venv_target_label = pw_build_PYTHON_BUILD_VENV 225*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.venv)) { 226*61c4878aSAndroid Build Coastguard Worker _venv_target_label = invoker.venv 227*61c4878aSAndroid Build Coastguard Worker } 228*61c4878aSAndroid Build Coastguard Worker _venv_target_label = 229*61c4878aSAndroid Build Coastguard Worker get_label_info(_venv_target_label, "label_no_toolchain") + 230*61c4878aSAndroid Build Coastguard Worker "($pw_build_PYTHON_TOOLCHAIN)" 231*61c4878aSAndroid Build Coastguard Worker 232*61c4878aSAndroid Build Coastguard Worker _venv_json = 233*61c4878aSAndroid Build Coastguard Worker get_label_info(_venv_target_label, "target_gen_dir") + "/" + 234*61c4878aSAndroid Build Coastguard Worker get_label_info(_venv_target_label, "name") + "/venv_metadata.json" 235*61c4878aSAndroid Build Coastguard Worker _script_args += [ 236*61c4878aSAndroid Build Coastguard Worker "--python-virtualenv-config", 237*61c4878aSAndroid Build Coastguard Worker rebase_path(_venv_json, root_build_dir), 238*61c4878aSAndroid Build Coastguard Worker ] 239*61c4878aSAndroid Build Coastguard Worker } 240*61c4878aSAndroid Build Coastguard Worker _script_args += [ 241*61c4878aSAndroid Build Coastguard Worker "--python-dep-list-files", 242*61c4878aSAndroid Build Coastguard Worker rebase_path(_metadata_path_list_file, root_build_dir), 243*61c4878aSAndroid Build Coastguard Worker ] 244*61c4878aSAndroid Build Coastguard Worker 245*61c4878aSAndroid Build Coastguard Worker # "--" indicates the end of arguments to the runner script. 246*61c4878aSAndroid Build Coastguard Worker # Everything beyond this point is interpreted as the command and arguments 247*61c4878aSAndroid Build Coastguard Worker # of the Python script to run. 248*61c4878aSAndroid Build Coastguard Worker _script_args += [ "--" ] 249*61c4878aSAndroid Build Coastguard Worker 250*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.script)) { 251*61c4878aSAndroid Build Coastguard Worker _script_args += [ rebase_path(invoker.script, root_build_dir) ] 252*61c4878aSAndroid Build Coastguard Worker } 253*61c4878aSAndroid Build Coastguard Worker 254*61c4878aSAndroid Build Coastguard Worker _forward_python_metadata_deps = false 255*61c4878aSAndroid Build Coastguard Worker if (defined(invoker._forward_python_metadata_deps)) { 256*61c4878aSAndroid Build Coastguard Worker _forward_python_metadata_deps = true 257*61c4878aSAndroid Build Coastguard Worker } 258*61c4878aSAndroid Build Coastguard Worker if (_forward_python_metadata_deps) { 259*61c4878aSAndroid Build Coastguard Worker _script_args += [ 260*61c4878aSAndroid Build Coastguard Worker "--python-dep-list-files", 261*61c4878aSAndroid Build Coastguard Worker rebase_path(_metadata_path_list_file, root_build_dir), 262*61c4878aSAndroid Build Coastguard Worker ] 263*61c4878aSAndroid Build Coastguard Worker } 264*61c4878aSAndroid Build Coastguard Worker 265*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.args)) { 266*61c4878aSAndroid Build Coastguard Worker _script_args += invoker.args 267*61c4878aSAndroid Build Coastguard Worker } 268*61c4878aSAndroid Build Coastguard Worker 269*61c4878aSAndroid Build Coastguard Worker # Assume third party PyPI deps should be available in the build_dir virtualenv. 270*61c4878aSAndroid Build Coastguard Worker _install_venv_3p_deps = true 271*61c4878aSAndroid Build Coastguard Worker if (!_use_build_dir_virtualenv || 272*61c4878aSAndroid Build Coastguard Worker (defined(invoker._skip_installing_external_python_deps) && 273*61c4878aSAndroid Build Coastguard Worker invoker._skip_installing_external_python_deps)) { 274*61c4878aSAndroid Build Coastguard Worker _install_venv_3p_deps = false 275*61c4878aSAndroid Build Coastguard Worker } 276*61c4878aSAndroid Build Coastguard Worker 277*61c4878aSAndroid Build Coastguard Worker # Check that script or module is a present and not a no-op. 278*61c4878aSAndroid Build Coastguard Worker _run_script_or_module = false 279*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.script) || defined(invoker.module)) { 280*61c4878aSAndroid Build Coastguard Worker _run_script_or_module = true 281*61c4878aSAndroid Build Coastguard Worker } 282*61c4878aSAndroid Build Coastguard Worker 283*61c4878aSAndroid Build Coastguard Worker target(_action_type, target_name) { 284*61c4878aSAndroid Build Coastguard Worker _ignore_vars = [ 285*61c4878aSAndroid Build Coastguard Worker "script", 286*61c4878aSAndroid Build Coastguard Worker "args", 287*61c4878aSAndroid Build Coastguard Worker "deps", 288*61c4878aSAndroid Build Coastguard Worker "inputs", 289*61c4878aSAndroid Build Coastguard Worker "outputs", 290*61c4878aSAndroid Build Coastguard Worker ] 291*61c4878aSAndroid Build Coastguard Worker forward_variables_from(invoker, "*", _ignore_vars) 292*61c4878aSAndroid Build Coastguard Worker 293*61c4878aSAndroid Build Coastguard Worker script = "$dir_pw_build/py/pw_build/python_runner.py" 294*61c4878aSAndroid Build Coastguard Worker args = _script_args 295*61c4878aSAndroid Build Coastguard Worker inputs = _inputs 296*61c4878aSAndroid Build Coastguard Worker outputs = _outputs 297*61c4878aSAndroid Build Coastguard Worker deps = _deps 298*61c4878aSAndroid Build Coastguard Worker 299*61c4878aSAndroid Build Coastguard Worker if (_install_venv_3p_deps && _run_script_or_module) { 300*61c4878aSAndroid Build Coastguard Worker deps += [ get_label_info(_venv_target_label, "label_no_toolchain") + 301*61c4878aSAndroid Build Coastguard Worker "._install_3p_deps($pw_build_PYTHON_TOOLCHAIN)" ] 302*61c4878aSAndroid Build Coastguard Worker } 303*61c4878aSAndroid Build Coastguard Worker } 304*61c4878aSAndroid Build Coastguard Worker} 305*61c4878aSAndroid Build Coastguard Worker 306*61c4878aSAndroid Build Coastguard Worker# Runs pw_python_action once per file over a set of sources. 307*61c4878aSAndroid Build Coastguard Worker# 308*61c4878aSAndroid Build Coastguard Worker# This template brings pw_python_action's features to action_foreach. Usage is 309*61c4878aSAndroid Build Coastguard Worker# the same as pw_python_action, except that sources must be provided and source 310*61c4878aSAndroid Build Coastguard Worker# expansion (e.g. "{{source}}") may be used in args and outputs. 311*61c4878aSAndroid Build Coastguard Worker# 312*61c4878aSAndroid Build Coastguard Worker# See the pw_python_action and action_foreach documentation for full details. 313*61c4878aSAndroid Build Coastguard Workertemplate("pw_python_action_foreach") { 314*61c4878aSAndroid Build Coastguard Worker assert(defined(invoker.sources) && invoker.sources != [], 315*61c4878aSAndroid Build Coastguard Worker "pw_python_action_foreach requires a list of one or more sources") 316*61c4878aSAndroid Build Coastguard Worker 317*61c4878aSAndroid Build Coastguard Worker pw_python_action(target_name) { 318*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.stamp) && invoker.stamp != false) { 319*61c4878aSAndroid Build Coastguard Worker if (invoker.stamp == true) { 320*61c4878aSAndroid Build Coastguard Worker # Use source file names in the generated stamp file path so they are 321*61c4878aSAndroid Build Coastguard Worker # unique for each source. 322*61c4878aSAndroid Build Coastguard Worker stamp = "$target_gen_dir/{{source_file_part}}.pw_pystamp" 323*61c4878aSAndroid Build Coastguard Worker } else { 324*61c4878aSAndroid Build Coastguard Worker stamp = invoker.stamp 325*61c4878aSAndroid Build Coastguard Worker } 326*61c4878aSAndroid Build Coastguard Worker } else { 327*61c4878aSAndroid Build Coastguard Worker stamp = false 328*61c4878aSAndroid Build Coastguard Worker } 329*61c4878aSAndroid Build Coastguard Worker 330*61c4878aSAndroid Build Coastguard Worker forward_variables_from(invoker, "*", [ "stamp" ]) 331*61c4878aSAndroid Build Coastguard Worker 332*61c4878aSAndroid Build Coastguard Worker _pw_action_type = "action_foreach" 333*61c4878aSAndroid Build Coastguard Worker } 334*61c4878aSAndroid Build Coastguard Worker} 335