diff options
Diffstat (limited to 'meson/docs/markdown/IndepthTutorial.md')
-rw-r--r-- | meson/docs/markdown/IndepthTutorial.md | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/meson/docs/markdown/IndepthTutorial.md b/meson/docs/markdown/IndepthTutorial.md new file mode 100644 index 000000000..edbbe5508 --- /dev/null +++ b/meson/docs/markdown/IndepthTutorial.md @@ -0,0 +1,150 @@ +# 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 +``` |