1*61c4878aSAndroid Build Coastguard Worker# Copyright 2022 The Pigweed Authors 2*61c4878aSAndroid Build Coastguard Worker# 3*61c4878aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4*61c4878aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of 5*61c4878aSAndroid Build Coastguard Worker# the License at 6*61c4878aSAndroid Build Coastguard Worker# 7*61c4878aSAndroid Build Coastguard Worker# https://www.apache.org/licenses/LICENSE-2.0 8*61c4878aSAndroid Build Coastguard Worker# 9*61c4878aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*61c4878aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11*61c4878aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12*61c4878aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under 13*61c4878aSAndroid Build Coastguard Worker# the License. 14*61c4878aSAndroid Build Coastguard Worker 15*61c4878aSAndroid Build Coastguard Workerimport("//build_overrides/pigweed.gni") 16*61c4878aSAndroid Build Coastguard Worker 17*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_build/python.gni") 18*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_build/python_action.gni") 19*61c4878aSAndroid Build Coastguard Worker 20*61c4878aSAndroid Build Coastguard Worker# Defines and creates a Python virtualenv. This template is used by Pigweed in 21*61c4878aSAndroid Build Coastguard Worker# https://cs.pigweed.dev/pigweed/+/main:pw_env_setup/BUILD.gn to 22*61c4878aSAndroid Build Coastguard Worker# create a virtualenv for use within the GN build that all Python actions will 23*61c4878aSAndroid Build Coastguard Worker# run in. 24*61c4878aSAndroid Build Coastguard Worker# 25*61c4878aSAndroid Build Coastguard Worker# Example: 26*61c4878aSAndroid Build Coastguard Worker# 27*61c4878aSAndroid Build Coastguard Worker# pw_python_venv("test_venv") { 28*61c4878aSAndroid Build Coastguard Worker# path = "test-venv" 29*61c4878aSAndroid Build Coastguard Worker# constraints = [ "//tools/constraints.list" ] 30*61c4878aSAndroid Build Coastguard Worker# requirements = [ "//tools/requirements.txt" ] 31*61c4878aSAndroid Build Coastguard Worker# source_packages = [ 32*61c4878aSAndroid Build Coastguard Worker# "$dir_pw_cli/py", 33*61c4878aSAndroid Build Coastguard Worker# "$dir_pw_console/py", 34*61c4878aSAndroid Build Coastguard Worker# "//tools:another_pw_python_package", 35*61c4878aSAndroid Build Coastguard Worker# ] 36*61c4878aSAndroid Build Coastguard Worker# } 37*61c4878aSAndroid Build Coastguard Worker# 38*61c4878aSAndroid Build Coastguard Worker# Args: 39*61c4878aSAndroid Build Coastguard Worker# path: The directory where the virtualenv will be created. This is relative 40*61c4878aSAndroid Build Coastguard Worker# to the GN root and must begin with "$root_build_dir/" if it lives in the 41*61c4878aSAndroid Build Coastguard Worker# output directory or "//" if it lives in elsewhere. 42*61c4878aSAndroid Build Coastguard Worker# 43*61c4878aSAndroid Build Coastguard Worker# constraints: A list of constraint files used when performing pip install 44*61c4878aSAndroid Build Coastguard Worker# into this virtualenv. By default this is set to pw_build_PIP_CONSTRAINTS 45*61c4878aSAndroid Build Coastguard Worker# 46*61c4878aSAndroid Build Coastguard Worker# requirements: A list of requirements files to install into this virtualenv 47*61c4878aSAndroid Build Coastguard Worker# on creation. By default this is set to pw_build_PIP_REQUIREMENTS 48*61c4878aSAndroid Build Coastguard Worker# 49*61c4878aSAndroid Build Coastguard Worker# pip_generate_hashes: (Default: false) Use --generate-hashes When 50*61c4878aSAndroid Build Coastguard Worker# running pip-compile to compute the final requirements.txt 51*61c4878aSAndroid Build Coastguard Worker# 52*61c4878aSAndroid Build Coastguard Worker# source_packages: A list of in-tree pw_python_package targets that will be 53*61c4878aSAndroid Build Coastguard Worker# checked for external third_party pip dependencies to install into this 54*61c4878aSAndroid Build Coastguard Worker# virtualenv. Note this list of targets isn't actually installed into the 55*61c4878aSAndroid Build Coastguard Worker# virtualenv. Only packages defined inside the [options] install_requires 56*61c4878aSAndroid Build Coastguard Worker# section of each pw_python_package's setup.cfg will be pip installed. See 57*61c4878aSAndroid Build Coastguard Worker# this page for a setup.cfg example: 58*61c4878aSAndroid Build Coastguard Worker# https://setuptools.pypa.io/en/latest/userguide/declarative_config.html 59*61c4878aSAndroid Build Coastguard Worker# 60*61c4878aSAndroid Build Coastguard Worker# output_logs: (Default: true) Commands will output logs. 61*61c4878aSAndroid Build Coastguard Worker# 62*61c4878aSAndroid Build Coastguard Workertemplate("pw_python_venv") { 63*61c4878aSAndroid Build Coastguard Worker assert(defined(invoker.path), "pw_python_venv requires a 'path'") 64*61c4878aSAndroid Build Coastguard Worker 65*61c4878aSAndroid Build Coastguard Worker _path = invoker.path 66*61c4878aSAndroid Build Coastguard Worker 67*61c4878aSAndroid Build Coastguard Worker _generated_requirements_file = 68*61c4878aSAndroid Build Coastguard Worker "$target_gen_dir/$target_name/generated_requirements.txt" 69*61c4878aSAndroid Build Coastguard Worker 70*61c4878aSAndroid Build Coastguard Worker _compiled_requirements_file = 71*61c4878aSAndroid Build Coastguard Worker "$target_gen_dir/$target_name/compiled_requirements.txt" 72*61c4878aSAndroid Build Coastguard Worker 73*61c4878aSAndroid Build Coastguard Worker _source_packages = [] 74*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.source_packages)) { 75*61c4878aSAndroid Build Coastguard Worker _source_packages += invoker.source_packages 76*61c4878aSAndroid Build Coastguard Worker } else { 77*61c4878aSAndroid Build Coastguard Worker not_needed([ 78*61c4878aSAndroid Build Coastguard Worker "_source_packages", 79*61c4878aSAndroid Build Coastguard Worker "_generated_requirements_file", 80*61c4878aSAndroid Build Coastguard Worker ]) 81*61c4878aSAndroid Build Coastguard Worker } 82*61c4878aSAndroid Build Coastguard Worker _output_logs = true 83*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.output_logs)) { 84*61c4878aSAndroid Build Coastguard Worker _output_logs = invoker.output_logs 85*61c4878aSAndroid Build Coastguard Worker } 86*61c4878aSAndroid Build Coastguard Worker if (!defined(invoker.output_logs) || 87*61c4878aSAndroid Build Coastguard Worker current_toolchain != pw_build_PYTHON_TOOLCHAIN) { 88*61c4878aSAndroid Build Coastguard Worker not_needed([ "_output_logs" ]) 89*61c4878aSAndroid Build Coastguard Worker } 90*61c4878aSAndroid Build Coastguard Worker 91*61c4878aSAndroid Build Coastguard Worker _source_package_labels = [] 92*61c4878aSAndroid Build Coastguard Worker foreach(pkg, _source_packages) { 93*61c4878aSAndroid Build Coastguard Worker _source_package_labels += [ get_label_info(pkg, "label_no_toolchain") ] 94*61c4878aSAndroid Build Coastguard Worker } 95*61c4878aSAndroid Build Coastguard Worker 96*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.requirements)) { 97*61c4878aSAndroid Build Coastguard Worker _requirements = invoker.requirements 98*61c4878aSAndroid Build Coastguard Worker } else { 99*61c4878aSAndroid Build Coastguard Worker _requirements = pw_build_PIP_REQUIREMENTS 100*61c4878aSAndroid Build Coastguard Worker } 101*61c4878aSAndroid Build Coastguard Worker 102*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.constraints)) { 103*61c4878aSAndroid Build Coastguard Worker _constraints = invoker.constraints 104*61c4878aSAndroid Build Coastguard Worker } else { 105*61c4878aSAndroid Build Coastguard Worker _constraints = pw_build_PIP_CONSTRAINTS 106*61c4878aSAndroid Build Coastguard Worker } 107*61c4878aSAndroid Build Coastguard Worker 108*61c4878aSAndroid Build Coastguard Worker _python_interpreter = _path + "/bin/python" 109*61c4878aSAndroid Build Coastguard Worker if (host_os == "win") { 110*61c4878aSAndroid Build Coastguard Worker _python_interpreter = _path + "/Scripts/python.exe" 111*61c4878aSAndroid Build Coastguard Worker } 112*61c4878aSAndroid Build Coastguard Worker 113*61c4878aSAndroid Build Coastguard Worker _venv_metadata_json_file = "$target_gen_dir/$target_name/venv_metadata.json" 114*61c4878aSAndroid Build Coastguard Worker _venv_metadata = { 115*61c4878aSAndroid Build Coastguard Worker gn_target_name = 116*61c4878aSAndroid Build Coastguard Worker get_label_info(":${invoker.target_name}", "label_no_toolchain") 117*61c4878aSAndroid Build Coastguard Worker path = rebase_path(_path, root_build_dir) 118*61c4878aSAndroid Build Coastguard Worker generated_requirements = 119*61c4878aSAndroid Build Coastguard Worker rebase_path(_generated_requirements_file, root_build_dir) 120*61c4878aSAndroid Build Coastguard Worker compiled_requirements = 121*61c4878aSAndroid Build Coastguard Worker rebase_path(_compiled_requirements_file, root_build_dir) 122*61c4878aSAndroid Build Coastguard Worker requirements = rebase_path(_requirements, root_build_dir) 123*61c4878aSAndroid Build Coastguard Worker constraints = rebase_path(_constraints, root_build_dir) 124*61c4878aSAndroid Build Coastguard Worker interpreter = rebase_path(_python_interpreter, root_build_dir) 125*61c4878aSAndroid Build Coastguard Worker source_packages = _source_package_labels 126*61c4878aSAndroid Build Coastguard Worker } 127*61c4878aSAndroid Build Coastguard Worker write_file(_venv_metadata_json_file, _venv_metadata, "json") 128*61c4878aSAndroid Build Coastguard Worker 129*61c4878aSAndroid Build Coastguard Worker pw_python_action("${target_name}._create_virtualenv") { 130*61c4878aSAndroid Build Coastguard Worker _pw_internal_run_in_venv = false 131*61c4878aSAndroid Build Coastguard Worker 132*61c4878aSAndroid Build Coastguard Worker # Note: The if the venv isn't in the out dir then we can't declare 133*61c4878aSAndroid Build Coastguard Worker # outputs and must stamp instead. 134*61c4878aSAndroid Build Coastguard Worker stamp = true 135*61c4878aSAndroid Build Coastguard Worker 136*61c4878aSAndroid Build Coastguard Worker # The virtualenv should depend on the version of Python currently in use. 137*61c4878aSAndroid Build Coastguard Worker stampfile = "$target_gen_dir/$target_name.pw_pystamp" 138*61c4878aSAndroid Build Coastguard Worker depfile = "$target_gen_dir/$target_name.d" 139*61c4878aSAndroid Build Coastguard Worker script = "$dir_pw_build/py/pw_build/create_gn_venv.py" 140*61c4878aSAndroid Build Coastguard Worker args = [ 141*61c4878aSAndroid Build Coastguard Worker "--depfile", 142*61c4878aSAndroid Build Coastguard Worker rebase_path(depfile, root_build_dir), 143*61c4878aSAndroid Build Coastguard Worker "--destination-dir", 144*61c4878aSAndroid Build Coastguard Worker rebase_path(_path, root_build_dir), 145*61c4878aSAndroid Build Coastguard Worker "--stampfile", 146*61c4878aSAndroid Build Coastguard Worker rebase_path(stampfile, root_build_dir), 147*61c4878aSAndroid Build Coastguard Worker ] 148*61c4878aSAndroid Build Coastguard Worker } 149*61c4878aSAndroid Build Coastguard Worker 150*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.source_packages) && 151*61c4878aSAndroid Build Coastguard Worker current_toolchain == pw_build_PYTHON_TOOLCHAIN) { 152*61c4878aSAndroid Build Coastguard Worker pw_python_action("${target_name}._generate_3p_requirements") { 153*61c4878aSAndroid Build Coastguard Worker inputs = _requirements + _constraints 154*61c4878aSAndroid Build Coastguard Worker 155*61c4878aSAndroid Build Coastguard Worker _pw_internal_run_in_venv = false 156*61c4878aSAndroid Build Coastguard Worker _forward_python_metadata_deps = true 157*61c4878aSAndroid Build Coastguard Worker 158*61c4878aSAndroid Build Coastguard Worker script = "$dir_pw_build/py/pw_build/generate_python_requirements.py" 159*61c4878aSAndroid Build Coastguard Worker 160*61c4878aSAndroid Build Coastguard Worker _pkg_gn_labels = [] 161*61c4878aSAndroid Build Coastguard Worker foreach(pkg, _source_packages) { 162*61c4878aSAndroid Build Coastguard Worker _pkg_gn_labels += [ get_label_info(pkg, "label_no_toolchain") + 163*61c4878aSAndroid Build Coastguard Worker "($pw_build_PYTHON_TOOLCHAIN)" ] 164*61c4878aSAndroid Build Coastguard Worker } 165*61c4878aSAndroid Build Coastguard Worker 166*61c4878aSAndroid Build Coastguard Worker # Add target packages to the python_metadata_deps. This will let 167*61c4878aSAndroid Build Coastguard Worker # GN expand the transitive pw_python_package deps which are read 168*61c4878aSAndroid Build Coastguard Worker # by generate_python_requirements.py 169*61c4878aSAndroid Build Coastguard Worker python_metadata_deps = _pkg_gn_labels 170*61c4878aSAndroid Build Coastguard Worker 171*61c4878aSAndroid Build Coastguard Worker args = [ 172*61c4878aSAndroid Build Coastguard Worker "--gn-root-build-dir", 173*61c4878aSAndroid Build Coastguard Worker rebase_path(root_build_dir, root_build_dir), 174*61c4878aSAndroid Build Coastguard Worker "--output-requirement-file", 175*61c4878aSAndroid Build Coastguard Worker rebase_path(_generated_requirements_file, root_build_dir), 176*61c4878aSAndroid Build Coastguard Worker ] 177*61c4878aSAndroid Build Coastguard Worker 178*61c4878aSAndroid Build Coastguard Worker if (_constraints != []) { 179*61c4878aSAndroid Build Coastguard Worker args += [ "--constraint-files" ] 180*61c4878aSAndroid Build Coastguard Worker } 181*61c4878aSAndroid Build Coastguard Worker foreach(_constraints_file, _constraints) { 182*61c4878aSAndroid Build Coastguard Worker args += [ rebase_path(_constraints_file, root_build_dir) ] 183*61c4878aSAndroid Build Coastguard Worker } 184*61c4878aSAndroid Build Coastguard Worker 185*61c4878aSAndroid Build Coastguard Worker args += [ 186*61c4878aSAndroid Build Coastguard Worker "--gn-packages", 187*61c4878aSAndroid Build Coastguard Worker string_join(",", _pkg_gn_labels), 188*61c4878aSAndroid Build Coastguard Worker ] 189*61c4878aSAndroid Build Coastguard Worker 190*61c4878aSAndroid Build Coastguard Worker outputs = [ _generated_requirements_file ] 191*61c4878aSAndroid Build Coastguard Worker deps = [ ":${invoker.target_name}._create_virtualenv($pw_build_PYTHON_TOOLCHAIN)" ] 192*61c4878aSAndroid Build Coastguard Worker } 193*61c4878aSAndroid Build Coastguard Worker } else { 194*61c4878aSAndroid Build Coastguard Worker group("${target_name}._generate_3p_requirements") { 195*61c4878aSAndroid Build Coastguard Worker } 196*61c4878aSAndroid Build Coastguard Worker } 197*61c4878aSAndroid Build Coastguard Worker 198*61c4878aSAndroid Build Coastguard Worker _pip_generate_hashes = false 199*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.pip_generate_hashes)) { 200*61c4878aSAndroid Build Coastguard Worker _pip_generate_hashes = invoker.pip_generate_hashes 201*61c4878aSAndroid Build Coastguard Worker } else { 202*61c4878aSAndroid Build Coastguard Worker not_needed([ "_pip_generate_hashes" ]) 203*61c4878aSAndroid Build Coastguard Worker } 204*61c4878aSAndroid Build Coastguard Worker 205*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.source_packages) || defined(invoker.requirements)) { 206*61c4878aSAndroid Build Coastguard Worker if (current_toolchain == pw_build_PYTHON_TOOLCHAIN) { 207*61c4878aSAndroid Build Coastguard Worker # Compile requirements with hashes 208*61c4878aSAndroid Build Coastguard Worker pw_python_action("${target_name}._compile_requirements") { 209*61c4878aSAndroid Build Coastguard Worker module = "piptools" 210*61c4878aSAndroid Build Coastguard Worker 211*61c4878aSAndroid Build Coastguard Worker # Set the venv to run this pip install in. 212*61c4878aSAndroid Build Coastguard Worker _pw_internal_run_in_venv = true 213*61c4878aSAndroid Build Coastguard Worker _skip_installing_external_python_deps = true 214*61c4878aSAndroid Build Coastguard Worker venv = get_label_info(":${invoker.target_name}", "label_no_toolchain") 215*61c4878aSAndroid Build Coastguard Worker 216*61c4878aSAndroid Build Coastguard Worker _pip_args = [] 217*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_INSTALL_OFFLINE) { 218*61c4878aSAndroid Build Coastguard Worker _pip_args += [ "--no-index" ] 219*61c4878aSAndroid Build Coastguard Worker } 220*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_INSTALL_DISABLE_CACHE) { 221*61c4878aSAndroid Build Coastguard Worker _pip_args += [ "--no-cache-dir" ] 222*61c4878aSAndroid Build Coastguard Worker } 223*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_INSTALL_FIND_LINKS != []) { 224*61c4878aSAndroid Build Coastguard Worker foreach(link_dir, pw_build_PYTHON_PIP_INSTALL_FIND_LINKS) { 225*61c4878aSAndroid Build Coastguard Worker _pip_args += 226*61c4878aSAndroid Build Coastguard Worker [ "--find-links=" + rebase_path(link_dir, root_build_dir) ] 227*61c4878aSAndroid Build Coastguard Worker } 228*61c4878aSAndroid Build Coastguard Worker } 229*61c4878aSAndroid Build Coastguard Worker 230*61c4878aSAndroid Build Coastguard Worker args = [ "compile" ] 231*61c4878aSAndroid Build Coastguard Worker 232*61c4878aSAndroid Build Coastguard Worker if (_pip_generate_hashes) { 233*61c4878aSAndroid Build Coastguard Worker args += [ 234*61c4878aSAndroid Build Coastguard Worker "--generate-hashes", 235*61c4878aSAndroid Build Coastguard Worker "--reuse-hashes", 236*61c4878aSAndroid Build Coastguard Worker ] 237*61c4878aSAndroid Build Coastguard Worker } 238*61c4878aSAndroid Build Coastguard Worker 239*61c4878aSAndroid Build Coastguard Worker args += [ 240*61c4878aSAndroid Build Coastguard Worker "--resolver=backtracking", 241*61c4878aSAndroid Build Coastguard Worker 242*61c4878aSAndroid Build Coastguard Worker # --allow-unsafe will force pinning pip and setuptools. 243*61c4878aSAndroid Build Coastguard Worker "--allow-unsafe", 244*61c4878aSAndroid Build Coastguard Worker "--output-file", 245*61c4878aSAndroid Build Coastguard Worker rebase_path(_compiled_requirements_file, root_build_dir), 246*61c4878aSAndroid Build Coastguard Worker 247*61c4878aSAndroid Build Coastguard Worker # Input requirements file: 248*61c4878aSAndroid Build Coastguard Worker rebase_path(_generated_requirements_file, root_build_dir), 249*61c4878aSAndroid Build Coastguard Worker ] 250*61c4878aSAndroid Build Coastguard Worker 251*61c4878aSAndroid Build Coastguard Worker # Pass offline related pip args through the pip-compile command. 252*61c4878aSAndroid Build Coastguard Worker if (_pip_args != []) { 253*61c4878aSAndroid Build Coastguard Worker args += [ 254*61c4878aSAndroid Build Coastguard Worker "--pip-args", 255*61c4878aSAndroid Build Coastguard Worker string_join(" ", _pip_args), 256*61c4878aSAndroid Build Coastguard Worker ] 257*61c4878aSAndroid Build Coastguard Worker } 258*61c4878aSAndroid Build Coastguard Worker 259*61c4878aSAndroid Build Coastguard Worker # Extra requirements files 260*61c4878aSAndroid Build Coastguard Worker foreach(_requirements_file, _requirements) { 261*61c4878aSAndroid Build Coastguard Worker args += [ rebase_path(_requirements_file, root_build_dir) ] 262*61c4878aSAndroid Build Coastguard Worker } 263*61c4878aSAndroid Build Coastguard Worker 264*61c4878aSAndroid Build Coastguard Worker inputs = [] 265*61c4878aSAndroid Build Coastguard Worker 266*61c4878aSAndroid Build Coastguard Worker # NOTE: constraint files are included in the content of the 267*61c4878aSAndroid Build Coastguard Worker # _generated_requirements_file. This occurs in the 268*61c4878aSAndroid Build Coastguard Worker # ._generate_3p_requirements target. 269*61c4878aSAndroid Build Coastguard Worker inputs += _constraints 270*61c4878aSAndroid Build Coastguard Worker inputs += _requirements 271*61c4878aSAndroid Build Coastguard Worker inputs += [ _generated_requirements_file ] 272*61c4878aSAndroid Build Coastguard Worker 273*61c4878aSAndroid Build Coastguard Worker deps = [ 274*61c4878aSAndroid Build Coastguard Worker ":${invoker.target_name}._generate_3p_requirements($pw_build_PYTHON_TOOLCHAIN)", 275*61c4878aSAndroid Build Coastguard Worker ":${invoker.target_name}._install_base_3p_deps($pw_build_PYTHON_TOOLCHAIN)", 276*61c4878aSAndroid Build Coastguard Worker ] 277*61c4878aSAndroid Build Coastguard Worker outputs = [ _compiled_requirements_file ] 278*61c4878aSAndroid Build Coastguard Worker } 279*61c4878aSAndroid Build Coastguard Worker 280*61c4878aSAndroid Build Coastguard Worker # This target will run 'pip install' in the venv to provide base 281*61c4878aSAndroid Build Coastguard Worker # dependencies needed to run piptools commands. That is required for the 282*61c4878aSAndroid Build Coastguard Worker # _compile_requirements sub target. 283*61c4878aSAndroid Build Coastguard Worker pw_python_action("${target_name}._install_base_3p_deps") { 284*61c4878aSAndroid Build Coastguard Worker module = "pip" 285*61c4878aSAndroid Build Coastguard Worker 286*61c4878aSAndroid Build Coastguard Worker # Set the venv to run this pip install in. 287*61c4878aSAndroid Build Coastguard Worker _pw_internal_run_in_venv = true 288*61c4878aSAndroid Build Coastguard Worker _skip_installing_external_python_deps = true 289*61c4878aSAndroid Build Coastguard Worker venv = get_label_info(":${invoker.target_name}", "label_no_toolchain") 290*61c4878aSAndroid Build Coastguard Worker 291*61c4878aSAndroid Build Coastguard Worker _base_requirement_file = "$dir_pw_env_setup/py/pw_env_setup/virtualenv_setup/python_base_requirements.txt" 292*61c4878aSAndroid Build Coastguard Worker 293*61c4878aSAndroid Build Coastguard Worker args = [ 294*61c4878aSAndroid Build Coastguard Worker "install", 295*61c4878aSAndroid Build Coastguard Worker "--requirement", 296*61c4878aSAndroid Build Coastguard Worker rebase_path(_base_requirement_file, root_build_dir), 297*61c4878aSAndroid Build Coastguard Worker ] 298*61c4878aSAndroid Build Coastguard Worker if (_output_logs) { 299*61c4878aSAndroid Build Coastguard Worker _pip_install_log_file = 300*61c4878aSAndroid Build Coastguard Worker "$target_gen_dir/$target_name/pip_install_log.txt" 301*61c4878aSAndroid Build Coastguard Worker args += [ 302*61c4878aSAndroid Build Coastguard Worker "--log", 303*61c4878aSAndroid Build Coastguard Worker rebase_path(_pip_install_log_file, root_build_dir), 304*61c4878aSAndroid Build Coastguard Worker ] 305*61c4878aSAndroid Build Coastguard Worker outputs = [ _pip_install_log_file ] 306*61c4878aSAndroid Build Coastguard Worker } 307*61c4878aSAndroid Build Coastguard Worker 308*61c4878aSAndroid Build Coastguard Worker # NOTE: Constraints should be ignored for this step. 309*61c4878aSAndroid Build Coastguard Worker 310*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_INSTALL_OFFLINE) { 311*61c4878aSAndroid Build Coastguard Worker args += [ "--no-index" ] 312*61c4878aSAndroid Build Coastguard Worker } 313*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_INSTALL_DISABLE_CACHE) { 314*61c4878aSAndroid Build Coastguard Worker args += [ "--no-cache-dir" ] 315*61c4878aSAndroid Build Coastguard Worker } 316*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_INSTALL_FIND_LINKS != []) { 317*61c4878aSAndroid Build Coastguard Worker foreach(link_dir, pw_build_PYTHON_PIP_INSTALL_FIND_LINKS) { 318*61c4878aSAndroid Build Coastguard Worker args += [ 319*61c4878aSAndroid Build Coastguard Worker "--find-links", 320*61c4878aSAndroid Build Coastguard Worker rebase_path(link_dir, root_build_dir), 321*61c4878aSAndroid Build Coastguard Worker ] 322*61c4878aSAndroid Build Coastguard Worker } 323*61c4878aSAndroid Build Coastguard Worker } 324*61c4878aSAndroid Build Coastguard Worker 325*61c4878aSAndroid Build Coastguard Worker deps = [ ":${invoker.target_name}._create_virtualenv($pw_build_PYTHON_TOOLCHAIN)" ] 326*61c4878aSAndroid Build Coastguard Worker stamp = true 327*61c4878aSAndroid Build Coastguard Worker pool = "$dir_pw_build/pool:pip($default_toolchain)" 328*61c4878aSAndroid Build Coastguard Worker } 329*61c4878aSAndroid Build Coastguard Worker 330*61c4878aSAndroid Build Coastguard Worker # Install all 3rd party Python dependencies. 331*61c4878aSAndroid Build Coastguard Worker pw_python_action("${target_name}._install_3p_deps") { 332*61c4878aSAndroid Build Coastguard Worker module = "pip" 333*61c4878aSAndroid Build Coastguard Worker 334*61c4878aSAndroid Build Coastguard Worker # Set the venv to run this pip install in. 335*61c4878aSAndroid Build Coastguard Worker _pw_internal_run_in_venv = true 336*61c4878aSAndroid Build Coastguard Worker _skip_installing_external_python_deps = true 337*61c4878aSAndroid Build Coastguard Worker venv = get_label_info(":${invoker.target_name}", "label_no_toolchain") 338*61c4878aSAndroid Build Coastguard Worker 339*61c4878aSAndroid Build Coastguard Worker args = pw_build_PYTHON_PIP_DEFAULT_OPTIONS 340*61c4878aSAndroid Build Coastguard Worker args += [ 341*61c4878aSAndroid Build Coastguard Worker "install", 342*61c4878aSAndroid Build Coastguard Worker "--upgrade", 343*61c4878aSAndroid Build Coastguard Worker ] 344*61c4878aSAndroid Build Coastguard Worker 345*61c4878aSAndroid Build Coastguard Worker if (_output_logs) { 346*61c4878aSAndroid Build Coastguard Worker _pip_install_log_file = 347*61c4878aSAndroid Build Coastguard Worker "$target_gen_dir/$target_name/pip_install_log.txt" 348*61c4878aSAndroid Build Coastguard Worker args += [ 349*61c4878aSAndroid Build Coastguard Worker "--log", 350*61c4878aSAndroid Build Coastguard Worker rebase_path(_pip_install_log_file, root_build_dir), 351*61c4878aSAndroid Build Coastguard Worker ] 352*61c4878aSAndroid Build Coastguard Worker } 353*61c4878aSAndroid Build Coastguard Worker 354*61c4878aSAndroid Build Coastguard Worker if (_pip_generate_hashes) { 355*61c4878aSAndroid Build Coastguard Worker args += [ "--require-hashes" ] 356*61c4878aSAndroid Build Coastguard Worker } 357*61c4878aSAndroid Build Coastguard Worker 358*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_INSTALL_OFFLINE) { 359*61c4878aSAndroid Build Coastguard Worker args += [ "--no-index" ] 360*61c4878aSAndroid Build Coastguard Worker } 361*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_INSTALL_DISABLE_CACHE) { 362*61c4878aSAndroid Build Coastguard Worker args += [ "--no-cache-dir" ] 363*61c4878aSAndroid Build Coastguard Worker } 364*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_INSTALL_FIND_LINKS != []) { 365*61c4878aSAndroid Build Coastguard Worker foreach(link_dir, pw_build_PYTHON_PIP_INSTALL_FIND_LINKS) { 366*61c4878aSAndroid Build Coastguard Worker args += [ 367*61c4878aSAndroid Build Coastguard Worker "--find-links", 368*61c4878aSAndroid Build Coastguard Worker rebase_path(link_dir, root_build_dir), 369*61c4878aSAndroid Build Coastguard Worker ] 370*61c4878aSAndroid Build Coastguard Worker } 371*61c4878aSAndroid Build Coastguard Worker } 372*61c4878aSAndroid Build Coastguard Worker 373*61c4878aSAndroid Build Coastguard Worker # Note: --no-build-isolation should be avoided for installing 3rd party 374*61c4878aSAndroid Build Coastguard Worker # Python packages that use C/C++ extension modules. 375*61c4878aSAndroid Build Coastguard Worker # https://setuptools.pypa.io/en/latest/userguide/ext_modules.html 376*61c4878aSAndroid Build Coastguard Worker inputs = _constraints + _requirements + [ _compiled_requirements_file ] 377*61c4878aSAndroid Build Coastguard Worker 378*61c4878aSAndroid Build Coastguard Worker # Use the pip-tools compiled requiremets file. This contains the fully 379*61c4878aSAndroid Build Coastguard Worker # expanded list of deps with constraints applied. 380*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.source_packages)) { 381*61c4878aSAndroid Build Coastguard Worker inputs += [ _compiled_requirements_file ] 382*61c4878aSAndroid Build Coastguard Worker args += [ 383*61c4878aSAndroid Build Coastguard Worker "--requirement", 384*61c4878aSAndroid Build Coastguard Worker rebase_path(_compiled_requirements_file, root_build_dir), 385*61c4878aSAndroid Build Coastguard Worker ] 386*61c4878aSAndroid Build Coastguard Worker } 387*61c4878aSAndroid Build Coastguard Worker 388*61c4878aSAndroid Build Coastguard Worker deps = [ 389*61c4878aSAndroid Build Coastguard Worker ":${invoker.target_name}._compile_requirements($pw_build_PYTHON_TOOLCHAIN)", 390*61c4878aSAndroid Build Coastguard Worker ":${invoker.target_name}._generate_3p_requirements($pw_build_PYTHON_TOOLCHAIN)", 391*61c4878aSAndroid Build Coastguard Worker ":${invoker.target_name}._install_base_3p_deps($pw_build_PYTHON_TOOLCHAIN)", 392*61c4878aSAndroid Build Coastguard Worker ] 393*61c4878aSAndroid Build Coastguard Worker stamp = true 394*61c4878aSAndroid Build Coastguard Worker pool = "$dir_pw_build/pool:pip($default_toolchain)" 395*61c4878aSAndroid Build Coastguard Worker } 396*61c4878aSAndroid Build Coastguard Worker 397*61c4878aSAndroid Build Coastguard Worker # Target to create a Python package cache for this pw_python_venv. 398*61c4878aSAndroid Build Coastguard Worker pw_python_action("${target_name}.vendor_wheels") { 399*61c4878aSAndroid Build Coastguard Worker _wheel_output_dir = "$target_gen_dir/$target_name/wheels" 400*61c4878aSAndroid Build Coastguard Worker _pip_download_logfile = 401*61c4878aSAndroid Build Coastguard Worker "$target_gen_dir/$target_name/pip_download_log.txt" 402*61c4878aSAndroid Build Coastguard Worker _pip_wheel_logfile = "$target_gen_dir/$target_name/pip_wheel_log.txt" 403*61c4878aSAndroid Build Coastguard Worker metadata = { 404*61c4878aSAndroid Build Coastguard Worker pw_python_package_wheels = [ _wheel_output_dir ] 405*61c4878aSAndroid Build Coastguard Worker } 406*61c4878aSAndroid Build Coastguard Worker 407*61c4878aSAndroid Build Coastguard Worker script = "$dir_pw_build/py/pw_build/generate_python_wheel_cache.py" 408*61c4878aSAndroid Build Coastguard Worker 409*61c4878aSAndroid Build Coastguard Worker # Set the venv to run this pip install in. 410*61c4878aSAndroid Build Coastguard Worker _pw_internal_run_in_venv = true 411*61c4878aSAndroid Build Coastguard Worker _skip_installing_external_python_deps = true 412*61c4878aSAndroid Build Coastguard Worker venv = get_label_info(":${invoker.target_name}", "label_no_toolchain") 413*61c4878aSAndroid Build Coastguard Worker 414*61c4878aSAndroid Build Coastguard Worker args = [ 415*61c4878aSAndroid Build Coastguard Worker "--pip-download-log", 416*61c4878aSAndroid Build Coastguard Worker rebase_path(_pip_download_logfile, root_build_dir), 417*61c4878aSAndroid Build Coastguard Worker "--wheel-dir", 418*61c4878aSAndroid Build Coastguard Worker rebase_path(_wheel_output_dir, root_build_dir), 419*61c4878aSAndroid Build Coastguard Worker "-r", 420*61c4878aSAndroid Build Coastguard Worker rebase_path(_compiled_requirements_file, root_build_dir), 421*61c4878aSAndroid Build Coastguard Worker ] 422*61c4878aSAndroid Build Coastguard Worker 423*61c4878aSAndroid Build Coastguard Worker if (pw_build_PYTHON_PIP_DOWNLOAD_ALL_PLATFORMS) { 424*61c4878aSAndroid Build Coastguard Worker args += [ "--download-all-platforms" ] 425*61c4878aSAndroid Build Coastguard Worker } 426*61c4878aSAndroid Build Coastguard Worker 427*61c4878aSAndroid Build Coastguard Worker deps = [ 428*61c4878aSAndroid Build Coastguard Worker ":${invoker.target_name}._compile_requirements($pw_build_PYTHON_TOOLCHAIN)", 429*61c4878aSAndroid Build Coastguard Worker ":${invoker.target_name}._generate_3p_requirements($pw_build_PYTHON_TOOLCHAIN)", 430*61c4878aSAndroid Build Coastguard Worker ] 431*61c4878aSAndroid Build Coastguard Worker 432*61c4878aSAndroid Build Coastguard Worker outputs = [ 433*61c4878aSAndroid Build Coastguard Worker _wheel_output_dir, 434*61c4878aSAndroid Build Coastguard Worker _pip_wheel_logfile, 435*61c4878aSAndroid Build Coastguard Worker _pip_download_logfile, 436*61c4878aSAndroid Build Coastguard Worker ] 437*61c4878aSAndroid Build Coastguard Worker pool = "$dir_pw_build/pool:pip($default_toolchain)" 438*61c4878aSAndroid Build Coastguard Worker } 439*61c4878aSAndroid Build Coastguard Worker 440*61c4878aSAndroid Build Coastguard Worker # End pw_build_PYTHON_TOOLCHAIN check 441*61c4878aSAndroid Build Coastguard Worker } else { 442*61c4878aSAndroid Build Coastguard Worker group("${target_name}._compile_requirements") { 443*61c4878aSAndroid Build Coastguard Worker public_deps = [ ":${target_name}($pw_build_PYTHON_TOOLCHAIN)" ] 444*61c4878aSAndroid Build Coastguard Worker } 445*61c4878aSAndroid Build Coastguard Worker group("${target_name}._install_3p_deps") { 446*61c4878aSAndroid Build Coastguard Worker public_deps = [ ":${target_name}($pw_build_PYTHON_TOOLCHAIN)" ] 447*61c4878aSAndroid Build Coastguard Worker } 448*61c4878aSAndroid Build Coastguard Worker group("${target_name}.vendor_wheels") { 449*61c4878aSAndroid Build Coastguard Worker public_deps = [ ":${target_name}($pw_build_PYTHON_TOOLCHAIN)" ] 450*61c4878aSAndroid Build Coastguard Worker } 451*61c4878aSAndroid Build Coastguard Worker } 452*61c4878aSAndroid Build Coastguard Worker } else { 453*61c4878aSAndroid Build Coastguard Worker group("${target_name}._compile_requirements") { 454*61c4878aSAndroid Build Coastguard Worker } 455*61c4878aSAndroid Build Coastguard Worker group("${target_name}._install_3p_deps") { 456*61c4878aSAndroid Build Coastguard Worker } 457*61c4878aSAndroid Build Coastguard Worker group("${target_name}.vendor_wheels") { 458*61c4878aSAndroid Build Coastguard Worker } 459*61c4878aSAndroid Build Coastguard Worker } 460*61c4878aSAndroid Build Coastguard Worker 461*61c4878aSAndroid Build Coastguard Worker # Have this target directly depend on _install_3p_deps 462*61c4878aSAndroid Build Coastguard Worker group("$target_name") { 463*61c4878aSAndroid Build Coastguard Worker public_deps = 464*61c4878aSAndroid Build Coastguard Worker [ ":${target_name}._install_3p_deps($pw_build_PYTHON_TOOLCHAIN)" ] 465*61c4878aSAndroid Build Coastguard Worker } 466*61c4878aSAndroid Build Coastguard Worker} 467