Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion python/private/internal_config_repo.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ config = struct(
enable_pystar = True,
enable_pipstar = {enable_pipstar},
enable_deprecation_warnings = {enable_deprecation_warnings},
bazel_9_or_later = {bazel_9_or_later},
BuiltinPyInfo = getattr(getattr(native, "legacy_globals", None), "PyInfo", {builtin_py_info_symbol}),
BuiltinPyRuntimeInfo = getattr(getattr(native, "legacy_globals", None), "PyRuntimeInfo", {builtin_py_runtime_info_symbol}),
BuiltinPyCcLinkParamsProvider = getattr(getattr(native, "legacy_globals", None), "PyCcLinkParamsProvider", {builtin_py_cc_link_params_provider}),
Expand Down Expand Up @@ -87,7 +88,10 @@ _TRANSITION_SETTINGS_DEBUG_TEMPLATE = """
"""

def _internal_config_repo_impl(rctx):
if not native.bazel_version or int(native.bazel_version.split(".")[0]) >= 8:
# An empty version signifies a development build, which is treated as
# the latest version.
bazel_major_version = int(native.bazel_version.split(".")[0]) if native.bazel_version else 99999
if bazel_major_version >= 8:
builtin_py_info_symbol = "None"
builtin_py_runtime_info_symbol = "None"
builtin_py_cc_link_params_provider = "None"
Expand All @@ -103,6 +107,7 @@ def _internal_config_repo_impl(rctx):
builtin_py_info_symbol = builtin_py_info_symbol,
builtin_py_runtime_info_symbol = builtin_py_runtime_info_symbol,
builtin_py_cc_link_params_provider = builtin_py_cc_link_params_provider,
bazel_9_or_later = str(bazel_major_version >= 9),
))

shim_content = _PY_INTERNAL_SHIM
Expand Down
25 changes: 18 additions & 7 deletions python/private/py_executable.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ load("@bazel_skylib//lib:paths.bzl", "paths")
load("@bazel_skylib//lib:structs.bzl", "structs")
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
load("@rules_python_internal//:rules_python_config.bzl", rp_config = "config")
load(":attr_builders.bzl", "attrb")
load(
":attributes.bzl",
Expand Down Expand Up @@ -69,6 +70,7 @@ load(":venv_runfiles.bzl", "create_venv_app_files")
_py_builtins = py_internal
_EXTERNAL_PATH_PREFIX = "external"
_ZIP_RUNFILES_DIRECTORY_NAME = "runfiles"
_LAUNCHER_MAKER_TOOLCHAIN_TYPE = "@bazel_tools//tools/launcher:launcher_maker_toolchain_type"

# Non-Google-specific attributes for executables
# These attributes are for rules that accept Python sources.
Expand Down Expand Up @@ -228,17 +230,19 @@ accepting arbitrary Python versions.
"@platforms//os:windows",
],
),
"_windows_launcher_maker": lambda: attrb.Label(
default = "@bazel_tools//tools/launcher:launcher_maker",
cfg = "exec",
executable = True,
),
"_zipper": lambda: attrb.Label(
cfg = "exec",
executable = True,
default = "@bazel_tools//tools/zip:zipper",
),
},
{
"_windows_launcher_maker": lambda: attrb.Label(
default = "@bazel_tools//tools/launcher:launcher_maker",
cfg = "exec",
executable = True,
),
} if not rp_config.bazel_9_or_later else {},
)

def convert_legacy_create_init_to_int(kwargs):
Expand Down Expand Up @@ -777,6 +781,11 @@ def _create_stage1_bootstrap(
is_executable = True,
)

def _find_launcher_maker(ctx):
if rp_config.bazel_9_or_later:
return (ctx.toolchains[_LAUNCHER_MAKER_TOOLCHAIN_TYPE].binary, _LAUNCHER_MAKER_TOOLCHAIN_TYPE)
return (ctx.executable._windows_launcher_maker, None)

def _create_windows_exe_launcher(
ctx,
*,
Expand All @@ -796,15 +805,17 @@ def _create_windows_exe_launcher(
launch_info.add("1" if use_zip_file else "0", format = "use_zip_file=%s")

launcher = ctx.attr._launcher[DefaultInfo].files_to_run.executable
executable, toolchain = _find_launcher_maker(ctx)
ctx.actions.run(
executable = ctx.executable._windows_launcher_maker,
executable = executable,
arguments = [launcher.path, launch_info, output.path],
inputs = [launcher],
outputs = [output],
mnemonic = "PyBuildLauncher",
progress_message = "Creating launcher for %{label}",
# Needed to inherit PATH when using non-MSVC compilers like MinGW
use_default_shell_env = True,
toolchain = toolchain,
)

def _create_zip_file(ctx, *, output, zip_main, runfiles):
Expand Down Expand Up @@ -1838,7 +1849,7 @@ def create_executable_rule_builder(implementation, **kwargs):
ruleb.ToolchainType(TOOLCHAIN_TYPE),
ruleb.ToolchainType(EXEC_TOOLS_TOOLCHAIN_TYPE, mandatory = False),
ruleb.ToolchainType("@bazel_tools//tools/cpp:toolchain_type", mandatory = False),
],
] + ([ruleb.ToolchainType(_LAUNCHER_MAKER_TOOLCHAIN_TYPE)] if rp_config.bazel_9_or_later else []),
cfg = dict(
implementation = _transition_executable_impl,
inputs = TRANSITION_LABELS + [labels.PYTHON_VERSION],
Expand Down
24 changes: 24 additions & 0 deletions tests/base_rules/py_executable_base_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""Tests common to py_binary and py_test (executable rules)."""

load("@rules_python//python:py_runtime_info.bzl", RulesPythonPyRuntimeInfo = "PyRuntimeInfo")
load("@rules_python_internal//:rules_python_config.bzl", rp_config = "config")
load("@rules_testing//lib:analysis_test.bzl", "analysis_test")
load("@rules_testing//lib:truth.bzl", "matching")
load("@rules_testing//lib:util.bzl", rt_util = "util")
Expand Down Expand Up @@ -114,6 +115,29 @@ def _test_basic_zip_impl(env, target):

_tests.append(_test_basic_zip)

def _test_cross_compile_to_unix(name, config):
rt_util.helper_target(
config.rule,
name = name + "_subject",
main_module = "dummy",
)
analysis_test(
name = name,
impl = _test_cross_compile_to_unix_impl,
target = name + "_subject",
# Cross-compilation of py_test fails since the default test toolchain
# requires an execution platform that matches the target platform.
config_settings = {
"//command_line_option:platforms": [platform_targets.EXOTIC_UNIX],
} if rp_config.bazel_9_or_later and not "py_test" in str(config.rule) else {},
expect_failure = True,
)

def _test_cross_compile_to_unix_impl(_env, _target):
pass

_tests.append(_test_cross_compile_to_unix)

def _test_executable_in_runfiles(name, config):
rt_util.helper_target(
config.rule,
Expand Down
8 changes: 8 additions & 0 deletions tests/support/platforms/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,11 @@ platform(
"@platforms//cpu:aarch64",
],
)

platform(
name = "exotic_unix",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:s390x",
],
)
4 changes: 4 additions & 0 deletions tests/support/platforms/platforms.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ platform_targets = struct(
WINDOWS = Label("//tests/support/platforms:windows"),
WINDOWS_AARCH64 = Label("//tests/support/platforms:windows_aarch64"),
WINDOWS_X86_64 = Label("//tests/support/platforms:windows_x86_64"),

# Unspecified Unix platform that is unlikely to be the host platform in CI,
# but still provides a Python toolchain.
EXOTIC_UNIX = Label("//tests/support/platforms:exotic_unix"),
)