• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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