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