# Reference manual

## Functions

The following functions are available in build files. Click on each to
see the description and usage. The objects returned by them are [list
afterwards](#returned-objects).

### add_global_arguments()

``` meson
  void add_global_arguments(arg1, arg2, ...)
```

Adds the positional arguments to the compiler command line. This
function has two keyword arguments:

- `language`: specifies the language(s) that the arguments should be
applied to. If a list of languages is given, the arguments are added
to each of the corresponding compiler command lines. Note that there
is no way to remove an argument set in this way. If you have an
argument that is only used in a subset of targets, you have to specify
it in per-target flags.

- `native` *(since 0.48.0)*: a boolean specifying whether the arguments should be
  applied to the native or cross compilation. If `true` the arguments
  will only be used for native compilations. If `false` the arguments
  will only be used in cross compilations. If omitted, the flags are
  added to native compilations if compiling natively and cross
  compilations (only) when cross compiling.

The arguments are used in all compiler invocations with the exception
of compile tests, because you might need to run a compile test with
and without the argument in question. For this reason only the
arguments explicitly specified are used during compile tests.

**Note:** Usually you should use `add_project_arguments` instead,
  because that works even when you project is used as a subproject.

**Note:** You must pass always arguments individually `arg1, arg2,
  ...` rather than as a string `'arg1 arg2', ...`

### add_global_link_arguments()

``` meson
    void add_global_link_arguments(*arg1*, *arg2*, ...)
```

Like `add_global_arguments` but the arguments are passed to the linker.

### add_languages()

``` meson
  bool add_languages(*langs*)
```

Add programming languages used by the project. Equivalent to having
them in the `project` declaration. This function is usually used to
add languages that are only used under some conditions, like this:

```meson
project('foobar', 'c')
if compiling_for_osx
  add_languages('objc')
endif
if add_languages('cpp', required : false)
  executable('cpp-app', 'main.cpp')
endif
```

Takes the following keyword arguments:

- `required`: defaults to `true`, which means that if any of the languages
specified is not found, Meson will halt. *(since 0.47.0)* The value of a
[`feature`](Build-options.md#features) option can also be passed.

- `native` *(since 0.54.0)*: if set to `true`, the language will be used to compile for the build
  machine, if `false`, for the host machine.

Returns `true` if all languages specified were found and `false` otherwise.

If `native` is omitted, the languages may be used for either build or host
machine, but are never required for the build machine.  (i.e. it is equivalent
to `add_languages(*langs*, native: false, required: *required*) and
add_languages(*langs*, native: true, required: false)`. This default behaviour
may change to `native: false` in a future Meson version.

### add_project_arguments()

``` meson
  void add_project_arguments(arg1, arg2, ...)
```

This function behaves in the same way as `add_global_arguments` except
that the arguments are only used for the current project, they won't
be used in any other subproject.

### add_project_link_arguments()

``` meson
  void add_project_link_arguments(*arg1*, *arg2*, ...)
```

Like `add_project_arguments` but the arguments are passed to the linker.

### add_test_setup()

``` meson
  void add_test_setup(*name*, ...)
```

Add a custom test setup that can be used to run the tests with a
custom setup, for example under Valgrind. The keyword arguments are
the following:

- `env`: environment variables to set, such as `['NAME1=value1',
  'NAME2=value2']`, or an [`environment()`
  object](#environment-object) which allows more sophisticated
  environment juggling. *(since 0.52.0)* A dictionary is also accepted.
- `exe_wrapper`: a list containing the wrapper command or script followed by the arguments to it
- `gdb`: if `true`, the tests are also run under `gdb`
- `timeout_multiplier`: a number to multiply the test timeout with.
  *Since 0.57* if timeout_multiplier is `<= 0` the test has infinite duration,
  in previous versions of Meson the test would fail with a timeout immediately.
- `is_default` *(since 0.49.0)*: a bool to set whether this is the default test setup.
  If `true`, the setup will be used whenever `meson test` is run
  without the `--setup` option.
- `exclude_suites` *(since 0.57.0)*: a list of test suites that should be
  excluded when using this setup.  Suites specified in the `--suite` option
  to `meson test` will always run, overriding `add_test_setup` if necessary.

To use the test setup, run `meson test --setup=*name*` inside the
build dir.

Note that all these options are also available while running the
`meson test` script for running tests instead of `ninja test` or
`msbuild RUN_TESTS.vcxproj`, etc depending on the backend.

### alias_target

``` meson
runtarget alias_target(target_name, dep1, ...)
```

*(since 0.52.0)*

This function creates a new top-level target. Like all top-level
targets, this integrates with the selected backend. For instance, with
you can run it as `meson compile target_name`. This is a dummy target
that does not execute any command, but ensures that all dependencies
are built. Dependencies can be any build target (e.g. return value of
[executable()](#executable), custom_target(), etc)

### assert()

``` meson
    void assert(*condition*, *message*)
```

Abort with an error message if `condition` evaluates to `false`.

*(since 0.53.0)* `message` argument is optional and defaults to print the condition
statement instead.

### benchmark()

``` meson
    void benchmark(name, executable, ...)
```

Creates a benchmark item that will be run when the benchmark target is
run. The behavior of this function is identical to [`test()`](#test)
except for:

* benchmark() has no `is_parallel` keyword because benchmarks are not run in parallel
* benchmark() does not automatically add the `MALLOC_PERTURB_` environment variable

*Note:* Prior to 0.52.0 benchmark would warn that `depends` and
`priority` were unsupported, this is incorrect.

### both_libraries()

``` meson
    buildtarget = both_libraries(library_name, list_of_sources, ...)
```

*(since 0.46.0)*

Builds both a static and shared library with the given sources.
Positional and keyword arguments are otherwise the same as for
[`library`](#library). Source files will be compiled only once and
object files will be reused to build both shared and static libraries,
unless `b_staticpic` user option or `pic` argument are set to false in
which case sources will be compiled twice.

The returned [buildtarget](#build-target-object) always represents the
shared library. In addition it supports the following extra methods:

- `get_shared_lib()` returns the shared library build target
- `get_static_lib()` returns the static library build target

### build_target()

Creates a build target whose type can be set dynamically with the
`target_type` keyword argument.

`target_type` may be set to one of:

- `executable`
- `shared_library`
- `shared_module`
- `static_library`
- `both_libraries`
- `library`
- `jar`

This declaration:

```meson
executable(<arguments and keyword arguments>)
```

is equivalent to this:

```meson
build_target(<arguments and keyword arguments>, target_type : 'executable')
```

The object returned by `build_target` and all convenience wrappers for
`build_target` such as [`executable`](#executable) and
[`library`](#library) has methods that are documented in the [object
methods section](#build-target-object) below.

### configuration_data()

``` meson
    configuration_data_object = configuration_data(...)
```

Creates an empty configuration object. You should add your
configuration with [its method calls](#configuration-data-object) and
finally use it in a call to `configure_file`.

*(since 0.49.0)* Takes an optional dictionary as first argument. If
provided, each key/value pair is added into the `configuration_data`
as if `set()` method was called for each of them.

### configure_file()

``` meson
    generated_file = configure_file(...)
```

This function can run in three modes depending on the keyword arguments
passed to it.

When a [`configuration_data()`](#configuration_data) object is passed
to the `configuration:` keyword argument, it takes a template file as
the `input:` (optional) and produces the `output:` (required) by
substituting values from the configuration data as detailed in [the
configuration file documentation](Configuration.md). *(since 0.49.0)*
A dictionary can be passed instead of a
[`configuration_data()`](#configuration_data) object.

When a list of strings is passed to the `command:` keyword argument,
it takes any source or configured file as the `input:` and assumes
that the `output:` is produced when the specified command is run.

*(since 0.47.0)* When the `copy:` keyword argument is set to `true`,
this function will copy the file provided in `input:` to a file in the
build directory with the name `output:` in the current directory.

These are all the supported keyword arguments:

- `capture` *(since 0.41.0)*: when this argument is set to true,
  Meson captures `stdout` of the `command` and writes it to the target
  file specified as `output`.
- `command`: as explained above, if specified, Meson does not create
  the file itself but rather runs the specified command, which allows
  you to do fully custom file generation. *(since 0.52.0)* The command can contain
  file objects and more than one file can be passed to the `input` keyword
  argument, see [`custom_target()`](#custom_target) for details about string
  substitutions.
- `copy` *(since 0.47.0)*: as explained above, if specified Meson only
  copies the file from input to output.
- `depfile` *(since 0.52.0)*: a dependency file that the command can write listing
  all the additional files this target depends on. A change
  in any one of these files triggers a reconfiguration.
- `format` *(since 0.46.0)*: the format of defines. It defaults to `meson`, and so substitutes
`#mesondefine` statements and variables surrounded by `@` characters, you can also use `cmake`
to replace `#cmakedefine` statements and variables with the `${variable}` syntax. Finally you can use
`cmake@` in which case substitutions will apply on `#cmakedefine` statements and variables with
the `@variable@` syntax.
- `input`: the input file name. If it's not specified in configuration
  mode, all the variables in the `configuration:` object (see above)
  are written to the `output:` file.
- `install` *(since 0.50.0)*: when true, this generated file is installed during
the install step, and `install_dir` must be set and not empty. When false, this
generated file is not installed regardless of the value of `install_dir`.
When omitted it defaults to true when `install_dir` is set and not empty,
false otherwise.
- `install_dir`: the subdirectory to install the generated file to
  (e.g. `share/myproject`), if omitted or given the value of empty
  string, the file is not installed.
- `install_mode` *(since 0.47.0)*: specify the file mode in symbolic format
  and optionally the owner/uid and group/gid for the installed files.
- `output`: the output file name. *(since 0.41.0)* may contain
  `@PLAINNAME@` or `@BASENAME@` substitutions. In configuration mode,
  the permissions of the input file (if it is specified) are copied to
  the output file.
- `output_format` *(since 0.47.0)*: the format of the output to generate when no input
  was specified. It defaults to `c`, in which case preprocessor directives
  will be prefixed with `#`, you can also use `nasm`, in which case the
  prefix will be `%`.
- `encoding` *(since 0.47.0)*: set the file encoding for the input and output file,
  defaults to utf-8. The supported encodings are those of python3, see
  [standard-encodings](https://docs.python.org/3/library/codecs.html#standard-encodings).

### custom_target()

``` meson
    customtarget custom_target(*name*, ...)
```

Create a custom top level build target. The only positional argument
is the name of this target and the keyword arguments are the
following.

- `build_by_default` *(since 0.38.0)*: causes, when set to true, to
  have this target be built by default. This means it will be built when
  `meson compile` is called without any arguments. The default value is `false`.
  *(since 0.50.0)* If `build_by_default` is explicitly set to false, `install`
  will no longer override it. If `build_by_default` is not set, `install` will
  still determine its default.
- `build_always` **(deprecated)**: if `true` this target is always considered out of
  date and is rebuilt every time.  Equivalent to setting both
  `build_always_stale` and `build_by_default` to true.
- `build_always_stale` *(since 0.47.0)*: if `true` the target is always considered out of date.
  Useful for things such as build timestamps or revision control tags.
  The associated command is run even if the outputs are up to date.
- `capture`: there are some compilers that can't be told to write
  their output to a file but instead write it to standard output. When
  this argument is set to true, Meson captures `stdout` and writes it
  to the target file. Note that your command argument list may not
  contain `@OUTPUT@` when capture mode is active.
- `console` *(since 0.48.0)*: keyword argument conflicts with `capture`, and is meant
  for commands that are resource-intensive and take a long time to
  finish. With the Ninja backend, setting this will add this target
  to [Ninja's `console` pool](https://ninja-build.org/manual.html#_the_literal_console_literal_pool),
  which has special properties such as not buffering stdout and
  serializing all targets in this pool.
- `command`: command to run to create outputs from inputs. The command
  may be strings or the return value of functions that return file-like
  objects such as [`find_program()`](#find_program),
  [`executable()`](#executable), [`configure_file()`](#configure_file),
  [`files()`](#files), [`custom_target()`](#custom_target), etc.
  Meson will automatically insert the appropriate dependencies on
  targets and files listed in this keyword argument.
  Note: always specify commands in array form `['commandname',
  '-arg1', '-arg2']` rather than as a string `'commandname -arg1
  -arg2'` as the latter will *not* work.
- `depend_files`: files ([`string`](#string-object),
  [`files()`](#files), or [`configure_file()`](#configure_file)) that
  this target depends on but are not listed in the `command` keyword
  argument. Useful for adding regen dependencies.
- `depends`: specifies that this target depends on the specified
  target(s), even though it does not take any of them as a command
  line argument. This is meant for cases where you have a tool that
  e.g. does globbing internally. Usually you should just put the
  generated sources as inputs and Meson will set up all dependencies
  automatically.
- `depfile`: a dependency file that the command can write listing
  all the additional files this target depends on, for example a C
  compiler would list all the header files it included, and a change
  in any one of these files triggers a recompilation
- `input`: list of source files. *(since 0.41.0)* the list is flattened.
- `install`: when true, this target is installed during the install step
- `install_dir`: directory to install to
- `install_mode` *(since 0.47.0)*: the file mode and optionally the
  owner/uid and group/gid
- `output`: list of output files
- `env` *(since 0.57.0)*: environment variables to set, such as
  `{'NAME1': 'value1', 'NAME2': 'value2'}` or `['NAME1=value1', 'NAME2=value2']`,
  or an [`environment()` object](#environment-object) which allows more
  sophisticated environment juggling.

The list of strings passed to the `command` keyword argument accept
the following special string substitutions:

- `@INPUT@`: the full path to the input passed to `input`. If more than
  one input is specified, all of them will be substituted as separate
  arguments only if the command uses `'@INPUT@'` as a
  standalone-argument. For instance, this would not work: `command :
  ['cp', './@INPUT@']`, but this would: `command : ['cp', '@INPUT@']`.
- `@OUTPUT@`: the full path to the output passed to `output`. If more
  than one outputs are specified, the behavior is the same as
  `@INPUT@`.
- `@INPUT0@` `@INPUT1@` `...`: the full path to the input with the specified array index in `input`
- `@OUTPUT0@` `@OUTPUT1@` `...`: the full path to the output with the specified array index in `output`
- `@OUTDIR@`: the full path to the directory where the output(s) must be written
- `@DEPFILE@`: the full path to the dependency file passed to `depfile`
- `@PLAINNAME@`: the input filename, without a path
- `@BASENAME@`: the input filename, with extension removed
- `@PRIVATE_DIR@` *(since 0.50.1)*: path to a directory where the custom target must store all its intermediate files.
- `@SOURCE_ROOT@`: the path to the root of the source tree. Depending on the backend,
  this may be an absolute or a relative to current workdir path.
- `@BUILD_ROOT@`: the path to the root of the build tree. Depending on the backend,
  this may be an absolute or a relative to current workdir path.
- `@CURRENT_SOURCE_DIR@`: this is the directory where the currently
  processed meson.build is located in.  Depending on the backend,
  this may be an absolute or a relative to current workdir path.

*(since 0.47.0)* The `depfile` keyword argument also accepts the
 `@BASENAME@` and `@PLAINNAME@` substitutions.

The returned object also has methods that are documented in the
[object methods section](#custom-target-object) below.

**Note:** Assuming that `command:` is executed by a POSIX `sh` shell
is not portable, notably to Windows. Instead, consider using a
`native: true` [executable()](#executable), or a python script.

### declare_dependency()

``` meson
    dependency_object declare_dependency(...)
```

This function returns a [dependency object](#dependency-object) that
behaves like the return value of [`dependency`](#dependency) but is
internal to the current build. The main use case for this is in
subprojects. This allows a subproject to easily specify how it should
be used. This makes it interchangeable with the same dependency that
is provided externally by the system. This function has the following
keyword arguments:

- `compile_args`: compile arguments to use.
- `dependencies`: other dependencies needed to use this dependency.
- `include_directories`: the directories to add to header search path,
  must be include_directories objects or *(since 0.50.0)* plain strings
- `link_args`: link arguments to use.
- `link_with`: libraries to link against.
- `link_whole` *(since 0.46.0)*: libraries to link fully, same as [`executable`](#executable).
- `sources`: sources to add to targets (or generated header files
  that should be built before sources including them are built)
- `version`: the version of this dependency, such as `1.2.3`. Defaults to the
  project version.
- `variables` *(since 0.54.0)*: a dictionary of arbitrary strings, this is meant to be used
  in subprojects where special variables would be provided via cmake or
  pkg-config. *since 0.56.0* it can also be a list of `'key=value'` strings.

### dependency()

``` meson
    dependency_object dependency(*dependency_name*, ...)
```

Finds an external dependency (usually a library installed on your
system) with the given name with `pkg-config` and [with
CMake](Dependencies.md#cmake) if `pkg-config` fails. Additionally,
frameworks (OSX only) and [library-specific fallback detection
logic](Dependencies.md#dependencies-with-custom-lookup-functionality)
are also supported.

Dependencies can also be resolved in two other ways:

* if the same name was used in a `meson.override_dependency` prior to
  the call to `dependency`, the overriding dependency will be returned
  unconditionally; that is, the overriding dependency will be used
  independent of whether an external dependency is installed in the system.
  Typically, `meson.override_dependency` will have been used by a
  subproject.

* by a fallback subproject which, if needed, will be brought into the current
  build specification as if [`subproject()`](#subproject) had been called.
  The subproject can be specified with the `fallback` argument.  Alternatively,
  if the `fallback` argument is absent, *since 0.55.0* Meson can
  automatically identify a subproject as a fallback if a wrap file
  [provides](Wrap-dependency-system-manual.md#provide-section) the
  dependency, or if a subproject has the same name as the dependency.
  In the latter case, the subproject must use `meson.override_dependency` to
  specify the replacement, or Meson will report a hard error.  See the
  [Wrap documentation](Wrap-dependency-system-manual.md#provide-section)
  for more details.  This automatic search can be controlled using the
  `allow_fallback` keyword argument.

This function supports the following keyword arguments:

- `default_options` *(since 0.37.0)*: an array of default option values
  that override those set in the subproject's `meson_options.txt`
  (like `default_options` in [`project()`](#project), they only have
  effect when Meson is run for the first time, and command line
  arguments override any default options in build files)
- `allow_fallback` (boolean argument, *since 0.56.0*): specifies whether Meson
  should automatically pick a fallback subproject in case the dependency
  is not found in the system.  If `true` and the dependency is not found
  on the system, Meson will fallback to a subproject that provides this
  dependency. If `false`, Meson will not fallback even if a subproject
  provides this dependency.  By default, Meson will do so if `required`
  is `true` or  [`enabled`](Build-options.md#features); see the [Wrap
  documentation](Wrap-dependency-system-manual.md#provide-section)
  for more details.
- `fallback` (string or array argument): manually specifies a subproject
  fallback to use in case the dependency is not found in the system.
  This is useful if the automatic search is not applicable or if you
  want to support versions of Meson older than 0.55.0.  If the value is an
  array `['subproj_name', 'subproj_dep']`, the first value is the name
  of the subproject and the second is the variable name in that
  subproject that contains a dependency object such as the return
  value of [`declare_dependency`](#declare_dependency) or
  [`dependency()`](#dependency), etc. Note that this means the
  fallback dependency may be a not-found dependency, in which
  case the value of the `required:` kwarg will be obeyed.
  *Since 0.54.0* the value can be a single string, the subproject name;
  in this case the subproject must use
  `meson.override_dependency('dependency_name', subproj_dep)`
  to specify the dependency object used in the superproject.
- `language` *(since 0.42.0)*: defines what language-specific
  dependency to find if it's available for multiple languages.
- `method`: defines the way the dependency is detected, the default is
  `auto` but can be overridden to be e.g. `qmake` for Qt development,
  and [different dependencies support different values](
  Dependencies.md#dependencies-with-custom-lookup-functionality)
  for this (though `auto` will work on all of them)
- `native`: if set to `true`, causes Meson to find the dependency on
  the build machine system rather than the host system (i.e. where the
  cross compiled binary will run on), usually only needed if you build
  a tool to be used during compilation.
- `not_found_message` *(since 0.50.0)*: an optional string that will
  be printed as a `message()` if the dependency was not found.
- `required`: when set to false, Meson will proceed with the build
  even if the dependency is not found. *(since 0.47.0)* The value of a
  [`feature`](Build-options.md#features) option can also be passed.
- `static`: tells the dependency provider to try to get static
  libraries instead of dynamic ones (note that this is not supported
  by all dependency backends)
- `version` *(since 0.37.0)*: specifies the required version, a string containing a
  comparison operator followed by the version string, examples include
  `>1.0.0`, `<=2.3.5` or `3.1.4` for exact matching.
  You can also specify multiple restrictions by passing a list to this
  keyword argument, such as: `['>=3.14.0', '<=4.1.0']`.
  These requirements are never met if the version is unknown.
- `include_type` *(since 0.52.0)*: an enum flag, marking how the dependency
  flags should be converted. Supported values are `'preserve'`, `'system'` and
  `'non-system'`. System dependencies may be handled differently on some
   platforms, for instance, using `-isystem` instead of `-I`, where possible.
   If `include_type` is set to `'preserve'`, no additional conversion will be
   performed. The default value is `'preserve'`.
- other
[library-specific](Dependencies.md#dependencies-with-custom-lookup-functionality)
keywords may also be accepted (e.g. `modules` specifies submodules to use for
dependencies such as Qt5 or Boost. `components` allows the user to manually
add CMake `COMPONENTS` for the `find_package` lookup)
- `disabler` *(since 0.49.0)*: if `true` and the dependency couldn't be found,
  returns a [disabler object](#disabler-object) instead of a not-found dependency.

If dependency_name is `''`, the dependency is always not found. So
with `required: false`, this always returns a dependency object for
which the `found()` method returns `false`, and which can be passed
like any other dependency to the `dependencies:` keyword argument of a
`build_target`. This can be used to implement a dependency which is
sometimes not required e.g. in some branches of a conditional, or with
a `fallback:` kwarg, can be used to declare an optional dependency
that only looks in the specified subproject, and only if that's
allowed by `--wrap-mode`.

The returned object also has methods that are documented in the
[object methods section](#dependency-object) below.

### disabler()

*(since 0.44.0)*

Returns a [disabler object](#disabler-object).

### error()

``` meson
    void error(message)
```

Print the argument string and halts the build process.

*(since 0.58.0)* Can take more than one argument that will be separated by
space.

### environment()

``` meson
    environment_object environment(...)
```

*(since 0.35.0)*

Returns an empty [environment variable object](#environment-object).

*(since 0.52.0)* Takes an optional dictionary as first argument. If
provided, each key/value pair is added into the `environment_object`
as if `set()` method was called for each of them.

### executable()

``` meson
    buildtarget executable(*exe_name*, *sources*, ...)
```

Creates a new executable. The first argument specifies its name and
the remaining positional arguments define the input files to use. They
can be of the following types:

- Strings relative to the current source directory
- [`files()`](#files) objects defined in any preceding build file
- The return value of configure-time generators such as [`configure_file()`](#configure_file)
- The return value of build-time generators such as
  [`custom_target()`](#custom_target) or
  [`generator.process()`](#generator-object)

These input files can be sources, objects, libraries, or any other
file. Meson will automatically categorize them based on the extension
and use them accordingly. For instance, sources (`.c`, `.cpp`,
`.vala`, `.rs`, etc) will be compiled and objects (`.o`, `.obj`) and
libraries (`.so`, `.dll`, etc) will be linked.

With the Ninja backend, Meson will create a build-time [order-only
dependency](https://ninja-build.org/manual.html#ref_dependencies) on
all generated input files, including unknown files. This is needed to
bootstrap the generation of the real dependencies in the
[depfile](https://ninja-build.org/manual.html#ref_headers) generated
by your compiler to determine when to rebuild sources. Ninja relies on
this dependency file for all input files, generated and non-generated.
The behavior is similar for other backends.

Executable supports the following keyword arguments. Note that just
like the positional arguments above, these keyword arguments can also
be passed to [shared and static libraries](#library).

- `<languagename>_pch`: precompiled header file to use for the given language
- `<languagename>_args`: compiler flags to use for the given language;
  eg: `cpp_args` for C++
- `build_by_default` *(since 0.38.0)*: causes, when set to true, to
   have this target be built by default. This means it will be built when
  `meson compile` is called without any arguments. The default value is
  `true` for all built target types.
- `build_rpath`: a string to add to target's rpath definition in the
  build dir, but which will be removed on install
- `dependencies`: one or more objects created with
  [`dependency`](#dependency) or [`find_library`](#compiler-object)
  (for external deps) or [`declare_dependency`](#declare_dependency)
  (for deps built by the project)
- `extra_files`: not used for the build itself but are shown as
  source files in IDEs that group files by targets (such as Visual
  Studio)
- `gui_app`: when set to true flags this target as a GUI application
  on platforms where this makes a differerence, **deprecated** since
  0.56.0, use `win_subsystem` instead.
- `link_args`: flags to use during linking. You can use UNIX-style
  flags here for all platforms.
- `link_depends`: strings, files, or custom targets the link step
  depends on such as a symbol visibility map. The purpose is to
  automatically trigger a re-link (but not a re-compile) of the target
  when this file changes.
- `link_language` *(since 0.51.0)* *(broken until 0.55.0)*: makes the linker for this
  target be for the specified language. It is generally unnecessary to set
  this, as Meson will detect the right linker to use in most cases. There are
  only two cases where this is needed. One, your main function in an
  executable is not in the language Meson picked, or second you want to force
  a library to use only one ABI.
- `link_whole` *(since 0.40.0)*: links all contents of the given static libraries
  whether they are used by not, equivalent to the `-Wl,--whole-archive` argument flag of GCC.
  *(since 0.41.0)* If passed a list that list will be flattened.
  *(since 0.51.0)* This argument also accepts outputs produced by
  custom targets. The user must ensure that the output is a library in
  the correct format.
- `link_with`: one or more shared or static libraries (built by this
  project) that this target should be linked with. *(since 0.41.0)* If passed a
  list this list will be flattened. *(since 0.51.0)* The arguments can also be custom targets.
  In this case Meson will assume that merely adding the output file in the linker command
  line is sufficient to make linking work. If this is not sufficient,
  then the build system writer must write all other steps manually.
- `export_dynamic` *(since 0.45.0)*: when set to true causes the target's symbols to be
  dynamically exported, allowing modules built using the
  [`shared_module`](#shared_module) function to refer to functions,
  variables and other symbols defined in the executable itself. Implies
  the `implib` argument.
- `implib` *(since 0.42.0)*: when set to true, an import library is generated for the
  executable (the name of the import library is based on *exe_name*).
  Alternatively, when set to a string, that gives the base name for
  the import library.  The import library is used when the returned
  build target object appears in `link_with:` elsewhere.  Only has any
  effect on platforms where that is meaningful (e.g. Windows). Implies
  the `export_dynamic` argument.
- `implicit_include_directories` *(since 0.42.0)*: a boolean telling whether Meson
  adds the current source and build directories to the include path,
  defaults to `true`.
- `include_directories`: one or more objects created with the
  `include_directories` function, or *(since 0.50.0)* strings, which
  will be transparently expanded to include directory objects
- `install`: when set to true, this executable should be installed, defaults to `false`
- `install_dir`: override install directory for this file. The value is
  relative to the `prefix` specified. F.ex, if you want to install
  plugins into a subdir, you'd use something like this: `install_dir :
  get_option('libdir') / 'projectname-1.0'`.
- `install_mode` *(since 0.47.0)*: specify the file mode in symbolic format
  and optionally the owner/uid and group/gid for the installed files.
- `install_rpath`: a string to set the target's rpath to after install
  (but *not* before that). On Windows, this argument has no effect.
- `objects`: list of prebuilt object files (usually for third party
  products you don't have source to) that should be linked in this
  target, **never** use this for object files that you build yourself.
- `name_suffix`: the string that will be used as the extension for the
  target by overriding the default. By default on Windows this is
  `exe` and on other platforms it is omitted. Set this to `[]`, or omit
  the keyword argument for the default behaviour.
- `override_options` *(since 0.40.0)*: takes an array of strings in the same format as
  `project`'s `default_options` overriding the values of these options
  for this target only.
- `gnu_symbol_visibility` *(since 0.48.0)*: specifies how symbols should be exported, see
  e.g [the GCC Wiki](https://gcc.gnu.org/wiki/Visibility) for more
  information. This value can either be an empty string or one of
  `default`, `internal`, `hidden`, `protected` or `inlineshidden`, which
  is the same as `hidden` but also includes things like C++ implicit
  constructors as specified in the GCC manual. Ignored on compilers that
  do not support GNU visibility arguments.
- `d_import_dirs`: list of directories to look in for string imports used
  in the D programming language
- `d_unittest`: when set to true, the D modules are compiled in debug mode
- `d_module_versions`: list of module version identifiers set when compiling D sources
- `d_debug`: list of module debug identifiers set when compiling D sources
- `pie` *(since 0.49.0)*: build a position-independent executable
- `native`: is a boolean controlling whether the target is compiled for the
  build or host machines. Defaults to false, building for the host machine.
- `win_subsystem` *(since 0.56.0)* specifies the subsystem type to use
  on the Windows platform. Typical values include `console` for text
  mode programs and `windows` for gui apps. The value can also contain
  version specification such as `windows,6.0`. See [MSDN
  documentation](https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem)
  for the full list. The default value is `console`.

The list of `sources`, `objects`, and `dependencies` is always
flattened, which means you can freely nest and add lists while
creating the final list.

The returned object also has methods that are documented in the
[object methods section](#build-target-object) below.

### find_library()

*(since 0.31.0)* **(deprecated)** Use `find_library()` method of
[the compiler object](#compiler-object) as obtained from
`meson.get_compiler(lang)`.

### find_program()

``` meson
    program find_program(program_name1, program_name2, ...)
```

`program_name1` here is a string that can be an executable or script
to be searched for in `PATH` or other places inside the project.
The search order is:

1. Program overrides set via [`meson.override_find_program()`](Reference-manual.md#meson-object)
1. [`[provide]` sections](Wrap-dependency-system-manual.md#provide-section)
   in subproject wrap files, if [`wrap_mode`](Builtin-options.md#core-options) is
   set to `forcefallback`
1. [`[binaries]` section](Machine-files.md#binaries) in your machine files
1. Directories provided using the `dirs:` kwarg (see below)
1. Project's source tree relative to the current subdir
   - If you use the return value of [`configure_file()`](#configure_file), the
     current subdir inside the build tree is used instead
1. `PATH` environment variable
1. [`[provide]` sections](Wrap-dependency-system-manual.md#provide-section) in
   subproject wrap files, if [`wrap_mode`](Builtin-options.md#core-options) is
   set to anything other than `nofallback`

*(since 0.37.0)* `program_name2` and later positional arguments are used as fallback
strings to search for. This is meant to be used for cases where the
program may have many alternative names, such as `foo` and
`foo.py`. The function will check for the arguments one by one and the
first one that is found is returned.

Keyword arguments are the following:

- `required` By default, `required` is set to `true` and Meson will
  abort if no program can be found. If `required` is set to `false`,
  Meson continue even if none of the programs can be found. You can
  then use the `.found()` method on the [returned object](#external-program-object) to check
  whether it was found or not. *(since 0.47.0)* The value of a
  [`feature`](Build-options.md#features) option can also be passed to the
  `required` keyword argument.

- `native` *(since 0.43.0)*: defines how this executable should be searched. By default
  it is set to `false`, which causes Meson to first look for the
  executable in the cross file (when cross building) and if it is not
  defined there, then from the system. If set to `true`, the cross
  file is ignored and the program is only searched from the system.

- `disabler` *(since 0.49.0)*: if `true` and the program couldn't be found, return a
  [disabler object](#disabler-object) instead of a not-found object.


- `version` *(since 0.52.0)*: specifies the required version, see
  [`dependency()`](#dependency) for argument format. The version of the program
  is determined by running `program_name --version` command. If stdout is empty
  it fallbacks to stderr. If the output contains more text than simply a version
  number, only the first occurrence of numbers separated by dots is kept.
  If the output is more complicated than that, the version checking will have to
  be done manually using [`run_command()`](#run_command).

- `dirs` *(since 0.53.0)*: extra list of absolute paths where to look for program
  names.

Meson will also autodetect scripts with a shebang line and run them
with the executable/interpreter specified in it both on Windows
(because the command invocator will reject the command otherwise) and
Unixes (if the script file does not have the executable bit set).
Hence, you *must not* manually add the interpreter while using this
script as part of a list of commands.

If you need to check for a program in a non-standard location, you can
just pass an absolute path to `find_program`, e.g.

```meson
setcap = find_program('setcap', '/usr/sbin/setcap', '/sbin/setcap', required : false)
```

It is also possible to pass an array to `find_program` in case you
need to construct the set of paths to search on the fly:

```meson
setcap = find_program(['setcap', '/usr/sbin/setcap', '/sbin/setcap'], required : false)
```

The returned object also has methods that are documented in the
[object methods section](#external-program-object) below.

### files()

``` meson
    file_array files(list_of_filenames)
```

This command takes the strings given to it in arguments and returns
corresponding File objects that you can use as sources for build
targets. The difference is that file objects remember the subdirectory
they were defined in and can be used anywhere in the source tree. As
an example suppose you have source file `foo.cpp` in subdirectory
`bar1` and you would like to use it in a build target that is defined
in `bar2`. To make this happen you first create the object in `bar1`
like this:

```meson
    foofile = files('foo.cpp')
```

Then you can use it in `bar2` like this:

```meson
    executable('myprog', 'myprog.cpp', foofile, ...)
```

Meson will then do the right thing.

### generator()

``` meson
    generator_object generator(*executable*, ...)
```

See also: [`custom_target`](#custom_target)

This function creates a [generator object](#generator-object) that can
be used to run custom compilation commands. The only positional
argument is the executable to use. It can either be a self-built
executable or one returned by find_program. Keyword arguments are the
following:

- `arguments`: a list of template strings that will be the command line
  arguments passed to the executable
- `depends` *(since 0.51.0)*: is an array of build targets that must be built before this
  generator can be run. This is used if you have a generator that calls
  a second executable that is built in this project.
- `depfile`: is a template string pointing to a dependency file that a
  generator can write listing all the additional files this target
  depends on, for example a C compiler would list all the header files
  it included, and a change in any one of these files triggers a
  recompilation
- `output`: a template string (or list of template strings) defining
  how an output file name is (or multiple output names are) generated
  from a single source file name
- `capture` *(since 0.43.0)*: when this argument is set to true, Meson
  captures `stdout` of the `executable` and writes it to the target file
  specified as `output`.

The returned object also has methods that are documented in the
[object methods section](#generator-object) below.

The template strings passed to all the above keyword arguments accept
the following special substitutions:

- `@PLAINNAME@`: the complete input file name, e.g: `foo.c` becomes `foo.c` (unchanged)
- `@BASENAME@`: the base of the input filename, e.g.: `foo.c.y` becomes `foo.c` (extension is removed)

Each string passed to the `output` keyword argument *must* be
constructed using one or both of these two substitutions.

In addition to the above substitutions, the `arguments` keyword
argument also accepts the following:

- `@OUTPUT@`: the full path to the output file
- `@INPUT@`: the full path to the input file
- `@DEPFILE@`: the full path to the depfile
- `@SOURCE_DIR@`: the full path to the root of the source tree
- `@CURRENT_SOURCE_DIR@`: this is the directory where the currently processed meson.build is located in
- `@BUILD_DIR@`: the full path to the root of the build dir where the output will be placed

NOTE: Generators should only be used for outputs that will ***only***
be used as inputs for a [build target](#build_target) or a [custom
target](#custom_target). When you use the processed output of a
generator in multiple targets, the generator will be run multiple
times to create outputs for each target. Each output will be created
in a target-private directory `@BUILD_DIR@`.

If you want to generate files for general purposes such as for
generating headers to be used by several sources, or data that will be
installed, and so on, use a [`custom_target`](#custom_target) instead.

### get_option()

``` meson
    value get_option(option_name)
```

Obtains the value of the [project build option](Build-options.md)
specified in the positional argument.

Note that the value returned for built-in options that end in `dir`
such as `bindir` and `libdir` is always a path relative to (and
inside) the `prefix`.

The only exceptions are: `sysconfdir`, `localstatedir`, and
`sharedstatedir` which will return the value passed during
configuration as-is, which may be absolute, or relative to `prefix`.
[`install_dir` arguments](Installing.md) handles that as expected, but
if you need the absolute path to one of these e.g. to use in a define
etc., you should use `get_option('prefix') /
get_option('localstatedir')`

For options of type `feature` a
[feature option object](#feature-option-object)
is returned instead of a string.
See [`feature` options](Build-options.md#features)
documentation for more details.

### get_variable()

``` meson
    value get_variable(variable_name, fallback)
```

This function can be used to dynamically obtain a variable. `res =
get_variable(varname, fallback)` takes the value of `varname` (which
must be a string) and stores the variable of that name into `res`. If
the variable does not exist, the variable `fallback` is stored to
`res`instead. If a fallback is not specified, then attempting to read
a non-existing variable will cause a fatal error.

### import()

``` meson
    module_object import(module_name)
```

Imports the given extension module. Returns an opaque object that can
be used to call the methods of the module. Here's an example for a
hypothetical `testmod` module.

```meson
    tmod = import('testmod')
    tmod.do_something()
```

### include_directories()

``` meson
    include_object include_directories(directory_names, ...)
```

Returns an opaque object which contains the directories (relative to
the current directory) given in the positional arguments. The result
can then be passed to the `include_directories:` keyword argument when
building executables or libraries. You can use the returned object in
any subdirectory you want, Meson will make the paths work
automatically.

Note that this function call itself does not add the directories into
the search path, since there is no global search path. For something
like that, see [`add_project_arguments()`](#add_project_arguments).

See also `implicit_include_directories` parameter of
[executable()](#executable), which adds current source and build
directories to include path.

Each directory given is converted to two include paths: one that is
relative to the source root and one relative to the build root.

For example, with the following source tree layout in
`/home/user/project.git`:

`meson.build`:
```meson
project(...)

subdir('include')
subdir('src')

...
```

`include/meson.build`:
```meson
inc = include_directories('.')

...
```

`src/meson.build`:
```meson
sources = [...]

executable('some-tool', sources,
  include_directories : inc,
  ...)

...
```

If the build tree is `/tmp/build-tree`, the following include paths
will be added to the `executable()` call: `-I/tmp/build-tree/include
-I/home/user/project.git/include`.

This function has one keyword argument `is_system` which, if set,
flags the specified directories as system directories. This means that
they will be used with the `-isystem` compiler argument rather than
`-I` on compilers that support this flag (in practice everything
except Visual Studio).

### install_data()

``` meson
    void install_data(list_of_files, ...)
```

Installs files from the source tree that are listed as positional
arguments. The following keyword arguments are supported:

- `install_dir`: the absolute or relative path to the installation
  directory. If this is a relative path, it is assumed to be relative
  to the prefix.

  If omitted, the directory defaults to `{datadir}/{projectname}` *(since 0.45.0)*.

- `install_mode`: specify the file mode in symbolic format and
  optionally the owner/uid and group/gid for the installed files. For
  example:

  `install_mode: 'rw-r--r--'` for just the file mode

  `install_mode: ['rw-r--r--', 'nobody', 'nogroup']` for the file mode and the user/group

  `install_mode: ['rw-r-----', 0, 0]` for the file mode and uid/gid

 To leave any of these three as the default, specify `false`.

- `rename` *(since 0.46.0)*: if specified renames each source file into corresponding
  file from `rename` list. Nested paths are allowed and they are
  joined with `install_dir`. Length of `rename` list must be equal to
  the number of sources.

See [Installing](Installing.md) for more examples.

### install_headers()

``` meson
    void install_headers(list_of_headers, ...)
```

Installs the specified header files from the source tree into the
system header directory (usually `/{prefix}/include`) during the
install step. This directory can be overridden by specifying it with
the `install_dir` keyword argument. If you just want to install into a
subdirectory of the system header directory, then use the `subdir`
argument. As an example if this has the value `myproj` then the
headers would be installed to `/{prefix}/include/myproj`.

For example, this will install `common.h` and `kola.h` into
`/{prefix}/include`:

```meson
install_headers('common.h', 'proj/kola.h')
```

This will install `common.h` and `kola.h` into `/{prefix}/include/myproj`:

```meson
install_headers('common.h', 'proj/kola.h', subdir : 'myproj')
```

This will install `common.h` and `kola.h` into `/{prefix}/cust/myproj`:

```meson
install_headers('common.h', 'proj/kola.h', install_dir : 'cust', subdir : 'myproj')
```

Accepts the following keywords:

- `install_mode` *(since 0.47.0)*: can be used to specify the file mode in symbolic
  format and optionally the owner/uid and group/gid for the installed files.
  An example value could be `['rwxr-sr-x', 'root', 'root']`.

### install_man()

``` meson
    void install_man(list_of_manpages, ...)
```

Installs the specified man files from the source tree into system's
man directory during the install step. This directory can be
overridden by specifying it with the `install_dir` keyword argument.

Accepts the following keywords:

- `install_mode` *(since 0.47.0)*: can be used to specify the file mode in symbolic
  format and optionally the owner/uid and group/gid for the installed files.
  An example value could be `['rwxr-sr-x', 'root', 'root']`.

- `locale` *(since 0.58.0)*: can be used to specify the locale into which the
  man page will be installed within the manual page directory tree.
  An example manual might be `foo.fr.1` with a locale of `fr`, such
  that `{mandir}/{locale}/man{num}/foo.1` becomes the installed file.

*(since 0.49.0)* [manpages are no longer compressed
 implicitly][install_man_49].

[install_man_49]:
https://mesonbuild.com/Release-notes-for-0-49-0.html#manpages-are-no-longer-compressed-implicitly

### install_subdir()

``` meson
    void install_subdir(subdir_name,
                        install_dir : ...,
                        exclude_files : ...,
                        exclude_directories : ...,
                        strip_directory : ...)
```

Installs the entire given subdirectory and its contents from the
source tree to the location specified by the keyword argument
`install_dir`.

If the subdirectory does not exist in the source tree, an empty directory is
created in the specified location. *(since 0.45.0)* A newly created
subdirectory may only be created in the keyword argument `install_dir`.

The following keyword arguments are supported:

- `exclude_files`: a list of file names that should not be installed.
  Names are interpreted as paths relative to the `subdir_name` location.
- `exclude_directories`: a list of directory names that should not be installed.
  Names are interpreted as paths relative to the `subdir_name` location.
- `install_dir`: the location to place the installed subdirectory.
- `install_mode` *(since 0.47.0)*: the file mode in symbolic format and optionally
  the owner/uid and group/gid for the installed files.
- `strip_directory` *(since 0.45.0)*: install directory contents. `strip_directory=false` by default.
  If `strip_directory=true` only the last component of the source path is used.

For a given directory `foo`:
```text
foo/
  bar/
    file1
  file2
```
`install_subdir('foo', install_dir : 'share', strip_directory : false)` creates
```text
share/
  foo/
    bar/
      file1
    file2
```

`install_subdir('foo', install_dir : 'share', strip_directory : true)` creates
```text
share/
  bar/
    file1
  file2
```

`install_subdir('foo/bar', install_dir : 'share', strip_directory : false)` creates
```text
share/
  bar/
    file1
```

`install_subdir('foo/bar', install_dir : 'share', strip_directory : true)` creates
```text
share/
  file1
```

`install_subdir('new_directory', install_dir : 'share')` creates
```text
share/
  new_directory/
```

### is_disabler()

``` meson
    bool is_disabler(var)
```

*(since 0.52.0)*

Returns true if a variable is a disabler and false otherwise.

### is_variable()

``` meson
    bool is_variable(varname)
```

Returns true if a variable of the given name exists and false otherwise.

### jar()

```meson
   jar_object jar(name, list_of_sources, ...)
```

Build a jar from the specified Java source files. Keyword arguments
are the same as [`executable`](#executable)'s, with the addition of
`main_class` which specifies the main class to execute when running
the jar with `java -jar file.jar`.

### join_paths()

``` meson
string join_paths(string1, string2, ...)
```

*(since 0.36.0)*

Joins the given strings into a file system path segment. For example
`join_paths('foo', 'bar')` results in `foo/bar`. If any one of the
individual segments is an absolute path, all segments before it are
dropped. That means that `join_paths('foo', '/bar')` returns `/bar`.

**Warning** Don't use `join_paths()` for sources in [`library`](#library) and
[`executable`](#executable), you should use [`files`](#files) instead.

*(since 0.49.0)* Using the`/` operator on strings is equivalent to calling
`join_paths`.

```meson
# res1 and res2 will have identical values
res1 = join_paths(foo, bar)
res2 = foo / bar
```

### library()

``` meson
    buildtarget library(library_name, list_of_sources, ...)
```

Builds a library that is either static, shared or both depending on
the value of `default_library`
user [option](https://mesonbuild.com/Builtin-options.html).
You should use this instead of [`shared_library`](#shared_library),
[`static_library`](#static_library) or
[`both_libraries`](#both_libraries) most of the time. This allows you
to toggle your entire project (including subprojects) from shared to
static with only one option. This option applies to libraries being
built internal to the entire project. For external dependencies, the
default library type preferred is shared. This can be adapted on a per
library basis using the [dependency()](#dependency)) `static` keyword.

The keyword arguments for this are the same as for
[`executable`](#executable) with the following additions:

- `name_prefix`: the string that will be used as the prefix for the
  target output filename by overriding the default (only used for
  libraries). By default this is `lib` on all platforms and compilers,
  except for MSVC shared libraries where it is omitted to follow
  convention, and Cygwin shared libraries where it is `cyg`.
- `name_suffix`: the string that will be used as the suffix for the
  target output filename by overriding the default (see also:
  [executable()](#executable)). By default, for shared libraries this
  is `dylib` on macOS, `dll` on Windows, and `so` everywhere else.
  For static libraries, it is `a` everywhere. By convention MSVC
  static libraries use the `lib` suffix, but we use `a` to avoid a
  potential name clash with shared libraries which also generate
  import libraries with a `lib` suffix.
- `rust_crate_type`: specifies the crate type for Rust
  libraries. Defaults to `dylib` for shared libraries and `rlib` for
  static libraries.

`static_library`, `shared_library` and `both_libraries` also accept
these keyword arguments.

Note: You can set `name_prefix` and `name_suffix` to `[]`, or omit
them for the default behaviour for each platform.

### message()

``` meson
    void message(text)
```

This function prints its argument to stdout.

*(since 0.54.0)* Can take more than one argument that will be
separated by space.

### warning()

``` meson
    void warning(text)
```

*(since 0.44.0)*

This function prints its argument to stdout prefixed with WARNING:.

*(since 0.54.0)* Can take more than one argument that will be separated by
space.

### summary()

``` meson
    void summary(key, value)
    void summary(dictionary)
```

*(since 0.53.0)*

This function is used to summarize build configuration at the end of the build
process. This function provides a way for projects (and subprojects) to report
this information in a clear way.

The content is a series of key/value pairs grouped into sections. If
the section keyword argument is omitted, those key/value pairs are
implicitly grouped into a section with no title. key/value pairs can
optionally be grouped into a dictionary, but keep in mind that
dictionaries does not guarantee ordering. `key` must be string,
`value` can be:

- an integer, boolean or string
- *since 0.57.0* an external program or a dependency
- *since 0.58.0* a feature option
- a list of those.

`summary()` can be called multiple times as long as the same
section/key pair doesn't appear twice. All sections will be collected
and printed at the end of the configuration in the same order as they
have been called.

Keyword arguments:
- `section`: title to group a set of key/value pairs.
- `bool_yn`: if set to true, all boolean values will be replaced by green YES
  or red NO.
- `list_sep` *(since 0.54.0)*: string used to separate list values (e.g. `', '`).

Example:
```meson
project('My Project', version : '1.0')
summary({'bindir': get_option('bindir'),
         'libdir': get_option('libdir'),
         'datadir': get_option('datadir'),
        }, section: 'Directories')
summary({'Some boolean': false,
         'Another boolean': true,
         'Some string': 'Hello World',
         'A list': ['string', 1, true],
        }, section: 'Configuration')
```

Output:
```
My Project 1.0

  Directories
    prefix         : /opt/gnome
    bindir         : bin
    libdir         : lib/x86_64-linux-gnu
    datadir        : share

  Configuration
    Some boolean   : False
    Another boolean: True
    Some string    : Hello World
    A list         : string
                     1
                     True
```

### project()

``` meson
    void project(project_name, list_of_languages, ...)
```

The first argument to this function must be a string defining the name
of this project.

The project name can be any string you want, it's not used for
anything except descriptive purposes. However since it is written to
e.g. the dependency manifest is usually makes sense to have it be the
same as the project tarball or pkg-config name. So for example you
would probably want to use the name _libfoobar_ instead of _The Foobar
Library_.

It may be followed by the list of programming languages that the project uses.

*(since 0.40.0)* The list of languages is optional.

These languages may be used both for `native: false` (the default)
(host machine) targets and for `native: true` (build machine) targets.
*(since 0.56.0)* The build machine compilers for the specified
languages are not required.

Supported values for languages are `c`, `cpp` (for `C++`), `cuda`, `d`,
`objc`, `objcpp`, `fortran`, `java`, `cs` (for `C#`), `vala` and `rust`.

Project supports the following keyword arguments.

- `default_options`: takes an array of strings. The strings are in the
  form `key=value` and have the same format as options to
  `meson configure`. For example to set the default project type you would
  set this: `default_options : ['buildtype=debugoptimized']`. Note
  that these settings are only used when running Meson for the first
  time. Global options such as `buildtype` can only be specified in
  the master project, settings in subprojects are ignored. Project
  specific options are used normally even in subprojects.


- `license`: takes a string or array of strings describing the license(s) the
  code is under. To avoid ambiguity it is recommended to use a standardized
  license identifier from the [SPDX license list](https://spdx.org/licenses/).
  Usually this would be something like `license : 'GPL-2.0-or-later'`, but if
  the code has multiple licenses you can specify them as an array like this:
  `license : ['proprietary', 'GPL-3.0-only']`. Note that the text is informal
  and is only written to the dependency manifest. Meson does not do any license
  validation, you are responsible for verifying that you abide by all licensing
  terms. You can access the value in your Meson build files with
  `meson.project_license()`.

- `meson_version`: takes a string describing which Meson version the
  project requires. Usually something like `>=0.28.0`.

- `subproject_dir`: specifies the top level directory name that holds
  Meson subprojects. This is only meant as a compatibility option
  for existing code bases that house their embedded source code in a
  custom directory. All new projects should not set this but instead
  use the default value. It should be noted that this keyword
  argument is ignored inside subprojects. There can be only one
  subproject dir and it is set in the top level Meson file.

- `version`: which is a free form string describing the version of
  this project. You can access the value in your Meson build files
  with `meson.project_version()`. Since 0.57.0 this can also be a
  `File` object pointing to a file that contains exactly one line of
  text.

### run_command()

``` meson
    runresult run_command(command, list_of_args, ...)
```

Runs the command specified in positional arguments. `command` can be a
string, or the output of [`find_program()`](#find_program),
[`files()`](#files) or [`configure_file()`](#configure_file), or [a
compiler object](#compiler-object).

Returns [an opaque object](#run-result-object) containing the result
of the invocation. The command is run from an *unspecified* directory,
and Meson will set three environment variables `MESON_SOURCE_ROOT`,
`MESON_BUILD_ROOT` and `MESON_SUBDIR` that specify the source
directory, build directory and subdirectory the target was defined in,
respectively.

This function supports the following keyword arguments:

 - `check` *(since 0.47.0)*: takes a boolean. If `true`, the exit status code of the command will
   be checked, and the configuration will fail if it is non-zero. The default is
   `false`.
 - `env` *(since 0.50.0)*: environment variables to set, such as `['NAME1=value1',
   'NAME2=value2']`, or an [`environment()`
   object](#environment-object) which allows more sophisticated
   environment juggling. *(since 0.52.0)* A dictionary is also accepted.

See also [External commands](External-commands.md).

### run_target

``` meson
runtarget run_target(target_name, ...)
```

This function creates a new top-level target that runs a specified
command with the specified arguments. Like all top-level targets, this
integrates with the selected backend. For instance, you can run it as
`meson compile target_name`. Note that a run target produces no output
as far as Meson is concerned. It is only meant for tasks such as
running a code formatter or flashing an external device's firmware
with a built file.

The command is run from an *unspecified* directory, and Meson will set
three environment variables `MESON_SOURCE_ROOT`, `MESON_BUILD_ROOT`
and `MESON_SUBDIR` that specify the source directory, build directory
and subdirectory the target was defined in, respectively.

 - `command` is a list containing the command to run and the arguments
   to pass to it. Each list item may be a string or a target. For
   instance, passing the return value of [`executable()`](#executable)
   as the first item will run that executable, or passing a string as
   the first item will find that command in `PATH` and run it.
- `depends` is a list of targets that this target depends on but which
  are not listed in the command array (because, for example, the
  script does file globbing internally)
- `env` *(since 0.57.0)*: environment variables to set, such as
  `{'NAME1': 'value1', 'NAME2': 'value2'}` or `['NAME1=value1', 'NAME2=value2']`,
  or an [`environment()` object](#environment-object) which allows more
  sophisticated environment juggling.

*Since 0.57.0* The template strings passed to `command` keyword arguments accept
the following special substitutions:
- `@SOURCE_ROOT@`: the path to the root of the source tree. Depending on the backend,
  this may be an absolute or a relative to current workdir path.
- `@BUILD_ROOT@`: the path to the root of the build tree. Depending on the backend,
  this may be an absolute or a relative to current workdir path.
- `@CURRENT_SOURCE_DIR@` *Since 0.57.1*: this is the directory where the currently
  processed meson.build is located in. Depending on the backend,
  this may be an absolute or a relative to current workdir path.

### set_variable()

``` meson
    void set_variable(variable_name, value)
```

Assigns a value to the given variable name. Calling
`set_variable('foo', bar)` is equivalent to `foo = bar`.

*(since 0.46.1)* The `value` parameter can be an array type.

### shared_library()

``` meson
    buildtarget shared_library(library_name, list_of_sources, ...)
```

Builds a shared library with the given sources. Positional and keyword
arguments are the same as for [`library`](#library) with the following
extra keyword arguments.

- `soversion`: a string specifying the soversion of this shared
  library, such as `0`. On Linux and Windows this is used to set the
  soversion (or equivalent) in the filename. For example, if
  `soversion` is `4`, a Windows DLL will be called `foo-4.dll` and one
  of the aliases of the Linux shared library would be
  `libfoo.so.4`. If this is not specified, the first part of `version`
  is used instead (see below). For example, if `version` is `3.6.0` and
  `soversion` is not defined, it is set to `3`.
- `version`: a string specifying the version of this shared library,
  such as `1.1.0`. On Linux and OS X, this is used to set the shared
  library version in the filename, such as `libfoo.so.1.1.0` and
  `libfoo.1.1.0.dylib`. If this is not specified, `soversion` is used
  instead (see above).
- `darwin_versions` *(since 0.48.0)*: an integer, string, or a list of
  versions to use for setting dylib `compatibility version` and
  `current version` on macOS. If a list is specified, it must be
  either zero, one, or two elements. If only one element is specified
  or if it's not a list, the specified value will be used for setting
  both compatibility version and current version. If unspecified, the
  `soversion` will be used as per the aforementioned rules.
- `vs_module_defs`: a string, a File object, or Custom Target for a
  Microsoft module definition file for controlling symbol exports,
  etc., on platforms where that is possible (e.g. Windows).

### shared_module()

``` meson
    buildtarget shared_module(module_name, list_of_sources, ...)
```

*(since 0.37.0)*

Builds a shared module with the given sources. Positional and keyword
arguments are the same as for [`library`](#library).

This is useful for building modules that will be `dlopen()`ed and
hence may contain undefined symbols that will be provided by the
library that is loading it.

If you want the shared module to be able to refer to functions and
variables defined in the [`executable`](#executable) it is loaded by,
you will need to set the `export_dynamic` argument of the executable to
`true`.

Supports the following extra keyword arguments:

- `vs_module_defs` *(since 0.52.0)*: a string, a File object, or
  Custom Target for a Microsoft module definition file for controlling
  symbol exports, etc., on platforms where that is possible
  (e.g. Windows).

**Note:** Linking to a shared module is not supported on some
platforms, notably OSX.  Consider using a
[`shared_library`](#shared_library) instead, if you need to both
`dlopen()` and link with a library.

### static_library()

``` meson
    buildtarget static_library(library_name, list_of_sources, ...)
```

Builds a static library with the given sources. Positional and keyword
arguments are as for [`library`](#library), as well as:

 - `pic` *(since 0.36.0)*: builds the library as positional
   independent code (so it can be linked into a shared library). This
   option has no effect on Windows and OS X since it doesn't make
   sense on Windows and PIC cannot be disabled on OS X.

- `prelink` *since0.57.0*: if `true` the object files in the target
  will be prelinked, meaning that it will contain only one prelinked
  object file rather than the individual object files.

### subdir()

``` meson
    void subdir(dir_name, ...)
```

Enters the specified subdirectory and executes the `meson.build` file
in it. Once that is done, it returns and execution continues on the
line following this `subdir()` command. Variables defined in that
`meson.build` file are then available for use in later parts of the
current build file and in all subsequent build files executed with
`subdir()`.

Note that this means that each `meson.build` file in a source tree can
and must only be executed once.

This function has one keyword argument.

 - `if_found`: takes one or several dependency objects and will only
   recurse in the subdir if they all return `true` when queried with
   `.found()`

### subdir_done()

``` meson
    subdir_done()
```

Stops further interpretation of the Meson script file from the point
of the invocation. All steps executed up to this point are valid and
will be executed by Meson. This means that all targets defined before
the call of `subdir_done` will be build.

If the current script was called by `subdir` the execution returns to
the calling directory and continues as if the script had reached the
end. If the current script is the top level script Meson configures
the project as defined up to this point.

Example:
```meson
project('example exit', 'cpp')
executable('exe1', 'exe1.cpp')
subdir_done()
executable('exe2', 'exe2.cpp')
```

The executable `exe1` will be build, while the executable `exe2` is not
build.

### subproject()

``` meson
    subproject_object subproject(subproject_name, ...)
```

Takes the project specified in the positional argument and brings that
in the current build specification by returning a [subproject
object](#subproject-object). Subprojects must always be placed inside
the `subprojects` directory at the top source directory. So for
example a subproject called `foo` must be located in
`${MESON_SOURCE_ROOT}/subprojects/foo`. Supports the following keyword
arguments:

 - `default_options` *(since 0.37.0)*: an array of default option values
   that override those set in the subproject's `meson_options.txt`
   (like `default_options` in `project`, they only have effect when
   Meson is run for the first time, and command line arguments override
   any default options in build files). *(since 0.54.0)*: `default_library`
   built-in option can also be overridden.
 - `version`: works just like the same as in `dependency`.
   It specifies what version the subproject should be, as an example `>=1.0.1`
 - `required` *(since 0.48.0)*: By default, `required` is `true` and
   Meson will abort if the subproject could not be setup. You can set
   this to `false` and then use the `.found()` method on the [returned
   object](#subproject-object). You may also pass the value of a
   [`feature`](Build-options.md#features) option, same as
   [`dependency()`](#dependency).

Note that you can use the returned [subproject
object](#subproject-object) to access any variable in the
subproject. However, if you want to use a dependency object from
inside a subproject, an easier way is to use the `fallback:` keyword
argument to [`dependency()`](#dependency).

[See additional documentation](Subprojects.md).

### test()

``` meson
    void test(name, executable, ...)
```

Defines a test to run with the test harness. Takes two positional
arguments, the first is the name of the test and the second is the
executable to run. The executable can be an [executable build target
object](#build-target-object) returned by
[`executable()`](#executable) or an [external program
object](#external-program-object) returned by
[`find_program()`](#find_program).

*(since 0.55.0)* When cross compiling, if an exe_wrapper is needed and
defined the environment variable `MESON_EXE_WRAPPER` will be set to
the string value of that wrapper (implementation detail: using
`mesonlib.join_args`). Test scripts may use this to run cross built
binaries. If your test needs `MESON_EXE_WRAPPER` in cross build
situations it is your responsibility to return code 77 to tell the
harness to report "skip".

By default, environment variable
[`MALLOC_PERTURB_`](http://man7.org/linux/man-pages/man3/mallopt.3.html)
is automatically set by `meson test` to a random value between 1..255.
This can help find memory leaks on configurations using glibc,
including with non-GCC compilers. However, this can have a performance
impact, and may fail a test due to external libraries whose internals
are out of the user's control. To check if this feature is causing an
expected runtime crash, disable the feature by temporarily setting
environment variable `MALLOC_PERTURB_=0`. While it's preferable to
only temporarily disable this check, if a project requires permanent
disabling of this check in meson.build do like:

```meson
nomalloc = environment({'MALLOC_PERTURB_': '0'})

test(..., env: nomalloc, ...)
```

#### test() Keyword arguments

- `args`: arguments to pass to the executable

- `env`: environment variables to set, such as `['NAME1=value1',
  'NAME2=value2']`, or an [`environment()`
  object](#environment-object) which allows more sophisticated
  environment juggling. *(since 0.52.0)* A dictionary is also accepted.

- `is_parallel`: when false, specifies that no other test must be
  running at the same time as this test

- `should_fail`: when true the test is considered passed if the
  executable returns a non-zero return value (i.e. reports an error)

- `suite`: `'label'` (or list of labels `['label1', 'label2']`)
  attached to this test. The suite name is qualified by a (sub)project
  name resulting in `(sub)project_name:label`. In the case of a list
  of strings, the suite names will be `(sub)project_name:label1`,
  `(sub)project_name:label2`, etc.

- `timeout`: the amount of seconds the test is allowed to run, a test
  that exceeds its time limit is always considered failed, defaults to
  30 seconds. *Since 0.57* if timeout is `<= 0` the test has infinite duration,
  in previous versions of Meson the test would fail with a timeout immediately.

- `workdir`: absolute path that will be used as the working directory
  for the test

- `depends` *(since 0.46.0)*: specifies that this test depends on the specified
  target(s), even though it does not take any of them as a command
  line argument. This is meant for cases where test finds those
  targets internally, e.g. plugins or globbing. Those targets are built
  before test is executed even if they have `build_by_default : false`.

- `protocol` *(since 0.50.0)*: specifies how the test results are parsed and can
  be one of `exitcode`, `tap`, or `gtest`. For more information about test
  harness protocol read [Unit Tests](Unit-tests.md). The following values are
  accepted:
  - `exitcode`: the executable's exit code is used by the test harness
    to record the outcome of the test).
  - `tap`: [Test Anything Protocol](https://www.testanything.org/).
  - `gtest` *(since 0.55.0)*: for Google Tests.
  - `rust` *(since 0.56.0)*: for native rust tests

- `priority` *(since 0.52.0)*:specifies the priority of a test. Tests with a
  higher priority are *started* before tests with a lower priority.
  The starting order of tests with identical priorities is
  implementation-defined. The default priority is 0, negative numbers are
  permitted.

Defined tests can be run in a backend-agnostic way by calling
`meson test` inside the build dir, or by using backend-specific
commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`.

### vcs_tag()

``` meson
    customtarget vcs_tag(...)
```

This command detects revision control commit information at build time
and places it in the specified output file. This file is guaranteed to
be up to date on every build. Keywords are similar to `custom_target`.

- `command`: string list with the command to execute, see
  [`custom_target`](#custom_target) for details on how this command
  must be specified
- `fallback`: version number to use when no revision control
  information is present, such as when building from a release tarball
  (defaults to `meson.project_version()`)
- `input`: file to modify (e.g. `version.c.in`) (required)
- `output`: file to write the results to (e.g. `version.c`) (required)
- `replace_string`: string in the input file to substitute with the
  commit information (defaults to `@VCS_TAG@`)

Meson will read the contents of `input`, substitute the
`replace_string` with the detected revision number, and write the
result to `output`. This method returns a
[`custom_target`](#custom_target) object that (as usual) should be
used to signal dependencies if other targets use the file outputted
by this.

For example, if you generate a header with this and want to use that
in a build target, you must add the return value to the sources of
that build target. Without that, Meson will not know the order in
which to build the targets.

If you desire more specific behavior than what this command provides,
you should use `custom_target`.

### range()

``` meson
    rangeobject range(stop)
    rangeobject range(start, stop[, step])
```

*Since 0.58.0*

Return an opaque object that can be only be used in `foreach` statements.
- `start` must be integer greater or equal to 0. Defaults to 0.
- `stop` must be integer greater or equal to `start`.
- `step` must be integer greater or equal to 1. Defaults to 1.

It cause the `foreach` loop to be called with the value from `start` included
to `stop` excluded with an increment of `step` after each loop.

```meson
# Loop 15 times with i from 0 to 14 included.
foreach i : range(15)
   ...
endforeach
```

The range object can also be assigned to a variable and indexed.
```meson
r = range(5, 10, 2)
assert(r[2] == 9)
```

## Built-in objects

These are built-in objects that are always available.

### `meson` object

The `meson` object allows you to introspect various properties of the
system. This object is always mapped in the `meson` variable. It has
the following methods.

- `add_dist_script(script_name, arg1, arg2, ...)` *(since 0.48.0)*: causes the script
  given as argument to run during `dist` operation after the
  distribution source has been generated but before it is
  archived. Note that this runs the script file that is in the
  _staging_ directory, not the one in the source directory. If the
  script file can not be found in the staging directory, it is a hard
  error. The `MESON_DIST_ROOT` environment variables is set when dist scripts is
  run.
  *(since 0.49.0)* Accepts multiple arguments for the script.
  *(since 0.54.0)* The `MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT`
  environment variables are set when dist scripts are run. They are path to the
  root source and build directory of the main project, even when the script
  comes from a subproject.
  *(since 0.55.0)* The output of `configure_file`, `files`, and `find_program`
  as well as strings.
  *(since 0.57.0)* `file` objects and the output of `configure_file` may be
  used as the `script_name` parameter.
  *(since 0.58.0)* This command can be invoked from a subproject, it was a hard
  error in earlier versions. Subproject dist scripts will only be executed
  when running `meson dist --include-subprojects`. `MESON_PROJECT_SOURCE_ROOT`,
  `MESON_PROJECT_BUILD_ROOT` and `MESON_PROJECT_DIST_ROOT` environment
  variables are set when dist scripts are run. They are identical to
  `MESON_SOURCE_ROOT`, `MESON_BUILD_ROOT` and `MESON_DIST_ROOT` for main project
  scripts, but for subproject scripts they have the path to the root of the
  subproject appended, usually `subprojects/<subproject-name>`.

- `add_install_script(script_name, arg1, arg2, ...)`: causes the script
  given as an argument to be run during the install step, this script
  will have the environment variables `MESON_SOURCE_ROOT`,
  `MESON_BUILD_ROOT`, `MESON_INSTALL_PREFIX`,
  `MESON_INSTALL_DESTDIR_PREFIX`, and `MESONINTROSPECT` set.
  All positional arguments are passed as parameters.
  *since 0.57.0* `skip_if_destdir` boolean keyword argument (defaults to `false`)
  can be specified. If `true` the script will not be run if DESTDIR is set during
  installation. This is useful in the case the script updates system wide
  cache that is only needed when copying files into final destination.

  *(since 0.54.0)* If `meson install` is called with the `--quiet` option, the
  environment variable `MESON_INSTALL_QUIET` will be set.

  *(since 0.55.0)* The output of `configure_file`, `files`, `find_program`,
  `custom_target`, indexes of `custom_target`, `executable`, `library`, and
  other built targets as well as strings.

  *(since 0.57.0)* `file` objects and the output of `configure_file` may be
  *used as the `script_name` parameter.

  Meson uses the `DESTDIR` environment variable as set by the
  inherited environment to determine the (temporary) installation
  location for files. Your install script must be aware of this while
  manipulating and installing files. The correct way to handle this is
  with the `MESON_INSTALL_DESTDIR_PREFIX` variable which is always set
  and contains `DESTDIR` (if set) and `prefix` joined together. This
  is useful because both are usually absolute paths and there are
  platform-specific edge-cases in joining two absolute paths.

  In case it is needed, `MESON_INSTALL_PREFIX` is also always set and
  has the value of the `prefix` option passed to Meson.

  `MESONINTROSPECT` contains the path to the introspect command that
  corresponds to the `meson` executable that was used to configure the
  build. (This might be a different path than the first executable
  found in `PATH`.) It can be used to query build configuration. Note
  that the value will contain many parts, f.ex., it may be `python3
  /path/to/meson.py introspect`. The user is responsible for splitting
  the string to an array if needed by splitting lexically like a UNIX
  shell would. If your script uses Python, `shlex.split()` is the
  easiest correct way to do this.

- `add_postconf_script(script_name, arg1, arg2, ...)`: runs the
  executable given as an argument after all project files have been
  generated. This script will have the environment variables
  `MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT` set.

  *(since 0.55.0)* The output of `configure_file`, `files`, and `find_program`
  as well as strings.

  *(since 0.57.0)* `file` objects and the output of `configure_file` may be
  *used as the `script_name` parameter.

- `backend()` *(since 0.37.0)*: returns a string representing the
  current backend: `ninja`, `vs2010`, `vs2015`, `vs2017`, `vs2019`,
  or `xcode`.

- `build_root()`: returns a string with the absolute path to the build
  root directory. *(deprecated since 0.56.0)*: this function will return the
  build root of the parent project if called from a subproject, which is usually
  not what you want. Try using `current_build_dir()` or `project_build_root()`.
  In the rare cases where the root of the main project is needed,
  use `global_build_root()` that has the same behaviour but with a more explicit
  name.

- `source_root()`: returns a string with the absolute path to the
  source root directory. Note: you should use the `files()` function
  to refer to files in the root source directory instead of
  constructing paths manually with `meson.source_root()`.
  *(deprecated since 0.56.0)*: This function will return the source root of the
  parent project if called from a subproject, which is usually not what you want.
  Try using `current_source_dir()` or `project_source_root()`.
  In the rare cases where the root of the main project is needed,
  use `global_source_root()` that has the same behaviour but with a more explicit
  name.

- `project_build_root()` *(since 0.56.0)*: returns a string with the absolute path
  to the build root directory of the current (sub)project.

- `project_source_root()` *(since 0.56.0)*: returns a string with the absolute path
  to the source root directory of the current (sub)project.

- `global_build_root()` *(since 0.58.0)*: returns a string with the absolute path
  to the build root directory. This function will return the build root of the
  main project if called from a subproject, which is usually not what you want.
  It is usually preferable to use `current_build_dir()` or `project_build_root()`.

- `global_source_root()` *(since 0.58.0)*: returns a string with the absolute path
  to the source root directory. This function will return the source root of the
  main project if called from a subproject, which is usually not what you want.
  It is usually preferable to use `current_source_dir()` or `project_source_root()`.

- `current_build_dir()`: returns a string with the absolute path to the
  current build directory.

- `current_source_dir()`: returns a string to the current source
  directory. Note: **you do not need to use this function** when
  passing files from the current source directory to a function since
  that is the default. Also, you can use the `files()` function to
  refer to files in the current or any other source directory instead
  of constructing paths manually with `meson.current_source_dir()`.

- `get_compiler(language)`: returns [an object describing a
  compiler](#compiler-object), takes one positional argument which is
  the language to use. It also accepts one keyword argument, `native`
  which when set to true makes Meson return the compiler for the build
  machine (the "native" compiler) and when false it returns the host
  compiler (the "cross" compiler). If `native` is omitted, Meson
  returns the "cross" compiler if we're currently cross-compiling and
  the "native" compiler if we're not.

- `get_cross_property(propname, fallback_value)`:
  *Deprecated since 0.58.0, use `get_external_property()` instead*.
  Returns the given property from a cross file, the optional fallback_value
  is returned if not cross compiling or the given property is not found.

- `get_external_property(propname, fallback_value, native: true/false)`
  *(since 0.54.0)*: returns the given property from a native or cross file.
  The optional fallback_value is returned if the given property is not found.
  The optional `native: true` forces retrieving a variable from the
  native file, even when cross-compiling.
  If `native: false` or not specified, variable is retrieved from the
  cross-file if cross-compiling, and from the native-file when not cross-compiling.

- `has_external_property(propname, native: true/false)`
  *(since 0.58.0)*: checks whether the given property exist in a native or
  cross file. The optional `native: true` forces checking for the variable
  in the native file, even when cross-compiling.
  If `native: false` or not specified, the variable is checked for in the
  cross-file if cross-compiling, and in the native-file when not cross-compiling.

- `can_run_host_binaries()` *(since 0.55.0)*: returns true if the build machine can run
  binaries compiled for the host. This returns true unless you are
  cross compiling, need a helper to run host binaries, and don't have one.
  For example when cross compiling from Linux to Windows, one can use `wine`
  as the helper.

- `has_exe_wrapper()`: *(since 0.55.0)* **(deprecated)**. Use `can_run_host_binaries` instead.

- `install_dependency_manifest(output_name)`: installs a manifest file
  containing a list of all subprojects, their versions and license
  files to the file name given as the argument.

- `is_cross_build()`: returns `true` if the current build is a [cross
  build](Cross-compilation.md) and `false` otherwise.

- `is_subproject()`: returns `true` if the current project is being
  built as a subproject of some other project and `false` otherwise.

- `is_unity()`: returns `true` when doing a [unity
  build](Unity-builds.md) (multiple sources are combined before
  compilation to reduce build time) and `false` otherwise.

- `override_find_program(progname, program)` *(since 0.46.0)*:
  specifies that whenever `find_program` is used to find a program
  named `progname`, Meson should not look it up on the system but
  instead return `program`, which may either be the result of
  `find_program`, `configure_file` or `executable`. *(since 0.55.0)* If a version
  check is passed to `find_program` for a program that has been overridden with
  an executable, the current project version is used.

  If `program` is an `executable`, it cannot be used during configure.

- `override_dependency(name, dep_object)` *(since 0.54.0)*:
  specifies that whenever `dependency(name, ...)` is used, Meson should not
  look it up on the system but instead return `dep_object`, which may either be
  the result of `dependency()` or `declare_dependency()`. It takes optional
  `native` keyword arguments. Doing this in a subproject allows the parent
  project to retrieve the dependency without having to know the dependency
  variable name: `dependency(name, fallback : subproject_name)`.

- `project_version()`: returns the version string specified in
  `project` function call.

- `project_license()`: returns the array of licenses specified in
  `project` function call.

- `project_name()`: returns the project name specified in the `project`
  function call.

- `version()`: return a string with the version of Meson.

- `add_devenv()`: *(Since 0.58.0)* add an [`environment()`](#environment) object
  to the list of environments that will be applied when using [`meson devenv`](Commands.md#devenv)
  command line. This is useful for developpers who wish to use the project without
  installing it, it is often needed to set for example the path to plugins
  directory, etc. Alternatively, a list or dictionary can be passed as first
  argument.
  ``` meson
  devenv = environment()
  devenv.set('PLUGINS_PATH', meson.current_build_dir())
  ...
  meson.add_devenv(devenv)
  ```

### `build_machine` object

Provides information about the build machine — the machine that is
doing the actual compilation. See
[Cross-compilation](Cross-compilation.md). It has the following
methods:

- `cpu_family()`: returns the CPU family name. [This
  table](Reference-tables.md#cpu-families) contains all known CPU
  families. These are guaranteed to continue working.

- `cpu()`: returns a more specific CPU name, such as `i686`, `amd64`,
  etc.

- `system()`: returns the operating system name.  [This
  table](Reference-tables.md#operating-system-names) Lists all of
  the currently known Operating System names, these are guaranteed to
  continue working.

- `endian()`: returns `big` on big-endian systems and `little` on
  little-endian systems.

Currently, these values are populated using
[`platform.system()`](https://docs.python.org/3.4/library/platform.html#platform.system)
and
[`platform.machine()`](https://docs.python.org/3.4/library/platform.html#platform.machine). If
you think the returned values for any of these are incorrect for your
system or CPU, or if your OS is not in the linked table, please file
[a bug report](https://github.com/mesonbuild/meson/issues/new) with
details and we'll look into it.

### `host_machine` object

Provides information about the host machine — the machine on which the
compiled binary will run. See
[Cross-compilation](Cross-compilation.md).

It has the same methods as [`build_machine`](#build_machine-object).

When not cross-compiling, all the methods return the same values as
`build_machine` (because the build machine is the host machine)

Note that while cross-compiling, it simply returns the values defined
in the cross-info file.

### `target_machine` object

Provides information about the target machine — the machine on which
the compiled binary's output will run. Hence, this object should only
be used while cross-compiling a compiler. See
[Cross-compilation](Cross-compilation.md).

It has the same methods as [`build_machine`](#build_machine-object).

When all compilation is 'native', all the methods return the same
values as `build_machine` (because the build machine is the host
machine and the target machine).

Note that while cross-compiling, it simply returns the values defined
in the cross-info file. If `target_machine` values are not defined in
the cross-info file, `host_machine` values are returned instead.

### `string` object

All [strings](Syntax.md#strings) have the following methods. Strings
are immutable, all operations return their results as a new string.

- `contains(string)`: returns true if string contains the string
  specified as the argument.

- `endswith(string)`: returns true if string ends with the string
  specified as the argument.

- `format()`: formats text, see the [Syntax
  manual](Syntax.md#string-formatting) for usage info.

- `join(list_of_strings)`: the opposite of split, for example
  `'.'.join(['a', 'b', 'c']` yields `'a.b.c'`.

- `replace('old_substr', 'new_str')` *(since 0.58.0)*: replaces instances of
  `old_substr` in the string with `new_str` and returns a new string

- `split(split_character)`: splits the string at the specified
  character (or whitespace if not set) and returns the parts in an
  array.

- `startswith(string)`: returns true if string starts with the string
  specified as the argument

- `substring(start,end)` *(since 0.56.0)*: returns a substring specified from start to end.
  Both `start` and `end` arguments are optional, so, for example, `'foobar'.substring()` will return `'foobar'`.

- `strip()`: removes whitespace at the beginning and end of the string.
  *(since 0.43.0)* Optionally can take one positional string argument,
  and all characters in that string will be stripped.

- `to_int()`: returns the string converted to an integer (error if string
  is not a number).

- `to_lower()`: creates a lower case version of the string.

- `to_upper()`: creates an upper case version of the string.

- `underscorify()`: creates a string where every non-alphabetical
  non-number character is replaced with `_`.

- `version_compare(comparison_string)`: does semantic version
  comparison, if `x = '1.2.3'` then `x.version_compare('>1.0.0')`
  returns `true`.

### `Number` object

[Numbers](Syntax.md#numbers) support these methods:

- `is_even()`: returns true if the number is even
- `is_odd()`: returns true if the number is odd
- `to_string()`: returns the value of the number as a string.

### `boolean` object

A [boolean](Syntax.md#booleans) object has two simple methods:

- `to_int()`: returns either `1` or `0`.

- `to_string()`: returns the string `'true'` if the boolean is true or
  `'false'` otherwise. You can also pass it two strings as positional
  arguments to specify what to return for true/false. For instance,
  `bool.to_string('yes', 'no')` will return `yes` if the boolean is
  true and `no` if it is false.

### `array` object

The following methods are defined for all [arrays](Syntax.md#arrays):

- `contains(item)`: returns `true` if the array contains the object
  given as argument, `false` otherwise

- `get(index, fallback)`: returns the object at the given index,
  negative indices count from the back of the array, indexing out of
  bounds returns the `fallback` value *(since 0.38.0)* or, if it is
  not specified, causes a fatal error

- `length()`: the size of the array

You can also iterate over arrays with the [`foreach`
statement](Syntax.md#foreach-statements).

### `dictionary` object

*(since 0.47.0)*

The following methods are defined for all [dictionaries](Syntax.md#dictionaries):

- `has_key(key)`: returns `true` if the dictionary contains the key
  given as argument, `false` otherwise

- `get(key, fallback)`: returns the value for the key given as first
  argument if it is present in the dictionary, or the optional
  fallback value given as the second argument. If a single argument
  was given and the key was not found, causes a fatal error

- `keys()`: returns an array of keys in the dictionary

You can also iterate over dictionaries with the [`foreach`
statement](Syntax.md#foreach-statements).

*(since 0.48.0)* Dictionaries can be added (e.g. `d1 = d2 + d3` and `d1 += d2`).
Values from the second dictionary overrides values from the first.

## Returned objects

These are objects returned by the [functions listed above](#functions).

### `compiler` object

This object is returned by
[`meson.get_compiler(lang)`](#meson-object). It represents a compiler
for a given language and allows you to query its properties. It has
the following methods:

- `alignment(typename)`: returns the alignment of the type specified in
  the positional argument, you can specify external dependencies to
  use with `dependencies` keyword argument.

- `cmd_array()`: returns an array containing the command(s) for the compiler.

- `compiles(code)`: returns true if the code fragment given in the
  positional argument compiles, you can specify external dependencies
  to use with `dependencies` keyword argument, `code` can be either a
  string containing source code or a `file` object pointing to the
  source code.

- `compute_int(expr, ...')`: computes the value of the given expression
  (as an example `1 + 2`). When cross compiling this is evaluated with
  an iterative algorithm, you can specify keyword arguments `low`
  (defaults to -1024), `high` (defaults to 1024) and `guess` to
  specify max and min values for the search and the value to try
  first.

- `find_library(lib_name, ...)`: tries to find the library specified in
  the positional argument. The [result
  object](#external-library-object) can be used just like the return
  value of `dependency`. If the keyword argument `required` is false,
  Meson will proceed even if the library is not found. By default the
  library is searched for in the system library directory
  (e.g. /usr/lib). This can be overridden with the `dirs` keyword
  argument, which can be either a string or a list of strings.
  *(since 0.47.0)* The value of a [`feature`](Build-options.md#features)
  option can also be passed to the `required` keyword argument.
  *(since 0.49.0)* If the keyword argument `disabler` is `true` and the
  dependency couldn't be found, return a [disabler object](#disabler-object)
  instead of a not-found dependency. *(since 0.50.0)* The `has_headers` keyword
  argument can be a list of header files that must be found as well, using
  `has_header()` method. All keyword arguments prefixed with `header_` will be
  passed down to `has_header()` method with the prefix removed. *(since 0.51.0)*
  The `static` keyword (boolean) can be set to `true` to limit the search to
  static libraries and `false` for dynamic/shared.

- `first_supported_argument(list_of_strings)`: given a list of
  strings, returns the first argument that passes the `has_argument`
  test or an empty array if none pass.

- `first_supported_link_argument(list_of_strings)` *(since 0.46.0)*:
  given a list of strings, returns the first argument that passes the
  `has_link_argument` test or an empty array if none pass.

- `get_define(definename)`: returns the given preprocessor symbol's
  value as a string or empty string if it is not defined.
  *(since 0.47.0)* This method will concatenate string literals as
  the compiler would. E.g. `"a" "b"` will become `"ab"`.

- `get_id()`: returns a string identifying the compiler. For example,
  `gcc`, `msvc`, [and more](Reference-tables.md#compiler-ids).

- `get_argument_syntax()` *(since 0.49.0)*: returns a string identifying the type
  of arguments the compiler takes. Can be one of `gcc`, `msvc`, or an undefined
  string value. This method is useful for identifying compilers that are not
  gcc or msvc, but use the same argument syntax as one of those two compilers
  such as clang or icc, especially when they use different syntax on different
  operating systems.

- `get_linker_id()` *(since 0.53.0)*: returns a string identifying the linker.
   For example, `ld.bfd`, `link`, [and more](Reference-tables.md#linker-ids).

- `get_supported_arguments(list_of_string)` *(since 0.43.0)*: returns
  an array containing only the arguments supported by the compiler,
  as if `has_argument` were called on them individually.

- `get_supported_link_arguments(list_of_string)` *(since 0.46.0)*: returns
  an array containing only the arguments supported by the linker,
  as if `has_link_argument` were called on them individually.

- `has_argument(argument_name)`: returns true if the compiler accepts
  the specified command line argument, that is, can compile code
  without erroring out or printing a warning about an unknown flag.

- `has_link_argument(argument_name)` *(since 0.46.0)*: returns true if
  the linker accepts the specified command line argument, that is, can
  compile and link code without erroring out or printing a warning
  about an unknown flag. Link arguments will be passed to the
  compiler, so should usually have the `-Wl,` prefix. On VisualStudio
  a `/link` argument will be prepended.

- `has_function(funcname)`: returns true if the given function is
  provided by the standard library or a library passed in with the
  `args` keyword, you can specify external dependencies to use with
  `dependencies` keyword argument.

- `check_header(header_name)` *(since 0.47.0)*: returns true if the
  specified header is *usable* with the specified prefix,
  dependencies, and arguments. You can specify external dependencies
  to use with `dependencies` keyword argument and extra code to put
  above the header test with the `prefix` keyword. In order to look
  for headers in a specific directory you can use `args :
  '-I/extra/include/dir`, but this should only be used in exceptional
  cases for includes that can't be detected via pkg-config and passed
  via `dependencies`. *(since 0.50.0)* The `required` keyword argument
  can be used to abort if the header cannot be found.

- `has_header(header_name)`: returns true if the specified header
  *exists*, and is faster than `check_header()` since it only does a
  pre-processor check. You can specify external dependencies to use
  with `dependencies` keyword argument and extra code to put above the
  header test with the `prefix` keyword. In order to look for headers
  in a specific directory you can use `args : '-I/extra/include/dir`,
  but this should only be used in exceptional cases for includes that
  can't be detected via pkg-config and passed via `dependencies`.
  *(since 0.50.0)* The `required` keyword argument can be used to
  abort if the header cannot be found.

- `has_header_symbol(headername, symbolname)`: detects
  whether a particular symbol (function, variable, #define, type
  definition, etc) is declared in the specified header, you can
  specify external dependencies to use with `dependencies` keyword
  argument. *(since 0.50.0)* The `required` keyword argument can be
  used to abort if the symbol cannot be found.

- `has_member(typename, membername)`: takes two arguments, type name
  and member name and returns true if the type has the specified
  member, you can specify external dependencies to use with
  `dependencies` keyword argument.

- `has_members(typename, membername1, membername2, ...)`: takes at
  least two arguments, type name and one or more member names, returns
  true if the type has all the specified members, you can specify
  external dependencies to use with `dependencies` keyword argument.

- `has_multi_arguments(arg1, arg2, arg3, ...)` *(since 0.37.0)*: the same as
  `has_argument` but takes multiple arguments and uses them all in a
  single compiler invocation.

- `has_multi_link_arguments(arg1, arg2, arg3, ...)` *(since 0.46.0)*:
  the same as `has_link_argument` but takes multiple arguments and
  uses them all in a single compiler invocation.

- `has_type(typename)`: returns true if the specified token is a type,
  you can specify external dependencies to use with `dependencies`
  keyword argument.

- `links(code)`: returns true if the code fragment given in the
  positional argument compiles and links, you can specify external
  dependencies to use with `dependencies` keyword argument, `code` can
  be either a string containing source code or a `file` object
  pointing to the source code.

- `run(code)`: attempts to compile and execute the given code fragment,
  returns a run result object, you can specify external dependencies
  to use with `dependencies` keyword argument, `code` can be either a
  string containing source code or a `file` object pointing to the
  source code.

- `symbols_have_underscore_prefix()` *(since 0.37.0)*: returns `true`
  if the C symbol mangling is one underscore (`_`) prefixed to the symbol.

- `sizeof(typename, ...)`: returns the size of the given type
  (e.g. `'int'`) or -1 if the type is unknown, to add includes set
  them in the `prefix` keyword argument, you can specify external
  dependencies to use with `dependencies` keyword argument.

- `version()`: returns the compiler's version number as a string.

- `has_function_attribute(name)` *(since 0.48.0)*: returns `true` if the
  compiler supports the GNU style (`__attribute__(...)`) `name`. This is
  preferable to manual compile checks as it may be optimized for compilers that
  do not support such attributes.
  [This table](Reference-tables.md#gcc-__attribute__) lists all of the
  supported attributes.

- `get_supported_function_attributes(list_of_names)` *(since 0.48.0)*:
  returns an array containing any names that are supported GCC style
  attributes. Equivalent to `has_function_attribute` was called on each of them
  individually.

The following keyword arguments can be used:

- `args`: used to pass a list of compiler arguments that are
  required to find the header or symbol. For example, you might need
  to pass the include path `-Isome/path/to/header` if a header is not
  in the default include path. *(since 0.38.0)* you should use the
  `include_directories` keyword described below. You may also want to
  pass a library name `-lfoo` for `has_function` to check for a function.
  Supported by all methods except `get_id`, `version`, and `find_library`.

- `include_directories` *(since 0.38.0)*: specifies extra directories for
  header searches.

- `name`: the name to use for printing a message about the compiler
  check. Supported by the methods `compiles()`, `links()`, and
  `run()`. If this keyword argument is not passed to those methods, no
  message will be printed about the check.

- `no_builtin_args`: when set to true, the compiler arguments controlled
  by built-in configuration options are not added.

- `prefix`: adds #includes and other things that are
  required for the symbol to be declared. System definitions should be
  passed via compiler args (eg: `_GNU_SOURCE` is often required for
  some symbols to be exposed on Linux, and it should be passed via
  `args` keyword argument, see below). Supported by the methods
  `sizeof`, `has_type`, `has_function`, `has_member`, `has_members`,
  `check_header`, `has_header`, `has_header_symbol`, `get_define`

**Note:** These compiler checks do not use compiler arguments added
with `add_*_arguments()`, via `-Dlang_args` on the command-line, or
through `CFLAGS`/`LDFLAGS`, etc in the environment. Hence, you can
trust that the tests will be fully self-contained, and won't fail
because of custom flags added by other parts of the build file or by
users.

Note that if you have a single prefix with all your dependencies, you
might find it easier to append to the environment variables
`C_INCLUDE_PATH` with GCC/Clang and `INCLUDE` with MSVC to expand the
default include path, and `LIBRARY_PATH` with GCC/Clang and `LIB` with
MSVC to expand the default library search path.

However, with GCC, these variables will be ignored when
cross-compiling. In that case you need to use a specs file. See:
<http://www.mingw.org/wiki/SpecsFileHOWTO>

### `build target` object

A build target is either an [executable](#executable), [shared
library](#shared_library), [static library](#static_library), [both
shared and static library](#both_libraries) or [shared
module](#shared_module).

- `extract_all_objects()`: is same as `extract_objects` but returns all
  object files generated by this target. *(since 0.46.0)* keyword argument
  `recursive` must be set to `true` to also return objects passed to
  the `object` argument of this target. By default only objects built
  for this target are returned to maintain backward compatibility with
  previous versions.  The default will eventually be changed to `true`
  in a future version.

- `extract_objects(source1, source2, ...)`: takes as its arguments
  a number of source files as [`string`](#string-object) or
  [`files()`](#files) and returns an opaque value representing the
  object files generated for those source files. This is typically used
  to take single object files and link them to unit tests or to compile
  some source files with custom flags. To use the object file(s)
  in another build target, use the `objects:` keyword argument.

- `full_path()`: returns a full path pointing to the result target file.
  NOTE: In most cases using the object itself will do the same job as
  this and will also allow Meson to setup inter-target dependencies
  correctly. Please file a bug if that doesn't work for you.

- `private_dir_include()`: returns a opaque value that works like
  `include_directories` but points to the private directory of this
  target, usually only needed if an another target needs to access
  some generated internal headers of this target

- `name()` *(since 0.54.0)*: returns the target name.


### `configuration` data object

This object is returned by
[`configuration_data()`](#configuration_data) and encapsulates
configuration values to be used for generating configuration files. A
more in-depth description can be found in the [the configuration wiki
page](Configuration.md) It has three methods:

- `get(varname, default_value)`: returns the value of `varname`, if the
  value has not been set returns `default_value` if it is defined
  *(since 0.38.0)* and errors out if not

- `get_unquoted(varname, default_value)` *(since 0.44.0)*: returns the value
  of `varname` but without surrounding double quotes (`"`). If the value has
  not been set returns `default_value` if it is defined and errors out if not.

- `has(varname)`: returns `true` if the specified variable is set

- `keys()`*(since 0.57.0)*: returns an array of keys of
  the configuration data object.

  You can iterate over this array with the [`foreach`
  statement](Syntax.md#foreach-statements).

- `merge_from(other)` *(since 0.42.0)*: takes as argument a different
  configuration data object and copies all entries from that object to
  the current.

- `set(varname, value)`, sets a variable to a given value

- `set10(varname, boolean_value)` is the same as above but the value
  is either `true` or `false` and will be written as 1 or 0,
  respectively

- `set_quoted(varname, value)` is same as `set` but quotes the value
  in double quotes (`"`)

They all take the `description` keyword that will be written in the
result file. The replacement assumes a file with C syntax. If your
generated file is source code in some other language, you probably
don't want to add a description field because it most likely will
cause a syntax error.

### `custom target` object

This object is returned by [`custom_target`](#custom_target) and
contains a target with the following methods:

- `full_path()`: returns a full path pointing to the result target file
  NOTE: In most cases using the object itself will do the same job as
  this and will also allow Meson to setup inter-target dependencies
  correctly. Please file a bug if that doesn't work for you.
  *(since 0.54.0)* It can be also called on indexes objects:
  `custom_targets[i].full_path()`.

- `[index]`: returns an opaque object that references this target, and
  can be used as a source in other targets. When it is used as such it
  will make that target depend on this custom target, but the only
  source added will be the one that corresponds to the index of the
  custom target's output argument.

- `to_list()` *(since 0.54.0)*: returns a list of opaque objects that references
  this target, and can be used as a source in other targets. This can be used to
  iterate outputs with `foreach` loop.

### `dependency` object

This object is returned by [`dependency()`](#dependency) and contains
an external dependency with the following methods:

 - `found()`: returns whether the dependency was found.

 - `name()` *(since 0.48.0)*: returns the name of the dependency that was
   searched. Returns `internal` for dependencies created with
   `declare_dependency()`.

 - `get_pkgconfig_variable(varname)` *(since 0.36.0)*: gets the
   pkg-config variable specified, or, if invoked on a non pkg-config
   dependency, error out. *(since 0.44.0)* You can also redefine a
   variable by passing a list to the `define_variable` parameter
   that can affect the retrieved variable: `['prefix', '/'])`.
   *(since 0.45.0)* A warning is issued if the variable is not defined,
   unless a `default` parameter is specified.

   *(Deprecated since 0.56.0*) use `get_variable(pkgconfig : ...)` instead

 - `get_configtool_variable(varname)` *(since 0.44.0)*: gets the
   command line argument from the config tool (with `--` prepended), or,
   if invoked on a non config-tool dependency, error out.

   *(Deprecated since 0.56.0*) use `get_variable(configtool : ...)` instead

 - `type_name()`: returns a string describing the type of the
   dependency, the most common values are `internal` for deps created
   with `declare_dependency()` and `pkgconfig` for system dependencies
   obtained with Pkg-config.

 - `version()`: the version number as a string, for example `1.2.8`.
   `unknown` if the dependency provider doesn't support determining the
   version.

 - `include_type()`: returns whether the value set by the `include_type` kwarg

 - `as_system(value)`: returns a copy of the dependency object, which has changed
   the value of `include_type` to `value`. The `value` argument is optional and
   defaults to `'preserve'`.

 - `as_link_whole()` *Since 0.56.0* Only dependencies created with
   `declare_dependency()`, returns a copy of the dependency object with all
   link_with arguments changed to link_whole. This is useful for example for
   fallback dependency from a subproject built with `default_library=static`.
   Note that all `link_with` objects must be static libraries otherwise an error
   will be raised when trying to `link_whole` a shared library.

 - `partial_dependency(compile_args : false, link_args : false, links
   : false, includes : false, sources : false)` *(since 0.46.0)*: returns
   a new dependency object with the same name, version, found status,
   type name, and methods as the object that called it. This new
   object will only inherit other attributes from its parent as
   controlled by keyword arguments.

   If the parent has any dependencies, those will be applied to the new
   partial dependency with the same rules. So, given:

   ```meson
   dep1 = declare_dependency(compile_args : '-Werror=foo', link_with : 'libfoo')
   dep2 = declare_dependency(compile_args : '-Werror=bar', dependencies : dep1)
   dep3 = dep2.partial_dependency(compile_args : true)
   ```

   dep3 will add `['-Werror=foo', '-Werror=bar']` to the compiler args
   of any target it is added to, but libfoo will not be added to the
   link_args.

   *Note*: A bug present until 0.50.1 results in the above behavior
   not working correctly.

   The following arguments will add the following attributes:

   - compile_args: any arguments passed to the compiler
   - link_args: any arguments passed to the linker
   - links: anything passed via link_with or link_whole
   - includes: any include_directories
   - sources: any compiled or static sources the dependency has

 - `get_variable(varname, cmake : str, pkgconfig : str, configtool : str,
   internal: str, default_value : str, pkgconfig_define : [str, str])`
   *(since 0.51.0)*: a generic variable getter method, which replaces the
   get_*type*_variable methods. This allows one to get the variable
   from a dependency without knowing specifically how that dependency
   was found. If default_value is set and the value cannot be gotten
   from the object then default_value is returned, if it is not set
   then an error is raised.
   *(since 0.54.0)* added `internal` keyword.
   *(since 0.58.0)* added `varname` as first positional argument. It is used as
   default value for `cmake`, `pkgconfig`, `configtool` and `internal` keyword
   arguments. It is useful in the common case where `pkgconfig` and `internal`
   use the same variable name, in which case it's easier to write `dep.get_variable('foo')`
   instead of `dep.get_variable(pkgconfig: 'foo', internal: 'foo')`.

### `disabler` object

A disabler object is an object that behaves in much the same way as
NaN numbers do in floating point math. That is when used in any
statement (function call, logical op, etc) they will cause the
statement evaluation to immediately short circuit to return a disabler
object. A disabler object has one method:

- `found()`: always returns `false`.

### `external program` object

This object is returned by [`find_program()`](#find_program) and
contains an external (i.e. not built as part of this project) program
and has the following methods:

- `found()`: returns whether the executable was found.

- `path()`: *(since 0.55.0)* **(deprecated)** use `full_path()` instead.
  Returns a string pointing to the script or executable
  **NOTE:** You should not need to use this method. Passing the object
  itself should work in all cases. For example: `run_command(obj, arg1, arg2)`.

- `full_path()` (*since 0.55.0*): which returns a string pointing to the script or
  executable **NOTE:** You should not need to use this method. Passing the object
  itself should work in all cases. For example: `run_command(obj, arg1, arg2)`.

### `environment` object

This object is returned by [`environment()`](#environment) and stores
detailed information about how environment variables should be set
during tests. It should be passed as the `env` keyword argument to
tests and other functions. It has the following methods.

- `append(varname, value1, value2, ...)`: appends the given values to
  the old value of the environment variable, e.g.  `env.append('FOO',
  'BAR', 'BAZ', separator : ';')` produces `BOB;BAR;BAZ` if `FOO` had
  the value `BOB` and plain `BAR;BAZ` if the value was not defined. If
  the separator is not specified explicitly, the default path
  separator for the host operating system will be used, i.e. ';' for
  Windows and ':' for UNIX/POSIX systems.

- `prepend(varname, value1, value2, ...)`: same as `append`
  except that it writes to the beginning of the variable.

- `set(varname, value1, value2)`: sets the environment variable
  specified in the first argument to the values in the second argument
  joined by the separator, e.g.  `env.set('FOO', 'BAR'),` sets envvar
  `FOO` to value `BAR`. See `append()` above for how separators work.

*Since 0.58.0* `append()` and `prepend()` methods can be called multiple times
on the same `varname`. Earlier Meson versions would warn and only the last
operation took effect.

```meson
env = environment()

# MY_PATH will be '0:1:2:3'
env.set('MY_PATH', '1')
env.append('MY_PATH', '2')
env.append('MY_PATH', '3')
env.prepend('MY_PATH', '0')
```

### `external library` object

This object is returned by [`find_library()`](#find_library) and
contains an external (i.e. not built as part of this project)
library. This object has the following methods:

- `found()`: returns whether the library was found.

- `type_name()` *(since 0.48.0)*: returns a string describing
  the type of the dependency, which will be `library` in this case.

- `partial_dependency(compile_args : false, link_args : false, links
  : false, includes : false, source : false)` *(since 0.46.0)*: returns
  a new dependency object with the same name, version, found status,
  type name, and methods as the object that called it. This new
  object will only inherit other attributes from its parent as
  controlled by keyword arguments.

### Feature option object

*(since 0.47.0)*

The following methods are defined for all [`feature` options](Build-options.md#features):

- `enabled()`: returns whether the feature was set to `'enabled'`
- `disabled()`: returns whether the feature was set to `'disabled'`
- `auto()`: returns whether the feature was set to `'auto'`

### `generator` object

This object is returned by [`generator()`](#generator) and contains a
generator that is used to transform files from one type to another by
an executable (e.g. `idl` files into source code and headers).

- `process(list_of_files, ...)`: takes a list of files, causes them to
  be processed and returns an object containing the result which can
  then, for example, be passed into a build target definition. The
  keyword argument `extra_args`, if specified, will be used to replace
  an entry `@EXTRA_ARGS@` in the argument list. The keyword argument
  `preserve_path_from`, if given, specifies that the output files need
  to maintain their directory structure inside the target temporary
  directory. The most common value for this is
  `meson.current_source_dir()`. With this value when a file called
  `subdir/one.input` is processed it generates a file `<target private
  directory>/subdir/one.out` as opposed to `<target private
  directory>/one.out`.

### `subproject` object

This object is returned by [`subproject()`](#subproject) and is an
opaque object representing it.

- `found()` *(since 0.48.0)*: returns whether the subproject was
  successfully setup

- `get_variable(name, fallback)`: fetches the specified variable from
  inside the subproject. This is useful to, for instance, get a
  [declared dependency](#declare_dependency) from the
  [subproject](Subprojects.md).

  If the variable does not exist, the variable `fallback` is returned.
  If a fallback is not specified, then attempting to read a non-existing
  variable will cause a fatal error.

### `run result` object

This object encapsulates the result of trying to compile and run a
sample piece of code with [`compiler.run()`](#compiler-object) or
[`run_command()`](#run_command). It has the following methods:

- `compiled()`: if true, the compilation succeeded, if false it did not
  and the other methods return unspecified data. This is only available
  for `compiler.run()` results.
- `returncode()`: the return code of executing the compiled binary
- `stderr()`: the standard error produced when the command was run
- `stdout()`: the standard out produced when the command was run
