-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to set python interpreter within cc_binary #77
Comments
Yeah, could you please put together a minimal example (in its own repository) that reproduces the problem? I'm struggling to understand whether you mean that you are trying to "embed" Python or that the shebang lines are wrong for some reason or that something else is happening. Thanks! |
This sounds like a problem that @rickeylev would know how to solve... What happens if you do this to pin the Python version for the |
I'm actually already pinning it here. When I change the version from my system one (3.10) to some other version (e.g. 3.11) I get the following error running
|
You aren't doing anything with |
I played around with the version and actually switching works. E.g. python version that is used in
I get the
Could the problem be that What would be the best way to solve this then? |
Given that your example didn't work with |
Sorry for the confusion, but the problem was not resolved by switching to |
Oh. :( Also, I see now that I misspoke earlier:
I should have said "the |
I think what's happening is the embedded interpreter is trying to take settings from the local environment. I saw this when I was trying to construct a runnable test linking with the hermetic python libraries: it kept trying to "escape" and use things from the local system. Eventually I traced it back to the Py_Initialize() call trying to automatically fill in various details based on the environment settings. The docs for how to initialize an embedded interpreter are here: https://docs.python.org/3/extending/embedding.html I think the two key things that have to be setup are:
For (1), I think this can be derived based on the location of e.g. the header files. You basically need the runfiles-relative path to where the stdlib etc are in the runfiles. For (2), this information comes from PyInfo.imports. What we probably want to do is generate a cc file with those values in them. Maybe something like this:
At the lesat, it probably makes sense to add (1) to the py_cc_toolchain info as e.g. a runtime_install_location (equiv of PYTHONHOME?) attribute or something, to avoid having to try and unpack so much. |
@rickeylev I faced this issue myself and I hacked a solution almost as you describe. However I discovered a conceptual ambiguity. In your rule you use the py_cc_info. As implemented, py_cc_info is about compile time dependencies since it exposes only that information related to compiling and linking a cc_library that depends on libpython. A cc_binary which embeds Python, however, needs to also express a runtime/data dependency on a certain collection files (Lib/, DLLS/, ...) currently listed under the "files" filegroup of the instantiated python toolchain repository (and also a a data dependency on any third party .py files). The "files" filegroup is exposed through the py_runtime rule of the @bazel_tools//tools/python:toolchain_type toolchain. In my hacks, I made use of the @bazel_tools//tools/python:toolchain_type toolchain (py_runtime instead of py_cc_info) to prepare such metadata for embedding runtime python dependency files. I successfully built a binary with an embedded python interpreter. Here is my implementation
Then again I'm pretty unskilled with Bazel and you can probably figure out a better way to do this. I just thought it might help to post my learnings here. |
Ahhh yes, excellent point. This seems obvious once you said it. So really, we don't need a runtime_install_dir value, but a The bzl code you posted looks pretty correct. You probably want |
@axbycc-mark Could you share an example for how you use the imports_file and the python_home_file in a cc_binary/cc_test target to appropriately set the PYTHONPATH and PYTHONHOME? When depending on numpy using your suggest approach above, I am consistently getting: |
@ahojnnes Continuing my example from above, here is the code I had in my actual .cc file.
Can you see if this little program works for you? |
@axbycc-mark Thank you very much. This is very helpful. |
After hacking at this for a bit, I came up with the following rule/macro combination that doesn't require any custom C++ code:
which can be used as follows:
|
@ahojnnes - I literally was looking at this issue earlier in the week, and checked back and you had written exactly what I was trying to write! Thank you so much for posting it. The only downside to the approach you describe is that if you |
@jared2501 I don't think that my rules above have this limitation. You only need to list the imports made in the cc_py_{test,binary} sources. Any transitive dependencies should be automatically added to the runfiles and imports. At least, it worked in some minimal tests for me. |
@ahojnnes does your solution avoid the:
error (with python 3.10) as described above? I think this comes from PYTHONPATH not including the default |
ok actually the issue for me I think is bzlmod related, instead of prefixing |
Could someone in this thread cobble together a minimal example of using pybind11's embedded functionality to plot from matplotlib. Similar to this but using pybind11_bazel with hermetic python? This has been a key blocker for me switching to bazel and I can't figure it out. |
I've actually started an example repo here to get two embedded examples to run but I'm still having significant issues. |
Hi @ptr-br, I don't know if you're still interested in this but I've updated your example and have it working hermetically on 3.9, 3.10, 3.11, and halfway on 3.12. I'm also trying to plot and that creates some unrelated dependency issues on systems and qt. If you want to take a look, I forked your project here https://github.com/JBPennington/pybind_cpp_w_python_example. |
@JBPennington, thanks. |
I'm trying to use pybind11_bazel to execute some python code within C++. When I build my python targets with
rules_python
I'm able to install packages that can be used by the interpreter.However, when I link these to the
data=
attribute ofcc_binary
and usepybind11
as a dependency, the default interpreter at/usr/bin/python3
is used instead of the one from the python targets.Is there any elegant way of telling bazel to use the same interpreter as for the python part?
If further explanation is needed I could come up with a minimal example, please let me know. I'm rather new to bazel so thanks for your help!
Thanks.
The text was updated successfully, but these errors were encountered: