Building the Application¶
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.
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('proximity', 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
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.
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 proximity.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: 'proximity.in', output: 'proximity', configuration: conf, install: true, install_dir: get_option('bindir') ) # Declare the application's sources and their installation directory. sources = [ '__init__.py', 'main.py', 'sensor.py' ] install_data(sources, install_dir: moduledir)
In this case, we instruct Meson to take the
proximity.in file in the
directory and copy it into the build directory as
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 (
meson.build file in the
data describes how the data files are
processed when the build occurs:
# Initialize a local variable to hold an installation path. pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) # 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.proximity.desktop.in', output: 'com.example.proximity.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.proximity.appdata.xml.in', output: 'com.example.proximity.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 the application icon to the appropriate locations for its theme. install_data('com.example.proximity.svg', install_dir: join_paths(get_option('datadir'), 'icons', 'hicolor', 'scalable', 'apps'))
Here, we tell Meson to copy the
com.example.proximity.desktop.in file into the build directory
com.example.proximity.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 (
com.example.proximity.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.
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
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
sudo ninja -C _build uninstall
All of the files that were installed should now have been cleanly removed from system locations.
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.