# 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
```
