Building a Python Project With Meson
I have already shown how to build a Vala program with Meson. In this post, I will show how to do the same for Python. You don’t really need to compile an interpreted language but Meson helps you to put the files in their correct installation directory.
Let’s say we have a program, called hello.py
that we want to install
using Meson. The first thing that we need to do is to make it executable
without the python
keyword. We can do it using something called
shebang. Shebang is a character sequence on the first line of the file
that tells the computer how to run the script. It starts with a #!
and
everything after that is the interpreter path.
#!/usr/bin/python3
if __name__ == '__main__':
print('Hello World')
Now if we will set the executable bit on (using chmod +x hello.py
) we
will be able to run the file like elf (executable) files. But the file
is not in the path yet and we don’t want to do it manually every time we
change something so for that we will use Meson.
Like with our Vala example, we will first declare our project using the
project
function. After that, we will copy the script using the
install_data
function to the binary directory (called bindir
in
Meson).
project('hello',
version: '1.0.0',
meson_version: '>= 0.50.0',
)
install_data('hello.py', install_dir: get_option('bindir'))
Assuming your executable file is called hello.py
and your build file
is called meson.build
you can put the script in the path by building
and installing the project:
meson build
sudo ninja -C build install
That was easy, but let’s make it more portable by replacing our
hardcoded python path with the correct python path on the system. We can
use /usr/bin/env
to do it but I want to use this opportunity to show
you how to use configuration variables with Meson. To do it we will
initialize a new configuration dictionary with the
configuration_data
function. To add a new value to the dictionary
we will call the set method on the configuration dictionary with the key
and the value.
To get the path of Python 3 on our system we can use the
find_python
function from the Python 3 module, just don’t forget
to import it first.
Now to use the configuration data we will use the configure_file
function instead of the install_data
function. We will pass it the
input file name, output file name, configuration, and install path. The
result should look like this:
project('hello',
version: '1.0.0',
meson_version: '>= 0.50.0',
)
python3 = import('python3')
conf = configuration_data()
conf.set('PYTHON', python3.find_python().path())
configure_file(
input: 'hello.in',
output: 'hello',
configuration: conf,
install: true,
install_dir: get_option('bindir')
)
Now we just need to add the PYTHON parameter in our code surrounded by @ and it will be replaced by the actual path. This is our final Python script:
#!@PYTHON@
if __name__ == '__main__':
print('Hello World')
That’s it, now you have a Python script as the command hello.