123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- # Copyright 2018 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- # Creates a group() that lists Python sources as |data|.
- # Having such targets serves two purposes:
- # 1) Causes files to be included in runtime_deps, so that they are uploaded to
- # swarming when running tests remotely.
- # 2) Causes "gn analyze" to know about all Python inputs so that tests will be
- # re-run when relevant Python files change.
- #
- # All non-trivial Python scripts should use a "pydeps" file to track their
- # sources. To create a .pydep file for a target in //example:
- #
- # build/print_python_deps.py \
- # --root example \
- # --output example/$target_name.pydeps \
- # path/to/your/script.py
- #
- # Keep the .pydep file up-to-date by adding to //PRESUBMIT.py under one of:
- # _ANDROID_SPECIFIC_PYDEPS_FILES, _GENERIC_PYDEPS_FILES
- #
- # Variables
- # pydeps_file: Path to .pydeps file to read sources from (optional).
- # data: Additional files to include in data. E.g. non-.py files needed by the
- # library, or .py files that are conditionally / lazily imported.
- #
- # Example
- # python_library("my_library_py") {
- # pydeps_file = "my_library.pydeps"
- # data = [ "foo.dat" ]
- # }
- template("python_library") {
- group(target_name) {
- forward_variables_from(invoker,
- [
- "data_deps",
- "deps",
- "testonly",
- "visibility",
- ])
- if (defined(invoker.pydeps_file)) {
- # Read and filter out comments.
- _pydeps_lines = read_file(invoker.pydeps_file, "list lines")
- _pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])
- # Dependencies are listed relative to the pydeps file directory, but data
- # parameter expects paths that are relative to the current BUILD.gn
- _script_dir = get_path_info(invoker.pydeps_file, "dir")
- _rebased_pydeps_entries = rebase_path(_pydeps_entries, ".", _script_dir)
- # Even though the .pydep file is not used at runtime, it must be added
- # so that "gn analyze" will mark the target as changed when .py files
- # are removed but none are added or modified.
- data = _rebased_pydeps_entries + [ invoker.pydeps_file ]
- } else {
- data = []
- }
- if (defined(invoker.data)) {
- data += invoker.data
- }
- }
- }
- # A template used for actions that execute a Python script, which has an
- # associated .pydeps file. In other words:
- #
- # - This is very similar to just an action(), except that |script| must point
- # to a Python script (e.g. "//build/.../foo.py") that has a corresponding
- # .pydeps file in the source tree (e.g. "//build/.../foo.pydeps").
- #
- # - The .pydeps file contains a list of python dependencies (imports really)
- # and is generated _manually_ by using a command like:
- #
- # build/print_python_deps.py --inplace build/android/gyp/foo.py
- #
- # Example
- # action_with_pydeps("create_foo") {
- # script = "myscript.py"
- # args = [...]
- # }
- template("action_with_pydeps") {
- action(target_name) {
- # Ensure that testonly and visibility are forwarded
- # explicitly, since this performs recursive scope lookups, which is
- # required to ensure their definition from scopes above the caller are
- # properly handled. All other variables are forwarded with "*", which
- # doesn't perform recursive lookups at all. See https://crbug.com/862232
- forward_variables_from(invoker,
- [
- "testonly",
- "visibility",
- ])
- forward_variables_from(invoker,
- "*",
- [
- "testonly",
- "visibility",
- ])
- # Read and filter out comments.
- # Happens every time the template is instantiated, but benchmarking shows no
- # perceivable impact on overall 'gn gen' speed.
- _pydeps_file = invoker.script + "deps"
- _pydeps_lines =
- read_file(_pydeps_file, "list lines") # https://crbug.com/1102058
- _pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])
- if (!defined(inputs)) {
- inputs = []
- }
- # Dependencies are listed relative to the script directory, but inputs
- # expects paths that are relative to the current BUILD.gn
- _script_dir = get_path_info(_pydeps_file, "dir")
- inputs += rebase_path(_pydeps_entries, ".", _script_dir)
- }
- }
- template("action_foreach_with_pydeps") {
- action_foreach(target_name) {
- # Ensure that testonly and visibility are forwarded
- # explicitly, since this performs recursive scope lookups, which is
- # required to ensure their definition from scopes above the caller are
- # properly handled. All other variables are forwarded with "*", which
- # doesn't perform recursive lookups at all. See https://crbug.com/862232
- forward_variables_from(invoker,
- [
- "testonly",
- "visibility",
- ])
- forward_variables_from(invoker,
- "*",
- [
- "testonly",
- "visibility",
- ])
- # Read and filter out comments.
- # Happens every time the template is instantiated, but benchmarking shows no
- # perceivable impact on overall 'gn gen' speed.
- if (defined(invoker.deps_file)) {
- _pydeps_file = invoker.deps_file
- } else {
- _pydeps_file = invoker.script + "deps"
- }
- _pydeps_lines = read_file(_pydeps_file, "list lines")
- _pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])
- if (!defined(inputs)) {
- inputs = []
- }
- # Dependencies are listed relative to the script directory, but inputs
- # expects paths that are relative to the current BUILD.gn
- _script_dir = get_path_info(script, "dir")
- inputs += rebase_path(_pydeps_entries, ".", _script_dir)
- }
- }
|