Meson — a new build system
Divide and Conquer
To compile your source code, you first need to create a new subdirectory that stores all the output from the compiler. This build directory is mandatory: Meson insists on a separate directory and cannot be tricked into storing the object files in the source directory.
This apparent tutelage has several advantages: For one, it keeps the files output from the compiler separate from the source code, improving understandability, especially of complex projects, and making sure the object files do not fall into the clutches of a version control system. On the other hand, you can simultaneously create several independent builds with different configurations. Thus, one build directory could contain the release version while a second houses a debug version.
How you name these build directories, and where they are, is up to you. In most cases, the default build directory is located at the top level of the source directory and is simply called build
:
cd helloworld/src mkdir build
The developer has to let Meson set up the new build directory (see also Figure 1):
meson ~/helloworld/src ~/helloworld/src/build
The first parameter specifies the directory containing the source code, which also houses the meson.build
file. The second parameter reveals the build directory. In it, Meson now creates all the necessary configuration files or build files for Ninja. From this, the developer can now build the actual program:
cd build ninja
Ninja automatically integrates all available processor cores. If you later want to recompile your program, a call to ninja
in the build
directory is all it takes. Further commands are not required. Meson has set up Ninja so that it automatically detects source code file changes and only rebuilds these – even with a subsequent edit of the meson.build
file.
By default, the compiler inserts debug information in the binaries and outputs all warnings. If the GCC compiler is used, Meson enables the -g
and -Wall
parameters. If you need an optimized program for a release, you will want to call Meson with the --buildtype=release
parameter. How to take further control over the compilation process is reveals in the "Full Control" box.
Full Control
Meson decides for itself which compiler to invoke and with what parameters. However, developers occasionally want to control the compilation process themselves – for example, to put together a package for a specific distribution. Again, this is no problem. You can specify which compiler to use with environment variables. For example, to use Clang instead of GCC:
CC=clang meson ~/helloworld/src \ ~/helloworld/src/build
You can even specify or override compiler flags by setting the appropriate environment variables before calling meson
. The --buildtype=plain
also disables Meson's own defaults:
CFLAGS="-o2" meson \ --buildtype=plain \ ~/helloworld/src ~/helloworld/build
If you want Ninja to install the compiled program, the target directory can be set in the DESTDIR
environmental variable:
DESTDIR=/opt/helloworld ninja install
Or, you can simply specify a different prefix with: ninja install --prefix /usr
On Linux, Meson always uses Ninja as the back end. A project for Visual Studio 2010 is created by the --backend=vs2010
parameter; Meson generates the equivalent for Xcode with --backend=xcode
. Ninja can also install the compiled program directly. To this end, you just call ninja install
.
Object of Desire
The programming language used by Meson in meson.build
is object-oriented. Although developers cannot implement classes themselves, some functions do return an object. For example, shared_library()
returns an object that represents the corresponding build target. This can be captured in a variable:
lib = static_library('hello', ['lib1.c','lib2.c'])
You then need to pass the object as an argument to another function – for example, to executable()
which links the program directly against the library:
executable('hello', 'main.c', link_with : lib)
If you use the functions defined in lib2.c
, you will probably want to check them with a test program first. You do not need to link this against the complete dynamic library – just against the lib2.c
object file.
Luckily, the object returned by shared_library()
itself has an extract_objects
method, which in turn returns an object file. You need to invoke this method in dot notation as in many object-oriented languages:
obj = lib.extract_objects('lib2.c')
The returned object can now be linked with the program:
executable('hello', 'main.c', objects : obj)
Many other objects support methods that programmers can call and use in a similar way.
Walking the Tree
If the source code is stored in subdirectories, the subdir
function changes to one of the subdirectories – in the following example, to the gui/
directory:
subdir('gui')
Meson then evaluates the configuration file meson.build
in this directory. However, it must not use a project
function, because the parent meson.build
already defines a project. If the header files for C or C++ projects are stored in the include
subdirectory, you can add them to the compiler's search path as follows:
header = include_directories('include') executable('hello', 'main.c',include_dirs : header)
Most major projects use external libraries like zlib
or the Gtk toolkit. To include such a library, only two lines are needed:
gtk = dependency('gtk+-3.0') executable('hello', 'main.c', deps : gtk)
The dependency()
function first checks to see whether the library is installed on the system. If it is missing, it aborts the build process; otherwise, Meson links it with the hello
program.
This automatic mechanism works with all libraries that supply a pkg-config
. Fortunately, Meson natively supports some particularly well-known frameworks without this file. Currently, these include Boost, Qt5, Google Test (gtest), and Google Mock (gmock).
In the case of Boost, you can thus easily select the desired modules using the following:
boost = dependency('boost', modules : ['thread', 'utility'])
Meson supports if
conditions that allow for more elaborate tests. Listing 2 shows an example: In a C project, it checks whether the sys/fstat.h
header file is available. To be able to do this, Meson is handed the compiler in the first line. The second line then asks the compiler whether the header file exists (see Figure 2).
Listing 2
Conditional Branching
« Previous 1 2 3 Next »
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
So Long Neofetch and Thanks for the Info
Today is a day that every Linux user who enjoys bragging about their system(s) will mourn, as Neofetch has come to an end.
-
Ubuntu 24.04 Comes with a “Flaw"
If you're thinking you might want to upgrade from your current Ubuntu release to the latest, there's something you might want to consider before doing so.
-
Canonical Releases Ubuntu 24.04
After a brief pause because of the XZ vulnerability, Ubuntu 24.04 is now available for install.
-
Linux Servers Targeted by Akira Ransomware
A group of bad actors who have already extorted $42 million have their sights set on the Linux platform.
-
TUXEDO Computers Unveils Linux Laptop Featuring AMD Ryzen CPU
This latest release is the first laptop to include the new CPU from Ryzen and Linux preinstalled.
-
XZ Gets the All-Clear
The back door xz vulnerability has been officially reverted for Fedora 40 and versions 38 and 39 were never affected.
-
Canonical Collaborates with Qualcomm on New Venture
This new joint effort is geared toward bringing Ubuntu and Ubuntu Core to Qualcomm-powered devices.
-
Kodi 21.0 Open-Source Entertainment Hub Released
After a year of development, the award-winning Kodi cross-platform, media center software is now available with many new additions and improvements.
-
Linux Usage Increases in Two Key Areas
If market share is your thing, you'll be happy to know that Linux is on the rise in two areas that, if they keep climbing, could have serious meaning for Linux's future.
-
Vulnerability Discovered in xz Libraries
An urgent alert for Fedora 40 has been posted and users should pay attention.