pybind / pybind/pybind11_bazel

pybind_extension linkage is problematic for projects with multiple pybind modules

Open
#125 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug enhancement OS: Linux OS: MacOS OS: Windows
Dominant language
Starlark
Stars
115
Forks
67
Avg merge
1h 13m
Merged PRs (30d)
1

Description

This has been a long standing issue that shows up in projects with non-trivial / isolated C modules. I'm just finally getting around to actually writing up this problem

Right now, pybind_extension creates a shared library is using cc_binary(). This statically links all the dependencies, transitively. To complicate matters, it uses -Bsymbolic -- what this does is change how the shared library looks up symbols, giving preference to symbols within the shared library (which, because of the static linking, includes all dependencies).

The net effect is the resulting shared library can't participate in process-global state. For example, lets say there's a foo-plugins library, normally provided as libfoo-plugins.so, with the intent that consumers can load the library and register plugins into a static map<...> PLUGINS that is global to the process. Now we create a mybind.so Python C module using pybind_extension, which depends on foo-plugins. Because of how it's linked in, mybind.so has its own private copy of the PLUGINS map. Later, when people start registering plugins and asking which are available, they'll get different answers depending on if they're within mybind.so or outside it.

Such globals aren't uncommon. Absl flags and module initializers are such an example, but are easily found in other C++ libraries.

The fix I suggest is to switch pybind_extension to using something like cc_shared_library, which provides some control over what is statically vs dynamically linked into the Python C module. cc_shared_library is annoying to use, but it can get the job done.

In any case, there needs to be a way to better control what is statically vs dynamically linked into the pybind_extension module.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the pybind_extension rule and inspect how its cc_binary linkage statically includes transitive dependencies and applies -Bsymbolic. Compare that behavior with cc_shared_library, focusing on how static versus dynamic dependencies can be controlled. Done means a pybind module can avoid private copies of process-global C++ state while preserving the needed extension linkage.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.