Building the Application¶
The app
directory and its subdirectories contain meson.build
files that
describe how the application is built. These are used by the Meson build
tool to configure the build process.
Meson is usually run so that it creates a build directory. This is where all the resources are put so that the Ninja build tool can perform the actual process of building and installing the application.
Top-Level Build File¶
In the app
directory itself, the meson.build
file begins with a
declaration of the project name, version and build system requirements:
# Define the project and its metadata.
project('pictures',
version: '0.1.0',
meson_version: '>= 0.40.0',
)
# Import the i18n module to allow other build scripts to access its features.
i18n = import('i18n')
# Declare the project's subdirectories.
subdir('data')
subdir('src')
subdir('po')
# Add a script to handle tasks that are not automatically performed by Meson.
meson.add_install_script('build-aux/meson/postinstall.py')
We also declare the data
and src
subdirectories, causing Meson to
examine them for any meson.build
files they may contain.
The last line causes a special script to be run after installation. It is not important to know what this is doing at this point.
Sources Build File¶
The meson.build
file in the src
directory describes how the source
files are processed when the build occurs:
# Initialize local variables to hold installation paths.
localedir = join_paths(get_option('prefix'), get_option('localedir'))
pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name())
moduledir = join_paths(pkgdatadir, meson.project_name())
# Find the python3 program to help define the PYTHON configuration variable
# that will be used in the pictures.in template.
python3 = find_program('python3')
conf = configuration_data()
conf.set('PYTHON', python3.path())
conf.set('VERSION', meson.project_version())
conf.set('localedir', localedir)
conf.set('pkgdatadir', pkgdatadir)
conf.set('project_name', meson.project_name())
# Replace placeholders in templates with the configuration data defined above
# and create the versions of these files for installation in the build
# directory.
configure_file(
input: 'pictures.in',
output: 'pictures',
configuration: conf,
install: true,
install_dir: get_option('bindir')
)
# Declare the application's sources and their installation directory.
sources = [
'__init__.py',
'main.py',
'widgets.py'
]
install_data(sources, install_dir: moduledir)
In this case, we instruct Meson to take the pictures.in
file in the src
directory and copy it into the build directory as pictures
–
this is the name given as the executable in the desktop entry file.
We also declare that the file should be installed, and that its installation
directory is the system location for executables (bindir
).
Data Build File¶
The meson.build
file in the data
describes how the data files are
processed when the build occurs:
# Translate the desktop file template using the message catalogs from the po
# directory, found in the project's root, generating a desktop file in the
# build directory.
desktop_file = i18n.merge_file(
input: 'com.example.pictures.desktop.in',
output: 'com.example.pictures.desktop',
type: 'desktop',
po_dir: '../po',
install: true,
install_dir: join_paths(get_option('datadir'), 'applications')
)
# If found, use a tool to validate the desktop file.
desktop_utils = find_program('desktop-file-validate', required: false)
if desktop_utils.found()
test('Validate desktop file', desktop_utils,
args: [desktop_file]
)
endif
# Also generate an AppStream file from the template.
appstream_file = i18n.merge_file(
input: 'com.example.pictures.appdata.xml.in',
output: 'com.example.pictures.appdata.xml',
po_dir: '../po',
install: true,
install_dir: join_paths(get_option('datadir'), 'appdata')
)
# Verify the AppStream file with the appropriate tool, if found.
appstream_util = find_program('appstream-util', required: false)
if appstream_util.found()
test('Validate appstream file', appstream_util,
args: ['validate', appstream_file]
)
endif
install_data('com.example.pictures.svg',
install_dir: join_paths(get_option('datadir'), 'icons', 'hicolor', 'scalable', 'apps'))
Here, we tell Meson to copy the com.example.pictures.desktop.in
file into the build directory
as com.example.pictures.desktop
. We also declare that it should be installed, and
that its installation directory is the applications
subdirectory of the
system location for data files (datadir
).
The com.example.pictures.svg
file is more easily described to
Meson. It will be installed in the appropriate subdirectory of the system
location for data files that is used for icons.
Building using Meson and Ninja¶
When building the application for deployment on the phone, we will use Flatpak to coordinate the build process. However, behind the scenes, we are using Meson and Ninja to perform the actual configuration and build. If you want to try and build the application for testing on your workstation, you can follow the steps below to build, install, and finally uninstall it.
To configure the build on the command line, enter the app
directory and
run Meson, specifying the source and build directories:
meson . _build
Build the application using Ninja, passing the build directory as an argument so that the build occurs within that directory. There is no need to specify a build rule because the default rule builds the application:
ninja -C _build
Finally, use sudo
to install the application in a standard location on your
system using the install
build rule:
sudo ninja -C _build install
To uninstall the application, run its uninstall
rule:
sudo ninja -C _build uninstall
All of the files that were installed should now have been cleanly removed from system locations.
Summary¶
We have examined the contents of some meson.build
files to see how simple
rules are used to describe the configuration process. We have also seen how
Meson and Ninja are used to configure and build the application.
The application can also be packaged for more convenient installation using the Flatpak framework. This is the subject of the next part of the example.