Initial support for Bzlmod. (#55)
diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000..e270b8a --- /dev/null +++ b/MODULE.bazel
@@ -0,0 +1,8 @@ +# Bazel extensions for pybind11 +module( + name = "pybind11_bazel", + version = "2.11.1", +) + +bazel_dep(name = "platforms", version = "0.0.7") +bazel_dep(name = "rules_cc", version = "0.0.8")
diff --git a/README.md b/README.md index ad1a86c..daf12c2 100644 --- a/README.md +++ b/README.md
@@ -69,3 +69,24 @@ 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") +``` + +Usage in your `BUILD` file is as described previously.
diff --git a/python_configure.bzl b/python_configure.bzl index 51c267e..abaf69a 100644 --- a/python_configure.bzl +++ b/python_configure.bzl
@@ -6,6 +6,8 @@ * `PYTHON_LIB_PATH`: Location of python libraries. """ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + _BAZEL_SH = "BAZEL_SH" _PYTHON_BIN_PATH = "PYTHON_BIN_PATH" _PYTHON_CONFIG_BIN_PATH = "PYTHON_CONFIG_BIN_PATH" @@ -441,3 +443,62 @@ will configure for that Python version instead of the installed binary. This configuration takes precedence over python_version. """ + +def _parse_my_own_version_from_module_dot_bazel(ctx): + lines = 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 _extension_impl(ctx): + toolchain = None + for module in ctx.modules: + if module.is_root: + if not module.tags.toolchain: + pass + elif len(module.tags.toolchain) == 1: + toolchain = module.tags.toolchain[0] + else: + _fail("The root module may not specify multiple `toolchain` " + + "tags. Found %r `toolchain` tags specified." % ( + len(module.tags.toolchain), + )) + elif module.tags.toolchain: + _fail("A non-root module may not specify any `toolchain` tags. " + + "Found %r `toolchain` tags specified by module %r." % ( + len(module.tags.toolchain), + module.name, + )) + if toolchain == None: + python_configure( + name = "local_config_python", + ) + else: + python_configure( + name = "local_config_python", + python_version = toolchain.python_version, + python_interpreter_target = toolchain.python_interpreter_target, + ) + + version = _parse_my_own_version_from_module_dot_bazel(ctx) + http_archive( + name = "pybind11", + build_file = "//:pybind11.BUILD", + strip_prefix = "pybind11-%s" % version, + urls = ["https://github.com/pybind/pybind11/archive/v%s.zip" % version], + ) + +extension = module_extension( + implementation = _extension_impl, + tag_classes = { + "toolchain": tag_class( + attrs = { + "python_version": attr.string(default = ""), + "python_interpreter_target": attr.label(), + }, + ), + }, +)