Skip to content

Commit

Permalink
Change py_binary to load from rules_python
Browse files Browse the repository at this point in the history
To follow the (future) migration of the python rules out of the set of
native rules: bazelbuild/bazel#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 <toplevel>
                    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
  • Loading branch information
stagnation committed Dec 18, 2024
1 parent 4f28899 commit c8c0afe
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 2 deletions.
2 changes: 1 addition & 1 deletion ImplementationReadme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 2 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -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")
Expand Down
4 changes: 3 additions & 1 deletion refresh_compile_commands.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ 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(
name,
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.
Expand Down Expand Up @@ -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],
Expand Down

0 comments on commit c8c0afe

Please sign in to comment.