xref: /aosp_15_r20/external/angle/build/config/python.gni (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker# Copyright 2018 The Chromium Authors
2*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
3*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
4*8975f5c5SAndroid Build Coastguard Worker
5*8975f5c5SAndroid Build Coastguard Worker# Creates a group() that lists Python sources as |data|.
6*8975f5c5SAndroid Build Coastguard Worker# Having such targets serves two purposes:
7*8975f5c5SAndroid Build Coastguard Worker# 1) Causes files to be included in runtime_deps, so that they are uploaded to
8*8975f5c5SAndroid Build Coastguard Worker#    swarming when running tests remotely.
9*8975f5c5SAndroid Build Coastguard Worker# 2) Causes "gn analyze" to know about all Python inputs so that tests will be
10*8975f5c5SAndroid Build Coastguard Worker#    re-run when relevant Python files change.
11*8975f5c5SAndroid Build Coastguard Worker#
12*8975f5c5SAndroid Build Coastguard Worker# All non-trivial Python scripts should use a "pydeps" file to track their
13*8975f5c5SAndroid Build Coastguard Worker# sources. To create a .pydep file for a target in //example:
14*8975f5c5SAndroid Build Coastguard Worker#
15*8975f5c5SAndroid Build Coastguard Worker#   build/print_python_deps.py \
16*8975f5c5SAndroid Build Coastguard Worker#       --root example \
17*8975f5c5SAndroid Build Coastguard Worker#       --output example/$target_name.pydeps \
18*8975f5c5SAndroid Build Coastguard Worker#       path/to/your/script.py
19*8975f5c5SAndroid Build Coastguard Worker#
20*8975f5c5SAndroid Build Coastguard Worker# Keep the .pydep file up-to-date by adding to //PRESUBMIT.py under one of:
21*8975f5c5SAndroid Build Coastguard Worker#     _ANDROID_SPECIFIC_PYDEPS_FILES, _GENERIC_PYDEPS_FILES
22*8975f5c5SAndroid Build Coastguard Worker#
23*8975f5c5SAndroid Build Coastguard Worker# Variables
24*8975f5c5SAndroid Build Coastguard Worker#   pydeps_file: Path to .pydeps file to read sources from (optional).
25*8975f5c5SAndroid Build Coastguard Worker#   data: Additional files to include in data. E.g. non-.py files needed by the
26*8975f5c5SAndroid Build Coastguard Worker#         library, or .py files that are conditionally / lazily imported.
27*8975f5c5SAndroid Build Coastguard Worker#
28*8975f5c5SAndroid Build Coastguard Worker# Example
29*8975f5c5SAndroid Build Coastguard Worker#   python_library("my_library_py") {
30*8975f5c5SAndroid Build Coastguard Worker#      pydeps_file = "my_library.pydeps"
31*8975f5c5SAndroid Build Coastguard Worker#      data = [ "foo.dat" ]
32*8975f5c5SAndroid Build Coastguard Worker#   }
33*8975f5c5SAndroid Build Coastguard Workertemplate("python_library") {
34*8975f5c5SAndroid Build Coastguard Worker  group(target_name) {
35*8975f5c5SAndroid Build Coastguard Worker    forward_variables_from(invoker,
36*8975f5c5SAndroid Build Coastguard Worker                           [
37*8975f5c5SAndroid Build Coastguard Worker                             "data_deps",
38*8975f5c5SAndroid Build Coastguard Worker                             "deps",
39*8975f5c5SAndroid Build Coastguard Worker                             "testonly",
40*8975f5c5SAndroid Build Coastguard Worker                             "visibility",
41*8975f5c5SAndroid Build Coastguard Worker                           ])
42*8975f5c5SAndroid Build Coastguard Worker
43*8975f5c5SAndroid Build Coastguard Worker    if (defined(invoker.pydeps_file)) {
44*8975f5c5SAndroid Build Coastguard Worker      # Read and filter out comments.
45*8975f5c5SAndroid Build Coastguard Worker      _pydeps_lines = read_file(invoker.pydeps_file, "list lines")
46*8975f5c5SAndroid Build Coastguard Worker      _pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])
47*8975f5c5SAndroid Build Coastguard Worker
48*8975f5c5SAndroid Build Coastguard Worker      # Dependencies are listed relative to the pydeps file directory, but data
49*8975f5c5SAndroid Build Coastguard Worker      # parameter expects paths that are relative to the current BUILD.gn
50*8975f5c5SAndroid Build Coastguard Worker      _script_dir = get_path_info(invoker.pydeps_file, "dir")
51*8975f5c5SAndroid Build Coastguard Worker      _rebased_pydeps_entries = rebase_path(_pydeps_entries, ".", _script_dir)
52*8975f5c5SAndroid Build Coastguard Worker
53*8975f5c5SAndroid Build Coastguard Worker      # Even though the .pydep file is not used at runtime, it must be added
54*8975f5c5SAndroid Build Coastguard Worker      # so that "gn analyze" will mark the target as changed when .py files
55*8975f5c5SAndroid Build Coastguard Worker      # are removed but none are added or modified.
56*8975f5c5SAndroid Build Coastguard Worker      data = _rebased_pydeps_entries + [ invoker.pydeps_file ]
57*8975f5c5SAndroid Build Coastguard Worker    } else {
58*8975f5c5SAndroid Build Coastguard Worker      data = []
59*8975f5c5SAndroid Build Coastguard Worker    }
60*8975f5c5SAndroid Build Coastguard Worker    if (defined(invoker.data)) {
61*8975f5c5SAndroid Build Coastguard Worker      data += invoker.data
62*8975f5c5SAndroid Build Coastguard Worker    }
63*8975f5c5SAndroid Build Coastguard Worker  }
64*8975f5c5SAndroid Build Coastguard Worker}
65*8975f5c5SAndroid Build Coastguard Worker
66*8975f5c5SAndroid Build Coastguard Worker# A template used for actions that execute a Python script, which has an
67*8975f5c5SAndroid Build Coastguard Worker# associated .pydeps file. In other words:
68*8975f5c5SAndroid Build Coastguard Worker#
69*8975f5c5SAndroid Build Coastguard Worker# - This is very similar to just an action(), except that |script| must point
70*8975f5c5SAndroid Build Coastguard Worker#   to a Python script (e.g. "//build/.../foo.py") that has a corresponding
71*8975f5c5SAndroid Build Coastguard Worker#   .pydeps file in the source tree (e.g. "//build/.../foo.pydeps").
72*8975f5c5SAndroid Build Coastguard Worker#
73*8975f5c5SAndroid Build Coastguard Worker# - The .pydeps file contains a list of python dependencies (imports really)
74*8975f5c5SAndroid Build Coastguard Worker#   and is generated _manually_ by using a command like:
75*8975f5c5SAndroid Build Coastguard Worker#
76*8975f5c5SAndroid Build Coastguard Worker#     build/print_python_deps.py --inplace build/android/gyp/foo.py
77*8975f5c5SAndroid Build Coastguard Worker#
78*8975f5c5SAndroid Build Coastguard Worker# Example
79*8975f5c5SAndroid Build Coastguard Worker#   action_with_pydeps("create_foo") {
80*8975f5c5SAndroid Build Coastguard Worker#     script = "myscript.py"
81*8975f5c5SAndroid Build Coastguard Worker#     args = [...]
82*8975f5c5SAndroid Build Coastguard Worker#   }
83*8975f5c5SAndroid Build Coastguard Workertemplate("action_with_pydeps") {
84*8975f5c5SAndroid Build Coastguard Worker  action(target_name) {
85*8975f5c5SAndroid Build Coastguard Worker    # Ensure that testonly and visibility are forwarded
86*8975f5c5SAndroid Build Coastguard Worker    # explicitly, since this performs recursive scope lookups, which is
87*8975f5c5SAndroid Build Coastguard Worker    # required to ensure their definition from scopes above the caller are
88*8975f5c5SAndroid Build Coastguard Worker    # properly handled. All other variables are forwarded with "*", which
89*8975f5c5SAndroid Build Coastguard Worker    # doesn't perform recursive lookups at all. See https://crbug.com/862232
90*8975f5c5SAndroid Build Coastguard Worker    forward_variables_from(invoker,
91*8975f5c5SAndroid Build Coastguard Worker                           [
92*8975f5c5SAndroid Build Coastguard Worker                             "testonly",
93*8975f5c5SAndroid Build Coastguard Worker                             "visibility",
94*8975f5c5SAndroid Build Coastguard Worker                           ])
95*8975f5c5SAndroid Build Coastguard Worker    forward_variables_from(invoker,
96*8975f5c5SAndroid Build Coastguard Worker                           "*",
97*8975f5c5SAndroid Build Coastguard Worker                           [
98*8975f5c5SAndroid Build Coastguard Worker                             "testonly",
99*8975f5c5SAndroid Build Coastguard Worker                             "visibility",
100*8975f5c5SAndroid Build Coastguard Worker                           ])
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker    # Read and filter out comments.
103*8975f5c5SAndroid Build Coastguard Worker    # Happens every time the template is instantiated, but benchmarking shows no
104*8975f5c5SAndroid Build Coastguard Worker    # perceivable impact on overall 'gn gen' speed.
105*8975f5c5SAndroid Build Coastguard Worker    _pydeps_file = invoker.script + "deps"
106*8975f5c5SAndroid Build Coastguard Worker
107*8975f5c5SAndroid Build Coastguard Worker    _pydeps_lines =
108*8975f5c5SAndroid Build Coastguard Worker        read_file(_pydeps_file, "list lines")  # https://crbug.com/1102058
109*8975f5c5SAndroid Build Coastguard Worker    _pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])
110*8975f5c5SAndroid Build Coastguard Worker
111*8975f5c5SAndroid Build Coastguard Worker    if (!defined(inputs)) {
112*8975f5c5SAndroid Build Coastguard Worker      inputs = []
113*8975f5c5SAndroid Build Coastguard Worker    }
114*8975f5c5SAndroid Build Coastguard Worker
115*8975f5c5SAndroid Build Coastguard Worker    # Dependencies are listed relative to the script directory, but inputs
116*8975f5c5SAndroid Build Coastguard Worker    # expects paths that are relative to the current BUILD.gn
117*8975f5c5SAndroid Build Coastguard Worker    _script_dir = get_path_info(_pydeps_file, "dir")
118*8975f5c5SAndroid Build Coastguard Worker    inputs += rebase_path(_pydeps_entries, ".", _script_dir)
119*8975f5c5SAndroid Build Coastguard Worker  }
120*8975f5c5SAndroid Build Coastguard Worker}
121*8975f5c5SAndroid Build Coastguard Worker
122*8975f5c5SAndroid Build Coastguard Workertemplate("action_foreach_with_pydeps") {
123*8975f5c5SAndroid Build Coastguard Worker  action_foreach(target_name) {
124*8975f5c5SAndroid Build Coastguard Worker    # Ensure that testonly and visibility are forwarded
125*8975f5c5SAndroid Build Coastguard Worker    # explicitly, since this performs recursive scope lookups, which is
126*8975f5c5SAndroid Build Coastguard Worker    # required to ensure their definition from scopes above the caller are
127*8975f5c5SAndroid Build Coastguard Worker    # properly handled. All other variables are forwarded with "*", which
128*8975f5c5SAndroid Build Coastguard Worker    # doesn't perform recursive lookups at all. See https://crbug.com/862232
129*8975f5c5SAndroid Build Coastguard Worker    forward_variables_from(invoker,
130*8975f5c5SAndroid Build Coastguard Worker                           [
131*8975f5c5SAndroid Build Coastguard Worker                             "testonly",
132*8975f5c5SAndroid Build Coastguard Worker                             "visibility",
133*8975f5c5SAndroid Build Coastguard Worker                           ])
134*8975f5c5SAndroid Build Coastguard Worker    forward_variables_from(invoker,
135*8975f5c5SAndroid Build Coastguard Worker                           "*",
136*8975f5c5SAndroid Build Coastguard Worker                           [
137*8975f5c5SAndroid Build Coastguard Worker                             "testonly",
138*8975f5c5SAndroid Build Coastguard Worker                             "visibility",
139*8975f5c5SAndroid Build Coastguard Worker                           ])
140*8975f5c5SAndroid Build Coastguard Worker
141*8975f5c5SAndroid Build Coastguard Worker    # Read and filter out comments.
142*8975f5c5SAndroid Build Coastguard Worker    # Happens every time the template is instantiated, but benchmarking shows no
143*8975f5c5SAndroid Build Coastguard Worker    # perceivable impact on overall 'gn gen' speed.
144*8975f5c5SAndroid Build Coastguard Worker    if (defined(invoker.deps_file)) {
145*8975f5c5SAndroid Build Coastguard Worker      _pydeps_file = invoker.deps_file
146*8975f5c5SAndroid Build Coastguard Worker    } else {
147*8975f5c5SAndroid Build Coastguard Worker      _pydeps_file = invoker.script + "deps"
148*8975f5c5SAndroid Build Coastguard Worker    }
149*8975f5c5SAndroid Build Coastguard Worker    _pydeps_lines = read_file(_pydeps_file, "list lines")
150*8975f5c5SAndroid Build Coastguard Worker    _pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])
151*8975f5c5SAndroid Build Coastguard Worker
152*8975f5c5SAndroid Build Coastguard Worker    if (!defined(inputs)) {
153*8975f5c5SAndroid Build Coastguard Worker      inputs = []
154*8975f5c5SAndroid Build Coastguard Worker    }
155*8975f5c5SAndroid Build Coastguard Worker
156*8975f5c5SAndroid Build Coastguard Worker    # Dependencies are listed relative to the script directory, but inputs
157*8975f5c5SAndroid Build Coastguard Worker    # expects paths that are relative to the current BUILD.gn
158*8975f5c5SAndroid Build Coastguard Worker    _script_dir = get_path_info(script, "dir")
159*8975f5c5SAndroid Build Coastguard Worker    inputs += rebase_path(_pydeps_entries, ".", _script_dir)
160*8975f5c5SAndroid Build Coastguard Worker  }
161*8975f5c5SAndroid Build Coastguard Worker}
162