2017-03-30 02:03:43 +08:00
|
|
|
# Wrap dependency system manual
|
|
|
|
|
2017-08-21 05:08:28 +08:00
|
|
|
One of the major problems of multiplatform development is wrangling
|
2020-01-08 05:44:31 +08:00
|
|
|
all your dependencies. This is awkward on many platforms, especially
|
|
|
|
on ones that do not have a built-in package manager. The latter problem
|
2019-11-09 00:18:38 +08:00
|
|
|
has been worked around by having third party package managers. They
|
|
|
|
are not really a solution for end user deployment, because you can't
|
|
|
|
tell them to install a package manager just to use your app. On these
|
2020-01-08 18:09:27 +08:00
|
|
|
platforms you must produce self-contained applications. Same applies
|
|
|
|
when destination platform is missing (up-to-date versions of) your
|
|
|
|
application's dependencies.
|
2017-08-21 05:08:28 +08:00
|
|
|
|
|
|
|
The traditional approach to this has been to bundle dependencies
|
|
|
|
inside your own project. Either as prebuilt libraries and headers or
|
|
|
|
by embedding the source code inside your source tree and rewriting
|
|
|
|
your build system to build them as part of your project.
|
|
|
|
|
|
|
|
This is both tedious and error prone because it is always done by
|
|
|
|
hand. The Wrap dependency system of Meson aims to provide an automated
|
|
|
|
way to do this.
|
2017-03-30 02:03:43 +08:00
|
|
|
|
|
|
|
## How it works
|
|
|
|
|
2017-08-21 05:08:28 +08:00
|
|
|
Meson has a concept of [subprojects](Subprojects.md). They are a way
|
|
|
|
of nesting one Meson project inside another. Any project that builds
|
|
|
|
with Meson can detect that it is built as a subproject and build
|
|
|
|
itself in a way that makes it easy to use (usually this means as a
|
|
|
|
static library).
|
2017-03-30 02:03:43 +08:00
|
|
|
|
2017-08-21 05:08:28 +08:00
|
|
|
To use this kind of a project as a dependency you could just copy and
|
2020-03-21 18:54:00 +08:00
|
|
|
extract it inside your project's `subprojects` directory.
|
2018-10-22 01:05:33 +08:00
|
|
|
|
|
|
|
However there is a simpler way. You can specify a Wrap file that tells Meson
|
2020-03-21 18:54:00 +08:00
|
|
|
how to download it for you. If you then use this subproject in your build,
|
2018-10-22 01:05:33 +08:00
|
|
|
Meson will automatically download and extract it during build. This makes
|
|
|
|
subproject embedding extremely easy.
|
|
|
|
|
|
|
|
All wrap files must have a name of `<project_name>.wrap` form and be in `subprojects` dir.
|
|
|
|
|
2020-03-21 18:54:00 +08:00
|
|
|
Currently Meson has four kinds of wraps:
|
2018-10-22 01:05:33 +08:00
|
|
|
- wrap-file
|
|
|
|
- wrap-git
|
2019-11-09 00:18:38 +08:00
|
|
|
- wrap-hg
|
|
|
|
- wrap-svn
|
2018-10-22 01:05:33 +08:00
|
|
|
|
2019-11-09 00:18:38 +08:00
|
|
|
## wrap format
|
2018-10-22 01:05:33 +08:00
|
|
|
|
2019-11-09 00:18:38 +08:00
|
|
|
Wrap files are written in ini format, with a single header containing the type
|
|
|
|
of wrap, followed by properties describing how to obtain the sources, validate
|
|
|
|
them, and modify them if needed. An example wrap-file for the wrap named
|
|
|
|
`libfoobar` would have a filename `libfoobar.wrap` and would look like this:
|
2017-03-30 02:03:43 +08:00
|
|
|
|
|
|
|
```ini
|
|
|
|
[wrap-file]
|
|
|
|
directory = libfoobar-1.0
|
|
|
|
|
2017-05-03 10:17:24 +08:00
|
|
|
source_url = https://example.com/foobar-1.0.tar.gz
|
2017-03-30 02:03:43 +08:00
|
|
|
source_filename = foobar-1.0.tar.gz
|
|
|
|
source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663
|
|
|
|
```
|
|
|
|
|
2019-11-09 00:18:38 +08:00
|
|
|
An example wrap-git will look like this:
|
2017-03-30 02:03:43 +08:00
|
|
|
|
2019-11-09 00:18:38 +08:00
|
|
|
```ini
|
|
|
|
[wrap-git]
|
|
|
|
url = https://github.com/libfoobar/libfoobar.git
|
|
|
|
revision = head
|
|
|
|
```
|
|
|
|
|
|
|
|
## Accepted configuration properties for wraps
|
|
|
|
- `directory` - name of the subproject root directory, defaults to the name of the wrap.
|
|
|
|
|
2018-10-18 08:07:04 +08:00
|
|
|
Since *0.55.0* those can be used in all wrap types, they were previously reserved to `wrap-file`:
|
2020-04-21 07:14:49 +08:00
|
|
|
|
2019-11-09 00:18:38 +08:00
|
|
|
- `patch_url` - download url to retrieve an optional overlay archive
|
2020-04-10 22:10:10 +08:00
|
|
|
- `patch_fallback_url` - fallback URL to be used when download from `patch_url` fails *Since: 0.55.0*
|
2019-11-09 00:18:38 +08:00
|
|
|
- `patch_filename` - filename of the downloaded overlay archive
|
|
|
|
- `patch_hash` - sha256 checksum of the downloaded overlay archive
|
2020-05-29 01:22:57 +08:00
|
|
|
- `patch_directory` - *Since 0.55.0* Overlay directory, alternative to `patch_filename` in the case
|
|
|
|
files are local instead of a downloaded archive. The directory must be placed in
|
|
|
|
`subprojects/packagefiles`.
|
2018-10-18 08:07:04 +08:00
|
|
|
|
|
|
|
### Specific to wrap-file
|
|
|
|
- `source_url` - download url to retrieve the wrap-file source archive
|
|
|
|
- `source_fallback_url` - fallback URL to be used when download from `source_url` fails *Since: 0.55.0*
|
|
|
|
- `source_filename` - filename of the downloaded source archive
|
|
|
|
- `source_hash` - sha256 checksum of the downloaded source archive
|
2019-11-09 00:18:38 +08:00
|
|
|
- `lead_directory_missing` - for `wrap-file` create the leading
|
|
|
|
directory name. Needed when the source file does not have a leading
|
|
|
|
directory.
|
|
|
|
|
2020-03-21 18:54:00 +08:00
|
|
|
Since *0.55.0* it is possible to use only the `source_filename` and
|
|
|
|
`patch_filename` value in a .wrap file (without `source_url` and `patch_url`) to
|
|
|
|
specify a local archive in the `subprojects/packagefiles` directory. The `*_hash`
|
|
|
|
entries are optional when using this method. This method should be prefered over
|
|
|
|
the old `packagecache` approach described below.
|
|
|
|
|
2019-11-09 00:18:38 +08:00
|
|
|
Since *0.49.0* if `source_filename` or `patch_filename` is found in the
|
|
|
|
project's `subprojects/packagecache` directory, it will be used instead
|
|
|
|
of downloading the file, even if `--wrap-mode` option is set to
|
|
|
|
`nodownload`. The file's hash will be checked.
|
|
|
|
|
|
|
|
### Specific to VCS-based wraps
|
|
|
|
- `url` - name of the wrap-git repository to clone. Required.
|
|
|
|
- `revision` - name of the revision to checkout. Must be either: a
|
|
|
|
valid value (such as a git tag) for the VCS's `checkout` command, or
|
|
|
|
(for git) `head` to track upstream's default branch. Required.
|
|
|
|
|
2020-04-05 11:56:33 +08:00
|
|
|
### Specific to wrap-git
|
2019-11-09 00:18:38 +08:00
|
|
|
- `depth` - shallowly clone the repository to X number of commits. Note
|
|
|
|
that git always allow shallowly cloning branches, but in order to
|
|
|
|
clone commit ids shallowly, the server must support
|
|
|
|
`uploadpack.allowReachableSHA1InWant=true`. *(since 0.52.0)*
|
|
|
|
- `push-url` - alternative url to configure as a git push-url. Useful if
|
|
|
|
the subproject will be developed and changes pushed upstream.
|
|
|
|
*(since 0.37.0)*
|
|
|
|
- `clone-recursive` - also clone submodules of the repository
|
|
|
|
*(since 0.48.0)*
|
2018-10-06 00:07:46 +08:00
|
|
|
|
2018-10-22 01:05:33 +08:00
|
|
|
## wrap-file with Meson build patch
|
|
|
|
|
2017-08-21 05:08:28 +08:00
|
|
|
Unfortunately most software projects in the world do not build with
|
2019-11-09 00:18:38 +08:00
|
|
|
Meson. Because of this Meson allows you to specify a patch URL.
|
2018-10-22 01:05:33 +08:00
|
|
|
|
2019-11-09 00:18:38 +08:00
|
|
|
For historic reasons this is called a "patch", however, it serves as an
|
|
|
|
overlay to add or replace files rather than modifying them. The file
|
|
|
|
must be an archive; it is downloaded and automatically extracted into
|
|
|
|
the subproject. The extracted files will include a meson build
|
|
|
|
definition for the given subproject.
|
2017-03-30 02:03:43 +08:00
|
|
|
|
2017-08-21 05:08:28 +08:00
|
|
|
This approach makes it extremely simple to embed dependencies that
|
|
|
|
require build system changes. You can write the Meson build definition
|
|
|
|
for the dependency in total isolation. This is a lot better than doing
|
|
|
|
it inside your own source tree, especially if it contains hundreds of
|
|
|
|
thousands of lines of code. Once you have a working build definition,
|
|
|
|
just zip up the Meson build files (and others you have changed) and
|
|
|
|
put them somewhere where you can download them.
|
2017-03-30 02:03:43 +08:00
|
|
|
|
2020-07-05 00:39:24 +08:00
|
|
|
Prior to *0.55.0* Meson build patches were only supported for wrap-file mode.
|
|
|
|
When using wrap-git, the repository must contain all Meson build definitions.
|
|
|
|
Since *0.55.0* Meson build patches are supported for any wrap modes, including
|
|
|
|
wrap-git.
|
2019-09-18 14:45:46 +08:00
|
|
|
|
2020-04-05 11:56:33 +08:00
|
|
|
## `provide` section
|
|
|
|
|
|
|
|
*Since *0.55.0*
|
|
|
|
|
|
|
|
Wrap files can define the dependencies it provides in the `[provide]` section.
|
2020-07-05 00:39:24 +08:00
|
|
|
|
|
|
|
```
|
|
|
|
[provide]
|
|
|
|
dependency_names = foo-1.0
|
|
|
|
```
|
|
|
|
|
|
|
|
When a wrap file provides the dependency `foo-1.0`, as above, any call to
|
|
|
|
`dependency('foo-1.0')` will automatically fallback to that subproject even if
|
|
|
|
no `fallback` keyword argument is given. A wrap file named `foo.wrap` implicitly
|
|
|
|
provides the dependency name `foo` even when the `[provide]` section is missing.
|
|
|
|
|
|
|
|
Optional dependencies, like `dependency('foo-1.0', required: get_option('foo_opt'))`
|
|
|
|
where `foo_opt` is a feature option set to `auto`, will not fallback to the
|
|
|
|
subproject defined in the wrap file, for 2 reasons:
|
|
|
|
- It allows for looking the dependency in other ways first, for example using
|
|
|
|
`cc.find_library('foo')`, and only fallback if that fails:
|
|
|
|
```
|
|
|
|
# this won't use fallback defined in foo.wrap
|
|
|
|
foo_dep = dependency('foo-1.0', required: false)
|
|
|
|
if not foo_dep.found()
|
|
|
|
foo_dep = cc.find_library('foo', has_headers: 'foo.h', required: false)
|
|
|
|
if not foo_dep.found()
|
|
|
|
# This will use the fallback
|
|
|
|
foo_dep = dependency('foo-1.0')
|
|
|
|
# or
|
|
|
|
foo_dep = dependency('foo-1.0', required: false, fallback: 'foo')
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
```
|
|
|
|
- Sometimes not-found dependency is preferable to a fallback when the feature is
|
|
|
|
not explicitly requested by the user. In that case
|
|
|
|
`dependency('foo-1.0', required: get_option('foo_opt'))` will only fallback
|
|
|
|
when the user sets `foo_opt` to `enabled` instead of `auto`.
|
|
|
|
|
|
|
|
If it is desired to fallback for an optional dependency, the `fallback` keyword
|
|
|
|
argument must be passed explicitly. For example
|
|
|
|
`dependency('foo-1.0', required: get_option('foo_opt'), fallback: 'foo')` will
|
|
|
|
use the fallback even when `foo_opt` is set to `auto`.
|
|
|
|
|
|
|
|
This mechanism assumes the subproject calls `meson.override_dependency('foo-1.0', foo_dep)`
|
|
|
|
so Meson knows which dependency object should be used as fallback. Since that
|
|
|
|
method was introduced in version *0.54.0*, as a transitional aid for projects
|
|
|
|
that do not yet make use of it the variable name can be provided in the wrap file
|
|
|
|
with entries in the format `foo-1.0 = foo_dep`.
|
2020-04-05 11:56:33 +08:00
|
|
|
|
2020-06-12 23:57:25 +08:00
|
|
|
For example when using a recent enough version of glib that uses
|
|
|
|
`meson.override_dependency()` to override `glib-2.0`, `gobject-2.0` and `gio-2.0`,
|
|
|
|
a wrap file would look like:
|
2020-04-05 11:56:33 +08:00
|
|
|
```ini
|
|
|
|
[wrap-git]
|
|
|
|
url=https://gitlab.gnome.org/GNOME/glib.git
|
|
|
|
revision=glib-2-62
|
|
|
|
|
|
|
|
[provide]
|
2020-06-12 23:57:25 +08:00
|
|
|
dependency_names = glib-2.0, gobject-2.0, gio-2.0
|
2020-04-05 11:56:33 +08:00
|
|
|
```
|
|
|
|
|
2020-06-12 23:57:25 +08:00
|
|
|
With older version of glib dependency variable names need to be specified:
|
2020-04-14 06:12:43 +08:00
|
|
|
```ini
|
|
|
|
[wrap-git]
|
|
|
|
url=https://gitlab.gnome.org/GNOME/glib.git
|
|
|
|
revision=glib-2-62
|
|
|
|
|
|
|
|
[provide]
|
2020-06-12 23:57:25 +08:00
|
|
|
glib-2.0=glib_dep
|
|
|
|
gobject-2.0=gobject_dep
|
|
|
|
gio-2.0=gio_dep
|
2020-04-14 06:12:43 +08:00
|
|
|
```
|
|
|
|
|
2020-04-21 07:14:49 +08:00
|
|
|
Programs can also be provided by wrap files, with the `program_names` key:
|
|
|
|
```ini
|
|
|
|
[provide]
|
|
|
|
program_names = myprog, otherprog
|
|
|
|
```
|
|
|
|
|
|
|
|
With such wrap file, `find_program('myprog')` will automatically fallback to use
|
|
|
|
the subproject, assuming it uses `meson.override_find_program('myprog')`.
|
|
|
|
|
2017-03-30 02:03:43 +08:00
|
|
|
## Using wrapped projects
|
|
|
|
|
2020-03-21 18:54:00 +08:00
|
|
|
Wraps provide a convenient way of obtaining a project into your subproject directory.
|
2018-10-22 01:05:33 +08:00
|
|
|
Then you use it as a regular subproject (see [subprojects](Subprojects.md)).
|
2017-03-30 02:03:43 +08:00
|
|
|
|
2018-10-22 01:05:33 +08:00
|
|
|
## Getting wraps
|
2017-03-30 02:03:43 +08:00
|
|
|
|
2020-03-21 18:54:00 +08:00
|
|
|
Usually you don't want to write your wraps by hand.
|
2017-03-30 02:03:43 +08:00
|
|
|
|
2020-03-21 18:54:00 +08:00
|
|
|
There is an online repository called [WrapDB](https://wrapdb.mesonbuild.com) that provides
|
2018-10-22 01:05:33 +08:00
|
|
|
many dependencies ready to use. You can read more about WrapDB [here](Using-the-WrapDB.md).
|
2017-03-30 02:03:43 +08:00
|
|
|
|
2018-10-22 01:05:33 +08:00
|
|
|
There is also a Meson subcommand to get and manage wraps (see [using wraptool](Using-wraptool.md)).
|