From c8c0afeb1da7bae310b4de3cb6be0a9d44ab8bd1 Mon Sep 17 00:00:00 2001 From: Nils Wireklint Date: Tue, 17 Dec 2024 16:49:08 +0100 Subject: [PATCH] Change py_binary to load from rules_python To follow the (future) migration of the python rules out of the set of native rules: https://github.com/bazelbuild/bazel/issues/17773 . This requires us to load the 'rules_python' module and while at it we parameterize the 'py_binary' so it is possible for consumers to switch to their own macros, following the model of pip_compile: https://github.com/bazelbuild/rules_python/blob/9b2b70adba5431162401a97b2bbab1dc938e7245/python/private/pypi/pip_compile.bzl#L32 This solves loading errors: ERROR: Traceback (most recent call last): File "/home/nwirekli/.cache/bazel/_bazel_nwirekli/1eeb85843c9866d288d7d5644c3b4615/ external/hedron_compile_commands+/refresh_compile_commands.bzl", line 67, column 27, in py_binary = native.py_binary, Error: no native function or rule 'py_binary' Available attributes: ... ERROR: error loading package under directory '': error loading package '@@hedron_compile_commands+//': initialization of module 'refresh_compile_commands.bzl' failed --- ImplementationReadme.md | 2 +- MODULE.bazel | 2 ++ refresh_compile_commands.bzl | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ImplementationReadme.md b/ImplementationReadme.md index 2a8c708b..fdb27766 100644 --- a/ImplementationReadme.md +++ b/ImplementationReadme.md @@ -116,7 +116,7 @@ We make the choice to set the compilation working directory ("directory" key) to I'm calling out this decision explicitly, because there's a tempting trap that caught Bazel's official editor plugins (Android Studio, Xcode, ...) before we helped fix them. -Do not be tempted to set the compilation "directory" to the bazel execroot (`bazel info execution_root`). The execroot may seem to work but breaks subtly on the next build; the execroot directory is reconfigured for whatever new target is being built, deleting the links to external workspaces and top-level packages not used by that particular build. Using the execroot might be tempting because that *is* where Bazel says it's going to invoke the command it gave you, but don't do it! It'll only have the subset of the code used for the last build, not for all build, breaking the paths used for editing the rest of the codebase. +Do not be tempted to set the compilation "directory" to the bazel execroot (`bazel info execution_root`). The execroot may seem to work but breaks subtly on the next build; the execroot directory is reconfigured for whatever new target is being built, deleting the links to external workspaces and top-level packages not used by that particular build. Using the execroot might be tempting because that *is* where Bazel says it's going to invoke the command it gave you, but don't do it! It'll only have the subset of the code used for the last build, not for all builds, breaking the paths used for editing the rest of the codebase. Remember that the key goal of `compile_commands.json` is to "de-Bazel" the build commands into something `clangd` can understand. Not pointing into Bazel's temporary build scratch space (execroot) is an important part of decoupling from Bazel's transitory state. diff --git a/MODULE.bazel b/MODULE.bazel index 23e060fe..d5fbc8d6 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,5 +1,7 @@ module(name = "hedron_compile_commands") +bazel_dep(name = "rules_python", version = "1.0.0") + p = use_extension("//:workspace_setup.bzl", "hedron_compile_commands_extension") pt = use_extension("//:workspace_setup_transitive.bzl", "hedron_compile_commands_extension") ptt = use_extension("//:workspace_setup_transitive_transitive.bzl", "hedron_compile_commands_extension") diff --git a/refresh_compile_commands.bzl b/refresh_compile_commands.bzl index 0210d42b..a8b65385 100644 --- a/refresh_compile_commands.bzl +++ b/refresh_compile_commands.bzl @@ -57,6 +57,7 @@ refresh_compile_commands( # Implementation load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") +load("@rules_python//python:py_binary.bzl", _py_binary = "py_binary") def refresh_compile_commands( @@ -64,6 +65,7 @@ def refresh_compile_commands( targets = None, exclude_headers = None, exclude_external_sources = False, + py_binary = _py_binary, **kwargs): # For the other common attributes. Tags, compatible_with, etc. https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes. # Convert the various, acceptable target shorthands into the dictionary format # In Python, `type(x) == y` is an antipattern, but [Starlark doesn't support inheritance](https://bazel.build/rules/language), so `isinstance` doesn't exist, and this is the correct way to switch on type. @@ -92,7 +94,7 @@ def refresh_compile_commands( _expand_template(name = script_name, labels_to_flags = targets, exclude_headers = exclude_headers, exclude_external_sources = exclude_external_sources, **kwargs) # Combine them so the wrapper calls the main script - native.py_binary( + py_binary( name = name, main = version_checker_script_name, srcs = [version_checker_script_name, script_name],