Getting Started¶
Installing¶
Installing Rust¶
PyOxidizer is a Rust application and requires Rust (1.36 or newer) to be installed in order to build PyOxidizer itself as well as Python application binaries.
You can verify your installed version of Rust by running:
$ rustc --version
rustc 1.38.0 (625451e37 2019-09-23)
If you don’t have Rust installed, https://www.rust-lang.org/ has very detailed instructions on how to install it.
Rust releases a new version every 6 weeks and language development moves
faster than other programming languages. It is common for the Rust packages
provided by common package managers to lag behind the latest Rust release by
several releases. For that reason, use of the rustup
tool for managing
Rust is highly recommended.
If you are a security paranoid individual and don’t want to follow the
official rustup
install instructions involving a curl | sh
(your
paranoia is understood), you can find instructions for alternative installation
methods at https://github.com/rust-lang/rustup.rs/#other-installation-methods.
Other System Dependencies¶
You will need a working C compiler/toolchain in order to build some Rust crates and their dependencies. If Rust cannot find a C compiler, it should print a message at build time and give you instructions on how to install one.
There is a known issue with PyOxidizer on Fedora 30+ that will require you
to install the libxcrypt-compat
package to avoid an error due to a missing
libcrypt.so.1
file. See https://github.com/indygreg/PyOxidizer/issues/89
for more info.
Installing PyOxidizer¶
PyOxidizer can be installed from its latest published crate:
$ cargo install pyoxidizer
From a Git repository using cargo:
# The latest commit in source control.
$ cargo install --git https://github.com/indygreg/PyOxidizer.git --branch main pyoxidizer
$ A specific release
$ cargo install --git https://github.com/indygreg/PyOxidizer.git --tag <TAG> pyoxidizer
Or by cloning the Git repository and building the project locally:
$ git clone https://github.com/indygreg/PyOxidizer.git
$ cd PyOxidizer
$ cargo install --path pyoxidizer
Note
PyOxidizer’s project policy is for the main
branch to be stable. So it
should always be relatively safe to use main
instead of a released
version.
Once the pyoxidizer
executable is installed, try to run it:
$ pyoxidizer
PyOxidizer 0.5
Gregory Szorc <gregory.szorc@gmail.com>
Build and distribute Python applications
USAGE:
pyoxidizer [SUBCOMMAND]
...
Congratulations, PyOxidizer is installed! Now let’s move on to using it.
Your First PyOxidizer Project¶
The pyoxidizer init-config-file
command will create a new PyOxidizer
configuration file in a directory of your choosing:
$ pyoxidizer init-config-file pyapp
This should have printed out details on what happened and what to do next. If you actually ran this in a terminal, hopefully you don’t need to continue following the directions here as the printed instructions are sufficient! But if you aren’t, keep reading.
The default configuration created by pyoxidizer init-config-file
will
produce an executable that embeds Python and starts a Python REPL by default.
Let’s test that:
$ cd pyapp
$ pyoxidizer run
resolving 1 targets
resolving target exe
...
Compiling pyapp v0.1.0 (/tmp/pyoxidizer.nv7QvpNPRgL5/pyapp)
Finished dev [unoptimized + debuginfo] target(s) in 26.07s
writing executable to /home/gps/src/pyapp/build/x86_64-unknown-linux-gnu/debug/exe/pyapp
>>>
If all goes according to plan, you just started a Rust executable which started a Python interpreter, which started an interactive Python debugger! Try typing in some Python code:
>>> print("hello, world")
hello, world
It works!
(To exit the REPL, press CTRL+d or CTRL+z.)
Continue reading Managing Projects with pyoxidizer to learn more about the
pyoxidizer
tool. Or read on for a preview of how to customize your
application’s behavior.
Customizing Python and Packaging Behavior¶
Embedding Python in a Rust executable and starting a REPL is cool and all. But you probably want to do something more exciting.
The autogenerated pyoxidizer.bzl
file created as part of running
pyoxidizer init-config-file
defines how your application is configured
and built. It controls everything from what Python distribution to use,
which Python packages to install, how the embedded Python interpreter is
configured, and what code to run in that interpreter.
Open pyoxidizer.bzl
in your favorite editor and find the line passing a
run_repl
argument, which configures the embedded interpreter to run
a Python REPL. Let’s replace that line with the following:
run_eval="import uuid; print(uuid.uuid4())",
We’re now telling the interpreter to run the Python statement
eval(import uuid; print(uuid.uuid4())
when it starts. Test that out:
$ pyoxidizer run
...
Compiling pyapp v0.1.0 (/home/gps/src/pyapp)
Finished dev [unoptimized + debuginfo] target(s) in 3.92s
Running `target/debug/pyapp`
writing executable to /home/gps/src/pyapp/build/x86_64-unknown-linux-gnu/debug/exe/pyapp
96f776c8-c32d-48d8-8c1c-aef8a735f535
It works!
This is still pretty trivial. But it demonstrates how the pyoxidizer.bzl
is used to influence the behavior of built executables.
Let’s do something a little bit more complicated, like package an existing Python application!
Find the embedded = dist.to_embedded_resources(
line in the
pyoxidizer.bzl
file. Let’s add a new line to make_exe()
just
below where embedded
is assigned:
embedded.add_python_resources(dist.pip_install(["pyflakes==2.1.1"]))
In addition, replace the run_*
argument to execute pyflakes
:
run_eval="from pyflakes.api import main; main()",
Now let’s try building and running the new configuration:
$ pyoxidizer run -- --help
...
Compiling pyapp v0.1.0 (/home/gps/src/pyapp)
Finished dev [unoptimized + debuginfo] target(s) in 5.49s
writing executable to /home/gps/src/pyapp/build/x86_64-unknown-linux-gnu/debug/exe/pyapp
Usage: pyapp [options]
Options:
--version show program's version number and exit
-h, --help show this help message and exit
You’ve just produced an executable for pyflakes
!
There are far more powerful packaging and configuration settings available.
Read all about them at Configuration Files and Packaging User Guide. Or continue
on to Managing Projects with pyoxidizer to learn more about the pyoxidizer
tool.