:::{default-domain} bzl :::
This guide explains how to use the Python toolchain 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.
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:
# 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"], )
In your BUILD.bazel
file, define a target using this rule and add it to the deps
of your cc_binary
or cc_library
.
# 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 ], )