:::{default-domain} bzl :::
When you depend on a PyPI package that includes C headers (like numpy
), you need to make those headers available to your cc_library
or cc_binary
targets.
The recommended way to do this is to inject a BUILD.bazel
file into the external repository for the package. This BUILD
file will create a cc_library
target that exposes the header files.
First, create a .bzl
file that has the extra logic we'll inject. Putting it in a separate bzl file avoids having to redownload and extract the whl file when our logic changes.
# pypi_extra_targets.bzl load("@rules_cc//cc:cc_library.bzl", "cc_library") def extra_numpy_targets(): cc_library( name = "headers", hdrs = glob(["**/*.h"]), visibility = ["//visibility:public"], )
In your MODULE.bazel
file, use the build_file_content
attribute of pip.parse
to inject the BUILD
file content for the numpy
package.
# MODULE.bazel load("@rules_python//python/extensions:pip.bzl", "parse", "whl_mods") pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") whl_mods = use_extension("@rules_python//python/extensions:pip.bzl", "whl_mods") # Define a specific modification for a wheel whl_mods( hub_name = "pypi_mods", whl_name = "numpy-1.0.0-py3-none-any.whl", # The exact wheel filename additive_build_content = """ load("@//:pypi_extra_targets.bzl", "numpy_hdrs") extra_numpy_targets() """, ) pip.parse( hub_name = "pypi", wheel_name = "numpy", requirements_lock = "//:requirements.txt", whl_modifications = { "@pypi_mods//:numpy.json": "numpy", }, extra_hub_aliases = { "numpy": ["headers"], } )
In your WORKSPACE
file, use the annotations
attribute of pip_parse
to inject additional BUILD
file content, then use extra_hub_targets
to expose that target in the @pypi
hub repo.
The {obj}package_annotation
helper can be used to construct the value for the annotations
attribute.
# WORKSPACE load("@rules_python//python:pip.bzl", "package_annotation", "pip_parse") pip_parse( name = "pypi", requirements_lock = "//:requirements.txt", annotations = { "numpy": package_annotation( additive_build_content = """\ load("@//:pypi_extra_targets.bzl", "numpy_hdrs") extra_numpy_targets() """ ), }, extra_hub_targets = { "numpy": ["headers"], }, )
In your BUILD.bazel
file, you can now depend on the generated headers
target.
# BUILD.bazel cc_library( name = "my_c_extension", srcs = ["my_c_extension.c"], deps = ["@pypi//numpy:headers"], )