How to include all required libraries to executable when using rust-cpython?

Hello everyone.

I'm newbie in Rust, but on advanced level in Python. And I think, if Python were a compilable language, it would be just like same Rust.

My question is: I want to compile a Python program. But I don't want to use PyInstaller because the files it compiles run very slowly.

I tried to use rust-cpython for this, but it doesn't add Python's compiled libraries to the executable file and it depends on a Python installation.

My Rust code (main.py it works right):

use cpython::Python;
use std::fs::read_to_string;

fn main() {
    let gil = Python::acquire_gil();
    let py = gil.python();
    let script = read_to_string("main.py").expect("File error.");

    py.run(script.as_str(), None, None).expect("Python error.");
}

In a nutshell, I want to use rust-cpython instead of PyInstaller, is that possible?

It seems that rust-cpython will automatically statically link to cpython if and only if the local cpython installation is not dynamically linked:

This makes sense as if the local cpython installation is dynamically linked, there is no static library to statically link against I would assume.

It isn't clear what you want to achieve here. Neither PyInstaller nor rust-cpython compile Python programs. PyInstaller bundles together a Python program, its dependencies and a Python interpreter into a standalone package, it doesn't compile the program in the usual sense of the word.

rust-cpython is a set of bindings and tools to allow Rust to call Python code and vice-versa. It doesn't compile Python code, just calls the existing interpreter. In particular, the Rust code you have there loads the Python from main.py at runtime.

If compiled Python code is really what you want, you may be better off looking into actual compilers for Python, of which Nuitka seems to be the main one that is still maintained. There may be others out there, but checking on a Python forum may get a better response.

If all you want is to link cpython statically into your Rust executable, then the answer from @bjorn3 may be what you want. Note that it still won't package everything into a single file unless you embed the Python code into your Rust code (using something like include_str!).

This is potentially also a source of misunderstanding. Python is dynamically typed and has a lot of features that rely on it having an interpreter available at runtime, like duck typing and the eval() function. Rust is statically typed and compiled so it doesn't have things like this. Rather, the preferred approach in Rust is to have everything checked before the program is run as far as possible. There is some limited support for dynamic typing in the Any trait, but it doesn't get used particularly much, because it is preferred in Rust to have the information on what a type is, or at least the methods it has, available to be checked at compile time.

3 Likes

The code in line that you show gives me the output "1", but I didn't quite understand what to do in this case.


Yes, I know Python doesn't compilable because Python is an interpreted language and Python bytecode is interpreted at run time. I want rust-cpython to add the existing /usr/lib/x86_64-linux-gnu/libpythonX.Y.so(and other libraries) to the executable file. In this way, my Python program will be able to run independently of a Python installation and at usual speed. Is this something that shouldn't be done with Rust?

So rust-cpython doesn't add Python's header files to the compilation unit like the C language does? In fact, I also don't know if there is a concept of "compilation unit" in Rust, as I said, I am new. :slight_smile:

Thank you for this, I didn't see this until now. I guess it does the same thing as Cython, is there a difference between them?

And thank you for that, this will be useful to me.

I mean, Rust's syntax is practical like a high-level language, but it's a compiled language. That's why I like Rust language.

That is impossible. You can't statically link to a dynamic library as the relocations necessary to statically link it are removed when producing a dynamic library.

You need a static library (extension: .a) to link against. This is probably part of a package separate from the main python package.

1 Like

Thank you for this info, I don't know much about dynamic and static libraries.

I couldn't find it in the Ubuntu repositories(I guess this is not the libpythonX.Y-dbg package). If I find or compile a compiled Python object (.o), I can compile it into a static library. Do you know where I can find a ready-made compiled Python object? Because I don't want to bother compiling Python.

You might also consider pyo3 with maturin. I'm just getting started trying it out, but it seems like a solid way to write Rust code with a few proc macro attribute decorators that can be compiled and assembled into a Python module. Also worth noting that you can add metadata to set the required Python dependencies.

1 Like

Thanks, I'm beginning to research.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.