The Meson Build System
http://mesonbuild.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
5.7 KiB
150 lines
5.7 KiB
# An in-depth tutorial |
|
|
|
In this tutorial we set up a project with multiple targets, unit tests |
|
and dependencies between targets. Our main product is a shared library |
|
called *foo* that is written in `C++11`. We are going to ignore the |
|
contents of the source files, as they are not really important from a |
|
build definition point of view. The library makes use of the `GLib` |
|
library so we need to detect and link it properly. We also make the |
|
resulting library installable. |
|
|
|
The source tree contains three subdirectories `src`, `include` and |
|
`test` that contain, respectively, the source code, headers and unit |
|
tests of our project. |
|
|
|
To start things up, here is the top level `meson.build` file. |
|
|
|
```meson |
|
project('c++ foolib', 'cpp', |
|
version : '1.0.0', |
|
license : 'MIT') |
|
add_global_arguments('-DSOME_TOKEN=value', language : 'cpp') |
|
glib_dep = dependency('glib-2.0') |
|
|
|
inc = include_directories('include') |
|
|
|
subdir('include') |
|
subdir('src') |
|
subdir('test') |
|
|
|
pkg_mod = import('pkgconfig') |
|
pkg_mod.generate(libraries : foolib, |
|
version : '1.0', |
|
name : 'libfoobar', |
|
filebase : 'foobar', |
|
description : 'A Library to barnicate your foos.') |
|
``` |
|
|
|
The definition always starts with a call to the `project` function. In |
|
it you must specify the project's name and programming languages to |
|
use, in this case only `C++`. We also specify two additional |
|
arguments, the project's version and the license it is under. Our |
|
project is version `1.0.0` and is specified to be under the MIT |
|
license. |
|
|
|
Then we find GLib, which is an *external dependency*. The `dependency` |
|
function tells Meson to find the library (by default using |
|
`pkg-config`). If the library is not found, Meson will raise an error |
|
and stop processing the build definition. |
|
|
|
Then we add a global compiler argument `-DSOME_TOKEN=value`. This flag |
|
is used for *all* C++ source file compilations. It is not possible to |
|
unset it for some targets. The reason for this is that it is hard to |
|
keep track of what compiler flags are in use if global settings change |
|
per target. |
|
|
|
Since `include` directory contains the header files, we need a way to |
|
tell compilations to add that directory to the compiler command line. |
|
This is done with the `include_directories` command that takes a |
|
directory and returns an object representing this directory. It is |
|
stored in variable `inc` which makes it accessible later on. |
|
|
|
After this are three `subdir` commands. These instruct Meson to go to |
|
the specified subdirectory, open the `meson.build` file that's in |
|
there and execute it. The last few lines are a stanza to generate a |
|
`pkg-config` file. We'll skip that for now and come back to it at the |
|
end of this document. |
|
|
|
The first subdirectory we go into is `include`. In it we have a a |
|
header file for the library that we want to install. This requires one |
|
line. |
|
|
|
```meson |
|
install_headers('foolib.h') |
|
``` |
|
|
|
This installs the given header file to the system's header directory. |
|
This is by default `/[install prefix]/include`, but it can be changed |
|
with a command line argument. |
|
|
|
The Meson definition of `src` subdir is simple. |
|
|
|
```meson |
|
foo_sources = ['source1.cpp', 'source2.cpp'] |
|
foolib = shared_library('foo', |
|
foo_sources, |
|
include_directories : inc, |
|
dependencies : glib_dep, |
|
install : true) |
|
``` |
|
|
|
Here we just tell Meson to build the library with the given sources. |
|
We also tell it to use the include directories we stored to variable |
|
`inc` earlier. Since this library uses GLib, we tell Meson to add all |
|
necessary compiler and linker flags with the `dependencies` keyword |
|
argument. Its value is `glib_dep` which we set at the top level |
|
`meson.build` file. The `install` argument tells Meson to install the |
|
result. As with the headers, the shared library is installed to the |
|
system's default location (usually `/[install prefix]/lib`) but is |
|
again overridable. |
|
|
|
The resulting library is stored in variable `foolib` just like the |
|
include directory was stored in the previous file. |
|
|
|
Once Meson has processed the `src` subdir it returns to the main Meson |
|
file and executes the next line that moves it into the `test` subdir. |
|
Its contents look like this. |
|
|
|
```meson |
|
testexe = executable('testexe', 'footest.cpp', |
|
include_directories : inc, |
|
link_with : foolib) |
|
test('foolib test', testexe) |
|
``` |
|
|
|
First we build a test executable that has the same include directory |
|
as the main library and which also links against the freshly built |
|
shared library. Note that you don't need to specify `glib_dep` here |
|
just to be able to use the built library `foolib`. If the executable |
|
used GLib functionality itself, then we would of course need to add it |
|
as a keyword argument here. |
|
|
|
Finally we define a test with the name `foolib test`. It consists of |
|
running the binary we just built. If the executable exits with a zero |
|
return value, the test is considered passed. Nonzero return values |
|
mark the test as failed. |
|
|
|
At this point we can return to the pkg-config generator line. All |
|
shared libraries should provide a pkg-config file, which explains how |
|
that library is used. Meson provides this simple generator that should |
|
be sufficient for most simple projects. All you need to do is list a |
|
few basic pieces of information and Meson takes care of generating an |
|
appropriate file. More advanced users might want to create their own |
|
pkg-config files using Meson's [configuration file generator |
|
system](Configuration.md). |
|
|
|
With these four files we are done. To configure, build and run the |
|
test suite, we just need to execute the following commands (starting |
|
at source tree root directory). |
|
|
|
```console |
|
$ meson builddir && cd builddir |
|
$ meson compile |
|
$ meson test |
|
``` |
|
|
|
To then install the project you only need one command. |
|
|
|
```console |
|
$ meson install |
|
```
|
|
|