|
|
|
---
|
|
|
|
short-description: Using meson projects as subprojects within other meson projects
|
|
|
|
...
|
|
|
|
|
|
|
|
# Subprojects
|
|
|
|
|
|
|
|
Some platforms do not provide a native packaging system. In these
|
|
|
|
cases it is common to bundle all third party libraries in your source
|
|
|
|
tree. This is usually frowned upon because it makes it hard to add
|
|
|
|
these kinds of projects into e.g. those Linux distributions that
|
|
|
|
forbid bundled libraries.
|
|
|
|
|
|
|
|
Meson tries to solve this problem by making it extremely easy to
|
|
|
|
provide both at the same time. The way this is done is that Meson
|
|
|
|
allows you to take any other Meson project and make it a part of your
|
|
|
|
build without (in the best case) any changes to its Meson setup. It
|
|
|
|
becomes a transparent part of the project. The basic idiom goes
|
|
|
|
something like this.
|
|
|
|
|
|
|
|
```meson
|
|
|
|
dep = dependency('foo', fallback : [subproject_name, variable_name])
|
|
|
|
```
|
|
|
|
|
|
|
|
As an example, suppose we have a simple project that provides a shared
|
|
|
|
library. It would be set up like this.
|
|
|
|
|
|
|
|
```meson
|
|
|
|
project('simple', 'c')
|
|
|
|
i = include_directories('include')
|
|
|
|
l = shared_library('simple', 'simple.c', include_directories : i, install : true)
|
|
|
|
simple_dep = declare_dependency(include_directories : i,
|
|
|
|
link_with : l)
|
|
|
|
```
|
|
|
|
|
|
|
|
Then we could use that from a master project. First we generate a
|
|
|
|
subdirectory called `subprojects` in the root of the master
|
|
|
|
directory. Then we create a subdirectory called `simple` and put the
|
|
|
|
subproject in that directory. Now the subproject can be used like
|
|
|
|
this.
|
|
|
|
|
|
|
|
```meson
|
|
|
|
project('master', 'c')
|
|
|
|
dep = dependency('simple', fallback : ['simple', 'simple_dep'])
|
|
|
|
exe = executable('prog', 'prog.c',
|
|
|
|
dependencies : dep, install : true)
|
|
|
|
```
|
|
|
|
|
|
|
|
With this setup the system dependency is used when it is available,
|
|
|
|
otherwise we fall back on the bundled version. If you wish to always
|
|
|
|
use the embedded version, then you would declare it like this:
|
|
|
|
|
|
|
|
```meson
|
|
|
|
simple_sp = subproject('simple')
|
|
|
|
dep = simple_sp.get_variable('simple_dep')
|
|
|
|
```
|
|
|
|
|
|
|
|
All Meson features of the subproject, such as project options keep
|
|
|
|
working and can be set in the master project. There are a few
|
|
|
|
limitations, the most important being that global compiler arguments
|
|
|
|
must be set in the main project before calling subproject. Subprojects
|
|
|
|
must not set global arguments because there is no way to do that
|
|
|
|
reliably over multiple subprojects. To check whether you are running
|
|
|
|
as a subproject, use the `is_subproject` function.
|
|
|
|
|
|
|
|
It should be noted that this only works for subprojects that are built
|
|
|
|
with Meson. It can not be used with any other build system. The reason
|
|
|
|
is the simple fact that there is no possible way to do this reliably
|
|
|
|
with mixed build systems.
|
|
|
|
|
|
|
|
Subprojects can use other subprojects, but all subprojects must reside
|
|
|
|
in the top level `subprojects` directory. Recursive use of subprojects
|
|
|
|
is not allowed, though, so you can't have subproject `a` that uses
|
|
|
|
subproject `b` and have `b` also use `a`.
|
|
|
|
|
|
|
|
# Command-line options
|
|
|
|
|
|
|
|
The usage of subprojects can be controlled by users and distros with
|
|
|
|
the following command-line options:
|
|
|
|
|
|
|
|
* **--wrap-mode=nodownload**
|
|
|
|
|
|
|
|
Meson will not use the network to download any subprojects or
|
|
|
|
fetch any wrap information. Only pre-existing sources will be used.
|
|
|
|
This is useful (mostly for distros) when you want to only use the
|
|
|
|
sources provided by a software release, and want to manually handle
|
|
|
|
or provide missing dependencies.
|
|
|
|
|
|
|
|
* **--wrap-mode=nofallback**
|
|
|
|
|
|
|
|
Meson will not use subproject fallbacks for any dependency
|
|
|
|
declarations in the build files, and will only look for them in the
|
|
|
|
system. Note that this does not apply to unconditional subproject()
|
|
|
|
calls, and those are meant to be used for sources that cannot be
|
|
|
|
provided by the system, such as copylibs.
|
|
|
|
|
|
|
|
* **--wrap-mode=forcefallback**
|
|
|
|
|
|
|
|
Meson will not look at the system for any dependencies which have
|
|
|
|
subproject fallbacks available, and will *only* use subprojects for
|
|
|
|
them. This is useful when you want to test your fallback setup, or
|
|
|
|
want to specifically build against the library sources provided by
|
|
|
|
your subprojects.
|
|
|
|
|
|
|
|
# Obtaining subprojects
|
|
|
|
|
|
|
|
Meson ships with a dependency system to automatically obtain
|
|
|
|
dependency subprojects. It is documented in the [Wrap dependency
|
|
|
|
system manual](Wrap-dependency-system-manual.md).
|
|
|
|
|
|
|
|
# Why must all subprojects be inside a single directory?
|
|
|
|
|
|
|
|
There are several reasons.
|
|
|
|
|
|
|
|
First of all, to maintain any sort of sanity, the system must prevent going
|
|
|
|
inside other subprojects with `subdir()` or variations thereof. Having the
|
|
|
|
subprojects in well defined places makes this easy. If subprojects could be
|
|
|
|
anywhere at all, it would be a lot harder.
|
|
|
|
|
|
|
|
Second of all it is extremely important that end users can easily see what
|
|
|
|
subprojects any project has. Because they are in one, and only one, place,
|
|
|
|
reviewing them becomes easy.
|
|
|
|
|
|
|
|
This is also a question of convention. Since all Meson projects have the same
|
|
|
|
layout w.r.t subprojects, switching between projects becomes easier. You don't
|
|
|
|
have to spend time on a new project traipsing through the source tree looking
|
|
|
|
for subprojects. They are always in the same place.
|
|
|
|
|
|
|
|
Finally if you can have subprojects anywhere, this increases the possibility of
|
|
|
|
having many different (possibly incompatible) versions of a dependency in your
|
|
|
|
source tree. Then changing some code (such as changing the order you traverse
|
|
|
|
directories) may cause a completely different version of the subproject to be
|
|
|
|
used by accident.
|