Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 1 | # Copyright 2022 The Bazel Authors. All rights reserved. |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | # you may not use this file except in compliance with the License. |
| 5 | # You may obtain a copy of the License at |
| 6 | # |
| 7 | # http://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, |
| 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | # See the License for the specific language governing permissions and |
| 13 | # limitations under the License. |
| 14 | """Implementation of py_library rule.""" |
| 15 | |
Richard Levasseur | d8966b8 | 2023-09-25 10:39:38 -0700 | [diff] [blame] | 16 | load("@bazel_skylib//lib:dicts.bzl", "dicts") |
Richard Levasseur | 3730803 | 2024-05-18 09:44:18 -0700 | [diff] [blame] | 17 | load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") |
| 18 | load("//python/private:flags.bzl", "PrecompileAddToRunfilesFlag") |
| 19 | load( |
| 20 | "//python/private:toolchain_types.bzl", |
| 21 | "EXEC_TOOLS_TOOLCHAIN_TYPE", |
| 22 | TOOLCHAIN_TYPE = "TARGET_TOOLCHAIN_TYPE", |
| 23 | ) |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 24 | load( |
Richard Levasseur | 09109e3 | 2023-09-20 15:40:51 -0700 | [diff] [blame] | 25 | ":attributes.bzl", |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 26 | "COMMON_ATTRS", |
| 27 | "PY_SRCS_ATTRS", |
| 28 | "SRCS_VERSION_ALL_VALUES", |
| 29 | "create_srcs_attr", |
| 30 | "create_srcs_version_attr", |
| 31 | ) |
| 32 | load( |
Richard Levasseur | 09109e3 | 2023-09-20 15:40:51 -0700 | [diff] [blame] | 33 | ":common.bzl", |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 34 | "check_native_allowed", |
| 35 | "collect_imports", |
| 36 | "collect_runfiles", |
| 37 | "create_instrumented_files_info", |
| 38 | "create_output_group_info", |
| 39 | "create_py_info", |
| 40 | "filter_to_py_srcs", |
| 41 | "union_attrs", |
| 42 | ) |
Richard Levasseur | 09109e3 | 2023-09-20 15:40:51 -0700 | [diff] [blame] | 43 | load(":providers.bzl", "PyCcLinkParamsProvider") |
| 44 | load(":py_internal.bzl", "py_internal") |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 45 | |
Richard Levasseur | 09109e3 | 2023-09-20 15:40:51 -0700 | [diff] [blame] | 46 | _py_builtins = py_internal |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 47 | |
| 48 | LIBRARY_ATTRS = union_attrs( |
| 49 | COMMON_ATTRS, |
| 50 | PY_SRCS_ATTRS, |
| 51 | create_srcs_version_attr(values = SRCS_VERSION_ALL_VALUES), |
| 52 | create_srcs_attr(mandatory = False), |
| 53 | ) |
| 54 | |
| 55 | def py_library_impl(ctx, *, semantics): |
| 56 | """Abstract implementation of py_library rule. |
| 57 | |
| 58 | Args: |
| 59 | ctx: The rule ctx |
| 60 | semantics: A `LibrarySemantics` struct; see `create_library_semantics_struct` |
| 61 | |
| 62 | Returns: |
| 63 | A list of modern providers to propagate. |
| 64 | """ |
| 65 | check_native_allowed(ctx) |
| 66 | direct_sources = filter_to_py_srcs(ctx.files.srcs) |
Richard Levasseur | e8dcfef | 2024-06-20 12:22:33 -0700 | [diff] [blame] | 67 | |
Richard Levasseur | 3730803 | 2024-05-18 09:44:18 -0700 | [diff] [blame] | 68 | precompile_result = semantics.maybe_precompile(ctx, direct_sources) |
| 69 | direct_pyc_files = depset(precompile_result.pyc_files) |
| 70 | default_outputs = depset(precompile_result.keep_srcs, transitive = [direct_pyc_files]) |
| 71 | |
| 72 | extra_runfiles_depsets = [depset(precompile_result.keep_srcs)] |
| 73 | if ctx.attr._precompile_add_to_runfiles_flag[BuildSettingInfo].value == PrecompileAddToRunfilesFlag.ALWAYS: |
| 74 | extra_runfiles_depsets.append(direct_pyc_files) |
| 75 | |
| 76 | runfiles = collect_runfiles( |
| 77 | ctx = ctx, |
| 78 | files = depset(transitive = extra_runfiles_depsets), |
| 79 | ) |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 80 | |
| 81 | cc_info = semantics.get_cc_info_for_library(ctx) |
Richard Levasseur | f676656 | 2023-11-21 12:55:33 -0800 | [diff] [blame] | 82 | py_info, deps_transitive_sources, builtins_py_info = create_py_info( |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 83 | ctx, |
| 84 | direct_sources = depset(direct_sources), |
| 85 | imports = collect_imports(ctx, semantics), |
Richard Levasseur | 3730803 | 2024-05-18 09:44:18 -0700 | [diff] [blame] | 86 | direct_pyc_files = direct_pyc_files, |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 87 | ) |
| 88 | |
| 89 | # TODO(b/253059598): Remove support for extra actions; https://github.com/bazelbuild/bazel/issues/16455 |
| 90 | listeners_enabled = _py_builtins.are_action_listeners_enabled(ctx) |
| 91 | if listeners_enabled: |
| 92 | _py_builtins.add_py_extra_pseudo_action( |
| 93 | ctx = ctx, |
| 94 | dependency_transitive_python_sources = deps_transitive_sources, |
| 95 | ) |
| 96 | |
| 97 | return [ |
Richard Levasseur | 3730803 | 2024-05-18 09:44:18 -0700 | [diff] [blame] | 98 | DefaultInfo(files = default_outputs, runfiles = runfiles), |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 99 | py_info, |
Richard Levasseur | f676656 | 2023-11-21 12:55:33 -0800 | [diff] [blame] | 100 | builtins_py_info, |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 101 | create_instrumented_files_info(ctx), |
| 102 | PyCcLinkParamsProvider(cc_info = cc_info), |
| 103 | create_output_group_info(py_info.transitive_sources, extra_groups = {}), |
| 104 | ] |
| 105 | |
Richard Levasseur | ec86f20 | 2024-06-13 17:11:46 -0700 | [diff] [blame] | 106 | _DEFAULT_PY_LIBRARY_DOC = """ |
Richard Levasseur | 3730803 | 2024-05-18 09:44:18 -0700 | [diff] [blame] | 107 | A library of Python code that can be depended upon. |
| 108 | |
| 109 | Default outputs: |
| 110 | * The input Python sources |
| 111 | * The precompiled artifacts from the sources. |
| 112 | |
| 113 | NOTE: Precompilation affects which of the default outputs are included in the |
| 114 | resulting runfiles. See the precompile-related attributes and flags for |
| 115 | more information. |
Richard Levasseur | ec86f20 | 2024-06-13 17:11:46 -0700 | [diff] [blame] | 116 | """ |
| 117 | |
| 118 | def create_py_library_rule(*, attrs = {}, **kwargs): |
| 119 | """Creates a py_library rule. |
| 120 | |
| 121 | Args: |
| 122 | attrs: dict of rule attributes. |
| 123 | **kwargs: Additional kwargs to pass onto the rule() call. |
| 124 | Returns: |
| 125 | A rule object |
| 126 | """ |
| 127 | |
| 128 | # Within Google, the doc attribute is overridden |
| 129 | kwargs.setdefault("doc", _DEFAULT_PY_LIBRARY_DOC) |
| 130 | return rule( |
| 131 | attrs = dicts.add(LIBRARY_ATTRS, attrs), |
| 132 | toolchains = [ |
| 133 | config_common.toolchain_type(TOOLCHAIN_TYPE, mandatory = False), |
| 134 | config_common.toolchain_type(EXEC_TOOLS_TOOLCHAIN_TYPE, mandatory = False), |
| 135 | ], |
| 136 | # TODO(b/253818097): fragments=py is only necessary so that |
| 137 | # RequiredConfigFragmentsTest passes |
| 138 | fragments = ["py"], |
Richard Levasseur | 3a57e4a | 2023-09-18 16:41:06 -0700 | [diff] [blame] | 139 | **kwargs |
| 140 | ) |