blob: 4d70b322c95bc433a1c8b40d32d6b3eff4226261 [file] [log] [blame] [view]
:::{default-domain} bzl
:::
# How to link to libpython
This guide explains how to use the Python [toolchain](toolchains) to get the linker
flags required for linking against `libpython`. This is often necessary when
embedding Python in a C/C++ application.
Currently, the `:current_py_cc_libs` target does *not* include `-lpython` et al
linker flags. This is intentional because it forces dynamic linking (via the
dynamic linker processing `DT_NEEDED` entries), which prevents users who want
to load it in some more custom way.
## Exposing linker flags in a rule
You can create a rule that gets the Python version from the toolchain and
constructs the correct linker flag. This rule can then provide the flag to
other C/C++ rules via the `CcInfo` provider.
Here's an example of a rule that creates the `-lpython<version>` flag:
```starlark
# python_libs.bzl
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "cc_common")
def _python_libs_impl(ctx):
toolchain = ctx.toolchains["@rules_python//python:toolchain_type"]
info = toolchain.py3_runtime.interpreter_version_info
link_flag = "-lpython{}.{}".format(info.major, info.minor)
cc_info = CcInfo(
linking_context = cc_common.create_linking_context(
user_link_flags = [link_flag],
),
)
return [cc_info]
python_libs = rule(
implementation = _python_libs_impl,
toolchains = ["@rules_python//python:toolchain_type"],
)
```
## Using the rule
In your `BUILD.bazel` file, define a target using this rule and add it to the
`deps` of your `cc_binary` or `cc_library`.
```starlark
# BUILD.bazel
load(":python_libs.bzl", "python_libs")
python_libs(
name = "py_libs",
)
cc_binary(
name = "my_app",
srcs = ["my_app.c"],
deps = [
":py_libs",
# Other dependencies
],
)
```