aboutsummaryrefslogtreecommitdiffstats
path: root/meson/docs/markdown/IndepthTutorial.md
diff options
context:
space:
mode:
Diffstat (limited to 'meson/docs/markdown/IndepthTutorial.md')
-rw-r--r--meson/docs/markdown/IndepthTutorial.md150
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
+```