Hello everyone again. Today I would like to continue where I left off in the first part of this post.

In the first part we saw how to add an executable and a dependency. Today I am going to talk in a bit more detail how to manage basic dependencies in Meson. Namely, how to manage internal dependencies and external dependencies. I will limit the scope of the post to libraries, executables and using dependency and declare_dependency.

In this post I reply to the question of how are basic targets with dependencies managed from the user-side in Meson.

In Meson, these are the basic targets you can have:

executable

shared_library

static_library

library

both_libraries

All these targets are shortcuts for build_target.

There are other targets such as run_target and custom_target but they will be left out of scope for this post.

In Meson all these targets are reasonably documented functions that should be easy to use for anyone familiar with Python or any mainstream language.

Functions in meson have a name, take zero or more positional arguments and optional keyword arguments. Functions return either void or a well defined object, with its own methods, that are also documented in the reference. Forget about doing string gymnastics as it is common in CMake: you can declare a target and get a result like this, with regular variable syntax:

startingmeson_lib = library('startingmeson', sources : ['myroutine.cpp', 'myroutine.hpp'])

You can include your header files as sources: Meson will do the right thing and this is useful, as far as my knowledge goes, for showing the files related to a target in IDEs.

Please note that what goes to the right of a keyword argument is not a keyword argument (in bold), but a regular function, even if it has the same name:

startingmeson2_lib = library('startingmeson', sources : ['myroutine2.cpp'], include_directories : include_directories('include'))

The “keyword argument matching function name” pattern is common in Meson.

The two examples above will create a library and return the library object with its corresponding methods for inspecting or passing that object around, as a regular object in most well-known languages do.

Plain library target prefers shared libraries so this would create a .dll in Windows, a .so in Linux and a .dylib in Mac unless you change the default library option with -Ddefault_library=static. You can also fix the result of the output with any of static_library, shared_library or both_libraries, which create only static, only shared or both at the same time respectively.

The build targets have plenty of keyword arguments, such as include_directories, cpp_args, link_with and dependencies, which are documented in the reference. Just search for the words static_library, shared_library, build_target, etc. You can also find usage examples in the manual.