Skip to content

Commit

Permalink
Move to rules_python and remove local_config_python.
Browse files Browse the repository at this point in the history
Fixes #71.
  • Loading branch information
junyer committed Feb 13, 2024
1 parent 8889d39 commit f77df95
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 615 deletions.
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ module(

bazel_dep(name = "platforms", version = "0.0.8")
bazel_dep(name = "rules_cc", version = "0.0.9")
bazel_dep(name = "rules_python", version = "0.30.0")
71 changes: 23 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,33 @@

Provided rules:

- `pybind_extension`: Builds a python extension, automatically adding the
required build flags and pybind11 dependencies. It defines a `*.so` target
which can be included as a `data` dependency of a `py_*` target.
- `pybind_library`: Builds a C++ library, automatically adding the required
build flags and pybind11 dependencies. This library can then be used as a
dependency of a `pybind_extension`. The arguments match a `cc_library`.
- `pybind_library_test`: Builds a C++ test for a `pybind_library`. The arguments
match a `cc_test`.
- `pybind_extension`: Builds a python extension, automatically adding the
required build flags and pybind11 dependencies. It defines a `*.so` target
which can be included as a `data` dependency of a `py_*` target.
- `pybind_library`: Builds a C++ library, automatically adding the required
build flags and pybind11 dependencies. This library can then be used as a
dependency of a `pybind_extension`. The arguments match a `cc_library`.
- `pybind_library_test`: Builds a C++ test for a `pybind_library`. The
arguments match a `cc_test`.

To test a `pybind_extension`, the most common approach is to write the test in
python and use the standard `py_test` build rule.

Provided targets:

- `@pybind11//:pybind11_embed`: Automatically adds required build flags to
embed Python.
Add as a dependency to your `cc_binary`.

`@pybind11//:pybind11_embed` currently supports Python 3 MacOS/Ubuntu/Debian
- `@pybind11//:pybind11_embed`: Automatically adds required build flags to
embed Python. Add as a dependency to your `cc_binary`.

`@pybind11//:pybind11_embed` currently supports Python 3 MacOS/Ubuntu/Debian
environments:
- pyenv
- pipenv
- virtualenv

If `pybind11_embed` doesn't work with your embedded Python project, add
`@pybind11` as a dependency to your `cc_binary` and [follow the instructions
for manually retrieving the build flags](https://docs.python.org/3/extending/embedding.html#embedding-python-in-c).


- pyenv
- pipenv
- virtualenv

If `pybind11_embed` doesn't work with your embedded Python project, add
`@pybind11` as a dependency to your `cc_binary` and
[follow the instructions for manually retrieving the build flags](https://docs.python.org/3/extending/embedding.html#embedding-python-in-c).

## Installation

Expand All @@ -46,10 +45,8 @@ http_archive(
name = "pybind11",
build_file = "@pybind11_bazel//:pybind11.BUILD",
strip_prefix = "pybind11-<stable-version>",
urls = ["https://github.com/pybind/pybind11/archive/v<stable-version>.tar.gz"],
urls = ["https://github.com/pybind/pybind11/archive/v<stable-version>.zip"],
)
load("@pybind11_bazel//:python_configure.bzl", "python_configure")
python_configure(name = "local_config_python")
```

Then, in your `BUILD` file:
Expand All @@ -58,35 +55,13 @@ Then, in your `BUILD` file:
load("@pybind11_bazel//:build_defs.bzl", "pybind_extension")
```

## Hermetic Python

To configure `pybind11_bazel` for hermetic Python, `python_configure` can take
the target providing the Python runtime as an argument:

```starlark
python_configure(
name = "local_config_python",
python_interpreter_target = "@python_interpreter//:python_bin",
)
```

## Bzlmod

In your `MODULE.bazel` file:

```starlark
python_configure = use_extension("@pybind11_bazel//:python_configure.bzl", "extension")
use_repo(python_configure, "local_config_python", "pybind11")
```

The `toolchain` tag can only be used by the root module (that is, not by a
module which is being used as a dependency) to set `python_version` or
`python_interpreter_target`. For example:

```starlark
python_configure = use_extension("@pybind11_bazel//:python_configure.bzl", "extension")
python_configure.toolchain(python_version = "3")
use_repo(python_configure, "local_config_python", "pybind11")
pybind11_configure = use_extension("@pybind11_bazel//:pybind11_configure.bzl", "pybind11_configure_extension")
use_repo(pybind11_configure, "pybind11")
```

Usage in your `BUILD` file is as described previously.
2 changes: 1 addition & 1 deletion build_defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ PYBIND_FEATURES = [

PYBIND_DEPS = [
"@pybind11",
"@local_config_python//:python_headers",
"@rules_python//python/cc:current_py_cc_headers",
]

# Builds a Python extension module using pybind11.
Expand Down
Empty file removed py/BUILD
Empty file.
68 changes: 0 additions & 68 deletions py/BUILD.tpl

This file was deleted.

4 changes: 2 additions & 2 deletions pybind11.BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ cc_library(
),
copts = OPTIONS,
includes = ["include"],
deps = ["@local_config_python//:python_headers"],
deps = ["@rules_python//python/cc:current_py_cc_headers"],
)

cc_library(
Expand All @@ -46,7 +46,7 @@ cc_library(
),
copts = OPTIONS,
includes = ["include"],
deps = ["@local_config_python//:python_embed"],
deps = ["@rules_python//python/cc:current_py_cc_libs"],
)

config_setting(
Expand Down
27 changes: 27 additions & 0 deletions pybind11_configure.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Module extension for "configuring" pybind11."""

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

def _parse_my_own_version_from_module_dot_bazel(module_ctx):
lines = module_ctx.read(Label("//:MODULE.bazel")).split("\n")
for line in lines:
parts = line.split("\"")
if parts[0] == " version = ":
return parts[1]
fail("Failed to parse my own version from `MODULE.bazel`! " +
"This should never happen!")

def _pybind11_configure_extension_impl(module_ctx):
version = _parse_my_own_version_from_module_dot_bazel(module_ctx)

# The pybind11_bazel version should typically just be the pybind11 version,
# but can end with ".bzl.<N>" if the Bazel plumbing was updated separately.
version = version.split(".bzl.")[0]
http_archive(
name = "pybind11",
build_file = "//:pybind11.BUILD",
strip_prefix = "pybind11-%s" % version,
urls = ["https://github.com/pybind/pybind11/archive/v%s.zip" % version],
)

pybind11_configure_extension = module_extension(implementation = _pybind11_configure_extension_impl)
Loading

0 comments on commit f77df95

Please sign in to comment.