1# Copyright 2019 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14 15import("python_action.gni") 16 17# Runs a program which isn't in Python. 18# 19# This is provided to avoid having to write a new Python wrapper script every 20# time a program needs to be run from GN. 21# 22# Args: 23# program: The program to run. Can be a full path or just a name (in which case 24# $PATH is searched). 25# 26# args: Optional list of arguments to the program. 27# 28# deps: Dependencies for this target. 29# 30# inputs: Optional list of build inputs to the program. 31# 32# outputs: Optional list of artifacts produced by the program's execution. 33# 34# env: Optional list of key-value pairs defining environment variables for 35# the program. 36# 37# env_file: Optional path to a file containing a list of newline-separated 38# key-value pairs defining environment variables for the program. 39# 40# args_file: Optional path to a file containing additional positional arguments 41# to the program. Each line of the file is appended to the invocation. Useful 42# for specifying arguments from GN metadata. 43# 44# skip_empty_args: If args_file is provided, boolean indicating whether to skip 45# running the program if the file is empty. Used to avoid running commands 46# which error when called without arguments. 47# 48# capture_output: If true, output from the program is hidden unless the program 49# exits with an error. Defaults to true. 50# 51# Example: 52# 53# pw_exec("hello_world") { 54# program = "/bin/sh" 55# args = [ 56# "-c", 57# "echo hello \$WORLD", 58# ] 59# env = [ 60# "WORLD=world", 61# ] 62# } 63# 64template("pw_exec") { 65 assert(defined(invoker.program), "pw_exec requires a program to run") 66 67 _script_args = [ 68 "--target", 69 target_name, 70 ] 71 72 if (defined(invoker.env_file)) { 73 _script_args += [ 74 "--env-file", 75 rebase_path(invoker.env_file), 76 ] 77 } 78 79 if (defined(invoker.args_file)) { 80 _script_args += [ 81 "--args-file", 82 rebase_path(invoker.args_file), 83 ] 84 85 if (defined(invoker.skip_empty_args) && invoker.skip_empty_args) { 86 _script_args += [ "--skip-empty-args" ] 87 } 88 } 89 90 if (defined(invoker.env)) { 91 foreach(_env, invoker.env) { 92 _script_args += [ 93 "--env", 94 _env, 95 ] 96 } 97 } 98 99 if (!defined(invoker.capture_output) || invoker.capture_output) { 100 _script_args += [ "--capture-output" ] 101 } 102 103 _script_args += [ 104 "--", 105 invoker.program, 106 ] 107 if (defined(invoker.args)) { 108 _script_args += invoker.args 109 } 110 111 pw_python_action(target_name) { 112 script = "$dir_pw_build/py/pw_build/exec.py" 113 args = _script_args 114 115 forward_variables_from(invoker, 116 [ 117 "deps", 118 "inputs", 119 "pool", 120 ]) 121 122 if (!defined(inputs)) { 123 inputs = [] 124 } 125 if (defined(invoker.env_file)) { 126 inputs += [ invoker.env_file ] 127 } 128 129 if (defined(invoker.outputs)) { 130 outputs = invoker.outputs 131 } else { 132 stamp = true 133 } 134 } 135} 136