| :::{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 | |
| ], | |
| ) | |
| ``` |